2010-06-09 00:52:24 +08:00
|
|
|
//===-- BreakpointID.cpp ----------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// C Includes
|
2012-09-04 22:55:50 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// C++ Includes
|
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
|
|
|
#include "lldb/Breakpoint/Breakpoint.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "lldb/Breakpoint/BreakpointID.h"
|
2014-12-17 07:40:14 +08:00
|
|
|
#include "lldb/Core/Error.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "lldb/Core/Stream.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
BreakpointID::BreakpointID(break_id_t bp_id, break_id_t loc_id)
|
|
|
|
: m_break_id(bp_id), m_location_id(loc_id) {}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2015-10-31 02:50:12 +08:00
|
|
|
BreakpointID::~BreakpointID() = default;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
static llvm::StringRef g_range_specifiers[] = {"-", "to", "To", "TO"};
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Tells whether or not STR is valid to use between two strings representing
|
|
|
|
// breakpoint IDs, to
|
|
|
|
// indicate a range of breakpoint IDs. This is broken out into a separate
|
|
|
|
// function so that we can
|
2010-06-09 00:52:24 +08:00
|
|
|
// easily change or add to the format for specifying ID ranges at a later date.
|
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
bool BreakpointID::IsRangeIdentifier(llvm::StringRef str) {
|
|
|
|
for (auto spec : g_range_specifiers) {
|
|
|
|
if (spec == str)
|
2016-09-07 04:57:50 +08:00
|
|
|
return true;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
bool BreakpointID::IsValidIDExpression(llvm::StringRef str) {
|
|
|
|
return BreakpointID::ParseCanonicalReference(str).hasValue();
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
llvm::ArrayRef<llvm::StringRef> BreakpointID::GetRangeSpecifiers() {
|
2016-10-06 01:58:46 +08:00
|
|
|
return llvm::makeArrayRef(g_range_specifiers);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
void BreakpointID::GetDescription(Stream *s, lldb::DescriptionLevel level) {
|
|
|
|
if (level == eDescriptionLevelVerbose)
|
|
|
|
s->Printf("%p BreakpointID:", static_cast<void *>(this));
|
|
|
|
|
|
|
|
if (m_break_id == LLDB_INVALID_BREAK_ID)
|
|
|
|
s->PutCString("<invalid>");
|
|
|
|
else if (m_location_id == LLDB_INVALID_BREAK_ID)
|
|
|
|
s->Printf("%i", m_break_id);
|
|
|
|
else
|
|
|
|
s->Printf("%i.%i", m_break_id, m_location_id);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
void BreakpointID::GetCanonicalReference(Stream *s, break_id_t bp_id,
|
|
|
|
break_id_t loc_id) {
|
|
|
|
if (bp_id == LLDB_INVALID_BREAK_ID)
|
|
|
|
s->PutCString("<invalid>");
|
|
|
|
else if (loc_id == LLDB_INVALID_BREAK_ID)
|
|
|
|
s->Printf("%i", bp_id);
|
|
|
|
else
|
|
|
|
s->Printf("%i.%i", bp_id, loc_id);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
llvm::Optional<BreakpointID>
|
|
|
|
BreakpointID::ParseCanonicalReference(llvm::StringRef input) {
|
|
|
|
break_id_t bp_id;
|
|
|
|
break_id_t loc_id = LLDB_INVALID_BREAK_ID;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
if (input.empty())
|
|
|
|
return llvm::None;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-10-06 01:07:47 +08:00
|
|
|
// If it doesn't start with an integer, it's not valid.
|
|
|
|
if (input.consumeInteger(0, bp_id))
|
|
|
|
return llvm::None;
|
|
|
|
|
|
|
|
// period is optional, but if it exists, it must be followed by a number.
|
|
|
|
if (input.consume_front(".")) {
|
|
|
|
if (input.consumeInteger(0, loc_id))
|
|
|
|
return llvm::None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// And at the end, the entire string must have been consumed.
|
|
|
|
if (!input.empty())
|
|
|
|
return llvm::None;
|
|
|
|
|
|
|
|
return BreakpointID(bp_id, loc_id);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-09-17 10:00:02 +08:00
|
|
|
bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Error &error) {
|
2016-09-07 04:57:50 +08:00
|
|
|
error.Clear();
|
2016-09-17 10:00:02 +08:00
|
|
|
if (str.empty())
|
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-09-17 10:00:02 +08:00
|
|
|
// First character must be a letter or _
|
2016-09-17 10:34:40 +08:00
|
|
|
if (!isalpha(str[0]) && str[0] != '_')
|
2016-09-17 10:00:02 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Cannot contain ., -, or space.
|
|
|
|
if (str.find_first_of(".- ") != llvm::StringRef::npos) {
|
|
|
|
error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"",
|
|
|
|
str.str().c_str());
|
2016-09-07 04:57:50 +08:00
|
|
|
return false;
|
2016-09-17 10:00:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2014-12-17 07:40:14 +08:00
|
|
|
}
|