OptionValueString.cpp revision 360660
1//===-- OptionValueString.cpp ------------------------------------*- C++
2//-*-===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Interpreter/OptionValueString.h"
11
12#include "lldb/Host/OptionParser.h"
13#include "lldb/Utility/Args.h"
14#include "lldb/Utility/Stream.h"
15
16using namespace lldb;
17using namespace lldb_private;
18
19void OptionValueString::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
20                                  uint32_t dump_mask) {
21  if (dump_mask & eDumpOptionType)
22    strm.Printf("(%s)", GetTypeAsCString());
23  if (dump_mask & eDumpOptionValue) {
24    if (dump_mask & eDumpOptionType)
25      strm.PutCString(" = ");
26    if (!m_current_value.empty() || m_value_was_set) {
27      if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) {
28        std::string expanded_escape_value;
29        Args::ExpandEscapedCharacters(m_current_value.c_str(),
30                                      expanded_escape_value);
31        if (dump_mask & eDumpOptionRaw)
32          strm.Printf("%s", expanded_escape_value.c_str());
33        else
34          strm.Printf("\"%s\"", expanded_escape_value.c_str());
35      } else {
36        if (dump_mask & eDumpOptionRaw)
37          strm.Printf("%s", m_current_value.c_str());
38        else
39          strm.Printf("\"%s\"", m_current_value.c_str());
40      }
41    }
42  }
43}
44
45Status OptionValueString::SetValueFromString(llvm::StringRef value,
46                                             VarSetOperationType op) {
47  Status error;
48
49  std::string value_str = value.str();
50  value = value.trim();
51  if (value.size() > 0) {
52    switch (value.front()) {
53    case '"':
54    case '\'': {
55      if (value.size() <= 1 || value.back() != value.front()) {
56        error.SetErrorString("mismatched quotes");
57        return error;
58      }
59      value = value.drop_front().drop_back();
60    } break;
61    }
62    value_str = value.str();
63  }
64
65  switch (op) {
66  case eVarSetOperationInvalid:
67  case eVarSetOperationInsertBefore:
68  case eVarSetOperationInsertAfter:
69  case eVarSetOperationRemove:
70    if (m_validator) {
71      error = m_validator(value_str.c_str(), m_validator_baton);
72      if (error.Fail())
73        return error;
74    }
75    error = OptionValue::SetValueFromString(value, op);
76    break;
77
78  case eVarSetOperationAppend: {
79    std::string new_value(m_current_value);
80    if (value.size() > 0) {
81      if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) {
82        std::string str;
83        Args::EncodeEscapeSequences(value_str.c_str(), str);
84        new_value.append(str);
85      } else
86        new_value.append(value);
87    }
88    if (m_validator) {
89      error = m_validator(new_value.c_str(), m_validator_baton);
90      if (error.Fail())
91        return error;
92    }
93    m_current_value.assign(new_value);
94    NotifyValueChanged();
95  } break;
96
97  case eVarSetOperationClear:
98    Clear();
99    NotifyValueChanged();
100    break;
101
102  case eVarSetOperationReplace:
103  case eVarSetOperationAssign:
104    if (m_validator) {
105      error = m_validator(value_str.c_str(), m_validator_baton);
106      if (error.Fail())
107        return error;
108    }
109    m_value_was_set = true;
110    if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) {
111      Args::EncodeEscapeSequences(value_str.c_str(), m_current_value);
112    } else {
113      SetCurrentValue(value_str);
114    }
115    NotifyValueChanged();
116    break;
117  }
118  return error;
119}
120
121lldb::OptionValueSP OptionValueString::DeepCopy() const {
122  return OptionValueSP(new OptionValueString(*this));
123}
124
125Status OptionValueString::SetCurrentValue(llvm::StringRef value) {
126  if (m_validator) {
127    Status error(m_validator(value.str().c_str(), m_validator_baton));
128    if (error.Fail())
129      return error;
130  }
131  m_current_value.assign(value);
132  return Status();
133}
134
135Status OptionValueString::AppendToCurrentValue(const char *value) {
136  if (value && value[0]) {
137    if (m_validator) {
138      std::string new_value(m_current_value);
139      new_value.append(value);
140      Status error(m_validator(value, m_validator_baton));
141      if (error.Fail())
142        return error;
143      m_current_value.assign(new_value);
144    } else
145      m_current_value.append(value);
146  }
147  return Status();
148}
149