示例#1
0
    void
    flatten_tree (TypeInfo const& ti, TypeInfoSet& set)
    {
      set.insert (ti);

      for (TypeInfo::BaseIterator i = ti.begin_base ();
           i != ti.end_base ();
           i++)
      {
        flatten_tree (i->type_info (), set);
      }
    }
示例#2
0
    void Dispatcher::
    dispatch (SyntaxTree::NodePtr const& n)
    {
      LevelMap levels;

      unsigned long max = compute_levels (n->type_info (), 0, levels);

      //cerr << "starting dispatch process for "
      //     << n->type_info ().type_id () << " with "
      //     << max << " levels" << endl;

      for (unsigned long l = 0; l < max + 1; l++)
      {
        TypeInfoSet dispatched;

        for (LevelMap::const_iterator i = levels.begin ();
             i != levels.end ();
             i++)
        {
          if (i->second == l)
          {
            TraversalMap::const_iterator v =
              traversal_map_.find (i->first.type_id ());

            if (v != traversal_map_.end () && !(v->second.suppressed))
            {
              //cerr << "dispatching traverser for "
              //     << n->type_info ().type_id () << " as "
              //     << i->first.type_id () << endl;

              v->second.traverser->traverse (n);
              flatten_tree (i->first, dispatched);
            }
          }
        }

        // Remove traversed types from level map.
        for (TypeInfoSet::const_iterator i = dispatched.begin ();
             i != dispatched.end ();
             i++)
        {
          levels.erase (*i);
        }
      }
    }
示例#3
0
  void Dispatcher::
  dispatch (SyntaxTree::Node* n)
  {
    LevelMap levels;

    unsigned long max = compute_levels (n->type_info (), 0, levels);

    for (unsigned long l = 0; l < max + 1; l++)
    {
      TypeInfoSet dispatched;

      for (LevelMap::const_iterator i = levels.begin ();
           i != levels.end ();
           i++)
      {
        if (i->second == l)
        {
          TraversalMap::const_iterator v =
            traversal_map_.find (i->first.type_id ());

          if (v != traversal_map_.end ())
          {
            v->second->traverse (n);
            flatten_tree (i->first, dispatched);
          }
        }
      }

      // Remove traversed types from level map.
      for (TypeInfoSet::const_iterator i = dispatched.begin ();
           i != dispatched.end ();
           i++)
      {
        levels.erase (*i);
      }
    }
  }
示例#4
0
static int parse_tree(struct nlmsghdr *n, struct ematch *tree)
{
	int index = 1;
	struct ematch *t;

	for (t = tree; t; t = t->next) {
		struct rtattr *tail = NLMSG_TAIL(n);
		struct tcf_ematch_hdr hdr = {
			.flags = t->relation
		};

		if (t->inverted)
			hdr.flags |= TCF_EM_INVERT;

		addattr_l(n, MAX_MSG, index++, NULL, 0);

		if (t->child) {
			__u32 r = t->child_ref;
			addraw_l(n, MAX_MSG, &hdr, sizeof(hdr));
			addraw_l(n, MAX_MSG, &r, sizeof(r));
		} else {
			int num = 0, err;
			char buf[64];
			struct ematch_util *e;

			if (t->args == NULL)
				return -1;

			strncpy(buf, (char*) t->args->data, sizeof(buf)-1);
			e = get_ematch_kind(buf);
			if (e == NULL) {
				fprintf(stderr, "Unknown ematch \"%s\"\n",
				    buf);
				return -1;
			}

			err = lookup_map_id(buf, &num, EMATCH_MAP);
			if (err < 0) {
				if (err == -ENOENT)
					map_warning(e->kind_num, buf);
				return err;
			}

			hdr.kind = num;
			if (e->parse_eopt(n, &hdr, t->args->next) < 0)
				return -1;
		}

		tail->rta_len = (void*) NLMSG_TAIL(n) - (void*) tail;
	}

	return 0;
}

static int flatten_tree(struct ematch *head, struct ematch *tree)
{
	int i, count = 0;
	struct ematch *t;

	for (;;) {
		count++;

		if (tree->child) {
			for (t = head; t->next; t = t->next);
			t->next = tree->child;
			count += flatten_tree(head, tree->child);
		}

		if (tree->relation == 0)
			break;

		tree = tree->next;
	}

	for (i = 0, t = head; t; t = t->next, i++)
		t->index = i;

	for (t = head; t; t = t->next)
		if (t->child)
			t->child_ref = t->child->index;

	return count;
}