1//===-- OptionValue.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
10#include "lldb/Interpreter/OptionValue.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/StringList.h"
17#include "lldb/Interpreter/OptionValues.h"
18
19using namespace lldb;
20using namespace lldb_private;
21
22
23//-------------------------------------------------------------------------
24// Get this value as a uint64_t value if it is encoded as a boolean,
25// uint64_t or int64_t. Other types will cause "fail_value" to be
26// returned
27//-------------------------------------------------------------------------
28uint64_t
29OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
30{
31    if (success_ptr)
32        *success_ptr = true;
33    switch (GetType())
34    {
35    case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
36    case OptionValue::eTypeSInt64:  return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
37    case OptionValue::eTypeUInt64:  return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
38    default:
39        break;
40    }
41    if (success_ptr)
42        *success_ptr = false;
43    return fail_value;
44}
45
46Error
47OptionValue::SetSubValue (const ExecutionContext *exe_ctx,
48                          VarSetOperationType op,
49                          const char *name,
50                          const char *value)
51{
52    Error error;
53    error.SetErrorStringWithFormat("SetSubValue is not supported");
54    return error;
55}
56
57
58OptionValueBoolean *
59OptionValue::GetAsBoolean ()
60{
61    if (GetType () == OptionValue::eTypeBoolean)
62        return static_cast<OptionValueBoolean *>(this);
63    return NULL;
64}
65
66const OptionValueBoolean *
67OptionValue::GetAsBoolean () const
68{
69    if (GetType () == OptionValue::eTypeBoolean)
70        return static_cast<const OptionValueBoolean *>(this);
71    return NULL;
72}
73
74
75OptionValueFileSpec *
76OptionValue::GetAsFileSpec ()
77{
78    if (GetType () == OptionValue::eTypeFileSpec)
79        return static_cast<OptionValueFileSpec *>(this);
80    return NULL;
81
82}
83
84const OptionValueFileSpec *
85OptionValue::GetAsFileSpec () const
86{
87    if (GetType () == OptionValue::eTypeFileSpec)
88        return static_cast<const OptionValueFileSpec *>(this);
89    return NULL;
90
91}
92
93OptionValueFileSpecList *
94OptionValue::GetAsFileSpecList ()
95{
96    if (GetType () == OptionValue::eTypeFileSpecList)
97        return static_cast<OptionValueFileSpecList *>(this);
98    return NULL;
99
100}
101
102const OptionValueFileSpecList *
103OptionValue::GetAsFileSpecList () const
104{
105    if (GetType () == OptionValue::eTypeFileSpecList)
106        return static_cast<const OptionValueFileSpecList *>(this);
107    return NULL;
108
109}
110
111OptionValueArch *
112OptionValue::GetAsArch ()
113{
114    if (GetType () == OptionValue::eTypeArch)
115        return static_cast<OptionValueArch *>(this);
116    return NULL;
117}
118
119
120const OptionValueArch *
121OptionValue::GetAsArch () const
122{
123    if (GetType () == OptionValue::eTypeArch)
124        return static_cast<const OptionValueArch *>(this);
125    return NULL;
126}
127
128OptionValueArray *
129OptionValue::GetAsArray ()
130{
131    if (GetType () == OptionValue::eTypeArray)
132        return static_cast<OptionValueArray *>(this);
133    return NULL;
134}
135
136
137const OptionValueArray *
138OptionValue::GetAsArray () const
139{
140    if (GetType () == OptionValue::eTypeArray)
141        return static_cast<const OptionValueArray *>(this);
142    return NULL;
143}
144
145OptionValueArgs *
146OptionValue::GetAsArgs ()
147{
148    if (GetType () == OptionValue::eTypeArgs)
149        return static_cast<OptionValueArgs *>(this);
150    return NULL;
151}
152
153
154const OptionValueArgs *
155OptionValue::GetAsArgs () const
156{
157    if (GetType () == OptionValue::eTypeArgs)
158        return static_cast<const OptionValueArgs *>(this);
159    return NULL;
160}
161
162OptionValueDictionary *
163OptionValue::GetAsDictionary ()
164{
165    if (GetType () == OptionValue::eTypeDictionary)
166        return static_cast<OptionValueDictionary *>(this);
167    return NULL;
168}
169
170const OptionValueDictionary *
171OptionValue::GetAsDictionary () const
172{
173    if (GetType () == OptionValue::eTypeDictionary)
174        return static_cast<const OptionValueDictionary *>(this);
175    return NULL;
176}
177
178OptionValueEnumeration *
179OptionValue::GetAsEnumeration ()
180{
181    if (GetType () == OptionValue::eTypeEnum)
182        return static_cast<OptionValueEnumeration *>(this);
183    return NULL;
184}
185
186const OptionValueEnumeration *
187OptionValue::GetAsEnumeration () const
188{
189    if (GetType () == OptionValue::eTypeEnum)
190        return static_cast<const OptionValueEnumeration *>(this);
191    return NULL;
192}
193
194OptionValueFormat *
195OptionValue::GetAsFormat ()
196{
197    if (GetType () == OptionValue::eTypeFormat)
198        return static_cast<OptionValueFormat *>(this);
199    return NULL;
200}
201
202const OptionValueFormat *
203OptionValue::GetAsFormat () const
204{
205    if (GetType () == OptionValue::eTypeFormat)
206        return static_cast<const OptionValueFormat *>(this);
207    return NULL;
208}
209
210OptionValuePathMappings *
211OptionValue::GetAsPathMappings ()
212{
213    if (GetType () == OptionValue::eTypePathMap)
214        return static_cast<OptionValuePathMappings *>(this);
215    return NULL;
216}
217
218const OptionValuePathMappings *
219OptionValue::GetAsPathMappings () const
220{
221    if (GetType () == OptionValue::eTypePathMap)
222        return static_cast<const OptionValuePathMappings *>(this);
223    return NULL;
224}
225
226OptionValueProperties *
227OptionValue::GetAsProperties ()
228{
229    if (GetType () == OptionValue::eTypeProperties)
230        return static_cast<OptionValueProperties *>(this);
231    return NULL;
232}
233
234const OptionValueProperties *
235OptionValue::GetAsProperties () const
236{
237    if (GetType () == OptionValue::eTypeProperties)
238        return static_cast<const OptionValueProperties *>(this);
239    return NULL;
240}
241
242OptionValueRegex *
243OptionValue::GetAsRegex ()
244{
245    if (GetType () == OptionValue::eTypeRegex)
246        return static_cast<OptionValueRegex *>(this);
247    return NULL;
248}
249
250const OptionValueRegex *
251OptionValue::GetAsRegex () const
252{
253    if (GetType () == OptionValue::eTypeRegex)
254        return static_cast<const OptionValueRegex *>(this);
255    return NULL;
256}
257
258OptionValueSInt64 *
259OptionValue::GetAsSInt64 ()
260{
261    if (GetType () == OptionValue::eTypeSInt64)
262        return static_cast<OptionValueSInt64 *>(this);
263    return NULL;
264}
265
266const OptionValueSInt64 *
267OptionValue::GetAsSInt64 () const
268{
269    if (GetType () == OptionValue::eTypeSInt64)
270        return static_cast<const OptionValueSInt64 *>(this);
271    return NULL;
272}
273
274OptionValueString *
275OptionValue::GetAsString ()
276{
277    if (GetType () == OptionValue::eTypeString)
278        return static_cast<OptionValueString *>(this);
279    return NULL;
280}
281
282const OptionValueString *
283OptionValue::GetAsString () const
284{
285    if (GetType () == OptionValue::eTypeString)
286        return static_cast<const OptionValueString *>(this);
287    return NULL;
288}
289
290OptionValueUInt64 *
291OptionValue::GetAsUInt64 ()
292{
293    if (GetType () == OptionValue::eTypeUInt64)
294        return static_cast<OptionValueUInt64 *>(this);
295    return NULL;
296}
297
298const OptionValueUInt64 *
299OptionValue::GetAsUInt64 () const
300{
301    if (GetType () == OptionValue::eTypeUInt64)
302        return static_cast<const OptionValueUInt64 *>(this);
303    return NULL;
304}
305
306OptionValueUUID *
307OptionValue::GetAsUUID ()
308{
309    if (GetType () == OptionValue::eTypeUUID)
310        return static_cast<OptionValueUUID *>(this);
311    return NULL;
312
313}
314
315const OptionValueUUID *
316OptionValue::GetAsUUID () const
317{
318    if (GetType () == OptionValue::eTypeUUID)
319        return static_cast<const OptionValueUUID *>(this);
320    return NULL;
321
322}
323
324bool
325OptionValue::GetBooleanValue (bool fail_value) const
326{
327    const OptionValueBoolean *option_value = GetAsBoolean ();
328    if (option_value)
329        return option_value->GetCurrentValue();
330    return fail_value;
331}
332
333bool
334OptionValue::SetBooleanValue (bool new_value)
335{
336    OptionValueBoolean *option_value = GetAsBoolean ();
337    if (option_value)
338    {
339        option_value->SetCurrentValue(new_value);
340        return true;
341    }
342    return false;
343}
344
345int64_t
346OptionValue::GetEnumerationValue (int64_t fail_value) const
347{
348    const OptionValueEnumeration *option_value = GetAsEnumeration();
349    if (option_value)
350        return option_value->GetCurrentValue();
351    return fail_value;
352}
353
354bool
355OptionValue::SetEnumerationValue (int64_t value)
356{
357    OptionValueEnumeration *option_value = GetAsEnumeration();
358    if (option_value)
359    {
360        option_value->SetCurrentValue(value);
361        return true;
362    }
363    return false;
364}
365
366FileSpec
367OptionValue::GetFileSpecValue () const
368{
369    const OptionValueFileSpec *option_value = GetAsFileSpec ();
370    if (option_value)
371        return option_value->GetCurrentValue();
372    return FileSpec();
373}
374
375
376bool
377OptionValue::SetFileSpecValue (const FileSpec &file_spec)
378{
379    OptionValueFileSpec *option_value = GetAsFileSpec ();
380    if (option_value)
381    {
382        option_value->SetCurrentValue(file_spec, false);
383        return true;
384    }
385    return false;
386}
387
388FileSpecList
389OptionValue::GetFileSpecListValue () const
390{
391    const OptionValueFileSpecList *option_value = GetAsFileSpecList ();
392    if (option_value)
393        return option_value->GetCurrentValue();
394    return FileSpecList();
395}
396
397
398lldb::Format
399OptionValue::GetFormatValue (lldb::Format fail_value) const
400{
401    const OptionValueFormat *option_value = GetAsFormat ();
402    if (option_value)
403        return option_value->GetCurrentValue();
404    return fail_value;
405}
406
407bool
408OptionValue::SetFormatValue (lldb::Format new_value)
409{
410    OptionValueFormat *option_value = GetAsFormat ();
411    if (option_value)
412    {
413        option_value->SetCurrentValue(new_value);
414        return true;
415    }
416    return false;
417}
418
419const RegularExpression *
420OptionValue::GetRegexValue () const
421{
422    const OptionValueRegex *option_value = GetAsRegex ();
423    if (option_value)
424        return option_value->GetCurrentValue();
425    return NULL;
426}
427
428
429int64_t
430OptionValue::GetSInt64Value (int64_t fail_value) const
431{
432    const OptionValueSInt64 *option_value = GetAsSInt64 ();
433    if (option_value)
434        return option_value->GetCurrentValue();
435    return fail_value;
436}
437
438bool
439OptionValue::SetSInt64Value (int64_t new_value)
440{
441    OptionValueSInt64 *option_value = GetAsSInt64 ();
442    if (option_value)
443    {
444        option_value->SetCurrentValue(new_value);
445        return true;
446    }
447    return false;
448}
449
450const char *
451OptionValue::GetStringValue (const char *fail_value) const
452{
453    const OptionValueString *option_value = GetAsString ();
454    if (option_value)
455        return option_value->GetCurrentValue();
456    return fail_value;
457}
458
459bool
460OptionValue::SetStringValue (const char *new_value)
461{
462    OptionValueString *option_value = GetAsString ();
463    if (option_value)
464    {
465        option_value->SetCurrentValue(new_value);
466        return true;
467    }
468    return false;
469}
470
471uint64_t
472OptionValue::GetUInt64Value (uint64_t fail_value) const
473{
474    const OptionValueUInt64 *option_value = GetAsUInt64 ();
475    if (option_value)
476        return option_value->GetCurrentValue();
477    return fail_value;
478}
479
480bool
481OptionValue::SetUInt64Value (uint64_t new_value)
482{
483    OptionValueUInt64 *option_value = GetAsUInt64 ();
484    if (option_value)
485    {
486        option_value->SetCurrentValue(new_value);
487        return true;
488    }
489    return false;
490}
491
492UUID
493OptionValue::GetUUIDValue () const
494{
495    const OptionValueUUID *option_value = GetAsUUID();
496    if (option_value)
497        return option_value->GetCurrentValue();
498    return UUID();
499}
500
501bool
502OptionValue::SetUUIDValue (const UUID &uuid)
503{
504    OptionValueUUID *option_value = GetAsUUID();
505    if (option_value)
506    {
507        option_value->SetCurrentValue(uuid);
508        return true;
509    }
510    return false;
511}
512
513const char *
514OptionValue::GetBuiltinTypeAsCString (Type t)
515{
516    switch (t)
517    {
518        case eTypeInvalid:      return "invalid";
519        case eTypeArch:         return "arch";
520        case eTypeArgs:         return "arguments";
521        case eTypeArray:        return "array";
522        case eTypeBoolean:      return "boolean";
523        case eTypeDictionary:   return "dictionary";
524        case eTypeEnum:         return "enum";
525        case eTypeFileSpec:     return "file";
526        case eTypeFileSpecList: return "file-list";
527        case eTypeFormat:       return "format";
528        case eTypePathMap:      return "path-map";
529        case eTypeProperties:   return "properties";
530        case eTypeRegex:        return "regex";
531        case eTypeSInt64:       return "int";
532        case eTypeString:       return "string";
533        case eTypeUInt64:       return "unsigned";
534        case eTypeUUID:         return "uuid";
535    }
536    return NULL;
537}
538
539
540lldb::OptionValueSP
541OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t type_mask, Error &error)
542{
543    // If only 1 bit is set in the type mask for a dictionary or array
544    // then we know how to decode a value from a cstring
545    lldb::OptionValueSP value_sp;
546    switch (type_mask)
547    {
548    case 1u << eTypeArch:       value_sp.reset(new OptionValueArch()); break;
549    case 1u << eTypeBoolean:    value_sp.reset(new OptionValueBoolean(false)); break;
550    case 1u << eTypeFileSpec:   value_sp.reset(new OptionValueFileSpec()); break;
551    case 1u << eTypeFormat:     value_sp.reset(new OptionValueFormat(eFormatInvalid));    break;
552    case 1u << eTypeSInt64:     value_sp.reset(new OptionValueSInt64()); break;
553    case 1u << eTypeString:     value_sp.reset(new OptionValueString()); break;
554    case 1u << eTypeUInt64:     value_sp.reset(new OptionValueUInt64()); break;
555    case 1u << eTypeUUID:       value_sp.reset(new OptionValueUUID()); break;
556    }
557
558    if (value_sp)
559        error = value_sp->SetValueFromCString (value_cstr, eVarSetOperationAssign);
560    else
561        error.SetErrorString("unsupported type mask");
562    return value_sp;
563}
564
565bool
566OptionValue::DumpQualifiedName (Stream &strm) const
567{
568    bool dumped_something = false;
569    lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
570    if (m_parent_sp)
571    {
572        if (m_parent_sp->DumpQualifiedName(strm))
573            dumped_something = true;
574    }
575    ConstString name (GetName());
576    if (name)
577    {
578        if (dumped_something)
579            strm.PutChar('.');
580        else
581            dumped_something = true;
582        strm << name;
583    }
584    return dumped_something;
585}
586
587size_t
588OptionValue::AutoComplete (CommandInterpreter &interpreter,
589                           const char *s,
590                           int match_start_point,
591                           int max_return_elements,
592                           bool &word_complete,
593                           StringList &matches)
594{
595    word_complete = false;
596    matches.Clear();
597    return matches.GetSize();
598}
599
600Error
601OptionValue::SetValueFromCString (const char *value, VarSetOperationType op)
602{
603    Error error;
604    switch (op)
605    {
606    case eVarSetOperationReplace:
607        error.SetErrorStringWithFormat ("%s objects do not support the 'replace' operation", GetTypeAsCString());
608        break;
609    case eVarSetOperationInsertBefore:
610        error.SetErrorStringWithFormat ("%s objects do not support the 'insert-before' operation", GetTypeAsCString());
611        break;
612    case eVarSetOperationInsertAfter:
613        error.SetErrorStringWithFormat ("%s objects do not support the 'insert-after' operation", GetTypeAsCString());
614        break;
615    case eVarSetOperationRemove:
616        error.SetErrorStringWithFormat ("%s objects do not support the 'remove' operation", GetTypeAsCString());
617        break;
618    case eVarSetOperationAppend:
619        error.SetErrorStringWithFormat ("%s objects do not support the 'append' operation", GetTypeAsCString());
620        break;
621    case eVarSetOperationClear:
622        error.SetErrorStringWithFormat ("%s objects do not support the 'clear' operation", GetTypeAsCString());
623        break;
624    case eVarSetOperationAssign:
625        error.SetErrorStringWithFormat ("%s objects do not support the 'assign' operation", GetTypeAsCString());
626        break;
627    case eVarSetOperationInvalid:
628        error.SetErrorStringWithFormat ("invalid operation performed on a %s object", GetTypeAsCString());
629        break;
630    }
631    return error;
632}
633
634