xref: /freebsd-src/contrib/llvm-project/lldb/source/Interpreter/CommandHistory.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
15ffd83dbSDimitry Andric //===-- CommandHistory.cpp ------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9fe6060f1SDimitry Andric #include <cinttypes>
10*bdd1243dSDimitry Andric #include <optional>
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "lldb/Interpreter/CommandHistory.h"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric using namespace lldb;
150b57cec5SDimitry Andric using namespace lldb_private;
160b57cec5SDimitry Andric 
GetSize() const170b57cec5SDimitry Andric size_t CommandHistory::GetSize() const {
180b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
190b57cec5SDimitry Andric   return m_history.size();
200b57cec5SDimitry Andric }
210b57cec5SDimitry Andric 
IsEmpty() const220b57cec5SDimitry Andric bool CommandHistory::IsEmpty() const {
230b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
240b57cec5SDimitry Andric   return m_history.empty();
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric 
27*bdd1243dSDimitry Andric std::optional<llvm::StringRef>
FindString(llvm::StringRef input_str) const280b57cec5SDimitry Andric CommandHistory::FindString(llvm::StringRef input_str) const {
290b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
300b57cec5SDimitry Andric   if (input_str.size() < 2)
31*bdd1243dSDimitry Andric     return std::nullopt;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   if (input_str[0] != g_repeat_char)
34*bdd1243dSDimitry Andric     return std::nullopt;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric   if (input_str[1] == g_repeat_char) {
370b57cec5SDimitry Andric     if (m_history.empty())
38*bdd1243dSDimitry Andric       return std::nullopt;
390b57cec5SDimitry Andric     return llvm::StringRef(m_history.back());
400b57cec5SDimitry Andric   }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   input_str = input_str.drop_front();
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   size_t idx = 0;
450b57cec5SDimitry Andric   if (input_str.front() == '-') {
460b57cec5SDimitry Andric     if (input_str.drop_front(1).getAsInteger(0, idx))
47*bdd1243dSDimitry Andric       return std::nullopt;
480b57cec5SDimitry Andric     if (idx >= m_history.size())
49*bdd1243dSDimitry Andric       return std::nullopt;
500b57cec5SDimitry Andric     idx = m_history.size() - idx;
510b57cec5SDimitry Andric   } else {
520b57cec5SDimitry Andric     if (input_str.getAsInteger(0, idx))
53*bdd1243dSDimitry Andric       return std::nullopt;
540b57cec5SDimitry Andric     if (idx >= m_history.size())
55*bdd1243dSDimitry Andric       return std::nullopt;
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   return llvm::StringRef(m_history[idx]);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
GetStringAtIndex(size_t idx) const610b57cec5SDimitry Andric llvm::StringRef CommandHistory::GetStringAtIndex(size_t idx) const {
620b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
630b57cec5SDimitry Andric   if (idx < m_history.size())
640b57cec5SDimitry Andric     return m_history[idx];
650b57cec5SDimitry Andric   return "";
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
operator [](size_t idx) const680b57cec5SDimitry Andric llvm::StringRef CommandHistory::operator[](size_t idx) const {
690b57cec5SDimitry Andric   return GetStringAtIndex(idx);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
GetRecentmostString() const720b57cec5SDimitry Andric llvm::StringRef CommandHistory::GetRecentmostString() const {
730b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
740b57cec5SDimitry Andric   if (m_history.empty())
750b57cec5SDimitry Andric     return "";
760b57cec5SDimitry Andric   return m_history.back();
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
AppendString(llvm::StringRef str,bool reject_if_dupe)790b57cec5SDimitry Andric void CommandHistory::AppendString(llvm::StringRef str, bool reject_if_dupe) {
800b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
810b57cec5SDimitry Andric   if (reject_if_dupe) {
820b57cec5SDimitry Andric     if (!m_history.empty()) {
830b57cec5SDimitry Andric       if (str == m_history.back())
840b57cec5SDimitry Andric         return;
850b57cec5SDimitry Andric     }
860b57cec5SDimitry Andric   }
875ffd83dbSDimitry Andric   m_history.push_back(std::string(str));
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
Clear()900b57cec5SDimitry Andric void CommandHistory::Clear() {
910b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
920b57cec5SDimitry Andric   m_history.clear();
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
Dump(Stream & stream,size_t start_idx,size_t stop_idx) const950b57cec5SDimitry Andric void CommandHistory::Dump(Stream &stream, size_t start_idx,
960b57cec5SDimitry Andric                           size_t stop_idx) const {
970b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
980b57cec5SDimitry Andric   stop_idx = std::min(stop_idx + 1, m_history.size());
990b57cec5SDimitry Andric   for (size_t counter = start_idx; counter < stop_idx; counter++) {
1000b57cec5SDimitry Andric     const std::string hist_item = m_history[counter];
1010b57cec5SDimitry Andric     if (!hist_item.empty()) {
1020b57cec5SDimitry Andric       stream.Indent();
1030b57cec5SDimitry Andric       stream.Printf("%4" PRIu64 ": %s\n", (uint64_t)counter, hist_item.c_str());
1040b57cec5SDimitry Andric     }
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric }
107