1dda28197Spatrick //===-- CommandHistory.cpp ------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9be691f3bSpatrick #include <cinttypes>
10*f6aab3d8Srobert #include <optional>
11061da546Spatrick 
12061da546Spatrick #include "lldb/Interpreter/CommandHistory.h"
13061da546Spatrick 
14061da546Spatrick using namespace lldb;
15061da546Spatrick using namespace lldb_private;
16061da546Spatrick 
GetSize() const17061da546Spatrick size_t CommandHistory::GetSize() const {
18061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
19061da546Spatrick   return m_history.size();
20061da546Spatrick }
21061da546Spatrick 
IsEmpty() const22061da546Spatrick bool CommandHistory::IsEmpty() const {
23061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
24061da546Spatrick   return m_history.empty();
25061da546Spatrick }
26061da546Spatrick 
27*f6aab3d8Srobert std::optional<llvm::StringRef>
FindString(llvm::StringRef input_str) const28061da546Spatrick CommandHistory::FindString(llvm::StringRef input_str) const {
29061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
30061da546Spatrick   if (input_str.size() < 2)
31*f6aab3d8Srobert     return std::nullopt;
32061da546Spatrick 
33061da546Spatrick   if (input_str[0] != g_repeat_char)
34*f6aab3d8Srobert     return std::nullopt;
35061da546Spatrick 
36061da546Spatrick   if (input_str[1] == g_repeat_char) {
37061da546Spatrick     if (m_history.empty())
38*f6aab3d8Srobert       return std::nullopt;
39061da546Spatrick     return llvm::StringRef(m_history.back());
40061da546Spatrick   }
41061da546Spatrick 
42061da546Spatrick   input_str = input_str.drop_front();
43061da546Spatrick 
44061da546Spatrick   size_t idx = 0;
45061da546Spatrick   if (input_str.front() == '-') {
46061da546Spatrick     if (input_str.drop_front(1).getAsInteger(0, idx))
47*f6aab3d8Srobert       return std::nullopt;
48061da546Spatrick     if (idx >= m_history.size())
49*f6aab3d8Srobert       return std::nullopt;
50061da546Spatrick     idx = m_history.size() - idx;
51061da546Spatrick   } else {
52061da546Spatrick     if (input_str.getAsInteger(0, idx))
53*f6aab3d8Srobert       return std::nullopt;
54061da546Spatrick     if (idx >= m_history.size())
55*f6aab3d8Srobert       return std::nullopt;
56061da546Spatrick   }
57061da546Spatrick 
58061da546Spatrick   return llvm::StringRef(m_history[idx]);
59061da546Spatrick }
60061da546Spatrick 
GetStringAtIndex(size_t idx) const61061da546Spatrick llvm::StringRef CommandHistory::GetStringAtIndex(size_t idx) const {
62061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
63061da546Spatrick   if (idx < m_history.size())
64061da546Spatrick     return m_history[idx];
65061da546Spatrick   return "";
66061da546Spatrick }
67061da546Spatrick 
operator [](size_t idx) const68061da546Spatrick llvm::StringRef CommandHistory::operator[](size_t idx) const {
69061da546Spatrick   return GetStringAtIndex(idx);
70061da546Spatrick }
71061da546Spatrick 
GetRecentmostString() const72061da546Spatrick llvm::StringRef CommandHistory::GetRecentmostString() const {
73061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
74061da546Spatrick   if (m_history.empty())
75061da546Spatrick     return "";
76061da546Spatrick   return m_history.back();
77061da546Spatrick }
78061da546Spatrick 
AppendString(llvm::StringRef str,bool reject_if_dupe)79061da546Spatrick void CommandHistory::AppendString(llvm::StringRef str, bool reject_if_dupe) {
80061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
81061da546Spatrick   if (reject_if_dupe) {
82061da546Spatrick     if (!m_history.empty()) {
83061da546Spatrick       if (str == m_history.back())
84061da546Spatrick         return;
85061da546Spatrick     }
86061da546Spatrick   }
87dda28197Spatrick   m_history.push_back(std::string(str));
88061da546Spatrick }
89061da546Spatrick 
Clear()90061da546Spatrick void CommandHistory::Clear() {
91061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
92061da546Spatrick   m_history.clear();
93061da546Spatrick }
94061da546Spatrick 
Dump(Stream & stream,size_t start_idx,size_t stop_idx) const95061da546Spatrick void CommandHistory::Dump(Stream &stream, size_t start_idx,
96061da546Spatrick                           size_t stop_idx) const {
97061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_mutex);
98061da546Spatrick   stop_idx = std::min(stop_idx + 1, m_history.size());
99061da546Spatrick   for (size_t counter = start_idx; counter < stop_idx; counter++) {
100061da546Spatrick     const std::string hist_item = m_history[counter];
101061da546Spatrick     if (!hist_item.empty()) {
102061da546Spatrick       stream.Indent();
103061da546Spatrick       stream.Printf("%4" PRIu64 ": %s\n", (uint64_t)counter, hist_item.c_str());
104061da546Spatrick     }
105061da546Spatrick   }
106061da546Spatrick }
107