1cfca06d7SDimitry Andric //===-- OptionValueFormatEntity.cpp ---------------------------------------===//
212bd4897SEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
612bd4897SEd Maste //
712bd4897SEd Maste //===----------------------------------------------------------------------===//
812bd4897SEd Maste
912bd4897SEd Maste #include "lldb/Interpreter/OptionValueFormatEntity.h"
1012bd4897SEd Maste
1112bd4897SEd Maste #include "lldb/Core/Module.h"
1212bd4897SEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
1374a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
1474a628f7SDimitry Andric #include "lldb/Utility/StringList.h"
1512bd4897SEd Maste using namespace lldb;
1612bd4897SEd Maste using namespace lldb_private;
1712bd4897SEd Maste
OptionValueFormatEntity(const char * default_format)18344a3780SDimitry Andric OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) {
1914f1b3e8SDimitry Andric if (default_format && default_format[0]) {
2012bd4897SEd Maste llvm::StringRef default_format_str(default_format);
21b76161e4SDimitry Andric Status error = FormatEntity::Parse(default_format_str, m_default_entry);
2214f1b3e8SDimitry Andric if (error.Success()) {
2312bd4897SEd Maste m_default_format = default_format;
2412bd4897SEd Maste m_current_format = default_format;
2512bd4897SEd Maste m_current_entry = m_default_entry;
2612bd4897SEd Maste }
2712bd4897SEd Maste }
2812bd4897SEd Maste }
2912bd4897SEd Maste
Clear()30b60736ecSDimitry Andric void OptionValueFormatEntity::Clear() {
3112bd4897SEd Maste m_current_entry = m_default_entry;
3212bd4897SEd Maste m_current_format = m_default_format;
3312bd4897SEd Maste m_value_was_set = false;
3412bd4897SEd Maste }
3512bd4897SEd Maste
EscapeBackticks(llvm::StringRef str,std::string & dst)3694994d37SDimitry Andric static void EscapeBackticks(llvm::StringRef str, std::string &dst) {
3794994d37SDimitry Andric dst.clear();
3894994d37SDimitry Andric dst.reserve(str.size());
3994994d37SDimitry Andric
4094994d37SDimitry Andric for (size_t i = 0, e = str.size(); i != e; ++i) {
4194994d37SDimitry Andric char c = str[i];
4294994d37SDimitry Andric if (c == '`') {
4394994d37SDimitry Andric if (i == 0 || str[i - 1] != '\\')
4494994d37SDimitry Andric dst += '\\';
4594994d37SDimitry Andric }
4694994d37SDimitry Andric dst += c;
4794994d37SDimitry Andric }
4894994d37SDimitry Andric }
4994994d37SDimitry Andric
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)5014f1b3e8SDimitry Andric void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx,
5114f1b3e8SDimitry Andric Stream &strm, uint32_t dump_mask) {
5212bd4897SEd Maste if (dump_mask & eDumpOptionType)
5312bd4897SEd Maste strm.Printf("(%s)", GetTypeAsCString());
5414f1b3e8SDimitry Andric if (dump_mask & eDumpOptionValue) {
5512bd4897SEd Maste if (dump_mask & eDumpOptionType)
5694994d37SDimitry Andric strm.PutCString(" = ");
5794994d37SDimitry Andric std::string escaped;
5894994d37SDimitry Andric EscapeBackticks(m_current_format, escaped);
5994994d37SDimitry Andric strm << '"' << escaped << '"';
6012bd4897SEd Maste }
6112bd4897SEd Maste }
6212bd4897SEd Maste
63e3b55780SDimitry Andric llvm::json::Value
ToJSON(const ExecutionContext * exe_ctx)64e3b55780SDimitry Andric OptionValueFormatEntity::ToJSON(const ExecutionContext *exe_ctx) {
65e3b55780SDimitry Andric std::string escaped;
66e3b55780SDimitry Andric EscapeBackticks(m_current_format, escaped);
67e3b55780SDimitry Andric return escaped;
68e3b55780SDimitry Andric }
69e3b55780SDimitry Andric
SetValueFromString(llvm::StringRef value_str,VarSetOperationType op)70b76161e4SDimitry Andric Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,
7114f1b3e8SDimitry Andric VarSetOperationType op) {
72b76161e4SDimitry Andric Status error;
7314f1b3e8SDimitry Andric switch (op) {
7412bd4897SEd Maste case eVarSetOperationClear:
7512bd4897SEd Maste Clear();
7612bd4897SEd Maste NotifyValueChanged();
7712bd4897SEd Maste break;
7812bd4897SEd Maste
7912bd4897SEd Maste case eVarSetOperationReplace:
8014f1b3e8SDimitry Andric case eVarSetOperationAssign: {
8114f1b3e8SDimitry Andric // Check if the string starts with a quote character after removing leading
82f73363f1SDimitry Andric // and trailing spaces. If it does start with a quote character, make sure
83f73363f1SDimitry Andric // it ends with the same quote character and remove the quotes before we
84f73363f1SDimitry Andric // parse the format string. If the string doesn't start with a quote, leave
85f73363f1SDimitry Andric // the string alone and parse as is.
865e95aa85SEd Maste llvm::StringRef trimmed_value_str = value_str.trim();
8714f1b3e8SDimitry Andric if (!trimmed_value_str.empty()) {
885e95aa85SEd Maste const char first_char = trimmed_value_str[0];
8914f1b3e8SDimitry Andric if (first_char == '"' || first_char == '\'') {
905e95aa85SEd Maste const size_t trimmed_len = trimmed_value_str.size();
9114f1b3e8SDimitry Andric if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) {
92b60736ecSDimitry Andric error.SetErrorString("mismatched quotes");
935e95aa85SEd Maste return error;
945e95aa85SEd Maste }
955e95aa85SEd Maste value_str = trimmed_value_str.substr(1, trimmed_len - 2);
965e95aa85SEd Maste }
975e95aa85SEd Maste }
9812bd4897SEd Maste FormatEntity::Entry entry;
9912bd4897SEd Maste error = FormatEntity::Parse(value_str, entry);
10014f1b3e8SDimitry Andric if (error.Success()) {
10112bd4897SEd Maste m_current_entry = std::move(entry);
102cfca06d7SDimitry Andric m_current_format = std::string(value_str);
10312bd4897SEd Maste m_value_was_set = true;
10412bd4897SEd Maste NotifyValueChanged();
10512bd4897SEd Maste }
10614f1b3e8SDimitry Andric } break;
10712bd4897SEd Maste
10812bd4897SEd Maste case eVarSetOperationInsertBefore:
10912bd4897SEd Maste case eVarSetOperationInsertAfter:
11012bd4897SEd Maste case eVarSetOperationRemove:
11112bd4897SEd Maste case eVarSetOperationAppend:
11212bd4897SEd Maste case eVarSetOperationInvalid:
1135e95aa85SEd Maste error = OptionValue::SetValueFromString(value_str, op);
11412bd4897SEd Maste break;
11512bd4897SEd Maste }
11612bd4897SEd Maste return error;
11712bd4897SEd Maste }
11812bd4897SEd Maste
AutoComplete(CommandInterpreter & interpreter,CompletionRequest & request)119ead24645SDimitry Andric void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
120f73363f1SDimitry Andric CompletionRequest &request) {
121ead24645SDimitry Andric FormatEntity::AutoComplete(request);
12212bd4897SEd Maste }
123