1//===-- WatchpointOptions.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/Breakpoint/WatchpointOptions.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/Core/Stream.h" 17#include "lldb/Core/StringList.h" 18#include "lldb/Core/Value.h" 19#include "lldb/Breakpoint/StoppointCallbackContext.h" 20#include "lldb/Target/Process.h" 21#include "lldb/Target/Target.h" 22#include "lldb/Target/ThreadSpec.h" 23#include "lldb/Expression/ClangUserExpression.h" 24 25using namespace lldb; 26using namespace lldb_private; 27 28bool 29WatchpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id) 30{ 31 return true; 32} 33 34//---------------------------------------------------------------------- 35// WatchpointOptions constructor 36//---------------------------------------------------------------------- 37WatchpointOptions::WatchpointOptions() : 38 m_callback (WatchpointOptions::NullCallback), 39 m_callback_baton_sp (), 40 m_callback_is_synchronous (false), 41 m_thread_spec_ap () 42{ 43} 44 45//---------------------------------------------------------------------- 46// WatchpointOptions copy constructor 47//---------------------------------------------------------------------- 48WatchpointOptions::WatchpointOptions(const WatchpointOptions& rhs) : 49 m_callback (rhs.m_callback), 50 m_callback_baton_sp (rhs.m_callback_baton_sp), 51 m_callback_is_synchronous (rhs.m_callback_is_synchronous), 52 m_thread_spec_ap () 53{ 54 if (rhs.m_thread_spec_ap.get() != NULL) 55 m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get())); 56} 57 58//---------------------------------------------------------------------- 59// WatchpointOptions assignment operator 60//---------------------------------------------------------------------- 61const WatchpointOptions& 62WatchpointOptions::operator=(const WatchpointOptions& rhs) 63{ 64 m_callback = rhs.m_callback; 65 m_callback_baton_sp = rhs.m_callback_baton_sp; 66 m_callback_is_synchronous = rhs.m_callback_is_synchronous; 67 if (rhs.m_thread_spec_ap.get() != NULL) 68 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); 69 return *this; 70} 71 72WatchpointOptions * 73WatchpointOptions::CopyOptionsNoCallback (WatchpointOptions &orig) 74{ 75 WatchpointHitCallback orig_callback = orig.m_callback; 76 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; 77 bool orig_is_sync = orig.m_callback_is_synchronous; 78 79 orig.ClearCallback(); 80 WatchpointOptions *ret_val = new WatchpointOptions(orig); 81 82 orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync); 83 84 return ret_val; 85} 86 87//---------------------------------------------------------------------- 88// Destructor 89//---------------------------------------------------------------------- 90WatchpointOptions::~WatchpointOptions() 91{ 92} 93 94//------------------------------------------------------------------ 95// Callbacks 96//------------------------------------------------------------------ 97void 98WatchpointOptions::SetCallback (WatchpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous) 99{ 100 m_callback_is_synchronous = callback_is_synchronous; 101 m_callback = callback; 102 m_callback_baton_sp = callback_baton_sp; 103} 104 105void 106WatchpointOptions::ClearCallback () 107{ 108 m_callback = WatchpointOptions::NullCallback; 109 m_callback_is_synchronous = false; 110 m_callback_baton_sp.reset(); 111} 112 113Baton * 114WatchpointOptions::GetBaton () 115{ 116 return m_callback_baton_sp.get(); 117} 118 119const Baton * 120WatchpointOptions::GetBaton () const 121{ 122 return m_callback_baton_sp.get(); 123} 124 125bool 126WatchpointOptions::InvokeCallback (StoppointCallbackContext *context, 127 lldb::user_id_t watch_id) 128{ 129 if (m_callback && context->is_synchronous == IsCallbackSynchronous()) 130 { 131 return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL, 132 context, 133 watch_id); 134 } 135 else 136 return true; 137} 138 139bool 140WatchpointOptions::HasCallback () 141{ 142 return m_callback != WatchpointOptions::NullCallback; 143} 144 145const ThreadSpec * 146WatchpointOptions::GetThreadSpecNoCreate () const 147{ 148 return m_thread_spec_ap.get(); 149} 150 151ThreadSpec * 152WatchpointOptions::GetThreadSpec () 153{ 154 if (m_thread_spec_ap.get() == NULL) 155 m_thread_spec_ap.reset (new ThreadSpec()); 156 157 return m_thread_spec_ap.get(); 158} 159 160void 161WatchpointOptions::SetThreadID (lldb::tid_t thread_id) 162{ 163 GetThreadSpec()->SetTID(thread_id); 164} 165 166void 167WatchpointOptions::GetCallbackDescription (Stream *s, lldb::DescriptionLevel level) const 168{ 169 if (m_callback_baton_sp.get()) 170 { 171 s->EOL(); 172 m_callback_baton_sp->GetDescription (s, level); 173 } 174} 175void 176WatchpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const 177{ 178 179 // Figure out if there are any options not at their default value, and only print 180 // anything if there are: 181 182 if ((GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ())) 183 { 184 if (level == lldb::eDescriptionLevelVerbose) 185 { 186 s->EOL (); 187 s->IndentMore(); 188 s->Indent(); 189 s->PutCString("Watchpoint Options:\n"); 190 s->IndentMore(); 191 s->Indent(); 192 } 193 else 194 s->PutCString(" Options: "); 195 196 if (m_thread_spec_ap.get()) 197 m_thread_spec_ap->GetDescription (s, level); 198 else if (level == eDescriptionLevelBrief) 199 s->PutCString ("thread spec: no "); 200 if (level == lldb::eDescriptionLevelFull) 201 { 202 s->IndentLess(); 203 s->IndentMore(); 204 } 205 } 206 207 GetCallbackDescription(s, level); 208} 209 210void 211WatchpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const 212{ 213 CommandData *data = (CommandData *)m_data; 214 215 if (level == eDescriptionLevelBrief) 216 { 217 s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no"); 218 return; 219 } 220 221 s->IndentMore (); 222 s->Indent("watchpoint commands:\n"); 223 224 s->IndentMore (); 225 if (data && data->user_source.GetSize() > 0) 226 { 227 const size_t num_strings = data->user_source.GetSize(); 228 for (size_t i = 0; i < num_strings; ++i) 229 { 230 s->Indent(data->user_source.GetStringAtIndex(i)); 231 s->EOL(); 232 } 233 } 234 else 235 { 236 s->PutCString ("No commands.\n"); 237 } 238 s->IndentLess (); 239 s->IndentLess (); 240} 241 242