IOChannel.cpp revision bedc667c905c55de911d8b9195039d82e6cf0121
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 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerunsigned char 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ElCompletionFn (EditLine *e, int ch) 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel *io_channel; 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (el_get(e, EL_CLIENTDATA, &io_channel) == 0) 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return io_channel->HandleCompletion (e, ch); 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_ERROR; 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerunsigned char 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::HandleCompletion (EditLine *e, int ch) 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (e == m_edit_line); 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const LineInfo *line_info = el_line(m_edit_line); 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBStringList completions; 7454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton int page_size = 40; 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7663094e0bb161580564954dee512955c1c79d3476Greg Clayton int num_completions = m_driver->GetDebugger().GetCommandInterpreter().HandleCompletion (line_info->buffer, 7763094e0bb161580564954dee512955c1c79d3476Greg Clayton line_info->cursor, 7863094e0bb161580564954dee512955c1c79d3476Greg Clayton line_info->lastchar, 7963094e0bb161580564954dee512955c1c79d3476Greg Clayton 0, 8063094e0bb161580564954dee512955c1c79d3476Greg Clayton -1, 8163094e0bb161580564954dee512955c1c79d3476Greg Clayton completions); 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions == -1) 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_insertstr (m_edit_line, m_completion_key); 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REDISPLAY; 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 886247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham else if (num_completions == -2) 896247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham { 906247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham el_deletestr (m_edit_line, line_info->cursor - line_info->buffer); 916247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham el_insertstr (m_edit_line, completions.GetStringAtIndex(0)); 926247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham return CC_REDISPLAY; 936247dbee41ec51e9a082df7e86269c0f47f28160Jim Ingham } 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we get a longer match display that first. 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *completion_str = completions.GetStringAtIndex(0); 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (completion_str != NULL && *completion_str != '\0') 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_insertstr (m_edit_line, completion_str); 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REDISPLAY; 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions > 1) 10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *comment = "\nAvailable completions:"; 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int num_elements = num_completions + 1; 1084a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite(comment, strlen (comment), NO_ASYNC); 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions < page_size) 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (int i = 1; i < num_elements; i++) 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 113bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton completion_str = completions.GetStringAtIndex(i); 1144a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite("\n\t", 2, NO_ASYNC); 1154a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite(completion_str, strlen (completion_str), NO_ASYNC); 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 1174a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite ("\n", 1, NO_ASYNC); 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int cur_pos = 1; 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char reply; 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int got_char; 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (cur_pos < num_elements) 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int endpoint = cur_pos + page_size; 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (endpoint > num_elements) 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner endpoint = num_elements; 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (; cur_pos < endpoint; cur_pos++) 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 131bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton completion_str = completions.GetStringAtIndex(cur_pos); 1324a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite("\n\t", 2, NO_ASYNC); 1334a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite(completion_str, strlen (completion_str), NO_ASYNC); 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cur_pos >= num_elements) 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1384a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite("\n", 1, NO_ASYNC); 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1424a348081030cdd2af758fddc869518357d9befd3Caroline Tice OutWrite("\nMore (Y/n/a): ", strlen ("\nMore (Y/n/a): "), NO_ASYNC); 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner reply = 'n'; 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner got_char = el_getc(m_edit_line, &reply); 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (got_char == -1 || reply == 'n') 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (reply == 'a') 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner page_size = num_elements - cur_pos; 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions == 0) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REFRESH_BEEP; 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REDISPLAY; 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::IOChannel 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 1624a348081030cdd2af758fddc869518357d9befd3Caroline Tice FILE *editline_in, 1634a348081030cdd2af758fddc869518357d9befd3Caroline Tice FILE *editline_out, 1644a348081030cdd2af758fddc869518357d9befd3Caroline Tice FILE *out, 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FILE *err, 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver *driver 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) : 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBBroadcaster ("IOChannel"), 169757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_output_mutex (), 170757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_enter_elgets_time (), 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_driver (driver), 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread (LLDB_INVALID_HOST_THREAD), 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread_should_exit (false), 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_out_file (out), 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_err_file (err), 17654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_command_queue (), 17754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_completion_key ("\t"), 1784a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), editline_in, editline_out, editline_out)), 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_history (history_init()), 18054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_history_event(), 1814a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_getting_command (false), 1824a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_expecting_prompt (false), 183388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice m_prompt_str (), 184388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice m_refresh_request_pending (false) 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (m_edit_line); 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_PROMPT, el_prompt); 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_EDITOR, "emacs"); 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_HIST, history, m_history); 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Source $PWD/.editrc then $HOME/.editrc 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_source (m_edit_line, NULL); 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 194882c554207e94f66ba8d652302a9d817f275dc4eCaroline Tice el_set (m_edit_line, EL_ADDFN, "lldb_complete", 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LLDB completion function", 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::ElCompletionFn); 197882c554207e94f66ba8d652302a9d817f275dc4eCaroline Tice el_set (m_edit_line, EL_BIND, m_completion_key, "lldb_complete", NULL); 198882c554207e94f66ba8d652302a9d817f275dc4eCaroline Tice el_set (m_edit_line, EL_BIND, "^r", "em-inc-search-prev", NULL); // Cycle through backwards search, entering string 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_set (m_edit_line, EL_CLIENTDATA, this); 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (m_history); 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_SETSIZE, 800); 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_SETUNIQUE, 1); 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Load history 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner HistorySaveLoad (false); 206757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 207757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // Set up mutex to make sure OutErr, OutWrite and RefreshPrompt do not interfere 208757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // with each other when writing. 209757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 210757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice int error; 211757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice ::pthread_mutexattr_t attr; 212757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice error = ::pthread_mutexattr_init (&attr); 213757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice assert (error == 0); 214757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice error = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 215757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice assert (error == 0); 216757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice error = ::pthread_mutex_init (&m_output_mutex, &attr); 217757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice assert (error == 0); 218757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice error = ::pthread_mutexattr_destroy (&attr); 219757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice assert (error == 0); 220757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 221757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // Initialize time that ::el_gets was last called. 222757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 223757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_enter_elgets_time.tv_sec = 0; 224757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_enter_elgets_time.tv_usec = 0; 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::~IOChannel () 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Save history 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner HistorySaveLoad (true); 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_history != NULL) 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history_end (m_history); 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_history = NULL; 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_edit_line != NULL) 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_end (m_edit_line); 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_edit_line = NULL; 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 243757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 244757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice ::pthread_mutex_destroy (&m_output_mutex); 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::HistorySaveLoad (bool save) 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_history != NULL) 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char history_path[PATH_MAX]; 2534ead2e9a5a74f465d00b0301c165fbebf4ee4ff3Johnny Chen ::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFilename()); 25454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton if ((size_t)SBFileSpec::ResolvePath (history_path, history_path, sizeof(history_path)) < sizeof(history_path) - 1) 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *path_ptr = history_path; 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (save) 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_SAVE, path_ptr); 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_LOAD, path_ptr); 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2654a348081030cdd2af758fddc869518357d9befd3Caroline Ticevoid 2664a348081030cdd2af758fddc869518357d9befd3Caroline TiceIOChannel::LibeditOutputBytesReceived (void *baton, const void *src, size_t src_len) 2674a348081030cdd2af758fddc869518357d9befd3Caroline Tice{ 2684a348081030cdd2af758fddc869518357d9befd3Caroline Tice // Make this a member variable. 2694a348081030cdd2af758fddc869518357d9befd3Caroline Tice // static std::string prompt_str; 2704a348081030cdd2af758fddc869518357d9befd3Caroline Tice IOChannel *io_channel = (IOChannel *) baton; 271388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice IOLocker locker (io_channel->m_output_mutex); 2724a348081030cdd2af758fddc869518357d9befd3Caroline Tice const char *bytes = (const char *) src; 2734a348081030cdd2af758fddc869518357d9befd3Caroline Tice 2744a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (io_channel->IsGettingCommand() && io_channel->m_expecting_prompt) 2754a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 2764a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->m_prompt_str.append (bytes, src_len); 2774a348081030cdd2af758fddc869518357d9befd3Caroline Tice // Log this to make sure the prompt is really what you think it is. 2784a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == 0) 2794a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 2804a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->m_expecting_prompt = false; 281388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice io_channel->m_refresh_request_pending = false; 2824a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->OutWrite (io_channel->m_prompt_str.c_str(), 2834a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->m_prompt_str.size(), NO_ASYNC); 2844a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->m_prompt_str.clear(); 2854a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 2864a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 2874a348081030cdd2af758fddc869518357d9befd3Caroline Tice else 2884a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 2894a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (io_channel->m_prompt_str.size() > 0) 2904a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->m_prompt_str.clear(); 291388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice std::string tmp_str (bytes, src_len); 292388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice if (tmp_str.find (el_prompt (io_channel->m_edit_line)) == 0) 293388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice io_channel->m_refresh_request_pending = false; 2944a348081030cdd2af758fddc869518357d9befd3Caroline Tice io_channel->OutWrite (bytes, src_len, NO_ASYNC); 2954a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 2964a348081030cdd2af758fddc869518357d9befd3Caroline Tice} 2974a348081030cdd2af758fddc869518357d9befd3Caroline Tice 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::LibeditGetInput (std::string &new_line) 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_edit_line != NULL) 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int line_len = 0; 304757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 305757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // Set boolean indicating whether or not el_gets is trying to get input (i.e. whether or not to attempt 306757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // to refresh the prompt after writing data). 307757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice SetGettingCommand (true); 3084a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_expecting_prompt = true; 309757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 310757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // Call el_gets to prompt the user and read the user's input. 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *line = ::el_gets (m_edit_line, &line_len); 312757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 313757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // Re-set the boolean indicating whether or not el_gets is trying to get input. 314757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice SetGettingCommand (false); 315757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (line) 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // strip any newlines off the end of the string... 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner --line_len; 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (line_len > 0) 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_ENTER, line); 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_line.assign (line, line_len); // Omit the newline 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Someone just hit ENTER, return the empty string 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_line.clear(); 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Return true to indicate success even if a string is empty 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Return false to indicate failure. This can happen when the file handle 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // is closed (EOF). 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_line.clear(); 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid * 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::IOReadThread (void *ptr) 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel *myself = static_cast<IOChannel *> (ptr); 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner myself->Run(); 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Run () 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBListener listener("IOChannel::Run"); 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string new_line; 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35563094e0bb161580564954dee512955c1c79d3476Greg Clayton SBBroadcaster interpreter_broadcaster (m_driver->GetDebugger().GetCommandInterpreter().GetBroadcaster()); 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (interpreter_broadcaster, 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandInterpreter::eBroadcastBitResetPrompt | 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandInterpreter::eBroadcastBitThreadShouldExit | 359388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice SBCommandInterpreter::eBroadcastBitQuitCommandReceived); 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (*this, 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadShouldExit); 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (*m_driver, 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver::eBroadcastBitReadyForInput | 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver::eBroadcastBitThreadShouldExit); 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Let anyone know that the IO channel is up and listening and ready for events 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (eBroadcastBitThreadDidStart); 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool done = false; 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (!done) 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBEvent event; 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.WaitForEvent (UINT32_MAX, event); 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!event.IsValid()) 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event.GetType(); 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.GetBroadcaster().IsValid()) 38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.BroadcasterMatchesPtr (m_driver)) 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & Driver::eBroadcastBitReadyForInput) 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string line; 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (CommandQueueIsEmpty()) 39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (LibeditGetInput(line) == false) 39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // EOF or some other file error occurred 39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetCommandFromQueue (line); 40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // TO BE DONE: FIGURE OUT WHICH COMMANDS SHOULD NOT BE REPEATED IF USER PRESSES PLAIN 'RETURN' 40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // AND TAKE CARE OF THAT HERE. 40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBEvent line_event(IOChannel::eBroadcastBitHasUserInput, 40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line.c_str(), 40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line.size()); 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEvent (line_event); 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event_type & Driver::eBroadcastBitThreadShouldExit) 41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 414ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen continue; 41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event.BroadcasterMatchesRef (interpreter_broadcaster)) 41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (event_type) 42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case SBCommandInterpreter::eBroadcastBitResetPrompt: 42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *new_prompt = SBEvent::GetCStringFromEvent (event); 42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (new_prompt) 42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner g_prompt_map[m_edit_line] = new_prompt; 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case SBCommandInterpreter::eBroadcastBitThreadShouldExit: 43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case SBCommandInterpreter::eBroadcastBitQuitCommandReceived: 43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event.BroadcasterMatchesPtr (this)) 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & IOChannel::eBroadcastBitThreadShouldExit) 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 440ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen continue; 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (IOChannel::eBroadcastBitThreadDidExit); 44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_driver = NULL; 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread = NULL; 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Start () 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 45309c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread = SBHostOS::ThreadCreate ("<lldb.driver.commandline_io>", IOChannel::IOReadThread, this, 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner NULL); 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45909c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton return (IS_VALID_LLDB_HOST_THREAD(m_read_thread)); 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Stop () 46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 46509c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (eBroadcastBitThreadShouldExit); 46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Don't call Host::ThreadCancel since el_gets won't respond to this 47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function call -- the thread will just die and all local variables in 47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // IOChannel::Run() won't get destructed down which is bad since there is 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a local listener holding onto broadcasters... To ensure proper shutdown, 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a ^D (control-D) sequence (0x04) should be written to other end of the 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the "in" file handle that was passed into the contructor as closing the 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // file handle doesn't seem to make el_gets() exit.... 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return SBHostOS::ThreadJoin (m_read_thread, NULL, NULL); 47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::RefreshPrompt () 48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 483757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // If we are not in the middle of getting input from the user, there is no need to 484757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice // refresh the prompt. 485388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice IOLocker locker (m_output_mutex); 486757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice if (! IsGettingCommand()) 487757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice return; 488757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 4894a348081030cdd2af758fddc869518357d9befd3Caroline Tice // If we haven't finished writing the prompt, there's no need to refresh it. 4904a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (m_expecting_prompt) 4914a348081030cdd2af758fddc869518357d9befd3Caroline Tice return; 492757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 493388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice if (m_refresh_request_pending) 494388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice return; 495388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_REFRESH); 497388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice m_refresh_request_pending = true; 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 5014a348081030cdd2af758fddc869518357d9befd3Caroline TiceIOChannel::OutWrite (const char *buffer, size_t len, bool asynchronous) 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (len == 0) 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 505757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 506bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda // We're in the process of exiting -- IOChannel::Run() has already completed 507bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda // and set m_driver to NULL - it is time for us to leave now. We might not 508bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda // print the final ^D to stdout in this case. We need to do some re-work on 509bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda // how the I/O streams are managed at some point. 510bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda if (m_driver == NULL) 511bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda { 512bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda return; 513bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda } 514bedc667c905c55de911d8b9195039d82e6cf0121Jason Molenda 5154a348081030cdd2af758fddc869518357d9befd3Caroline Tice // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output. 5164a348081030cdd2af758fddc869518357d9befd3Caroline Tice IOLocker locker (m_output_mutex); 517b38df1e945846a5d956974ec157902a6ad748868Caroline Tice if (m_driver->EditlineReaderIsTop() && asynchronous) 518c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Tice ::fwrite (undo_prompt_string, 1, 4, m_out_file); 5194a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::fwrite (buffer, 1, len, m_out_file); 5204a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (asynchronous) 5214a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten); 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 5254a348081030cdd2af758fddc869518357d9befd3Caroline TiceIOChannel::ErrWrite (const char *buffer, size_t len, bool asynchronous) 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (len == 0) 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 529757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 5304a348081030cdd2af758fddc869518357d9befd3Caroline Tice // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output. 5314a348081030cdd2af758fddc869518357d9befd3Caroline Tice IOLocker locker (m_output_mutex); 5324a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (asynchronous) 533c5f0b99c2c2e40dca22cf11208da70ae979a37e8Caroline Tice ::fwrite (undo_prompt_string, 1, 4, m_err_file); 5344a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::fwrite (buffer, 1, len, m_err_file); 5354a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (asynchronous) 5364a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten); 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::AddCommandToQueue (const char *command) 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_command_queue.push (std::string(command)); 54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 54424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::GetCommandFromQueue (std::string &cmd) 54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_command_queue.empty()) 54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cmd.swap(m_command_queue.front()); 55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_command_queue.pop (); 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint 55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::CommandQueueSize () const 55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 55824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_command_queue.size(); 55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ClearCommandQueue () 56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 56424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (!m_command_queue.empty()) 56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_command_queue.pop(); 56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 56924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::CommandQueueIsEmpty () const 57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_command_queue.empty(); 57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 573757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 574757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticebool 575757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOChannel::IsGettingCommand () const 576757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{ 577757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice return m_getting_command; 578757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice} 579757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 580757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticevoid 581757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOChannel::SetGettingCommand (bool new_value) 582757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{ 583757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_getting_command = new_value; 584757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice} 585757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 586757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOLocker::IOLocker (pthread_mutex_t &mutex) : 587757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_mutex_ptr (&mutex) 588757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{ 589757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice if (m_mutex_ptr) 590757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice ::pthread_mutex_lock (m_mutex_ptr); 591757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 592757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice} 593757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice 594757500e29b7856823f2f4aedd30f206ec009147eCaroline TiceIOLocker::~IOLocker () 595757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice{ 596757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice if (m_mutex_ptr) 597757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice ::pthread_mutex_unlock (m_mutex_ptr); 598757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice} 599