125 lines · cpp
1//===-- OptionValueFormatEntity.cpp ---------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Interpreter/OptionValueFormatEntity.h"10 11#include "lldb/Core/Module.h"12#include "lldb/Interpreter/CommandInterpreter.h"13#include "lldb/Interpreter/OptionValue.h"14#include "lldb/Utility/Stream.h"15#include "lldb/Utility/StringList.h"16using namespace lldb;17using namespace lldb_private;18 19OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) {20 if (default_format && default_format[0]) {21 llvm::StringRef default_format_str(default_format);22 Status error = FormatEntity::Parse(default_format_str, m_default_entry);23 if (error.Success()) {24 m_default_format = default_format;25 m_current_format = default_format;26 m_current_entry = m_default_entry;27 }28 }29}30 31void OptionValueFormatEntity::Clear() {32 m_current_entry = m_default_entry;33 m_current_format = m_default_format;34 m_value_was_set = false;35}36 37static std::string EscapeBackticks(llvm::StringRef str) {38 std::string dst;39 dst.reserve(str.size());40 for (size_t i = 0, e = str.size(); i != e; ++i) {41 char c = str[i];42 if (c == '`') {43 if (i == 0 || str[i - 1] != '\\')44 dst += '\\';45 }46 dst += c;47 }48 return dst;49}50 51void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx,52 Stream &strm, uint32_t dump_mask) {53 if (dump_mask & eDumpOptionType)54 strm.Printf("(%s)", GetTypeAsCString());55 if (dump_mask & eDumpOptionValue) {56 if (dump_mask & eDumpOptionType)57 strm.PutCString(" = ");58 strm << '"' << EscapeBackticks(m_current_format) << '"';59 if (dump_mask & eDumpOptionDefaultValue &&60 m_current_format != m_default_format) {61 DefaultValueFormat label(strm);62 strm << '"' << EscapeBackticks(m_default_format) << '"';63 }64 }65}66 67llvm::json::Value68OptionValueFormatEntity::ToJSON(const ExecutionContext *exe_ctx) const {69 return EscapeBackticks(m_current_format);70}71 72Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,73 VarSetOperationType op) {74 Status error;75 switch (op) {76 case eVarSetOperationClear:77 Clear();78 NotifyValueChanged();79 break;80 81 case eVarSetOperationReplace:82 case eVarSetOperationAssign: {83 // Check if the string starts with a quote character after removing leading84 // and trailing spaces. If it does start with a quote character, make sure85 // it ends with the same quote character and remove the quotes before we86 // parse the format string. If the string doesn't start with a quote, leave87 // the string alone and parse as is.88 llvm::StringRef trimmed_value_str = value_str.trim();89 if (!trimmed_value_str.empty()) {90 const char first_char = trimmed_value_str[0];91 if (first_char == '"' || first_char == '\'') {92 const size_t trimmed_len = trimmed_value_str.size();93 if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) {94 error = Status::FromErrorString("mismatched quotes");95 return error;96 }97 value_str = trimmed_value_str.substr(1, trimmed_len - 2);98 }99 }100 FormatEntity::Entry entry;101 error = FormatEntity::Parse(value_str, entry);102 if (error.Success()) {103 m_current_entry = std::move(entry);104 m_current_format = std::string(value_str);105 m_value_was_set = true;106 NotifyValueChanged();107 }108 } break;109 110 case eVarSetOperationInsertBefore:111 case eVarSetOperationInsertAfter:112 case eVarSetOperationRemove:113 case eVarSetOperationAppend:114 case eVarSetOperationInvalid:115 error = OptionValue::SetValueFromString(value_str, op);116 break;117 }118 return error;119}120 121void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,122 CompletionRequest &request) {123 FormatEntity::AutoComplete(request);124}125