blob: 3501423a7325d69d1537b591e9cab55786b67321 [file] [log] [blame]
Greg Clayton554f68d2015-02-04 22:00:53 +00001//===-- OptionValueFormatEntity.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Clayton554f68d2015-02-04 22:00:53 +000010#include "lldb/Interpreter/OptionValueFormatEntity.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Module.h"
Greg Clayton554f68d2015-02-04 22:00:53 +000017#include "lldb/Interpreter/CommandInterpreter.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000018#include "lldb/Utility/Stream.h"
Zachary Turner573ab902017-03-21 18:25:04 +000019#include "lldb/Utility/StringList.h"
Greg Clayton554f68d2015-02-04 22:00:53 +000020using namespace lldb;
21using namespace lldb_private;
22
Kate Stoneb9c1b512016-09-06 20:57:50 +000023OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format)
24 : OptionValue(), m_current_format(), m_default_format(), m_current_entry(),
25 m_default_entry() {
26 if (default_format && default_format[0]) {
27 llvm::StringRef default_format_str(default_format);
Zachary Turner97206d52017-05-12 04:51:55 +000028 Status error = FormatEntity::Parse(default_format_str, m_default_entry);
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 if (error.Success()) {
30 m_default_format = default_format;
31 m_current_format = default_format;
32 m_current_entry = m_default_entry;
Greg Clayton554f68d2015-02-04 22:00:53 +000033 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000034 }
Greg Clayton554f68d2015-02-04 22:00:53 +000035}
36
Kate Stoneb9c1b512016-09-06 20:57:50 +000037bool OptionValueFormatEntity::Clear() {
38 m_current_entry = m_default_entry;
39 m_current_format = m_default_format;
40 m_value_was_set = false;
41 return true;
Greg Clayton554f68d2015-02-04 22:00:53 +000042}
43
Jonas Devlieghere64011592018-10-01 13:22:24 +000044static void EscapeBackticks(llvm::StringRef str, std::string &dst) {
45 dst.clear();
46 dst.reserve(str.size());
47
48 for (size_t i = 0, e = str.size(); i != e; ++i) {
49 char c = str[i];
50 if (c == '`') {
51 if (i == 0 || str[i - 1] != '\\')
52 dst += '\\';
53 }
54 dst += c;
55 }
56}
57
Kate Stoneb9c1b512016-09-06 20:57:50 +000058void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx,
59 Stream &strm, uint32_t dump_mask) {
60 if (dump_mask & eDumpOptionType)
61 strm.Printf("(%s)", GetTypeAsCString());
62 if (dump_mask & eDumpOptionValue) {
Greg Clayton554f68d2015-02-04 22:00:53 +000063 if (dump_mask & eDumpOptionType)
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 strm.PutCString(" = \"");
Jonas Devlieghere64011592018-10-01 13:22:24 +000065 std::string escaped;
66 EscapeBackticks(m_current_format, escaped);
67 strm << escaped << '"';
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 }
69}
70
Zachary Turner97206d52017-05-12 04:51:55 +000071Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,
72 VarSetOperationType op) {
73 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 switch (op) {
75 case eVarSetOperationClear:
76 Clear();
77 NotifyValueChanged();
78 break;
79
80 case eVarSetOperationReplace:
81 case eVarSetOperationAssign: {
82 // Check if the string starts with a quote character after removing leading
Adrian Prantl05097242018-04-30 16:49:04 +000083 // and trailing spaces. If it does start with a quote character, make sure
84 // it ends with the same quote character and remove the quotes before we
85 // parse the format string. If the string doesn't start with a quote, leave
86 // the string alone and parse as is.
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 llvm::StringRef trimmed_value_str = value_str.trim();
88 if (!trimmed_value_str.empty()) {
89 const char first_char = trimmed_value_str[0];
90 if (first_char == '"' || first_char == '\'') {
91 const size_t trimmed_len = trimmed_value_str.size();
92 if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) {
93 error.SetErrorStringWithFormat("mismatched quotes");
94 return error;
95 }
96 value_str = trimmed_value_str.substr(1, trimmed_len - 2);
97 }
Greg Clayton554f68d2015-02-04 22:00:53 +000098 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 FormatEntity::Entry entry;
100 error = FormatEntity::Parse(value_str, entry);
101 if (error.Success()) {
102 m_current_entry = std::move(entry);
103 m_current_format = value_str;
104 m_value_was_set = true;
105 NotifyValueChanged();
Greg Clayton554f68d2015-02-04 22:00:53 +0000106 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 } break;
108
109 case eVarSetOperationInsertBefore:
110 case eVarSetOperationInsertAfter:
111 case eVarSetOperationRemove:
112 case eVarSetOperationAppend:
113 case eVarSetOperationInvalid:
114 error = OptionValue::SetValueFromString(value_str, op);
115 break;
116 }
117 return error;
Greg Clayton554f68d2015-02-04 22:00:53 +0000118}
119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
121 return OptionValueSP(new OptionValueFormatEntity(*this));
Greg Clayton554f68d2015-02-04 22:00:53 +0000122}
123
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000124size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
125 CompletionRequest &request) {
126 return FormatEntity::AutoComplete(request);
Greg Clayton554f68d2015-02-04 22:00:53 +0000127}