124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- IOChannel.cpp -------------------------------------------*- 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#include "IOChannel.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <map>
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommandInterpreter.h"
15f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBDebugger.h"
16f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBError.h"
17f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBEvent.h"
18f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBFileSpec.h"
19f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBHostOS.h"
20f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBListener.h"
21f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBStringList.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23d6e167d0fe8666347554226424bb39e36686e0d6Eli Friedman#include <string.h>
24d6e167d0fe8666347554226424bb39e36686e0d6Eli Friedman#include <limits.h>
25d6e167d0fe8666347554226424bb39e36686e0d6Eli Friedman
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertypedef std::map<EditLine *, std::string> PromptMap;
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *g_default_prompt = "(lldb) ";
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerPromptMap g_prompt_map;
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Tice// Printing the following string causes libedit to back up to the beginning of the line & blank it out.
33c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Ticeconst char undo_prompt_string[4] = { (char) 13, (char) 27, (char) 91, (char) 75};
34c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Tice
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char*
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerel_prompt(EditLine *el)
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PromptMap::const_iterator pos = g_prompt_map.find (el);
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (pos == g_prompt_map.end())
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return g_default_prompt;
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return pos->second.c_str();
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::GetPrompt ()
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PromptMap::const_iterator pos = g_prompt_map.find (m_edit_line);
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (pos == g_prompt_map.end())
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return g_default_prompt;
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return pos->second.c_str();
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
53bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Inghambool
54bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim InghamIOChannel::EditLineHasCharacters ()
55bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham{
56bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham    const LineInfo *line_info  = el_line(m_edit_line);
57bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham    if (line_info)
585d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham    {
595d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham        // Sometimes we get called after the user has submitted the line, but before editline has
605d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham        // cleared the buffer.  In that case the cursor will be pointing at the newline.  That's
615d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham        // equivalent to having no characters on the line, since it has already been submitted.
625d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham        if (*line_info->cursor == '\n')
635d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham            return false;
645d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham        else
655d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham            return line_info->cursor != line_info->buffer;
665d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham    }
67bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham    else
68bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham        return false;
69bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham}
70bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham
71bab9b647fad841cf7c301f0bd8b1da3c0e72bfa2Jim Ingham
728ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chenvoid
738ab2c22f22bd5ff09c98441f148406e0a890084eJohnny ChenIOChannel::EraseCharsBeforeCursor ()
748ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen{
758ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen    const LineInfo *line_info  = el_line(m_edit_line);
768ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen    el_deletestr(m_edit_line, line_info->cursor - line_info->buffer);
778ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen}
788ab2c22f22bd5ff09c98441f148406e0a890084eJohnny Chen
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerunsigned char
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ElCompletionFn (EditLine *e, int ch)
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    IOChannel *io_channel;
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (el_get(e, EL_CLIENTDATA, &io_channel) == 0)
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return io_channel->HandleCompletion (e, ch);
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return CC_ERROR;
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
932eaca13a907b3c2ce41602b646d073851dc696ebJim Inghamvoid
942eaca13a907b3c2ce41602b646d073851dc696ebJim InghamIOChannel::ElResize()
952eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham{
962eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    el_resize(m_edit_line);
972eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham}
982eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerunsigned char
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::HandleCompletion (EditLine *e, int ch)
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    assert (e == m_edit_line);
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const LineInfo *line_info  = el_line(m_edit_line);
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBStringList completions;
10654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    int page_size = 40;
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10863094e0bb161580564954dee512955c1c79d3476Greg Clayton    int num_completions = m_driver->GetDebugger().GetCommandInterpreter().HandleCompletion (line_info->buffer,
10963094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                                            line_info->cursor,
11063094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                                            line_info->lastchar,
11163094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                                            0,
11263094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                                            -1,
11363094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                                            completions);
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_completions == -1)
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        el_insertstr (m_edit_line, m_completion_key);
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return CC_REDISPLAY;
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
1206247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham    else if (num_completions == -2)
1216247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham    {
1226247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham        el_deletestr (m_edit_line, line_info->cursor - line_info->buffer);
1236247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham        el_insertstr (m_edit_line, completions.GetStringAtIndex(0));
1246247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham        return CC_REDISPLAY;
1256247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham    }
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // If we get a longer match display that first.
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *completion_str = completions.GetStringAtIndex(0);
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (completion_str != NULL && *completion_str != '\0')
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        el_insertstr (m_edit_line, completion_str);
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return CC_REDISPLAY;
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_completions > 1)
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const char *comment = "\nAvailable completions:";
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int num_elements = num_completions + 1;
1404a348081030cdd2af758fddc869518357d9befd3Caroline Tice        OutWrite(comment,  strlen (comment), NO_ASYNC);
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (num_completions < page_size)
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for (int i = 1; i < num_elements; i++)
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
145bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                completion_str = completions.GetStringAtIndex(i);
1464a348081030cdd2af758fddc869518357d9befd3Caroline Tice                OutWrite("\n\t", 2, NO_ASYNC);
1474a348081030cdd2af758fddc869518357d9befd3Caroline Tice                OutWrite(completion_str, strlen (completion_str), NO_ASYNC);
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
1494a348081030cdd2af758fddc869518357d9befd3Caroline Tice            OutWrite ("\n", 1, NO_ASYNC);
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            int cur_pos = 1;
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            char reply;
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            int got_char;
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            while (cur_pos < num_elements)
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                int endpoint = cur_pos + page_size;
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (endpoint > num_elements)
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    endpoint = num_elements;
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                for (; cur_pos < endpoint; cur_pos++)
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
163bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                    completion_str = completions.GetStringAtIndex(cur_pos);
1644a348081030cdd2af758fddc869518357d9befd3Caroline Tice                    OutWrite("\n\t", 2, NO_ASYNC);
1654a348081030cdd2af758fddc869518357d9befd3Caroline Tice                    OutWrite(completion_str, strlen (completion_str), NO_ASYNC);
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (cur_pos >= num_elements)
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
1704a348081030cdd2af758fddc869518357d9befd3Caroline Tice                    OutWrite("\n", 1, NO_ASYNC);
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1744a348081030cdd2af758fddc869518357d9befd3Caroline Tice                OutWrite("\nMore (Y/n/a): ", strlen ("\nMore (Y/n/a): "), NO_ASYNC);
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                reply = 'n';
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                got_char = el_getc(m_edit_line, &reply);
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (got_char == -1 || reply == 'n')
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (reply == 'a')
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    page_size = num_elements - cur_pos;
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_completions == 0)
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return CC_REFRESH_BEEP;
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return CC_REDISPLAY;
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::IOChannel
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
1944a348081030cdd2af758fddc869518357d9befd3Caroline Tice    FILE *editline_in,
1954a348081030cdd2af758fddc869518357d9befd3Caroline Tice    FILE *editline_out,
1964a348081030cdd2af758fddc869518357d9befd3Caroline Tice    FILE *out,
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FILE *err,
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Driver *driver
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) :
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBBroadcaster ("IOChannel"),
201757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    m_output_mutex (),
202757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    m_enter_elgets_time (),
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_driver (driver),
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_read_thread (LLDB_INVALID_HOST_THREAD),
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_read_thread_should_exit (false),
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_out_file (out),
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_err_file (err),
20854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    m_command_queue (),
20954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    m_completion_key ("\t"),
2104a348081030cdd2af758fddc869518357d9befd3Caroline Tice    m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), editline_in, editline_out,  editline_out)),
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_history (history_init()),
21254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    m_history_event(),
2134a348081030cdd2af758fddc869518357d9befd3Caroline Tice    m_getting_command (false),
2144a348081030cdd2af758fddc869518357d9befd3Caroline Tice    m_expecting_prompt (false),
215388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice	m_prompt_str (),
216388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice    m_refresh_request_pending (false)
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    assert (m_edit_line);
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::el_set (m_edit_line, EL_PROMPT, el_prompt);
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::el_set (m_edit_line, EL_EDITOR, "emacs");
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::el_set (m_edit_line, EL_HIST, history, m_history);
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
223882c554207e94f66ba8d652302a9d817f275dc4eCaroline Tice    el_set (m_edit_line, EL_ADDFN, "lldb_complete",
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            "LLDB completion function",
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            IOChannel::ElCompletionFn);
226882c554207e94f66ba8d652302a9d817f275dc4eCaroline Tice    el_set (m_edit_line, EL_BIND, m_completion_key, "lldb_complete", NULL);
227882c554207e94f66ba8d652302a9d817f275dc4eCaroline Tice    el_set (m_edit_line, EL_BIND, "^r", "em-inc-search-prev", NULL);  // Cycle through backwards search, entering string
228abd370a4be26a5fc288ca090e80b12c1bc14ac8bJohnny Chen    el_set (m_edit_line, EL_BIND, "^w", "ed-delete-prev-word", NULL); // Delete previous word, behave like bash does.
2292a4e9af22db482a276a109af57b23a95d0f38ddfSean Callanan    el_set (m_edit_line, EL_BIND, "\e[3~", "ed-delete-next-char", NULL); // Fix the delete key.
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    el_set (m_edit_line, EL_CLIENTDATA, this);
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2323bbbdc3c3ca4d449e9033a6e8c1686b8b6ed0769Johnny Chen    // Source $PWD/.editrc then $HOME/.editrc
2333bbbdc3c3ca4d449e9033a6e8c1686b8b6ed0769Johnny Chen    ::el_source (m_edit_line, NULL);
2343bbbdc3c3ca4d449e9033a6e8c1686b8b6ed0769Johnny Chen
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    assert (m_history);
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::history (m_history, &m_history_event, H_SETSIZE, 800);
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::history (m_history, &m_history_event, H_SETUNIQUE, 1);
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Load history
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    HistorySaveLoad (false);
240757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
241757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    // Set up mutex to make sure OutErr, OutWrite and RefreshPrompt do not interfere
242757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    // with each other when writing.
243757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
244757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    int error;
245757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    ::pthread_mutexattr_t attr;
246757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    error = ::pthread_mutexattr_init (&attr);
247757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    assert (error == 0);
248757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    error = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
249757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    assert (error == 0);
250757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    error = ::pthread_mutex_init (&m_output_mutex, &attr);
251757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    assert (error == 0);
252757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    error = ::pthread_mutexattr_destroy (&attr);
253757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    assert (error == 0);
254757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
255757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    // Initialize time that ::el_gets was last called.
256757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
257757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    m_enter_elgets_time.tv_sec = 0;
258757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    m_enter_elgets_time.tv_usec = 0;
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::~IOChannel ()
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Save history
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    HistorySaveLoad (true);
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_history != NULL)
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::history_end (m_history);
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_history = NULL;
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_edit_line != NULL)
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::el_end (m_edit_line);
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_edit_line = NULL;
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
277757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
278757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    ::pthread_mutex_destroy (&m_output_mutex);
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::HistorySaveLoad (bool save)
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_history != NULL)
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        char history_path[PATH_MAX];
2874ead2e9a5a74f465d00b0301c165fbebf4ee4ff3Johnny Chen        ::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFilename());
28854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        if ((size_t)SBFileSpec::ResolvePath (history_path, history_path, sizeof(history_path)) < sizeof(history_path) - 1)
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const char *path_ptr = history_path;
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (save)
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ::history (m_history, &m_history_event, H_SAVE, path_ptr);
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ::history (m_history, &m_history_event, H_LOAD, path_ptr);
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2994a348081030cdd2af758fddc869518357d9befd3Caroline Ticevoid
3004a348081030cdd2af758fddc869518357d9befd3Caroline TiceIOChannel::LibeditOutputBytesReceived (void *baton, const void *src, size_t src_len)
3014a348081030cdd2af758fddc869518357d9befd3Caroline Tice{
3024a348081030cdd2af758fddc869518357d9befd3Caroline Tice	// Make this a member variable.
3034a348081030cdd2af758fddc869518357d9befd3Caroline Tice    // static std::string prompt_str;
3044a348081030cdd2af758fddc869518357d9befd3Caroline Tice    IOChannel *io_channel = (IOChannel *) baton;
305388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice    IOLocker locker (io_channel->m_output_mutex);
3064a348081030cdd2af758fddc869518357d9befd3Caroline Tice    const char *bytes = (const char *) src;
3074a348081030cdd2af758fddc869518357d9befd3Caroline Tice
3084a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (io_channel->IsGettingCommand() && io_channel->m_expecting_prompt)
3094a348081030cdd2af758fddc869518357d9befd3Caroline Tice    {
3104a348081030cdd2af758fddc869518357d9befd3Caroline Tice        io_channel->m_prompt_str.append (bytes, src_len);
3114a348081030cdd2af758fddc869518357d9befd3Caroline Tice		// Log this to make sure the prompt is really what you think it is.
3124a348081030cdd2af758fddc869518357d9befd3Caroline Tice        if (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == 0)
3134a348081030cdd2af758fddc869518357d9befd3Caroline Tice        {
3144a348081030cdd2af758fddc869518357d9befd3Caroline Tice            io_channel->m_expecting_prompt = false;
315388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice            io_channel->m_refresh_request_pending = false;
3164a348081030cdd2af758fddc869518357d9befd3Caroline Tice            io_channel->OutWrite (io_channel->m_prompt_str.c_str(),
3174a348081030cdd2af758fddc869518357d9befd3Caroline Tice                                  io_channel->m_prompt_str.size(), NO_ASYNC);
3184a348081030cdd2af758fddc869518357d9befd3Caroline Tice            io_channel->m_prompt_str.clear();
3194a348081030cdd2af758fddc869518357d9befd3Caroline Tice        }
3204a348081030cdd2af758fddc869518357d9befd3Caroline Tice    }
3214a348081030cdd2af758fddc869518357d9befd3Caroline Tice    else
3224a348081030cdd2af758fddc869518357d9befd3Caroline Tice    {
3234a348081030cdd2af758fddc869518357d9befd3Caroline Tice        if (io_channel->m_prompt_str.size() > 0)
3244a348081030cdd2af758fddc869518357d9befd3Caroline Tice            io_channel->m_prompt_str.clear();
325388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice        std::string tmp_str (bytes, src_len);
326388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice        if (tmp_str.find (el_prompt (io_channel->m_edit_line)) == 0)
327388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice            io_channel->m_refresh_request_pending = false;
3284a348081030cdd2af758fddc869518357d9befd3Caroline Tice        io_channel->OutWrite (bytes, src_len, NO_ASYNC);
3294a348081030cdd2af758fddc869518357d9befd3Caroline Tice    }
3304a348081030cdd2af758fddc869518357d9befd3Caroline Tice}
3314a348081030cdd2af758fddc869518357d9befd3Caroline Tice
332e09196066b61294d30c56ca86d8443bd3078a2f5Enrico GranataIOChannel::LibeditGetInputResult
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::LibeditGetInput (std::string &new_line)
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
335e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata    IOChannel::LibeditGetInputResult retval = IOChannel::eLibeditGetInputResultUnknown;
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_edit_line != NULL)
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int line_len = 0;
339757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
340757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        // Set boolean indicating whether or not el_gets is trying to get input (i.e. whether or not to attempt
341757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        // to refresh the prompt after writing data).
342757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        SetGettingCommand (true);
3434a348081030cdd2af758fddc869518357d9befd3Caroline Tice        m_expecting_prompt = true;
344757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
345757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        // Call el_gets to prompt the user and read the user's input.
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const char *line = ::el_gets (m_edit_line, &line_len);
347757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
348757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        // Re-set the boolean indicating whether or not el_gets is trying to get input.
349757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        SetGettingCommand (false);
350757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (line)
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
353e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata            retval = IOChannel::eLibeditGetInputValid;
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // strip any newlines off the end of the string...
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            while (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r'))
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                --line_len;
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (line_len > 0)
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ::history (m_history, &m_history_event, H_ENTER, line);
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                new_line.assign (line, line_len);   // Omit the newline
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
364e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                retval = IOChannel::eLibeditGetInputEmpty;
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Someone just hit ENTER, return the empty string
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                new_line.clear();
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Return true to indicate success even if a string is empty
369e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata            return retval;
370e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        }
371e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        else
372e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata        {
373e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata            retval = (line_len == 0 ? IOChannel::eLibeditGetInputEOF : IOChannel::eLibeditGetInputResultError);
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Return false to indicate failure. This can happen when the file handle
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // is closed (EOF).
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    new_line.clear();
379e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata    return retval;
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid *
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::IOReadThread (void *ptr)
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    IOChannel *myself = static_cast<IOChannel *> (ptr);
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    myself->Run();
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Run ()
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBListener listener("IOChannel::Run");
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string new_line;
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39663094e0bb161580564954dee512955c1c79d3476Greg Clayton    SBBroadcaster interpreter_broadcaster (m_driver->GetDebugger().GetCommandInterpreter().GetBroadcaster());
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    listener.StartListeningForEvents (interpreter_broadcaster,
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                      SBCommandInterpreter::eBroadcastBitResetPrompt |
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                      SBCommandInterpreter::eBroadcastBitThreadShouldExit |
400388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                      SBCommandInterpreter::eBroadcastBitQuitCommandReceived);
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    listener.StartListeningForEvents (*this,
40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                      IOChannel::eBroadcastBitThreadShouldExit);
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    listener.StartListeningForEvents (*m_driver,
40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                      Driver::eBroadcastBitReadyForInput |
40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                      Driver::eBroadcastBitThreadShouldExit);
40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Let anyone know that the IO channel is up and listening and ready for events
41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    BroadcastEventByType (eBroadcastBitThreadDidStart);
41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool done = false;
41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (!done)
41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SBEvent event;
41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        listener.WaitForEvent (UINT32_MAX, event);
41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!event.IsValid())
41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            continue;
41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t event_type = event.GetType();
42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (event.GetBroadcaster().IsValid())
42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (event.BroadcasterMatchesPtr (m_driver))
42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (event_type & Driver::eBroadcastBitReadyForInput)
42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    std::string line;
42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (CommandQueueIsEmpty())
43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
432e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                        IOChannel::LibeditGetInputResult getline_result = LibeditGetInput(line);
433e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                        if (getline_result == IOChannel::eLibeditGetInputEOF)
434e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                        {
435e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                            // EOF occurred
436e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                            // pretend that a quit was typed so the user gets a potential
437e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                            // chance to confirm
438e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                            line.assign("quit");
439e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                        }
440e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                        else if (getline_result == IOChannel::eLibeditGetInputResultError || getline_result == IOChannel::eLibeditGetInputResultUnknown)
44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
442e09196066b61294d30c56ca86d8443bd3078a2f5Enrico Granata                            // some random error occurred, exit and don't ask because the state might be corrupt
44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            done = true;
44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            continue;
44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        GetCommandFromQueue (line);
45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // TO BE DONE: FIGURE OUT WHICH COMMANDS SHOULD NOT BE REPEATED IF USER PRESSES PLAIN 'RETURN'
45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // AND TAKE CARE OF THAT HERE.
45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    SBEvent line_event(IOChannel::eBroadcastBitHasUserInput,
45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                             line.c_str(),
45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                             line.size());
45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    BroadcastEvent (line_event);
45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else if (event_type & Driver::eBroadcastBitThreadShouldExit)
46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    done = true;
463ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen                    continue;
46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else if (event.BroadcasterMatchesRef (interpreter_broadcaster))
46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                switch (event_type)
46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case SBCommandInterpreter::eBroadcastBitResetPrompt:
47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        const char *new_prompt = SBEvent::GetCStringFromEvent (event);
47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (new_prompt)
47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            g_prompt_map[m_edit_line] = new_prompt;
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case SBCommandInterpreter::eBroadcastBitThreadShouldExit:
47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case SBCommandInterpreter::eBroadcastBitQuitCommandReceived:
48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    done = true;
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else if (event.BroadcasterMatchesPtr (this))
48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (event_type & IOChannel::eBroadcastBitThreadShouldExit)
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    done = true;
489ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen                    continue;
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    BroadcastEventByType (IOChannel::eBroadcastBitThreadDidExit);
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_driver = NULL;
496b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea    m_read_thread = 0;
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Start ()
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
50209c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton    if (IS_VALID_LLDB_HOST_THREAD(m_read_thread))
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_read_thread = SBHostOS::ThreadCreate ("<lldb.driver.commandline_io>", IOChannel::IOReadThread, this,
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                            NULL);
50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
50809c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton    return (IS_VALID_LLDB_HOST_THREAD(m_read_thread));
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Stop ()
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
51409c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton    if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    BroadcastEventByType (eBroadcastBitThreadShouldExit);
51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Don't call Host::ThreadCancel since el_gets won't respond to this
52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // function call -- the thread will just die and all local variables in
52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // IOChannel::Run() won't get destructed down which is bad since there is
52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // a local listener holding onto broadcasters... To ensure proper shutdown,
52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // a ^D (control-D) sequence (0x04) should be written to other end of the
52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // the "in" file handle that was passed into the contructor as closing the
52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // file handle doesn't seem to make el_gets() exit....
52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return SBHostOS::ThreadJoin (m_read_thread, NULL, NULL);
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::RefreshPrompt ()
53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
532757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    // If we are not in the middle of getting input from the user, there is no need to
533757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    // refresh the prompt.
534388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice    IOLocker locker (m_output_mutex);
535757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    if (! IsGettingCommand())
536757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        return;
537757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
5384a348081030cdd2af758fddc869518357d9befd3Caroline Tice	// If we haven't finished writing the prompt, there's no need to refresh it.
5394a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (m_expecting_prompt)
5404a348081030cdd2af758fddc869518357d9befd3Caroline Tice        return;
541757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
542388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice    if (m_refresh_request_pending)
543388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice        return;
544388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice
54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::el_set (m_edit_line, EL_REFRESH);
546388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice    m_refresh_request_pending = true;
54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
5504a348081030cdd2af758fddc869518357d9befd3Caroline TiceIOChannel::OutWrite (const char *buffer, size_t len, bool asynchronous)
55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
552c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata    if (len == 0 || buffer == NULL)
55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
554757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
555bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    // We're in the process of exiting -- IOChannel::Run() has already completed
556bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    // and set m_driver to NULL - it is time for us to leave now.  We might not
557bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    // print the final ^D to stdout in this case.  We need to do some re-work on
558bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    // how the I/O streams are managed at some point.
559bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    if (m_driver == NULL)
560bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    {
561bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda        return;
562bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda    }
563bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda
5644a348081030cdd2af758fddc869518357d9befd3Caroline Tice    // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output.
5654a348081030cdd2af758fddc869518357d9befd3Caroline Tice    IOLocker locker (m_output_mutex);
566b38df1e945846a5d956974ec157902a6ad748868Caroline Tice    if (m_driver->EditlineReaderIsTop() && asynchronous)
567c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Tice        ::fwrite (undo_prompt_string, 1, 4, m_out_file);
5684a348081030cdd2af758fddc869518357d9befd3Caroline Tice    ::fwrite (buffer, 1, len, m_out_file);
5694a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (asynchronous)
5704a348081030cdd2af758fddc869518357d9befd3Caroline Tice        m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten);
57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
5744a348081030cdd2af758fddc869518357d9befd3Caroline TiceIOChannel::ErrWrite (const char *buffer, size_t len, bool asynchronous)
57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
576c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata    if (len == 0 || buffer == NULL)
57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
578757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
5794a348081030cdd2af758fddc869518357d9befd3Caroline Tice    // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output.
5804a348081030cdd2af758fddc869518357d9befd3Caroline Tice    IOLocker locker (m_output_mutex);
5814a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (asynchronous)
582c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Tice        ::fwrite (undo_prompt_string, 1, 4, m_err_file);
5834a348081030cdd2af758fddc869518357d9befd3Caroline Tice    ::fwrite (buffer, 1, len, m_err_file);
5844a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (asynchronous)
5854a348081030cdd2af758fddc869518357d9befd3Caroline Tice        m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten);
58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
58724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
58824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
58924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::AddCommandToQueue (const char *command)
59024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
59124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_command_queue.push (std::string(command));
59224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
59324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
59424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
59524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::GetCommandFromQueue (std::string &cmd)
59624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
59724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_command_queue.empty())
59824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
59924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    cmd.swap(m_command_queue.front());
60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_command_queue.pop ();
60124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
60224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
60324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
60424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint
60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::CommandQueueSize () const
60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
60724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_command_queue.size();
60824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
60924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
61124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ClearCommandQueue ()
61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (!m_command_queue.empty())
61424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_command_queue.pop();
61524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
61624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
61724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
61824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::CommandQueueIsEmpty () const
61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
62024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_command_queue.empty();
62124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
622757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
623757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticebool
624757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOChannel::IsGettingCommand () const
625757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{
626757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    return m_getting_command;
627757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice}
628757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
629757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticevoid
630757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOChannel::SetGettingCommand (bool new_value)
631757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{
632757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    m_getting_command = new_value;
633757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice}
634757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
635757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOLocker::IOLocker (pthread_mutex_t &mutex) :
636757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    m_mutex_ptr (&mutex)
637757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{
638757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    if (m_mutex_ptr)
639757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        ::pthread_mutex_lock (m_mutex_ptr);
640757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
641757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice}
642757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice
643757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOLocker::~IOLocker ()
644757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{
645757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    if (m_mutex_ptr)
646757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        ::pthread_mutex_unlock (m_mutex_ptr);
647757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice}
648