DTboolean PlugBase::set_incoming_connection (PlugBase* incoming) { PROFILER(SCRIPTING); // // Lock this owner and the incoming owner // std::unique_lock<std::recursive_mutex> lock_this(owner()->lock(),std::try_to_lock); std::unique_lock<std::recursive_mutex> lock_incoming(incoming->owner()->lock(),std::try_to_lock); DTboolean lock_this_status = lock_this.owns_lock(); DTboolean lock_incoming_status = lock_incoming.owns_lock(); while (!lock_this_status || !lock_incoming_status) { if (lock_this_status) lock_this.unlock(); if (lock_incoming_status) lock_incoming.unlock(); lock_this_status = lock_this.owns_lock(); lock_incoming_status = lock_incoming.owns_lock(); } // // Do modifications // PlugBase *&incoming_ref = connections()._incoming; if (is_compatible(incoming) && incoming_ref != incoming) { // Disconnect old node if (incoming_ref) { owner()->incoming_plug_was_disconnected(incoming_ref, this); incoming_ref->remove_outgoing_connection(this); } // Connect new node incoming_ref = incoming; // Add this plug to the outgoing connections incoming_ref->add_outgoing_connection(this); set_dirty(); owner()->incoming_plug_was_attached(incoming_ref, this); return true; } else { if (!is_compatible(incoming)) LOG_MESSAGE << plug_type() << " doesn't match " << incoming->plug_type(); } return false; }
void software_list_device::find_approx_matches(const std::string &name, int matches, const software_info **list, const char *interface) { // if no name, return if (name.empty()) return; // initialize everyone's states std::vector<double> penalty(matches); for (int matchnum = 0; matchnum < matches; matchnum++) { penalty[matchnum] = 2.0; list[matchnum] = nullptr; } // iterate over our info (will cause a parse if needed) std::u32string const search(ustr_from_utf8(normalize_unicode(name, unicode_normalization_form::D, true))); for (const software_info &swinfo : get_info()) { for (const software_part &swpart : swinfo.parts()) { if ((interface == nullptr || swpart.matches_interface(interface)) && is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE) { // pick the best match between driver name and description double const longpenalty = util::edit_distance(search, ustr_from_utf8(normalize_unicode(swinfo.longname(), unicode_normalization_form::D, true))); double const shortpenalty = util::edit_distance(search, ustr_from_utf8(normalize_unicode(swinfo.shortname(), unicode_normalization_form::D, true))); double const curpenalty = (std::min)(longpenalty, shortpenalty); // make sure it isn't already in the table bool skip = false; for (int matchnum = 0; !skip && (matchnum < matches) && list[matchnum]; matchnum++) { if ((penalty[matchnum] == curpenalty) && (swinfo.longname() == list[matchnum]->longname()) && (swinfo.shortname() == list[matchnum]->shortname())) skip = true; } if (!skip) { // insert into the sorted table of matches for (int matchnum = matches - 1; matchnum >= 0; matchnum--) { // stop if we're worse than the current entry if (curpenalty >= penalty[matchnum]) break; // as long as this isn't the last entry, bump this one down if (matchnum < matches - 1) { penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } } } } }
static int query_format(struct vf_instance *vf, unsigned int fmt) { if (fmt == vf->priv->fmt || !vf->priv->fmt) { if (vf->priv->outfmt) { if (!is_compatible(fmt, vf->priv->outfmt)) return 0; fmt = vf->priv->outfmt; } return vf_next_query_format(vf, fmt); } return 0; }
DTboolean PlugBase::add_outgoing_connection (PlugBase* outgoing) { PROFILER(SCRIPTING); // // Lock this owner and the outgoing owner // std::unique_lock<std::recursive_mutex> lock_this(owner()->lock(),std::try_to_lock); std::unique_lock<std::recursive_mutex> lock_outgoing(outgoing->owner()->lock(),std::try_to_lock); DTboolean lock_this_status = lock_this.owns_lock(); DTboolean lock_outgoing_status = lock_outgoing.owns_lock(); while (!lock_this_status || !lock_outgoing_status) { if (lock_this_status) lock_this.unlock(); if (lock_outgoing_status) lock_outgoing.unlock(); lock_this_status = lock_this.owns_lock(); lock_outgoing_status = lock_outgoing.owns_lock(); } // // Do modifications // std::vector<PlugBase*> &outgoing_ref = connections()._outgoing; // Check if only a single output is allowed if (!info().is_single_output() || (info().is_single_output() && outgoing_ref.size() == 0)) { // Check compatibility if (is_compatible(outgoing)) { auto i = std::find(outgoing_ref.begin(), outgoing_ref.end(), outgoing); if (i == outgoing_ref.end()) { outgoing_ref.push_back(outgoing); outgoing->set_dirty(); outgoing->set_incoming_connection(this); // Increasse Ref count for owner owner()->outgoing_plug_was_attached(this, outgoing); } return true; } } return false; }
void software_list_device::find_approx_matches(const char *name, int matches, const software_info **list, const char *interface) { // if no name, return if (name == nullptr || name[0] == 0) return; // initialize everyone's states std::vector<int> penalty(matches); for (int matchnum = 0; matchnum < matches; matchnum++) { penalty[matchnum] = 9999; list[matchnum] = nullptr; } // iterate over our info (will cause a parse if needed) for (const software_info &swinfo : get_info()) { const software_part &part = swinfo.parts().front(); if ((interface == nullptr || part.matches_interface(interface)) && is_compatible(part) == SOFTWARE_IS_COMPATIBLE) { // pick the best match between driver name and description int longpenalty = driver_list::penalty_compare(name, swinfo.longname().c_str()); int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname().c_str()); int curpenalty = std::min(longpenalty, shortpenalty); // insert into the sorted table of matches for (int matchnum = matches - 1; matchnum >= 0; matchnum--) { // stop if we're worse than the current entry if (curpenalty >= penalty[matchnum]) break; // as long as this isn't the last entry, bump this one down if (matchnum < matches - 1) { penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } } }
bool Function::IsCompatibleWithExecutionModel(SpvExecutionModel model, std::string* reason) const { bool return_value = true; std::stringstream ss_reason; for (const auto& is_compatible : execution_model_limitations_) { std::string message; if (!is_compatible(model, &message)) { if (!reason) return false; return_value = false; if (!message.empty()) { ss_reason << message << "\n"; } } } if (!return_value && reason) { *reason = ss_reason.str(); } return return_value; }
bool equal(succeed_iterator<F, BinaryFun> const& other) const { BOOST_ASSERT(is_compatible(other)); return this->base() == other.base(); }
// This function typechecks the nodes in the free text expression. // When first called, the node is the pointer to the free text expr syntax tree. // This function also helps form the basic predicates. // This function returns the type of the predicate represented by the syntax tree rooted at node. // The type can be basic or composite. // A composite return type from this function implies that we should not worry about forming of // basic predicates under this node, they have already been formed. // The return value is immaterial in advent of an error. static int form_basic_preds_and_typecheck (syntree *node, int *status, int *basic_pred_type) { // The predicate types are basic or composite predicate. // If a predicate is of basic type, its subtype is either OR, AND or ACCRUE; or the node type, if the subtree // under the node contains none of OR, AND or ACCRUE ops. int left_pred_type = FT_BASIC_PRED_TYPE, right_pred_type = FT_BASIC_PRED_TYPE; int left_pred_subtype = 0, right_pred_subtype = 0; ASSERT (node); // If the node type is word type or phrase type or not type, return from the function as there is no processing // involved on these sub-trees. if (node->type == FT_WORD_TYPE || node->type == FT_PHRASE_TYPE || node->type == FT_NOT_TYPE) { *basic_pred_type = node->type; return (FT_BASIC_PRED_TYPE); } // A vector space style condition string is in basic predicate form already. // Also there is nothing to be typechecked in this type of condition string, since the parser // only parses a legitimate vector space type condition string. if (node->type == FT_ACCRUE_TYPE) { *basic_pred_type = node->type; return (FT_BASIC_PRED_TYPE); } // A OR op should not have a NOT as a child. if (node->type == FT_OR_TYPE) { if (node->left_tree->type == FT_NOT_TYPE || node->right_tree->type == FT_NOT_TYPE) { logwrite ("Error: you cannot have a Negated query word (preceded by NOT op) adjacent to an OR op. Please rephrase" " the CONTAINS condition string."); *status = TMAN_ERROR; // Return type is insignificant if status is an error return (0); } } // For other nodes, traverse down. if (node->left_tree) { left_pred_type = form_basic_preds_and_typecheck (node->left_tree, status, &left_pred_subtype); } if (*status == TMAN_OK && node->right_tree) { right_pred_type = form_basic_preds_and_typecheck (node->right_tree, status, &right_pred_subtype); } // Form the basic predicate only if there is no error encountered yet. // This processing is required for OR and AND nodes only. if (*status == TMAN_OK && (node->type == FT_OR_TYPE || node->type == FT_AND_TYPE )) { // This node should not be of the ACCRUE type. ASSERT (node->type != FT_ACCRUE_TYPE); // A node can include itself with its children in a basic predicate if all of them have compatible types. // In this case, the node at the upper level is supposed to form the basic predicate. // In case the root of the syntax tree can form a basic predicate with its children, // the basic predicate for the whole tree is formed at the place where the function // form_basic_preds_and_typecheck was called for the first time. if ((left_pred_type == FT_BASIC_PRED_TYPE && right_pred_type == FT_BASIC_PRED_TYPE) && (is_compatible (left_pred_subtype, node->type) && is_compatible (right_pred_subtype, node->type))) { *basic_pred_type = node->type; return (FT_BASIC_PRED_TYPE); } // When a node and its children don't have compatible types, a basic predicate is formed for each of the children. // These basic pred nodes replace the children. // A composite type is returned from this node, so that no node at the higher level tries to make a basic pred // using this node as described above. if (left_pred_type == FT_BASIC_PRED_TYPE) { ft_basic_pred *new_left_tree; // It is an error if the basic predicate is comprised of a tree having NOT at the root. if (left_pred_subtype == FT_NOT_TYPE) { logwrite ("Error: in CONTAINS condition string, you must combine a negated word with at least" " one non-negated word/phrase using AND."); *status = TMAN_ERROR; // Return type is insignificant if status is an error return (0); } new_left_tree = ft_basic_pred_new (&(node->left_tree), left_pred_subtype, status); node->left_tree = (syntree *) new_left_tree; } if (right_pred_type == FT_BASIC_PRED_TYPE) { ft_basic_pred *new_right_tree; // It is an error if the basic predicate is comprised of a tree having not at the root. if (right_pred_subtype == FT_NOT_TYPE) { logwrite ("Error: in CONTAINS condition string, you must combine a negated word with at least" " one non-negated word/phrase using AND."); *status = TMAN_ERROR; // Return type is insignificant if status is an error return (0); } new_right_tree = ft_basic_pred_new (&(node->right_tree), right_pred_subtype, status); node->right_tree = (syntree *) new_right_tree; } return (FT_COMP_PRED_TYPE); } if (*status == TMAN_ERROR) { // Return type is insignificant if status is an error return (0); } // This code should not be reachable. TMAN_HALT; return (0); // Never reached. }
static inline struct bstr * parse_object(struct bstr *args, struct bstr *arg, struct tcf_meta_val *obj, unsigned long *dst, struct tcf_meta_val *left) { struct meta_entry *entry; unsigned long num; struct bstr *a; if (arg->quoted) { obj->kind = TCF_META_TYPE_VAR << 12; obj->kind |= TCF_META_ID_VALUE; *dst = (unsigned long) arg; return bstr_next(arg); } num = bstrtoul(arg); if (num != ULONG_MAX) { obj->kind = TCF_META_TYPE_INT << 12; obj->kind |= TCF_META_ID_VALUE; *dst = (unsigned long) num; return bstr_next(arg); } entry = lookup_meta_entry(arg); if (entry == NULL) { PARSE_ERR(arg, "meta: unknown meta id\n"); return PARSE_FAILURE; } obj->kind = entry->id | (map_type(entry->mask[0]) << 12); if (left) { struct tcf_meta_val *right = obj; if (TCF_META_TYPE(right->kind) == TCF_META_TYPE(left->kind)) goto compatible; if (can_adopt(left) && !can_adopt(right)) { if (is_compatible(left, right)) left->kind = overwrite_type(left, right); else goto not_compatible; } else if (can_adopt(right) && !can_adopt(left)) { if (is_compatible(right, left)) right->kind = overwrite_type(right, left); else goto not_compatible; } else if (can_adopt(left) && can_adopt(right)) { if (is_compatible(left, right)) left->kind = overwrite_type(left, right); else if (is_compatible(right, left)) right->kind = overwrite_type(right, left); else goto not_compatible; } else goto not_compatible; } compatible: a = bstr_next(arg); while(a) { if (!bstrcmp(a, "shift")) { unsigned long shift; if (a->next == NULL) { PARSE_ERR(a, "meta: missing argument"); return PARSE_FAILURE; } a = bstr_next(a); shift = bstrtoul(a); if (shift == ULONG_MAX) { PARSE_ERR(a, "meta: invalid shift, must " \ "be numeric"); return PARSE_FAILURE; } obj->shift = (__u8) shift; a = bstr_next(a); } else if (!bstrcmp(a, "mask")) { unsigned long mask; if (a->next == NULL) { PARSE_ERR(a, "meta: missing argument"); return PARSE_FAILURE; } a = bstr_next(a); mask = bstrtoul(a); if (mask == ULONG_MAX) { PARSE_ERR(a, "meta: invalid mask, must be " \ "numeric"); return PARSE_FAILURE; } *dst = (unsigned long) mask; a = bstr_next(a); } else break; } return a; not_compatible: PARSE_ERR(arg, "lvalue and rvalue are not compatible."); return PARSE_FAILURE; }