const Property * OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx, bool will_modify, const char *name) const { const Property *property = NULL; if (name && name[0]) { const char *sub_name = NULL; ConstString key; size_t key_len = ::strcspn (name, ".[{"); if (name[key_len]) { key.SetCStringWithLength (name, key_len); sub_name = name + key_len; } else key.SetCString (name); property = GetProperty (exe_ctx, will_modify, key); if (sub_name && property) { if (sub_name[0] == '.') { OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties(); if (sub_properties) return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1); } property = NULL; } } return property; }
const ConstString & Host::GetOSString() { static ConstString g_os_string; if (!g_os_string) { const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); } return g_os_string; }
const ConstString & Host::GetOSString() { static ConstString g_os_string; if (!g_os_string) { #if defined (__APPLE__) const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); #elif defined (__linux__) g_os_string.SetCString("linux"); #elif defined (__FreeBSD__) g_os_string.SetCString("freebsd"); #endif } return g_os_string; }
lldb::OptionValueSP OptionValueDictionary::GetSubValue (const ExecutionContext *exe_ctx, const char *name, bool will_modify, Error &error) const { lldb::OptionValueSP value_sp; if (name && name[0]) { const char *sub_name = nullptr; ConstString key; const char *open_bracket = ::strchr (name, '['); if (open_bracket) { const char *key_start = open_bracket + 1; const char *key_end = nullptr; switch (open_bracket[1]) { case '\'': ++key_start; key_end = strchr(key_start, '\''); if (key_end) { if (key_end[1] == ']') { if (key_end[2]) sub_name = key_end + 2; } else { error.SetErrorStringWithFormat ("invalid value path '%s', single quoted key names must be formatted as ['<key>'] where <key> is a string that doesn't contain quotes", name); return value_sp; } } else { error.SetErrorString ("missing '] key name terminator, key name started with ['"); return value_sp; } break; case '"': ++key_start; key_end = strchr(key_start, '"'); if (key_end) { if (key_end[1] == ']') { if (key_end[2]) sub_name = key_end + 2; break; } error.SetErrorStringWithFormat ("invalid value path '%s', double quoted key names must be formatted as [\"<key>\"] where <key> is a string that doesn't contain quotes", name); return value_sp; } else { error.SetErrorString ("missing \"] key name terminator, key name started with [\""); return value_sp; } break; default: key_end = strchr(key_start, ']'); if (key_end) { if (key_end[1]) sub_name = key_end + 1; } else { error.SetErrorString ("missing ] key name terminator, key name started with ["); return value_sp; } break; } if (key_start && key_end) { key.SetCStringWithLength (key_start, key_end - key_start); value_sp = GetValueForKey (key); if (value_sp) { if (sub_name) return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); } else { error.SetErrorStringWithFormat("dictionary does not contain a value for the key name '%s'", key.GetCString()); } } } if (!value_sp && error.AsCString() == nullptr) { error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimited by single or double quotes", name, GetTypeAsCString()); } } return value_sp; }
lldb::OptionValueSP OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx, const char *name, bool will_modify, Error &error) const { lldb::OptionValueSP value_sp; if (name && name[0]) { const char *sub_name = NULL; ConstString key; size_t key_len = ::strcspn (name, ".[{"); if (name[key_len]) { key.SetCStringWithLength (name, key_len); sub_name = name + key_len; } else key.SetCString (name); value_sp = GetValueForKey (exe_ctx, key, will_modify); if (sub_name && value_sp) { switch (sub_name[0]) { case '.': return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error); case '{': // Predicate matching for predicates like // "<setting-name>{<predicate>}" // strings are parsed by the current OptionValueProperties subclass // to mean whatever they want to. For instance a subclass of // OptionValueProperties for a lldb_private::Target might implement: // "target.run-args{arch==i386}" -- only set run args if the arch is i386 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if exectable basename is "test" and arch is "x86_64" if (sub_name[1]) { const char *predicate_start = sub_name + 1; const char *predicate_end = strchr(predicate_start, '}'); if (predicate_end) { std::string predicate(predicate_start, predicate_end); if (PredicateMatches(exe_ctx, predicate.c_str())) { if (predicate_end[1]) { // Still more subvalue string to evaluate return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error); } else { // We have a match! break; } } } } // Predicate didn't match or wasn't correctly formed value_sp.reset(); break; case '[': // Array or dictionary access for subvalues like: // "[12]" -- access 12th array element // "['hello']" -- dictionary access of key named hello return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); default: value_sp.reset(); break; } } } return value_sp; }