xref: /src/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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