Exemple #1
0
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;
}
Exemple #2
0
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;
					}
				}
			}
		}
	}
}
Exemple #3
0
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;
}
Exemple #4
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;
}
Exemple #5
0
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;
			}
		}
	}
}
Exemple #6
0
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();
 }
Exemple #8
0
// 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;
}