1 //===-- OptionValueBoolean.cpp ------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "lldb/Interpreter/OptionValueBoolean.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Core/StringList.h"
19 #include "lldb/Host/PosixApi.h"
20 #include "lldb/Interpreter/Args.h"
21 #include "llvm/ADT/STLExtras.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 void OptionValueBoolean::DumpValue(const ExecutionContext *exe_ctx,
27                                    Stream &strm, uint32_t dump_mask) {
28   if (dump_mask & eDumpOptionType)
29     strm.Printf("(%s)", GetTypeAsCString());
30   //    if (dump_mask & eDumpOptionName)
31   //        DumpQualifiedName (strm);
32   if (dump_mask & eDumpOptionValue) {
33     if (dump_mask & eDumpOptionType)
34       strm.PutCString(" = ");
35     strm.PutCString(m_current_value ? "true" : "false");
36   }
37 }
38 
39 Error OptionValueBoolean::SetValueFromString(llvm::StringRef value_str,
40                                              VarSetOperationType op) {
41   Error error;
42   switch (op) {
43   case eVarSetOperationClear:
44     Clear();
45     NotifyValueChanged();
46     break;
47 
48   case eVarSetOperationReplace:
49   case eVarSetOperationAssign: {
50     bool success = false;
51     bool value =
52         Args::StringToBoolean(value_str.str().c_str(), false, &success);
53     if (success) {
54       m_value_was_set = true;
55       m_current_value = value;
56       NotifyValueChanged();
57     } else {
58       if (value_str.size() == 0)
59         error.SetErrorString("invalid boolean string value <empty>");
60       else
61         error.SetErrorStringWithFormat("invalid boolean string value: '%s'",
62                                        value_str.str().c_str());
63     }
64   } break;
65 
66   case eVarSetOperationInsertBefore:
67   case eVarSetOperationInsertAfter:
68   case eVarSetOperationRemove:
69   case eVarSetOperationAppend:
70   case eVarSetOperationInvalid:
71     error = OptionValue::SetValueFromString(value_str, op);
72     break;
73   }
74   return error;
75 }
76 
77 lldb::OptionValueSP OptionValueBoolean::DeepCopy() const {
78   return OptionValueSP(new OptionValueBoolean(*this));
79 }
80 
81 size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
82                                         const char *s, int match_start_point,
83                                         int max_return_elements,
84                                         bool &word_complete,
85                                         StringList &matches) {
86   word_complete = false;
87   matches.Clear();
88   struct StringEntry {
89     const char *string;
90     const size_t length;
91   };
92   static const StringEntry g_autocomplete_entries[] = {
93       {"true", 4}, {"false", 5}, {"on", 2}, {"off", 3},
94       {"yes", 3},  {"no", 2},    {"1", 1},  {"0", 1},
95   };
96   const size_t k_num_autocomplete_entries =
97       llvm::array_lengthof(g_autocomplete_entries);
98 
99   if (s && s[0]) {
100     const size_t s_len = strlen(s);
101     for (size_t i = 0; i < k_num_autocomplete_entries; ++i) {
102       if (s_len <= g_autocomplete_entries[i].length)
103         if (::strncasecmp(s, g_autocomplete_entries[i].string, s_len) == 0)
104           matches.AppendString(g_autocomplete_entries[i].string);
105     }
106   } else {
107     // only suggest "true" or "false" by default
108     for (size_t i = 0; i < 2; ++i)
109       matches.AppendString(g_autocomplete_entries[i].string);
110   }
111   return matches.GetSize();
112 }
113