Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp
39587 views
//===-- BreakpointID.cpp --------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <cstdio>9#include <optional>1011#include "lldb/Breakpoint/Breakpoint.h"12#include "lldb/Breakpoint/BreakpointID.h"13#include "lldb/Utility/Status.h"14#include "lldb/Utility/Stream.h"1516using namespace lldb;17using namespace lldb_private;1819BreakpointID::BreakpointID(break_id_t bp_id, break_id_t loc_id)20: m_break_id(bp_id), m_location_id(loc_id) {}2122BreakpointID::~BreakpointID() = default;2324static llvm::StringRef g_range_specifiers[] = {"-", "to", "To", "TO"};2526// Tells whether or not STR is valid to use between two strings representing27// breakpoint IDs, to indicate a range of breakpoint IDs. This is broken out28// into a separate function so that we can easily change or add to the format29// for specifying ID ranges at a later date.3031bool BreakpointID::IsRangeIdentifier(llvm::StringRef str) {32return llvm::is_contained(g_range_specifiers, str);33}3435bool BreakpointID::IsValidIDExpression(llvm::StringRef str) {36return BreakpointID::ParseCanonicalReference(str).has_value();37}3839llvm::ArrayRef<llvm::StringRef> BreakpointID::GetRangeSpecifiers() {40return llvm::ArrayRef(g_range_specifiers);41}4243void BreakpointID::GetDescription(Stream *s, lldb::DescriptionLevel level) {44if (level == eDescriptionLevelVerbose)45s->Printf("%p BreakpointID:", static_cast<void *>(this));4647if (m_break_id == LLDB_INVALID_BREAK_ID)48s->PutCString("<invalid>");49else if (m_location_id == LLDB_INVALID_BREAK_ID)50s->Printf("%i", m_break_id);51else52s->Printf("%i.%i", m_break_id, m_location_id);53}5455void BreakpointID::GetCanonicalReference(Stream *s, break_id_t bp_id,56break_id_t loc_id) {57if (bp_id == LLDB_INVALID_BREAK_ID)58s->PutCString("<invalid>");59else if (loc_id == LLDB_INVALID_BREAK_ID)60s->Printf("%i", bp_id);61else62s->Printf("%i.%i", bp_id, loc_id);63}6465std::optional<BreakpointID>66BreakpointID::ParseCanonicalReference(llvm::StringRef input) {67break_id_t bp_id;68break_id_t loc_id = LLDB_INVALID_BREAK_ID;6970if (input.empty())71return std::nullopt;7273// If it doesn't start with an integer, it's not valid.74if (input.consumeInteger(0, bp_id))75return std::nullopt;7677// period is optional, but if it exists, it must be followed by a number.78if (input.consume_front(".")) {79if (input.consumeInteger(0, loc_id))80return std::nullopt;81}8283// And at the end, the entire string must have been consumed.84if (!input.empty())85return std::nullopt;8687return BreakpointID(bp_id, loc_id);88}8990bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) {91error.Clear();92if (str.empty())93{94error.SetErrorString("Empty breakpoint names are not allowed");95return false;96}9798// First character must be a letter or _99if (!isalpha(str[0]) && str[0] != '_')100{101error.SetErrorStringWithFormat("Breakpoint names must start with a "102"character or underscore: %s",103str.str().c_str());104return false;105}106107// Cannot contain ., -, or space.108if (str.find_first_of(".- ") != llvm::StringRef::npos) {109error.SetErrorStringWithFormat("Breakpoint names cannot contain "110"'.' or '-' or spaces: \"%s\"",111str.str().c_str());112return false;113}114115return true;116}117118119