Esempio n. 1
0
/* Find the splay tree node for the definition of NAME at LINE in
   SOURCE, or zero if there is none.  */
static splay_tree_node
find_definition (const char *name,
                 struct macro_source_file *file,
                 int line)
{
  struct macro_table *t = file->table;
  splay_tree_node n;

  /* Construct a macro_key object, just for the query.  */
  struct macro_key query;

  query.name = name;
  query.start_file = file;
  query.start_line = line;
  query.end_file = NULL;

  n = splay_tree_lookup (t->definitions, (splay_tree_key) &query);
  if (! n)
    {
      /* It's okay for us to do two queries like this: the real work
         of the searching is done when we splay, and splaying the tree
         a second time at the same key is a constant time operation.
         If this still bugs you, you could always just extend the
         splay tree library with a predecessor-or-equal operation, and
         use that.  */
      splay_tree_node pred = splay_tree_predecessor (t->definitions,
                                                     (splay_tree_key) &query);
     
      if (pred)
        {
          /* Make sure this predecessor actually has the right name.
             We just want to search within a given name's definitions.  */
          struct macro_key *found = (struct macro_key *) pred->key;

          if (strcmp (found->name, name) == 0)
            n = pred;
        }
    }

  if (n)
    {
      struct macro_key *found = (struct macro_key *) n->key;

      /* Okay, so this definition has the right name, and its scope
         begins before the given source location.  But does its scope
         end after the given source location?  */
      if (compare_locations (file, line, found->end_file, found->end_line) < 0)
        return n;
      else
        return 0;
    }
  else
    return 0;
}
Esempio n. 2
0
/* Compare a macro key KEY against NAME, the source file FILE, and
   line number LINE.

   Sort definitions by name; for two definitions with the same name,
   place the one whose definition comes earlier before the one whose
   definition comes later.

   Return -1, 0, or 1 if key comes before, is identical to, or comes
   after NAME, FILE, and LINE.  */
static int
key_compare (struct macro_key *key,
             const char *name, struct macro_source_file *file, int line)
{
  int names = strcmp (key->name, name);

  if (names)
    return names;

  return compare_locations (key->start_file, key->start_line,
                            file, line);
}
Esempio n. 3
0
static int
foreach_macro_in_scope (splay_tree_node node, void *info)
{
  struct macro_for_each_data *datum = (struct macro_for_each_data *) info;
  struct macro_key *key = (struct macro_key *) node->key;
  struct macro_definition *def;
  char *datum_fullname;

  datum_fullname = macro_source_fullname (datum->file);
  def = fixup_definition (datum_fullname, datum->line,
			  (struct macro_definition *) node->value);
  xfree (datum_fullname);

  /* See if this macro is defined before the passed-in line, and
     extends past that line.  */
  if (compare_locations (key->start_file, key->start_line,
			 datum->file, datum->line) < 0
      && (!key->end_file
	  || compare_locations (key->end_file, key->end_line,
				datum->file, datum->line) >= 0))
    datum->fn (key->name, def, key->start_file, key->start_line);
  return 0;
}
Esempio n. 4
0
int
TextPointer::CompareToWithError (const TextPointer *pointer, MoonError *error) const
{
	if (!verify_textpointer_in_document (this, error) ||
	    !verify_textpointer_in_document (pointer, error))
		return -1;

	if (this->GetParent() == pointer->GetParent()) {
		DependencyObjectCollection *children = this->GetParentNode()->GetDocumentChildren();
		if (children && children->GetCount() > 0)
			return compare_locations (this->GetLocation(), pointer->GetLocation());
		else
			return this->ResolveLocation() - pointer->ResolveLocation();
	}
	else {
		GPtrArray *this_array = g_ptr_array_new();
		GPtrArray *pointer_array = g_ptr_array_new();

		DependencyObject *el = GetParent();
		while (el) {
			g_ptr_array_insert (this_array, 0, el);
			if (el->Is (Type::RICHTEXTBOX))
				break;
			el = el->GetParent() ? el->GetParent()->GetParent() : NULL;
			if (!el)
				break;
		}

		el = pointer->GetParent();
		while (el) {
			g_ptr_array_insert (pointer_array, 0, el);
			if (el->Is (Type::RICHTEXTBOX))
				break;
			el = el->GetParent() ? el->GetParent()->GetParent() : NULL;
			if (!el)
				break;
		}

		guint32 count_to_compare = MIN (this_array->len, pointer_array->len);

		for (guint32 i = 0; i < count_to_compare; i ++) {
			DependencyObject *this_el = (DependencyObject*)g_ptr_array_index (this_array, i);
			DependencyObject *pointer_el = (DependencyObject*)g_ptr_array_index (pointer_array, i);

			if (this_el == pointer_el)
				continue;

			if (i == 0) {
				// this shouldn't happen... there shouldn't be a difference between two paths on the first element, since that should always be a RTB
				int rv = this_array->len < pointer_array->len ? -1 : 1;
				g_ptr_array_free (this_array, TRUE);
				g_ptr_array_free (pointer_array, TRUE);
				return rv;
			}

			/* at this point this_el and pointer_el are
			   different.  check index i-1's idea of their
			   positions */
			DependencyObject *common_parent = (DependencyObject*)g_ptr_array_index (this_array, i-1);
			IDocumentNode *common_parent_node = IDocumentNode::CastToIDocumentNode (common_parent);
			int this_index = common_parent_node->GetDocumentChildren()->IndexOf (Value (this_el));
			int pointer_index = common_parent_node->GetDocumentChildren()->IndexOf (Value (pointer_el));
			g_ptr_array_free (this_array, TRUE);
			g_ptr_array_free (pointer_array, TRUE);
			return this_index < pointer_index ? -1 : 1;
		}

		// if we make it here, it means we've run through
		// "count_to_compare" items that were identical, and
		// one of the paths is longer (so represents a child
		// of items[count_to_compare].

		// so we need to figure out which array has more
		// elements, then compare that against the other
		// TextPointer's location

		if (count_to_compare < this_array->len) {
			// @this's parent is a child of pointer_array[count_to_compare-1]
			DependencyObject *parent = (DependencyObject*)g_ptr_array_index(pointer_array, count_to_compare - 1);
			IDocumentNode *parent_node = IDocumentNode::CastToIDocumentNode (parent);
			guint32 child_index = parent_node->GetDocumentChildren()->IndexOf (Value ((DependencyObject*)g_ptr_array_index(this_array, count_to_compare)));

			return pointer->GetLocation() > child_index ? -1 : 1;
		}
		else if (count_to_compare < pointer_array->len) {
			// @pointer's parent is a child of this_array[count_to_compare-1]
			DependencyObject *parent = (DependencyObject*)g_ptr_array_index(this_array, count_to_compare - 1);
			IDocumentNode *parent_node = IDocumentNode::CastToIDocumentNode (parent);
			guint32 child_index = parent_node->GetDocumentChildren()->IndexOf (Value ((DependencyObject*)g_ptr_array_index(pointer_array, count_to_compare)));

			return child_index >= this->GetLocation () ? -1 : 1;
		}
	}
	return -1;
}