1 //===-- CommandHistory.cpp --------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <inttypes.h> 11 12 #include "lldb/Interpreter/CommandHistory.h" 13 #include "lldb/Host/StringConvert.h" 14 15 using namespace lldb; 16 using namespace lldb_private; 17 18 CommandHistory::CommandHistory() : m_mutex(), m_history() 19 {} 20 21 CommandHistory::~CommandHistory () 22 {} 23 24 size_t 25 CommandHistory::GetSize () const 26 { 27 std::lock_guard<std::recursive_mutex> guard(m_mutex); 28 return m_history.size(); 29 } 30 31 bool 32 CommandHistory::IsEmpty () const 33 { 34 std::lock_guard<std::recursive_mutex> guard(m_mutex); 35 return m_history.empty(); 36 } 37 38 const char* 39 CommandHistory::FindString (const char* input_str) const 40 { 41 std::lock_guard<std::recursive_mutex> guard(m_mutex); 42 if (!input_str) 43 return nullptr; 44 if (input_str[0] != g_repeat_char) 45 return nullptr; 46 if (input_str[1] == '-') 47 { 48 bool success; 49 size_t idx = StringConvert::ToUInt32 (input_str+2, 0, 0, &success); 50 if (!success) 51 return nullptr; 52 if (idx > m_history.size()) 53 return nullptr; 54 idx = m_history.size() - idx; 55 return m_history[idx].c_str(); 56 57 } 58 else if (input_str[1] == g_repeat_char) 59 { 60 if (m_history.empty()) 61 return nullptr; 62 else 63 return m_history.back().c_str(); 64 } 65 else 66 { 67 bool success; 68 uint32_t idx = StringConvert::ToUInt32 (input_str+1, 0, 0, &success); 69 if (!success) 70 return nullptr; 71 if (idx >= m_history.size()) 72 return nullptr; 73 return m_history[idx].c_str(); 74 } 75 } 76 77 const char* 78 CommandHistory::GetStringAtIndex (size_t idx) const 79 { 80 std::lock_guard<std::recursive_mutex> guard(m_mutex); 81 if (idx < m_history.size()) 82 return m_history[idx].c_str(); 83 return nullptr; 84 } 85 86 const char* 87 CommandHistory::operator [] (size_t idx) const 88 { 89 return GetStringAtIndex(idx); 90 } 91 92 const char* 93 CommandHistory::GetRecentmostString () const 94 { 95 std::lock_guard<std::recursive_mutex> guard(m_mutex); 96 if (m_history.empty()) 97 return nullptr; 98 return m_history.back().c_str(); 99 } 100 101 void 102 CommandHistory::AppendString (const std::string& str, 103 bool reject_if_dupe) 104 { 105 std::lock_guard<std::recursive_mutex> guard(m_mutex); 106 if (reject_if_dupe) 107 { 108 if (!m_history.empty()) 109 { 110 if (str == m_history.back()) 111 return; 112 } 113 } 114 m_history.push_back(std::string(str)); 115 } 116 117 void 118 CommandHistory::Clear () 119 { 120 std::lock_guard<std::recursive_mutex> guard(m_mutex); 121 m_history.clear(); 122 } 123 124 void 125 CommandHistory::Dump (Stream& stream, 126 size_t start_idx, 127 size_t stop_idx) const 128 { 129 std::lock_guard<std::recursive_mutex> guard(m_mutex); 130 stop_idx = std::min(stop_idx + 1, m_history.size()); 131 for (size_t counter = start_idx; 132 counter < stop_idx; 133 counter++) 134 { 135 const std::string hist_item = m_history[counter]; 136 if (!hist_item.empty()) 137 { 138 stream.Indent(); 139 stream.Printf("%4" PRIu64 ": %s\n", (uint64_t)counter, hist_item.c_str()); 140 } 141 } 142 } 143