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 "lldb/Interpreter/CommandHistory.h"
11 #include "lldb/Interpreter/Args.h"
12 
13 using namespace lldb;
14 using namespace lldb_private;
15 
16 
CommandHistory()17 CommandHistory::CommandHistory () :
18     m_mutex(Mutex::eMutexTypeRecursive),
19     m_history()
20 {}
21 
~CommandHistory()22 CommandHistory::~CommandHistory ()
23 {}
24 
25 size_t
GetSize() const26 CommandHistory::GetSize () const
27 {
28     Mutex::Locker locker(m_mutex);
29     return m_history.size();
30 }
31 
32 bool
IsEmpty() const33 CommandHistory::IsEmpty () const
34 {
35     Mutex::Locker locker(m_mutex);
36     return m_history.empty();
37 }
38 
39 const char*
FindString(const char * input_str) const40 CommandHistory::FindString (const char* input_str) const
41 {
42     Mutex::Locker locker(m_mutex);
43     if (!input_str)
44         return NULL;
45     if (input_str[0] != g_repeat_char)
46         return NULL;
47     if (input_str[1] == '-')
48     {
49         bool success;
50         size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
51         if (!success)
52             return NULL;
53         if (idx > m_history.size())
54             return NULL;
55         idx = m_history.size() - idx;
56         return m_history[idx].c_str();
57 
58     }
59     else if (input_str[1] == g_repeat_char)
60     {
61         if (m_history.empty())
62             return NULL;
63         else
64             return m_history.back().c_str();
65     }
66     else
67     {
68         bool success;
69         uint32_t idx = Args::StringToUInt32 (input_str+1, 0, 0, &success);
70         if (!success)
71             return NULL;
72         if (idx >= m_history.size())
73             return NULL;
74         return m_history[idx].c_str();
75     }
76 }
77 
78 const char*
GetStringAtIndex(size_t idx) const79 CommandHistory::GetStringAtIndex (size_t idx) const
80 {
81     Mutex::Locker locker(m_mutex);
82     if (idx < m_history.size())
83         return m_history[idx].c_str();
84     return NULL;
85 }
86 
87 const char*
operator [](size_t idx) const88 CommandHistory::operator [] (size_t idx) const
89 {
90     return GetStringAtIndex(idx);
91 }
92 
93 const char*
GetRecentmostString() const94 CommandHistory::GetRecentmostString () const
95 {
96     Mutex::Locker locker(m_mutex);
97     if (m_history.empty())
98         return NULL;
99     return m_history.back().c_str();
100 }
101 
102 void
AppendString(const std::string & str,bool reject_if_dupe)103 CommandHistory::AppendString (const std::string& str,
104                               bool reject_if_dupe)
105 {
106     Mutex::Locker locker(m_mutex);
107     if (reject_if_dupe)
108     {
109         if (!m_history.empty())
110         {
111             if (str == m_history.back())
112                 return;
113         }
114     }
115     m_history.push_back(std::string(str));
116 }
117 
118 void
Clear()119 CommandHistory::Clear ()
120 {
121     Mutex::Locker locker(m_mutex);
122     m_history.clear();
123 }
124 
125 void
Dump(Stream & stream,size_t start_idx,size_t stop_idx) const126 CommandHistory::Dump (Stream& stream,
127                       size_t start_idx,
128                       size_t stop_idx) const
129 {
130     Mutex::Locker locker(m_mutex);
131     stop_idx = std::min(stop_idx, m_history.size() - 1);
132     for (size_t counter = start_idx;
133          counter <= stop_idx;
134          counter++)
135     {
136         const std::string hist_item = m_history[counter];
137         if (!hist_item.empty())
138         {
139             stream.Indent();
140             stream.Printf ("%4zu: %s\n", counter, hist_item.c_str());
141         }
142     }
143 }
144