[lldb][NFC] Fix all formatting errors in .cpp file headers
Summary:
A *.cpp file header in LLDB (and in LLDB) should like this:
```
//===-- TestUtilities.cpp -------------------------------------------------===//
```
However in LLDB most of our source files have arbitrary changes to this format and
these changes are spreading through LLDB as folks usually just use the existing
source files as templates for their new files (most notably the unnecessary
editor language indicator `-*- C++ -*-` is spreading and in every review
someone is pointing out that this is wrong, resulting in people pointing out that this
is done in the same way in other files).
This patch removes most of these inconsistencies including the editor language indicators,
all the different missing/additional '-' characters, files that center the file name, missing
trailing `===//` (mostly caused by clang-format breaking the line).
Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D73258
2020-01-24 15:23:27 +08:00
|
|
|
//===-- OptionValueDictionary.cpp -----------------------------------------===//
|
2012-08-23 01:17:09 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2012-08-23 01:17:09 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "lldb/Interpreter/OptionValueDictionary.h"
|
|
|
|
|
2013-01-29 07:47:25 +08:00
|
|
|
#include "lldb/DataFormatters/FormatManager.h"
|
2022-06-22 21:16:04 +08:00
|
|
|
#include "lldb/Interpreter/OptionValueEnumeration.h"
|
2012-08-23 01:17:09 +08:00
|
|
|
#include "lldb/Interpreter/OptionValueString.h"
|
2018-04-18 02:53:35 +08:00
|
|
|
#include "lldb/Utility/Args.h"
|
2018-08-07 19:07:21 +08:00
|
|
|
#include "lldb/Utility/State.h"
|
2022-06-22 21:16:04 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2012-08-23 01:17:09 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx,
|
|
|
|
Stream &strm, uint32_t dump_mask) {
|
|
|
|
const Type dict_type = ConvertTypeMaskToType(m_type_mask);
|
|
|
|
if (dump_mask & eDumpOptionType) {
|
|
|
|
if (m_type_mask != eTypeInvalid)
|
|
|
|
strm.Printf("(%s of %ss)", GetTypeAsCString(),
|
|
|
|
GetBuiltinTypeAsCString(dict_type));
|
|
|
|
else
|
|
|
|
strm.Printf("(%s)", GetTypeAsCString());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
if (dump_mask & eDumpOptionValue) {
|
2018-10-26 08:00:17 +08:00
|
|
|
const bool one_line = dump_mask & eDumpOptionCommand;
|
2012-08-23 01:17:09 +08:00
|
|
|
if (dump_mask & eDumpOptionType)
|
|
|
|
strm.PutCString(" =");
|
|
|
|
|
|
|
|
collection::iterator pos, end = m_values.end();
|
|
|
|
|
2018-10-26 08:00:17 +08:00
|
|
|
if (!one_line)
|
|
|
|
strm.IndentMore();
|
2012-08-23 01:17:09 +08:00
|
|
|
|
|
|
|
for (pos = m_values.begin(); pos != end; ++pos) {
|
|
|
|
OptionValue *option_value = pos->second.get();
|
2018-10-26 08:00:17 +08:00
|
|
|
|
|
|
|
if (one_line)
|
|
|
|
strm << ' ';
|
|
|
|
else
|
|
|
|
strm.EOL();
|
|
|
|
|
2020-02-11 20:31:00 +08:00
|
|
|
strm.Indent(pos->first.GetStringRef());
|
2012-08-23 01:17:09 +08:00
|
|
|
|
|
|
|
const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
|
|
|
|
switch (dict_type) {
|
2016-09-07 04:57:50 +08:00
|
|
|
default:
|
2012-08-23 01:17:09 +08:00
|
|
|
case eTypeArray:
|
|
|
|
case eTypeDictionary:
|
|
|
|
case eTypeProperties:
|
|
|
|
case eTypeFileSpecList:
|
|
|
|
case eTypePathMap:
|
|
|
|
strm.PutChar(' ');
|
|
|
|
option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
2012-08-23 01:17:09 +08:00
|
|
|
|
|
|
|
case eTypeBoolean:
|
2015-01-13 04:44:02 +08:00
|
|
|
case eTypeChar:
|
2012-08-23 01:17:09 +08:00
|
|
|
case eTypeEnum:
|
2020-07-17 02:34:50 +08:00
|
|
|
case eTypeFileLineColumn:
|
2012-08-23 01:17:09 +08:00
|
|
|
case eTypeFileSpec:
|
|
|
|
case eTypeFormat:
|
|
|
|
case eTypeSInt64:
|
|
|
|
case eTypeString:
|
|
|
|
case eTypeUInt64:
|
|
|
|
case eTypeUUID:
|
|
|
|
// No need to show the type for dictionaries of simple items
|
|
|
|
strm.PutCString("=");
|
2014-04-20 08:31:37 +08:00
|
|
|
option_value->DumpValue(exe_ctx, strm,
|
|
|
|
(dump_mask & (~eDumpOptionType)) |
|
|
|
|
extra_dump_options);
|
2012-08-23 01:17:09 +08:00
|
|
|
break;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
2018-10-26 08:00:17 +08:00
|
|
|
if (!one_line)
|
|
|
|
strm.IndentLess();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t OptionValueDictionary::GetArgs(Args &args) const {
|
|
|
|
args.Clear();
|
|
|
|
collection::const_iterator pos, end = m_values.end();
|
|
|
|
for (pos = m_values.begin(); pos != end; ++pos) {
|
|
|
|
StreamString strm;
|
|
|
|
strm.Printf("%s=", pos->first.GetCString());
|
|
|
|
pos->second->DumpValue(nullptr, strm, eDumpOptionValue | eDumpOptionRaw);
|
2016-09-20 01:54:06 +08:00
|
|
|
args.AppendArgument(strm.GetString());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-16 05:37:05 +08:00
|
|
|
return args.GetArgumentCount();
|
|
|
|
}
|
|
|
|
|
2017-05-12 12:51:55 +08:00
|
|
|
Status OptionValueDictionary::SetArgs(const Args &args,
|
|
|
|
VarSetOperationType op) {
|
|
|
|
Status error;
|
2012-08-23 01:17:09 +08:00
|
|
|
const size_t argc = args.GetArgumentCount();
|
|
|
|
switch (op) {
|
|
|
|
case eVarSetOperationClear:
|
|
|
|
Clear();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eVarSetOperationAppend:
|
|
|
|
case eVarSetOperationReplace:
|
|
|
|
case eVarSetOperationAssign:
|
2016-11-23 01:10:15 +08:00
|
|
|
if (argc == 0) {
|
|
|
|
error.SetErrorString(
|
|
|
|
"assign operation takes one or more key=value arguments");
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
for (const auto &entry : args) {
|
2019-09-13 19:26:48 +08:00
|
|
|
if (entry.ref().empty()) {
|
2016-11-23 01:10:15 +08:00
|
|
|
error.SetErrorString("empty argument");
|
|
|
|
return error;
|
|
|
|
}
|
2019-09-13 19:26:48 +08:00
|
|
|
if (!entry.ref().contains('=')) {
|
2016-11-23 01:10:15 +08:00
|
|
|
error.SetErrorString(
|
|
|
|
"assign operation takes one or more key=value arguments");
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::StringRef key, value;
|
2019-09-13 19:26:48 +08:00
|
|
|
std::tie(key, value) = entry.ref().split('=');
|
2016-11-23 01:10:15 +08:00
|
|
|
bool key_valid = false;
|
|
|
|
if (key.empty()) {
|
|
|
|
error.SetErrorString("empty dictionary key");
|
|
|
|
return error;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-11-23 01:10:15 +08:00
|
|
|
if (key.front() == '[') {
|
|
|
|
// Key name starts with '[', so the key value must be in single or
|
2018-05-01 00:49:04 +08:00
|
|
|
// double quotes like: ['<key>'] ["<key>"]
|
2016-11-23 01:10:15 +08:00
|
|
|
if ((key.size() > 2) && (key.back() == ']')) {
|
|
|
|
// Strip leading '[' and trailing ']'
|
|
|
|
key = key.substr(1, key.size() - 2);
|
|
|
|
const char quote_char = key.front();
|
|
|
|
if ((quote_char == '\'') || (quote_char == '"')) {
|
|
|
|
if ((key.size() > 2) && (key.back() == quote_char)) {
|
|
|
|
// Strip the quotes
|
|
|
|
key = key.substr(1, key.size() - 2);
|
2012-08-23 01:17:09 +08:00
|
|
|
key_valid = true;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2016-11-23 01:10:15 +08:00
|
|
|
// square brackets, no quotes
|
|
|
|
key_valid = true;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
2016-11-23 01:10:15 +08:00
|
|
|
} else {
|
|
|
|
// No square brackets or quotes
|
|
|
|
key_valid = true;
|
|
|
|
}
|
|
|
|
if (!key_valid) {
|
|
|
|
error.SetErrorStringWithFormat(
|
|
|
|
"invalid key \"%s\", the key must be a bare string or "
|
|
|
|
"surrounded by brackets with optional quotes: [<key>] or "
|
|
|
|
"['<key>'] or [\"<key>\"]",
|
|
|
|
key.str().c_str());
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2022-06-22 21:16:04 +08:00
|
|
|
if (m_type_mask == 1u << eTypeEnum) {
|
|
|
|
auto enum_value =
|
|
|
|
std::make_shared<OptionValueEnumeration>(m_enum_values, 0);
|
|
|
|
error = enum_value->SetValueFromString(value);
|
2016-11-23 01:10:15 +08:00
|
|
|
if (error.Fail())
|
|
|
|
return error;
|
|
|
|
m_value_was_set = true;
|
2022-06-22 21:16:04 +08:00
|
|
|
SetValueForKey(ConstString(key), enum_value, true);
|
2016-11-23 01:10:15 +08:00
|
|
|
} else {
|
2022-06-22 21:16:04 +08:00
|
|
|
lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask(
|
|
|
|
value.str().c_str(), m_type_mask, error));
|
|
|
|
if (value_sp) {
|
|
|
|
if (error.Fail())
|
|
|
|
return error;
|
|
|
|
m_value_was_set = true;
|
|
|
|
SetValueForKey(ConstString(key), value_sp, true);
|
|
|
|
} else {
|
|
|
|
error.SetErrorString("dictionaries that can contain multiple types "
|
|
|
|
"must subclass OptionValueArray");
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-08-23 01:17:09 +08:00
|
|
|
case eVarSetOperationRemove:
|
|
|
|
if (argc > 0) {
|
|
|
|
for (size_t i = 0; i < argc; ++i) {
|
|
|
|
ConstString key(args.GetArgumentAtIndex(i));
|
|
|
|
if (!DeleteValueForKey(key)) {
|
|
|
|
error.SetErrorStringWithFormat(
|
|
|
|
"no value found named '%s', aborting remove operation",
|
|
|
|
key.GetCString());
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
} else {
|
2015-02-20 19:14:59 +08:00
|
|
|
error.SetErrorString("remove operation takes one or more key arguments");
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
|
2012-08-23 01:17:09 +08:00
|
|
|
case eVarSetOperationInsertBefore:
|
|
|
|
case eVarSetOperationInsertAfter:
|
|
|
|
case eVarSetOperationInvalid:
|
2015-02-20 19:14:59 +08:00
|
|
|
error = OptionValue::SetValueFromString(llvm::StringRef(), op);
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2017-05-12 12:51:55 +08:00
|
|
|
Status OptionValueDictionary::SetValueFromString(llvm::StringRef value,
|
|
|
|
VarSetOperationType op) {
|
2016-11-03 04:34:10 +08:00
|
|
|
Args args(value.str());
|
2017-05-12 12:51:55 +08:00
|
|
|
Status error = SetArgs(args, op);
|
2015-01-14 05:13:08 +08:00
|
|
|
if (error.Success())
|
|
|
|
NotifyValueChanged();
|
|
|
|
return error;
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
lldb::OptionValueSP
|
|
|
|
OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx,
|
2017-05-12 12:51:55 +08:00
|
|
|
llvm::StringRef name, bool will_modify,
|
|
|
|
Status &error) const {
|
2012-08-23 01:17:09 +08:00
|
|
|
lldb::OptionValueSP value_sp;
|
2016-11-18 02:08:12 +08:00
|
|
|
if (name.empty())
|
|
|
|
return nullptr;
|
2012-08-23 01:17:09 +08:00
|
|
|
|
2016-11-18 02:08:12 +08:00
|
|
|
llvm::StringRef left, temp;
|
|
|
|
std::tie(left, temp) = name.split('[');
|
|
|
|
if (left.size() == name.size()) {
|
|
|
|
error.SetErrorStringWithFormat("invalid value path '%s', %s values only "
|
|
|
|
"support '[<key>]' subvalues where <key> "
|
|
|
|
"a string value optionally delimited by "
|
|
|
|
"single or double quotes",
|
|
|
|
name.str().c_str(), GetTypeAsCString());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
assert(!temp.empty());
|
2012-08-23 01:17:09 +08:00
|
|
|
|
2017-11-02 07:46:21 +08:00
|
|
|
llvm::StringRef key, quote_char;
|
2012-08-23 01:17:09 +08:00
|
|
|
|
2016-11-18 02:08:12 +08:00
|
|
|
if (temp[0] == '\"' || temp[0] == '\'') {
|
|
|
|
quote_char = temp.take_front();
|
|
|
|
temp = temp.drop_front();
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-11-18 02:08:12 +08:00
|
|
|
llvm::StringRef sub_name;
|
|
|
|
std::tie(key, sub_name) = temp.split(']');
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-11-18 02:08:12 +08:00
|
|
|
if (!key.consume_back(quote_char) || key.empty()) {
|
|
|
|
error.SetErrorStringWithFormat("invalid value path '%s', "
|
|
|
|
"key names must be formatted as ['<key>'] where <key> "
|
|
|
|
"is a string that doesn't contain quotes and the quote"
|
|
|
|
" char is optional", name.str().c_str());
|
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-11-18 02:08:12 +08:00
|
|
|
|
|
|
|
value_sp = GetValueForKey(ConstString(key));
|
|
|
|
if (!value_sp) {
|
|
|
|
error.SetErrorStringWithFormat(
|
|
|
|
"dictionary does not contain a value for the key name '%s'",
|
|
|
|
key.str().c_str());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sub_name.empty())
|
|
|
|
return value_sp;
|
|
|
|
return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error);
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|
|
|
|
|
2017-05-12 12:51:55 +08:00
|
|
|
Status OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx,
|
|
|
|
VarSetOperationType op,
|
|
|
|
llvm::StringRef name,
|
|
|
|
llvm::StringRef value) {
|
|
|
|
Status error;
|
2012-08-23 01:17:09 +08:00
|
|
|
const bool will_modify = true;
|
|
|
|
lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
|
|
|
|
if (value_sp)
|
2016-11-18 02:08:12 +08:00
|
|
|
error = value_sp->SetValueFromString(value, op);
|
2016-09-07 04:57:50 +08:00
|
|
|
else {
|
2014-04-20 08:31:37 +08:00
|
|
|
if (error.AsCString() == nullptr)
|
2016-11-18 02:08:12 +08:00
|
|
|
error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
return error;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
|
|
|
|
lldb::OptionValueSP
|
2019-03-07 05:22:25 +08:00
|
|
|
OptionValueDictionary::GetValueForKey(ConstString key) const {
|
2012-08-23 01:17:09 +08:00
|
|
|
lldb::OptionValueSP value_sp;
|
|
|
|
collection::const_iterator pos = m_values.find(key);
|
|
|
|
if (pos != m_values.end())
|
|
|
|
value_sp = pos->second;
|
|
|
|
return value_sp;
|
|
|
|
}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
bool OptionValueDictionary::SetValueForKey(ConstString key,
|
2012-08-23 01:17:09 +08:00
|
|
|
const lldb::OptionValueSP &value_sp,
|
|
|
|
bool can_replace) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// Make sure the value_sp object is allowed to contain values of the type
|
|
|
|
// passed in...
|
2012-08-23 01:17:09 +08:00
|
|
|
if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) {
|
|
|
|
if (!can_replace) {
|
|
|
|
collection::const_iterator pos = m_values.find(key);
|
|
|
|
if (pos != m_values.end())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
m_values[key] = value_sp;
|
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-08-23 01:17:09 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
bool OptionValueDictionary::DeleteValueForKey(ConstString key) {
|
2012-08-23 01:17:09 +08:00
|
|
|
collection::iterator pos = m_values.find(key);
|
|
|
|
if (pos != m_values.end()) {
|
|
|
|
m_values.erase(pos);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-20 05:49:42 +08:00
|
|
|
OptionValueSP
|
|
|
|
OptionValueDictionary::DeepCopy(const OptionValueSP &new_parent) const {
|
|
|
|
auto copy_sp = OptionValue::DeepCopy(new_parent);
|
|
|
|
// copy_sp->GetAsDictionary cannot be used here as it doesn't work for derived
|
|
|
|
// types that override GetType returning a different value.
|
|
|
|
auto *dict_value_ptr = static_cast<OptionValueDictionary *>(copy_sp.get());
|
|
|
|
lldbassert(dict_value_ptr);
|
|
|
|
|
|
|
|
for (auto &value : dict_value_ptr->m_values)
|
|
|
|
value.second = value.second->DeepCopy(copy_sp);
|
|
|
|
|
|
|
|
return copy_sp;
|
2012-08-23 01:17:09 +08:00
|
|
|
}
|