PythonObject PythonObject::ResolveName(llvm::StringRef name) const { // Resolve the name in the context of the specified object. If, // for example, `this` refers to a PyModule, then this will look for // `name` in this module. If `this` refers to a PyType, then it will // resolve `name` as an attribute of that type. If `this` refers to // an instance of an object, then it will resolve `name` as the value // of the specified field. // // This function handles dotted names so that, for example, if `m_py_obj` // refers to the `sys` module, and `name` == "path.append", then it // will find the function `sys.path.append`. size_t dot_pos = name.find_first_of('.'); if (dot_pos == llvm::StringRef::npos) { // No dots in the name, we should be able to find the value immediately // as an attribute of `m_py_obj`. return GetAttributeValue(name); } // Look up the first piece of the name, and resolve the rest as a child of that. PythonObject parent = ResolveName(name.substr(0, dot_pos)); if (!parent.IsAllocated()) return PythonObject(); // Tail recursion.. should be optimized by the compiler return parent.ResolveName(name.substr(dot_pos + 1)); }
bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) { error.Clear(); if (str.empty()) { error.SetErrorStringWithFormat("Empty breakpoint names are not allowed"); return false; } // First character must be a letter or _ if (!isalpha(str[0]) && str[0] != '_') { error.SetErrorStringWithFormat("Breakpoint names must start with a " "character or underscore: %s", str.str().c_str()); return false; } // Cannot contain ., -, or space. if (str.find_first_of(".- ") != llvm::StringRef::npos) { error.SetErrorStringWithFormat("Breakpoint names cannot contain " "'.' or '-': \"%s\"", str.str().c_str()); return false; } return true; }
PythonObject PythonObject::ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict) { size_t dot_pos = name.find_first_of('.'); llvm::StringRef piece = name.substr(0, dot_pos); PythonObject result = dict.GetItemForKey(PythonString(piece)); if (dot_pos == llvm::StringRef::npos) { // There was no dot, we're done. return result; } // There was a dot. The remaining portion of the name should be looked up in // the context of the object that was found in the dictionary. return result.ResolveName(name.substr(dot_pos + 1)); }
lldb::OptionValueSP OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx, llvm::StringRef name, bool will_modify, Error &error) const { lldb::OptionValueSP value_sp; if (name.empty()) return OptionValueSP(); llvm::StringRef sub_name; ConstString key; size_t key_len = name.find_first_of(".[{"); if (key_len != llvm::StringRef::npos) { key.SetString(name.take_front(key_len)); sub_name = name.drop_front(key_len); } else key.SetString(name); value_sp = GetValueForKey(exe_ctx, key, will_modify); if (sub_name.empty() || !value_sp) return value_sp; switch (sub_name[0]) { case '.': { lldb::OptionValueSP return_val_sp; return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), will_modify, error); if (!return_val_sp) { if (Properties::IsSettingExperimental(sub_name.drop_front())) { size_t experimental_len = strlen(Properties::GetExperimentalSettingsName()); if (sub_name[experimental_len + 1] == '.') return_val_sp = value_sp->GetSubValue( exe_ctx, sub_name.drop_front(experimental_len + 2), will_modify, error); // It isn't an error if an experimental setting is not present. if (!return_val_sp) error.Clear(); } } return return_val_sp; } 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 executable basename is "test" and arch is "x86_64" if (sub_name[1]) { llvm::StringRef predicate_start = sub_name.drop_front(); size_t pos = predicate_start.find_first_of('}'); if (pos != llvm::StringRef::npos) { auto predicate = predicate_start.take_front(pos); auto rest = predicate_start.drop_front(pos); if (PredicateMatches(exe_ctx, predicate)) { if (!rest.empty()) { // Still more subvalue string to evaluate return value_sp->GetSubValue(exe_ctx, rest, 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; }