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/Host/StringConvert.h" 13 #include "lldb/Interpreter/CommandHistory.h" 14 15 using namespace lldb; 16 using namespace lldb_private; 17 18 CommandHistory::CommandHistory() : m_mutex(), m_history() {} 19 20 CommandHistory::~CommandHistory() {} 21 22 size_t CommandHistory::GetSize() const { 23 std::lock_guard<std::recursive_mutex> guard(m_mutex); 24 return m_history.size(); 25 } 26 27 bool CommandHistory::IsEmpty() const { 28 std::lock_guard<std::recursive_mutex> guard(m_mutex); 29 return m_history.empty(); 30 } 31 32 const char *CommandHistory::FindString(const char *input_str) const { 33 std::lock_guard<std::recursive_mutex> guard(m_mutex); 34 if (!input_str) 35 return nullptr; 36 if (input_str[0] != g_repeat_char) 37 return nullptr; 38 if (input_str[1] == '-') { 39 bool success; 40 size_t idx = StringConvert::ToUInt32(input_str + 2, 0, 0, &success); 41 if (!success) 42 return nullptr; 43 if (idx > m_history.size()) 44 return nullptr; 45 idx = m_history.size() - idx; 46 return m_history[idx].c_str(); 47 48 } else if (input_str[1] == g_repeat_char) { 49 if (m_history.empty()) 50 return nullptr; 51 else 52 return m_history.back().c_str(); 53 } else { 54 bool success; 55 uint32_t idx = StringConvert::ToUInt32(input_str + 1, 0, 0, &success); 56 if (!success) 57 return nullptr; 58 if (idx >= m_history.size()) 59 return nullptr; 60 return m_history[idx].c_str(); 61 } 62 } 63 64 const char *CommandHistory::GetStringAtIndex(size_t idx) const { 65 std::lock_guard<std::recursive_mutex> guard(m_mutex); 66 if (idx < m_history.size()) 67 return m_history[idx].c_str(); 68 return nullptr; 69 } 70 71 const char *CommandHistory::operator[](size_t idx) const { 72 return GetStringAtIndex(idx); 73 } 74 75 const char *CommandHistory::GetRecentmostString() const { 76 std::lock_guard<std::recursive_mutex> guard(m_mutex); 77 if (m_history.empty()) 78 return nullptr; 79 return m_history.back().c_str(); 80 } 81 82 void CommandHistory::AppendString(const std::string &str, bool reject_if_dupe) { 83 std::lock_guard<std::recursive_mutex> guard(m_mutex); 84 if (reject_if_dupe) { 85 if (!m_history.empty()) { 86 if (str == m_history.back()) 87 return; 88 } 89 } 90 m_history.push_back(std::string(str)); 91 } 92 93 void CommandHistory::Clear() { 94 std::lock_guard<std::recursive_mutex> guard(m_mutex); 95 m_history.clear(); 96 } 97 98 void CommandHistory::Dump(Stream &stream, size_t start_idx, 99 size_t stop_idx) const { 100 std::lock_guard<std::recursive_mutex> guard(m_mutex); 101 stop_idx = std::min(stop_idx + 1, m_history.size()); 102 for (size_t counter = start_idx; counter < stop_idx; counter++) { 103 const std::string hist_item = m_history[counter]; 104 if (!hist_item.empty()) { 105 stream.Indent(); 106 stream.Printf("%4" PRIu64 ": %s\n", (uint64_t)counter, hist_item.c_str()); 107 } 108 } 109 } 110