180814287SRaphael Isemann //===-- OptionValueFormatEntity.cpp ---------------------------------------===// 2554f68d3SGreg Clayton // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6554f68d3SGreg Clayton // 7554f68d3SGreg Clayton //===----------------------------------------------------------------------===// 8554f68d3SGreg Clayton 9554f68d3SGreg Clayton #include "lldb/Interpreter/OptionValueFormatEntity.h" 10554f68d3SGreg Clayton 11554f68d3SGreg Clayton #include "lldb/Core/Module.h" 12554f68d3SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 13bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 14573ab909SZachary Turner #include "lldb/Utility/StringList.h" 15554f68d3SGreg Clayton using namespace lldb; 16554f68d3SGreg Clayton using namespace lldb_private; 17554f68d3SGreg Clayton 18*8cdcd41eSTatyana Krasnukha OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) { 19b9c1b51eSKate Stone if (default_format && default_format[0]) { 20554f68d3SGreg Clayton llvm::StringRef default_format_str(default_format); 2197206d57SZachary Turner Status error = FormatEntity::Parse(default_format_str, m_default_entry); 22b9c1b51eSKate Stone if (error.Success()) { 23554f68d3SGreg Clayton m_default_format = default_format; 24554f68d3SGreg Clayton m_current_format = default_format; 25554f68d3SGreg Clayton m_current_entry = m_default_entry; 26554f68d3SGreg Clayton } 27554f68d3SGreg Clayton } 28554f68d3SGreg Clayton } 29554f68d3SGreg Clayton 308d6aa688SJim Ingham void OptionValueFormatEntity::Clear() { 31554f68d3SGreg Clayton m_current_entry = m_default_entry; 32554f68d3SGreg Clayton m_current_format = m_default_format; 33554f68d3SGreg Clayton m_value_was_set = false; 34554f68d3SGreg Clayton } 35554f68d3SGreg Clayton 3664011593SJonas Devlieghere static void EscapeBackticks(llvm::StringRef str, std::string &dst) { 3764011593SJonas Devlieghere dst.clear(); 3864011593SJonas Devlieghere dst.reserve(str.size()); 3964011593SJonas Devlieghere 4064011593SJonas Devlieghere for (size_t i = 0, e = str.size(); i != e; ++i) { 4164011593SJonas Devlieghere char c = str[i]; 4264011593SJonas Devlieghere if (c == '`') { 4364011593SJonas Devlieghere if (i == 0 || str[i - 1] != '\\') 4464011593SJonas Devlieghere dst += '\\'; 4564011593SJonas Devlieghere } 4664011593SJonas Devlieghere dst += c; 4764011593SJonas Devlieghere } 4864011593SJonas Devlieghere } 4964011593SJonas Devlieghere 50b9c1b51eSKate Stone void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx, 51b9c1b51eSKate Stone Stream &strm, uint32_t dump_mask) { 52554f68d3SGreg Clayton if (dump_mask & eDumpOptionType) 53554f68d3SGreg Clayton strm.Printf("(%s)", GetTypeAsCString()); 54b9c1b51eSKate Stone if (dump_mask & eDumpOptionValue) { 55554f68d3SGreg Clayton if (dump_mask & eDumpOptionType) 56b76e25a2SJonas Devlieghere strm.PutCString(" = "); 5764011593SJonas Devlieghere std::string escaped; 5864011593SJonas Devlieghere EscapeBackticks(m_current_format, escaped); 59b76e25a2SJonas Devlieghere strm << '"' << escaped << '"'; 60554f68d3SGreg Clayton } 61554f68d3SGreg Clayton } 62554f68d3SGreg Clayton 6397206d57SZachary Turner Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str, 64b9c1b51eSKate Stone VarSetOperationType op) { 6597206d57SZachary Turner Status error; 66b9c1b51eSKate Stone switch (op) { 67554f68d3SGreg Clayton case eVarSetOperationClear: 68554f68d3SGreg Clayton Clear(); 69554f68d3SGreg Clayton NotifyValueChanged(); 70554f68d3SGreg Clayton break; 71554f68d3SGreg Clayton 72554f68d3SGreg Clayton case eVarSetOperationReplace: 73b9c1b51eSKate Stone case eVarSetOperationAssign: { 74b9c1b51eSKate Stone // Check if the string starts with a quote character after removing leading 7505097246SAdrian Prantl // and trailing spaces. If it does start with a quote character, make sure 7605097246SAdrian Prantl // it ends with the same quote character and remove the quotes before we 7705097246SAdrian Prantl // parse the format string. If the string doesn't start with a quote, leave 7805097246SAdrian Prantl // the string alone and parse as is. 79b2e0c119SGreg Clayton llvm::StringRef trimmed_value_str = value_str.trim(); 80b9c1b51eSKate Stone if (!trimmed_value_str.empty()) { 81b2e0c119SGreg Clayton const char first_char = trimmed_value_str[0]; 82b9c1b51eSKate Stone if (first_char == '"' || first_char == '\'') { 83b2e0c119SGreg Clayton const size_t trimmed_len = trimmed_value_str.size(); 84b9c1b51eSKate Stone if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) { 8589533764SJonas Devlieghere error.SetErrorString("mismatched quotes"); 86b2e0c119SGreg Clayton return error; 87b2e0c119SGreg Clayton } 88b2e0c119SGreg Clayton value_str = trimmed_value_str.substr(1, trimmed_len - 2); 89b2e0c119SGreg Clayton } 90b2e0c119SGreg Clayton } 91554f68d3SGreg Clayton FormatEntity::Entry entry; 92554f68d3SGreg Clayton error = FormatEntity::Parse(value_str, entry); 93b9c1b51eSKate Stone if (error.Success()) { 94554f68d3SGreg Clayton m_current_entry = std::move(entry); 95adcd0268SBenjamin Kramer m_current_format = std::string(value_str); 96554f68d3SGreg Clayton m_value_was_set = true; 97554f68d3SGreg Clayton NotifyValueChanged(); 98554f68d3SGreg Clayton } 99b9c1b51eSKate Stone } break; 100554f68d3SGreg Clayton 101554f68d3SGreg Clayton case eVarSetOperationInsertBefore: 102554f68d3SGreg Clayton case eVarSetOperationInsertAfter: 103554f68d3SGreg Clayton case eVarSetOperationRemove: 104554f68d3SGreg Clayton case eVarSetOperationAppend: 105554f68d3SGreg Clayton case eVarSetOperationInvalid: 106c95f7e2aSPavel Labath error = OptionValue::SetValueFromString(value_str, op); 107554f68d3SGreg Clayton break; 108554f68d3SGreg Clayton } 109554f68d3SGreg Clayton return error; 110554f68d3SGreg Clayton } 111554f68d3SGreg Clayton 112b9c1b51eSKate Stone lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const { 113554f68d3SGreg Clayton return OptionValueSP(new OptionValueFormatEntity(*this)); 114554f68d3SGreg Clayton } 115554f68d3SGreg Clayton 116ae34ed2cSRaphael Isemann void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter, 117a2e76c0bSRaphael Isemann CompletionRequest &request) { 118ae34ed2cSRaphael Isemann FormatEntity::AutoComplete(request); 119554f68d3SGreg Clayton } 120