IOChannel.cpp revision bef1583b89e73de77c8b0897fcf42b5b1fcabe4c
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 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char* 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerel_prompt(EditLine *el) 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PromptMap::const_iterator pos = g_prompt_map.find (el); 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos == g_prompt_map.end()) 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return g_default_prompt; 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return pos->second.c_str(); 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char * 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::GetPrompt () 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PromptMap::const_iterator pos = g_prompt_map.find (m_edit_line); 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos == g_prompt_map.end()) 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return g_default_prompt; 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return pos->second.c_str(); 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerunsigned char 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ElCompletionFn (EditLine *e, int ch) 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel *io_channel; 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (el_get(e, EL_CLIENTDATA, &io_channel) == 0) 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return io_channel->HandleCompletion (e, ch); 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_ERROR; 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerunsigned char 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::HandleCompletion (EditLine *e, int ch) 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (e == m_edit_line); 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const LineInfo *line_info = el_line(m_edit_line); 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBStringList completions; 7154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton int page_size = 40; 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7363094e0bb161580564954dee512955c1c79d3476Greg Clayton int num_completions = m_driver->GetDebugger().GetCommandInterpreter().HandleCompletion (line_info->buffer, 7463094e0bb161580564954dee512955c1c79d3476Greg Clayton line_info->cursor, 7563094e0bb161580564954dee512955c1c79d3476Greg Clayton line_info->lastchar, 7663094e0bb161580564954dee512955c1c79d3476Greg Clayton 0, 7763094e0bb161580564954dee512955c1c79d3476Greg Clayton -1, 7863094e0bb161580564954dee512955c1c79d3476Greg Clayton completions); 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions == -1) 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_insertstr (m_edit_line, m_completion_key); 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REDISPLAY; 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we get a longer match display that first. 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *completion_str = completions.GetStringAtIndex(0); 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (completion_str != NULL && *completion_str != '\0') 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_insertstr (m_edit_line, completion_str); 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REDISPLAY; 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions > 1) 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *comment = "\nAvailable completions:"; 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int num_elements = num_completions + 1; 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite(comment, strlen (comment)); 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions < page_size) 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (int i = 1; i < num_elements; i++) 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 104bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton completion_str = completions.GetStringAtIndex(i); 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite("\n\t", 2); 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite(completion_str, strlen (completion_str)); 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite ("\n", 1); 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int cur_pos = 1; 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char reply; 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int got_char; 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (cur_pos < num_elements) 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int endpoint = cur_pos + page_size; 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (endpoint > num_elements) 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner endpoint = num_elements; 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (; cur_pos < endpoint; cur_pos++) 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 122bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton completion_str = completions.GetStringAtIndex(cur_pos); 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite("\n\t", 2); 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite(completion_str, strlen (completion_str)); 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cur_pos >= num_elements) 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite("\n", 1); 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OutWrite("\nMore (Y/n/a): ", strlen ("\nMore (Y/n/a): ")); 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner reply = 'n'; 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner got_char = el_getc(m_edit_line, &reply); 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (got_char == -1 || reply == 'n') 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (reply == 'a') 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner page_size = num_elements - cur_pos; 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_completions == 0) 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REFRESH_BEEP; 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return CC_REDISPLAY; 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::IOChannel 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FILE *in, 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FILE *out, 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FILE *err, 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver *driver 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) : 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBBroadcaster ("IOChannel"), 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_driver (driver), 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread (LLDB_INVALID_HOST_THREAD), 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread_should_exit (false), 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_out_file (out), 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_err_file (err), 16454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_command_queue (), 16554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_completion_key ("\t"), 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFileName(), in, out, err)), 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_history (history_init()), 16854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_history_event(), 16954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_getting_command (false) 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (m_edit_line); 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_PROMPT, el_prompt); 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_EDITOR, "emacs"); 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_HIST, history, m_history); 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Source $PWD/.editrc then $HOME/.editrc 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_source (m_edit_line, NULL); 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_set(m_edit_line, EL_ADDFN, "lldb_complete", 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "LLDB completion function", 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::ElCompletionFn); 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_set(m_edit_line, EL_BIND, m_completion_key, "lldb_complete", NULL); 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner el_set (m_edit_line, EL_CLIENTDATA, this); 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (m_history); 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_SETSIZE, 800); 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_SETUNIQUE, 1); 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Load history 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner HistorySaveLoad (false); 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::~IOChannel () 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Save history 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner HistorySaveLoad (true); 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_history != NULL) 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history_end (m_history); 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_history = NULL; 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_edit_line != NULL) 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_end (m_edit_line); 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_edit_line = NULL; 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::HistorySaveLoad (bool save) 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_history != NULL) 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char history_path[PATH_MAX]; 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFileName()); 21754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton if ((size_t)SBFileSpec::ResolvePath (history_path, history_path, sizeof(history_path)) < sizeof(history_path) - 1) 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *path_ptr = history_path; 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (save) 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_SAVE, path_ptr); 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_LOAD, path_ptr); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::LibeditGetInput (std::string &new_line) 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_edit_line != NULL) 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int line_len = 0; 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *line = ::el_gets (m_edit_line, &line_len); 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (line) 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // strip any newlines off the end of the string... 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner --line_len; 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (line_len > 0) 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::history (m_history, &m_history_event, H_ENTER, line); 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_line.assign (line, line_len); // Omit the newline 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Someone just hit ENTER, return the empty string 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_line.clear(); 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Return true to indicate success even if a string is empty 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Return false to indicate failure. This can happen when the file handle 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // is closed (EOF). 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_line.clear(); 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid * 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::IOReadThread (void *ptr) 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel *myself = static_cast<IOChannel *> (ptr); 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner myself->Run(); 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Run () 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBListener listener("IOChannel::Run"); 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string new_line; 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27463094e0bb161580564954dee512955c1c79d3476Greg Clayton SBBroadcaster interpreter_broadcaster (m_driver->GetDebugger().GetCommandInterpreter().GetBroadcaster()); 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (interpreter_broadcaster, 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandInterpreter::eBroadcastBitResetPrompt | 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandInterpreter::eBroadcastBitThreadShouldExit | 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandInterpreter::eBroadcastBitQuitCommandReceived); 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (*this, 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadShouldExit); 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (*m_driver, 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver::eBroadcastBitReadyForInput | 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver::eBroadcastBitThreadShouldExit); 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Let anyone know that the IO channel is up and listening and ready for events 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (eBroadcastBitThreadDidStart); 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool done = false; 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (!done) 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBEvent event; 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.WaitForEvent (UINT32_MAX, event); 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!event.IsValid()) 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event.GetType(); 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.GetBroadcaster().IsValid()) 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.BroadcasterMatchesPtr (m_driver)) 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & Driver::eBroadcastBitReadyForInput) 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string line; 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (CommandQueueIsEmpty()) 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (LibeditGetInput(line) == false) 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // EOF or some other file error occurred 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetCommandFromQueue (line); 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // TO BE DONE: FIGURE OUT WHICH COMMANDS SHOULD NOT BE REPEATED IF USER PRESSES PLAIN 'RETURN' 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // AND TAKE CARE OF THAT HERE. 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBEvent line_event(IOChannel::eBroadcastBitHasUserInput, 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line.c_str(), 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line.size()); 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEvent (line_event); 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event_type & Driver::eBroadcastBitThreadShouldExit) 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event.BroadcasterMatchesRef (interpreter_broadcaster)) 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (event_type) 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case SBCommandInterpreter::eBroadcastBitResetPrompt: 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *new_prompt = SBEvent::GetCStringFromEvent (event); 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (new_prompt) 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner g_prompt_map[m_edit_line] = new_prompt; 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case SBCommandInterpreter::eBroadcastBitThreadShouldExit: 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case SBCommandInterpreter::eBroadcastBitQuitCommandReceived: 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event.BroadcasterMatchesPtr (this)) 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & IOChannel::eBroadcastBitThreadShouldExit) 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (IOChannel::eBroadcastBitThreadDidExit); 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_driver = NULL; 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread = NULL; 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Start () 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_read_thread != LLDB_INVALID_HOST_THREAD) 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread = SBHostOS::ThreadCreate ("<lldb.driver.commandline_io>", IOChannel::IOReadThread, this, 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner NULL); 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return (m_read_thread != LLDB_INVALID_HOST_THREAD); 37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::Stop () 38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 3840a164a1664bce107a4049b838485863320c8292aEli Friedman if (m_read_thread == LLDB_INVALID_HOST_THREAD) 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (eBroadcastBitThreadShouldExit); 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Don't call Host::ThreadCancel since el_gets won't respond to this 39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function call -- the thread will just die and all local variables in 39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // IOChannel::Run() won't get destructed down which is bad since there is 39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a local listener holding onto broadcasters... To ensure proper shutdown, 39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // a ^D (control-D) sequence (0x04) should be written to other end of the 39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the "in" file handle that was passed into the contructor as closing the 39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // file handle doesn't seem to make el_gets() exit.... 39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return SBHostOS::ThreadJoin (m_read_thread, NULL, NULL); 39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::RefreshPrompt () 40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::el_set (m_edit_line, EL_REFRESH); 40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::OutWrite (const char *buffer, size_t len) 40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (len == 0) 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fwrite (buffer, 1, len, m_out_file); 41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ErrWrite (const char *buffer, size_t len) 41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (len == 0) 41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fwrite (buffer, 1, len, m_err_file); 41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::AddCommandToQueue (const char *command) 42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_command_queue.push (std::string(command)); 42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::GetCommandFromQueue (std::string &cmd) 42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_command_queue.empty()) 43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cmd.swap(m_command_queue.front()); 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_command_queue.pop (); 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::CommandQueueSize () const 43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_command_queue.size(); 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::ClearCommandQueue () 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (!m_command_queue.empty()) 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_command_queue.pop(); 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerIOChannel::CommandQueueIsEmpty () const 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_command_queue.empty(); 45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 455