1254721Semaste//===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Interpreter/OptionValueProperties.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste// C++ Includes
14254721Semaste// Other libraries and framework includes
15254721Semaste// Project includes
16254721Semaste#include "lldb/Core/Flags.h"
17254721Semaste#include "lldb/Core/Stream.h"
18254721Semaste#include "lldb/Core/StringList.h"
19254721Semaste#include "lldb/Core/UserSettingsController.h"
20254721Semaste#include "lldb/Interpreter/Args.h"
21254721Semaste#include "lldb/Interpreter/OptionValues.h"
22254721Semaste#include "lldb/Interpreter/Property.h"
23254721Semaste
24254721Semasteusing namespace lldb;
25254721Semasteusing namespace lldb_private;
26254721Semaste
27254721Semaste
28254721SemasteOptionValueProperties::OptionValueProperties (const ConstString &name) :
29254721Semaste    OptionValue (),
30254721Semaste    m_name (name),
31254721Semaste    m_properties (),
32254721Semaste    m_name_to_index ()
33254721Semaste{
34254721Semaste}
35254721Semaste
36254721SemasteOptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
37254721Semaste    OptionValue (global_properties),
38254721Semaste    m_name (global_properties.m_name),
39254721Semaste    m_properties (global_properties.m_properties),
40254721Semaste    m_name_to_index (global_properties.m_name_to_index)
41254721Semaste{
42254721Semaste    // We now have an exact copy of "global_properties". We need to now
43254721Semaste    // find all non-global settings and copy the property values so that
44254721Semaste    // all non-global settings get new OptionValue instances created for
45254721Semaste    // them.
46254721Semaste    const size_t num_properties = m_properties.size();
47254721Semaste    for (size_t i=0; i<num_properties; ++i)
48254721Semaste    {
49254721Semaste        // Duplicate any values that are not global when contructing properties from
50254721Semaste        // a global copy
51254721Semaste        if (m_properties[i].IsGlobal() == false)
52254721Semaste        {
53254721Semaste            lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
54254721Semaste            m_properties[i].SetOptionValue(new_value_sp);
55254721Semaste        }
56254721Semaste    }
57254721Semaste}
58254721Semaste
59254721Semaste
60254721Semaste
61254721Semastesize_t
62254721SemasteOptionValueProperties::GetNumProperties() const
63254721Semaste{
64254721Semaste    return m_properties.size();
65254721Semaste}
66254721Semaste
67254721Semaste
68254721Semastevoid
69254721SemasteOptionValueProperties::Initialize (const PropertyDefinition *defs)
70254721Semaste{
71254721Semaste    for (size_t i=0; defs[i].name; ++i)
72254721Semaste    {
73254721Semaste        Property property(defs[i]);
74254721Semaste        assert(property.IsValid());
75254721Semaste        m_name_to_index.Append(property.GetName().GetCString(),m_properties.size());
76254721Semaste        property.GetValue()->SetParent(shared_from_this());
77254721Semaste        m_properties.push_back(property);
78254721Semaste    }
79254721Semaste    m_name_to_index.Sort();
80254721Semaste}
81254721Semaste
82254721Semastevoid
83254721SemasteOptionValueProperties::AppendProperty(const ConstString &name,
84254721Semaste                                      const ConstString &desc,
85254721Semaste                                      bool is_global,
86254721Semaste                                      const OptionValueSP &value_sp)
87254721Semaste{
88254721Semaste    Property property(name, desc, is_global, value_sp);
89254721Semaste    m_name_to_index.Append(name.GetCString(),m_properties.size());
90254721Semaste    m_properties.push_back(property);
91254721Semaste    value_sp->SetParent (shared_from_this());
92254721Semaste    m_name_to_index.Sort();
93254721Semaste}
94254721Semaste
95254721Semaste
96254721Semaste
97254721Semaste//bool
98254721Semaste//OptionValueProperties::GetQualifiedName (Stream &strm)
99254721Semaste//{
100254721Semaste//    bool dumped_something = false;
101254721Semaste////    lldb::OptionValuePropertiesSP parent_sp(GetParent ());
102254721Semaste////    if (parent_sp)
103254721Semaste////    {
104254721Semaste////        parent_sp->GetQualifiedName (strm);
105254721Semaste////        strm.PutChar('.');
106254721Semaste////        dumped_something = true;
107254721Semaste////    }
108254721Semaste//    if (m_name)
109254721Semaste//    {
110254721Semaste//        strm << m_name;
111254721Semaste//        dumped_something = true;
112254721Semaste//    }
113254721Semaste//    return dumped_something;
114254721Semaste//}
115254721Semaste//
116254721Semastelldb::OptionValueSP
117254721SemasteOptionValueProperties::GetValueForKey  (const ExecutionContext *exe_ctx,
118254721Semaste                                        const ConstString &key,
119254721Semaste                                        bool will_modify) const
120254721Semaste{
121254721Semaste    lldb::OptionValueSP value_sp;
122254721Semaste    size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX);
123254721Semaste    if (idx < m_properties.size())
124254721Semaste        value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
125254721Semaste    return value_sp;
126254721Semaste}
127254721Semaste
128254721Semastelldb::OptionValueSP
129254721SemasteOptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
130254721Semaste                                    const char *name,
131254721Semaste                                    bool will_modify,
132254721Semaste                                    Error &error) const
133254721Semaste{
134254721Semaste    lldb::OptionValueSP value_sp;
135254721Semaste
136254721Semaste    if (name && name[0])
137254721Semaste    {
138254721Semaste        const char *sub_name = NULL;
139254721Semaste        ConstString key;
140254721Semaste        size_t key_len = ::strcspn (name, ".[{");
141254721Semaste
142254721Semaste        if (name[key_len])
143254721Semaste        {
144254721Semaste            key.SetCStringWithLength (name, key_len);
145254721Semaste            sub_name = name + key_len;
146254721Semaste        }
147254721Semaste        else
148254721Semaste            key.SetCString (name);
149254721Semaste
150254721Semaste        value_sp = GetValueForKey (exe_ctx, key, will_modify);
151254721Semaste        if (sub_name && value_sp)
152254721Semaste        {
153254721Semaste            switch (sub_name[0])
154254721Semaste            {
155254721Semaste            case '.':
156254721Semaste                return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
157254721Semaste
158254721Semaste            case '{':
159254721Semaste                // Predicate matching for predicates like
160254721Semaste                // "<setting-name>{<predicate>}"
161254721Semaste                // strings are parsed by the current OptionValueProperties subclass
162254721Semaste                // to mean whatever they want to. For instance a subclass of
163254721Semaste                // OptionValueProperties for a lldb_private::Target might implement:
164254721Semaste                // "target.run-args{arch==i386}"   -- only set run args if the arch is i386
165254721Semaste                // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
166254721Semaste                // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if exectable basename is "test" and arch is "x86_64"
167254721Semaste                if (sub_name[1])
168254721Semaste                {
169254721Semaste                    const char *predicate_start = sub_name + 1;
170254721Semaste                    const char *predicate_end = strchr(predicate_start, '}');
171254721Semaste                    if (predicate_end)
172254721Semaste                    {
173254721Semaste                        std::string predicate(predicate_start, predicate_end);
174254721Semaste                        if (PredicateMatches(exe_ctx, predicate.c_str()))
175254721Semaste                        {
176254721Semaste                            if (predicate_end[1])
177254721Semaste                            {
178254721Semaste                                // Still more subvalue string to evaluate
179254721Semaste                                return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
180254721Semaste                            }
181254721Semaste                            else
182254721Semaste                            {
183254721Semaste                                // We have a match!
184254721Semaste                                break;
185254721Semaste                            }
186254721Semaste                        }
187254721Semaste                    }
188254721Semaste                }
189254721Semaste                // Predicate didn't match or wasn't correctly formed
190254721Semaste                value_sp.reset();
191254721Semaste                break;
192254721Semaste
193254721Semaste            case '[':
194254721Semaste                // Array or dictionary access for subvalues like:
195254721Semaste                // "[12]"       -- access 12th array element
196254721Semaste                // "['hello']"  -- dictionary access of key named hello
197254721Semaste                return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
198254721Semaste
199254721Semaste            default:
200254721Semaste                value_sp.reset();
201254721Semaste                break;
202254721Semaste            }
203254721Semaste        }
204254721Semaste    }
205254721Semaste    return value_sp;
206254721Semaste}
207254721Semaste
208254721SemasteError
209254721SemasteOptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
210254721Semaste                                    VarSetOperationType op,
211254721Semaste                                    const char *name,
212254721Semaste                                    const char *value)
213254721Semaste{
214254721Semaste    Error error;
215254721Semaste    const bool will_modify = true;
216254721Semaste    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
217254721Semaste    if (value_sp)
218254721Semaste        error = value_sp->SetValueFromCString(value, op);
219254721Semaste    else
220254721Semaste    {
221254721Semaste        if (error.AsCString() == NULL)
222254721Semaste            error.SetErrorStringWithFormat("invalid value path '%s'", name);
223254721Semaste    }
224254721Semaste    return error;
225254721Semaste}
226254721Semaste
227254721Semaste
228254721SemasteConstString
229254721SemasteOptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
230254721Semaste{
231254721Semaste    const Property *property = GetPropertyAtIndex(NULL, false, idx);
232254721Semaste    if (property)
233254721Semaste        return property->GetName();
234254721Semaste    return ConstString();
235254721Semaste
236254721Semaste}
237254721Semaste
238254721Semasteconst char *
239254721SemasteOptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
240254721Semaste{
241254721Semaste    const Property *property = GetPropertyAtIndex(NULL, false, idx);
242254721Semaste    if (property)
243254721Semaste        return property->GetDescription();
244254721Semaste    return NULL;
245254721Semaste}
246254721Semaste
247254721Semasteuint32_t
248254721SemasteOptionValueProperties::GetPropertyIndex (const ConstString &name) const
249254721Semaste{
250254721Semaste    return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
251254721Semaste}
252254721Semaste
253254721Semasteconst Property *
254254721SemasteOptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
255254721Semaste{
256254721Semaste    return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
257254721Semaste}
258254721Semaste
259254721Semasteconst Property *
260254721SemasteOptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
261254721Semaste{
262254721Semaste    return ProtectedGetPropertyAtIndex (idx);
263254721Semaste}
264254721Semaste
265254721Semastelldb::OptionValueSP
266254721SemasteOptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
267254721Semaste                                                bool will_modify,
268254721Semaste                                                uint32_t idx) const
269254721Semaste{
270254721Semaste    const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
271254721Semaste    if (setting)
272254721Semaste        return setting->GetValue();
273254721Semaste    return OptionValueSP();
274254721Semaste}
275254721Semaste
276254721SemasteOptionValuePathMappings *
277254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
278254721Semaste{
279254721Semaste    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
280254721Semaste    if (value_sp)
281254721Semaste        return value_sp->GetAsPathMappings();
282254721Semaste    return NULL;
283254721Semaste}
284254721Semaste
285254721SemasteOptionValueFileSpecList *
286254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
287254721Semaste{
288254721Semaste    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
289254721Semaste    if (value_sp)
290254721Semaste        return value_sp->GetAsFileSpecList();
291254721Semaste    return NULL;
292254721Semaste}
293254721Semaste
294254721SemasteOptionValueArch *
295254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
296254721Semaste{
297254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
298254721Semaste    if (property)
299254721Semaste        return property->GetValue()->GetAsArch();
300254721Semaste    return NULL;
301254721Semaste}
302254721Semaste
303254721Semastebool
304254721SemasteOptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
305254721Semaste{
306254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
307254721Semaste    if (property)
308254721Semaste    {
309254721Semaste        OptionValue *value = property->GetValue().get();
310254721Semaste        if (value)
311254721Semaste        {
312254721Semaste            const OptionValueArray *array = value->GetAsArray();
313254721Semaste            if (array)
314254721Semaste                return array->GetArgs(args);
315254721Semaste            else
316254721Semaste            {
317254721Semaste                const OptionValueDictionary *dict = value->GetAsDictionary();
318254721Semaste                if (dict)
319254721Semaste                    return dict->GetArgs(args);
320254721Semaste            }
321254721Semaste        }
322254721Semaste    }
323254721Semaste    return false;
324254721Semaste}
325254721Semaste
326254721Semastebool
327254721SemasteOptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
328254721Semaste{
329254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
330254721Semaste    if (property)
331254721Semaste    {
332254721Semaste        OptionValue *value = property->GetValue().get();
333254721Semaste        if (value)
334254721Semaste        {
335254721Semaste            OptionValueArray *array = value->GetAsArray();
336254721Semaste            if (array)
337254721Semaste                return array->SetArgs(args, eVarSetOperationAssign).Success();
338254721Semaste            else
339254721Semaste            {
340254721Semaste                OptionValueDictionary *dict = value->GetAsDictionary();
341254721Semaste                if (dict)
342254721Semaste                    return dict->SetArgs(args, eVarSetOperationAssign).Success();
343254721Semaste            }
344254721Semaste        }
345254721Semaste    }
346254721Semaste    return false;
347254721Semaste}
348254721Semaste
349254721Semastebool
350254721SemasteOptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
351254721Semaste{
352254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
353254721Semaste    if (property)
354254721Semaste    {
355254721Semaste        OptionValue *value = property->GetValue().get();
356254721Semaste        if (value)
357254721Semaste            return value->GetBooleanValue(fail_value);
358254721Semaste    }
359254721Semaste    return fail_value;
360254721Semaste}
361254721Semaste
362254721Semastebool
363254721SemasteOptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
364254721Semaste{
365254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
366254721Semaste    if (property)
367254721Semaste    {
368254721Semaste        OptionValue *value = property->GetValue().get();
369254721Semaste        if (value)
370254721Semaste        {
371254721Semaste            value->SetBooleanValue(new_value);
372254721Semaste            return true;
373254721Semaste        }
374254721Semaste    }
375254721Semaste    return false;
376254721Semaste}
377254721Semaste
378254721SemasteOptionValueDictionary *
379254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
380254721Semaste{
381254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
382254721Semaste    if (property)
383254721Semaste        return property->GetValue()->GetAsDictionary();
384254721Semaste    return NULL;
385254721Semaste}
386254721Semaste
387254721Semasteint64_t
388254721SemasteOptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
389254721Semaste{
390254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
391254721Semaste    if (property)
392254721Semaste    {
393254721Semaste        OptionValue *value = property->GetValue().get();
394254721Semaste        if (value)
395254721Semaste            return value->GetEnumerationValue(fail_value);
396254721Semaste    }
397254721Semaste    return fail_value;
398254721Semaste}
399254721Semaste
400254721Semastebool
401254721SemasteOptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
402254721Semaste{
403254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
404254721Semaste    if (property)
405254721Semaste    {
406254721Semaste        OptionValue *value = property->GetValue().get();
407254721Semaste        if (value)
408254721Semaste            return value->SetEnumerationValue(new_value);
409254721Semaste    }
410254721Semaste    return false;
411254721Semaste}
412254721Semaste
413254721Semaste
414254721SemasteOptionValueFileSpec *
415254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
416254721Semaste{
417254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
418254721Semaste    if (property)
419254721Semaste    {
420254721Semaste        OptionValue *value = property->GetValue().get();
421254721Semaste        if (value)
422254721Semaste            return value->GetAsFileSpec();
423254721Semaste    }
424254721Semaste    return NULL;
425254721Semaste}
426254721Semaste
427254721Semaste
428254721SemasteFileSpec
429254721SemasteOptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
430254721Semaste{
431254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
432254721Semaste    if (property)
433254721Semaste    {
434254721Semaste        OptionValue *value = property->GetValue().get();
435254721Semaste        if (value)
436254721Semaste            return value->GetFileSpecValue();
437254721Semaste    }
438254721Semaste    return FileSpec();
439254721Semaste}
440254721Semaste
441254721Semaste
442254721Semastebool
443254721SemasteOptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
444254721Semaste{
445254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
446254721Semaste    if (property)
447254721Semaste    {
448254721Semaste        OptionValue *value = property->GetValue().get();
449254721Semaste        if (value)
450254721Semaste            return value->SetFileSpecValue(new_file_spec);
451254721Semaste    }
452254721Semaste    return false;
453254721Semaste}
454254721Semaste
455254721Semasteconst RegularExpression *
456254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
457254721Semaste{
458254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
459254721Semaste    if (property)
460254721Semaste    {
461254721Semaste        OptionValue *value = property->GetValue().get();
462254721Semaste        if (value)
463254721Semaste            return value->GetRegexValue();
464254721Semaste    }
465254721Semaste    return NULL;
466254721Semaste}
467254721Semaste
468254721SemasteOptionValueSInt64 *
469254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
470254721Semaste{
471254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
472254721Semaste    if (property)
473254721Semaste    {
474254721Semaste        OptionValue *value = property->GetValue().get();
475254721Semaste        if (value)
476254721Semaste            return value->GetAsSInt64();
477254721Semaste    }
478254721Semaste    return NULL;
479254721Semaste}
480254721Semaste
481254721Semasteint64_t
482254721SemasteOptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
483254721Semaste{
484254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
485254721Semaste    if (property)
486254721Semaste    {
487254721Semaste        OptionValue *value = property->GetValue().get();
488254721Semaste        if (value)
489254721Semaste            return value->GetSInt64Value(fail_value);
490254721Semaste    }
491254721Semaste    return fail_value;
492254721Semaste}
493254721Semaste
494254721Semastebool
495254721SemasteOptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
496254721Semaste{
497254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
498254721Semaste    if (property)
499254721Semaste    {
500254721Semaste        OptionValue *value = property->GetValue().get();
501254721Semaste        if (value)
502254721Semaste            return value->SetSInt64Value(new_value);
503254721Semaste    }
504254721Semaste    return false;
505254721Semaste}
506254721Semaste
507254721Semasteconst char *
508254721SemasteOptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
509254721Semaste{
510254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
511254721Semaste    if (property)
512254721Semaste    {
513254721Semaste        OptionValue *value = property->GetValue().get();
514254721Semaste        if (value)
515254721Semaste            return value->GetStringValue(fail_value);
516254721Semaste    }
517254721Semaste    return fail_value;
518254721Semaste}
519254721Semaste
520254721Semastebool
521254721SemasteOptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
522254721Semaste{
523254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
524254721Semaste    if (property)
525254721Semaste    {
526254721Semaste        OptionValue *value = property->GetValue().get();
527254721Semaste        if (value)
528254721Semaste            return value->SetStringValue(new_value);
529254721Semaste    }
530254721Semaste    return false;
531254721Semaste}
532254721Semaste
533254721SemasteOptionValueString *
534254721SemasteOptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
535254721Semaste{
536254721Semaste    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
537254721Semaste    if (value_sp)
538254721Semaste        return value_sp->GetAsString();
539254721Semaste    return NULL;
540254721Semaste}
541254721Semaste
542254721Semaste
543254721Semasteuint64_t
544254721SemasteOptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
545254721Semaste{
546254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
547254721Semaste    if (property)
548254721Semaste    {
549254721Semaste        OptionValue *value = property->GetValue().get();
550254721Semaste        if (value)
551254721Semaste            return value->GetUInt64Value(fail_value);
552254721Semaste    }
553254721Semaste    return fail_value;
554254721Semaste}
555254721Semaste
556254721Semastebool
557254721SemasteOptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
558254721Semaste{
559254721Semaste    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
560254721Semaste    if (property)
561254721Semaste    {
562254721Semaste        OptionValue *value = property->GetValue().get();
563254721Semaste        if (value)
564254721Semaste            return value->SetUInt64Value(new_value);
565254721Semaste    }
566254721Semaste    return false;
567254721Semaste}
568254721Semaste
569254721Semastebool
570254721SemasteOptionValueProperties::Clear ()
571254721Semaste{
572254721Semaste    const size_t num_properties = m_properties.size();
573254721Semaste    for (size_t i=0; i<num_properties; ++i)
574254721Semaste        m_properties[i].GetValue()->Clear();
575254721Semaste    return true;
576254721Semaste}
577254721Semaste
578254721Semaste
579254721SemasteError
580254721SemasteOptionValueProperties::SetValueFromCString (const char *value, VarSetOperationType op)
581254721Semaste{
582254721Semaste    Error error;
583254721Semaste
584254721Semaste//    Args args(value_cstr);
585254721Semaste//    const size_t argc = args.GetArgumentCount();
586254721Semaste    switch (op)
587254721Semaste    {
588254721Semaste        case eVarSetOperationClear:
589254721Semaste            Clear ();
590254721Semaste            break;
591254721Semaste
592254721Semaste        case eVarSetOperationReplace:
593254721Semaste        case eVarSetOperationAssign:
594254721Semaste        case eVarSetOperationRemove:
595254721Semaste        case eVarSetOperationInsertBefore:
596254721Semaste        case eVarSetOperationInsertAfter:
597254721Semaste        case eVarSetOperationAppend:
598254721Semaste        case eVarSetOperationInvalid:
599254721Semaste            error = OptionValue::SetValueFromCString (value, op);
600254721Semaste            break;
601254721Semaste    }
602254721Semaste
603254721Semaste    return error;
604254721Semaste}
605254721Semaste
606254721Semastevoid
607254721SemasteOptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
608254721Semaste{
609254721Semaste    const size_t num_properties = m_properties.size();
610254721Semaste    for (size_t i=0; i<num_properties; ++i)
611254721Semaste    {
612254721Semaste        const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
613254721Semaste        if (property)
614254721Semaste        {
615254721Semaste            OptionValue *option_value = property->GetValue().get();
616254721Semaste            assert (option_value);
617254721Semaste            const bool transparent_value = option_value->ValueIsTransparent ();
618254721Semaste            property->Dump (exe_ctx,
619254721Semaste                            strm,
620254721Semaste                            dump_mask);
621254721Semaste            if (!transparent_value)
622254721Semaste                strm.EOL();
623254721Semaste        }
624254721Semaste    }
625254721Semaste}
626254721Semaste
627254721SemasteError
628254721SemasteOptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
629254721Semaste                                          Stream &strm,
630254721Semaste                                          const char *property_path,
631254721Semaste                                          uint32_t dump_mask)
632254721Semaste{
633254721Semaste    Error error;
634254721Semaste    const bool will_modify = false;
635254721Semaste    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
636254721Semaste    if (value_sp)
637254721Semaste    {
638254721Semaste        if (!value_sp->ValueIsTransparent ())
639254721Semaste        {
640254721Semaste            if (dump_mask & eDumpOptionName)
641254721Semaste                strm.PutCString (property_path);
642254721Semaste            if (dump_mask & ~eDumpOptionName)
643254721Semaste                strm.PutChar (' ');
644254721Semaste        }
645254721Semaste        value_sp->DumpValue (exe_ctx, strm, dump_mask);
646254721Semaste    }
647254721Semaste    return error;
648254721Semaste}
649254721Semaste
650254721Semastelldb::OptionValueSP
651254721SemasteOptionValueProperties::DeepCopy () const
652254721Semaste{
653254721Semaste    assert(!"this shouldn't happen");
654263363Semaste    return lldb::OptionValueSP();
655254721Semaste}
656254721Semaste
657254721Semasteconst Property *
658254721SemasteOptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
659254721Semaste                                          bool will_modify,
660254721Semaste                                          const char *name) const
661254721Semaste{
662254721Semaste    const Property *property = NULL;
663254721Semaste    if (name && name[0])
664254721Semaste    {
665254721Semaste        const char *sub_name = NULL;
666254721Semaste        ConstString key;
667254721Semaste        size_t key_len = ::strcspn (name, ".[{");
668254721Semaste
669254721Semaste        if (name[key_len])
670254721Semaste        {
671254721Semaste            key.SetCStringWithLength (name, key_len);
672254721Semaste            sub_name = name + key_len;
673254721Semaste        }
674254721Semaste        else
675254721Semaste            key.SetCString (name);
676254721Semaste
677254721Semaste        property = GetProperty (exe_ctx, will_modify, key);
678254721Semaste        if (sub_name && property)
679254721Semaste        {
680254721Semaste            if (sub_name[0] == '.')
681254721Semaste            {
682254721Semaste                OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
683254721Semaste                if (sub_properties)
684254721Semaste                    return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
685254721Semaste            }
686254721Semaste            property = NULL;
687254721Semaste        }
688254721Semaste    }
689254721Semaste    return property;
690254721Semaste}
691254721Semaste
692254721Semastevoid
693254721SemasteOptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
694254721Semaste                                            Stream &strm) const
695254721Semaste{
696254721Semaste    size_t max_name_len = 0;
697254721Semaste    const size_t num_properties = m_properties.size();
698254721Semaste    for (size_t i=0; i<num_properties; ++i)
699254721Semaste    {
700254721Semaste        const Property *property = ProtectedGetPropertyAtIndex(i);
701254721Semaste        if (property)
702254721Semaste            max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
703254721Semaste    }
704254721Semaste    for (size_t i=0; i<num_properties; ++i)
705254721Semaste    {
706254721Semaste        const Property *property = ProtectedGetPropertyAtIndex(i);
707254721Semaste        if (property)
708254721Semaste            property->DumpDescription (interpreter, strm, max_name_len, false);
709254721Semaste    }
710254721Semaste}
711254721Semaste
712254721Semastevoid
713254721SemasteOptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
714254721Semaste{
715254721Semaste    const size_t num_properties = m_properties.size();
716254721Semaste    StreamString strm;
717254721Semaste    for (size_t i=0; i<num_properties; ++i)
718254721Semaste    {
719254721Semaste        const Property *property = ProtectedGetPropertyAtIndex(i);
720254721Semaste        if (property)
721254721Semaste        {
722254721Semaste            const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
723254721Semaste            if (properties)
724254721Semaste            {
725254721Semaste                properties->Apropos (keyword, matching_properties);
726254721Semaste            }
727254721Semaste            else
728254721Semaste            {
729254721Semaste                bool match = false;
730254721Semaste                const char *name = property->GetName().GetCString();
731254721Semaste                if (name && ::strcasestr(name, keyword))
732254721Semaste                    match = true;
733254721Semaste                else
734254721Semaste                {
735254721Semaste                    const char *desc = property->GetDescription();
736254721Semaste                    if (desc && ::strcasestr(desc, keyword))
737254721Semaste                        match = true;
738254721Semaste                }
739254721Semaste                if (match)
740254721Semaste                {
741254721Semaste                    matching_properties.push_back (property);
742254721Semaste                }
743254721Semaste            }
744254721Semaste        }
745254721Semaste    }
746254721Semaste}
747254721Semaste
748254721Semastelldb::OptionValuePropertiesSP
749254721SemasteOptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
750254721Semaste                                       const ConstString &name)
751254721Semaste{
752254721Semaste    lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
753254721Semaste    if (option_value_sp)
754254721Semaste    {
755254721Semaste        OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
756254721Semaste        if (ov_properties)
757254721Semaste            return ov_properties->shared_from_this();
758254721Semaste    }
759254721Semaste    return lldb::OptionValuePropertiesSP();
760254721Semaste}
761254721Semaste
762254721Semaste
763254721Semaste
764