1 //===-- CommandHistory.cpp ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <inttypes.h> 10 11 #include "lldb/Interpreter/CommandHistory.h" 12 13 using namespace lldb; 14 using namespace lldb_private; 15 16 CommandHistory::CommandHistory() : m_mutex(), m_history() {} 17 18 CommandHistory::~CommandHistory() {} 19 20 size_t CommandHistory::GetSize() const { 21 std::lock_guard<std::recursive_mutex> guard(m_mutex); 22 return m_history.size(); 23 } 24 25 bool CommandHistory::IsEmpty() const { 26 std::lock_guard<std::recursive_mutex> guard(m_mutex); 27 return m_history.empty(); 28 } 29 30 llvm::Optional<llvm::StringRef> 31 CommandHistory::FindString(llvm::StringRef input_str) const { 32 std::lock_guard<std::recursive_mutex> guard(m_mutex); 33 if (input_str.size() < 2) 34 return llvm::None; 35 36 if (input_str[0] != g_repeat_char) 37 return llvm::None; 38 39 if (input_str[1] == g_repeat_char) { 40 if (m_history.empty()) 41 return llvm::None; 42 return llvm::StringRef(m_history.back()); 43 } 44 45 input_str = input_str.drop_front(); 46 47 size_t idx = 0; 48 if (input_str.front() == '-') { 49 if (input_str.drop_front(1).getAsInteger(0, idx)) 50 return llvm::None; 51 if (idx >= m_history.size()) 52 return llvm::None; 53 idx = m_history.size() - idx; 54 } else { 55 if (input_str.getAsInteger(0, idx)) 56 return llvm::None; 57 if (idx >= m_history.size()) 58 return llvm::None; 59 } 60 61 return llvm::StringRef(m_history[idx]); 62 } 63 64 llvm::StringRef 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]; 68 return ""; 69 } 70 71 llvm::StringRef CommandHistory::operator[](size_t idx) const { 72 return GetStringAtIndex(idx); 73 } 74 75 llvm::StringRef CommandHistory::GetRecentmostString() const { 76 std::lock_guard<std::recursive_mutex> guard(m_mutex); 77 if (m_history.empty()) 78 return ""; 79 return m_history.back(); 80 } 81 82 void CommandHistory::AppendString(llvm::StringRef 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