예제 #1
0
Node::List File::glob(const string& path, const regex& pattern)
{
    DIR* directory;
    struct dirent* entry;
    Node::List result;

    if (directory = opendir(path.c_str())) {
        while ((entry = readdir(directory)) != NULL) {
            if (
                (entry->d_type == DT_REG) 
                && (regex_match(entry->d_name, pattern))
            )
            {
                result.emplace_back(
                    path + '/' + entry->d_name,
                    &File::build,
                    &File::timestamp,
                    Node::List(),
                    false
                );
            }
        }

        closedir(directory);
    }

    return result;
}
예제 #2
0
Node::List convert(Node::List list)
{
    Node::List result;

    std::transform(
       list.begin(), list.end(),
       std::back_inserter(result),
       [] (const Node& node) { return T(node); }
    );

    return result;
}
예제 #3
0
 inline Object(Node::List dependencies)
     : Node(
         dependencies.begin()->path + std::string(".o"),
         &Object::build,
         &File::timestamp,
         dependencies
     )
 {
 }
예제 #4
0
void
Variation::difference(Root const* root, Variation const* var, unsigned level, Node::List& nodes) const
{
	//M_ASSERT(root);
	//M_ASSERT(var);

	Key const& endKey = var->successor();

	unsigned	i = 0;
	unsigned k = 0;
	unsigned m = m_list.size();
	unsigned n = var->m_list.size();

	if (m > 0 && n > 0)
	{
		KeyNode const* lhs = m_list[0];			// node from current game
		KeyNode const* rhs = var->m_list[0];	// node from previous game

		if (lhs->key() < rhs->key())
		{
			do
				++i;
			while (i < m && m_list[i]->key() < rhs->key());

			nodes.push_back(root->newAction(Action::Insert, level, rhs->startKey()));
			nodes.insert(nodes.end(), m_list.begin(), m_list.begin() + i);
			nodes.push_back(root->newAction(Action::Finish, level));
		}
		else if (rhs->key() < lhs->key())
		{
			do
				++k;
			while (k < n && var->m_list[k]->key() < lhs->key());

			Key const& after = k == n ? endKey : var->m_list[k]->startKey();
			nodes.push_back(root->newAction(Action::Remove, level, rhs->startKey(), after));
		}
	}

	while (i < m && k < n)
	{
		KeyNode const* lhs = m_list[i];			// node from current game
		KeyNode const* rhs = var->m_list[k];	// node from previous game

		Type lhsType = lhs->type();
		Type rhsType = rhs->type();

		if (lhsType == rhsType)
		{
			if (lhsType == TVariation)
			{
				Variation const* lhsVar = static_cast<Variation const*>(lhs);
				Variation const* rhsVar = static_cast<Variation const*>(rhs);

				lhsVar->difference(root, rhsVar, level + 1, nodes);
			}
			else if (*lhs != rhs)
			{
				if (	lhsType == TMove
					&& (	static_cast<Move const*>(lhs)->ply() == 0
						|| static_cast<Move const*>(rhs)->ply() == 0
						|| *static_cast<Move const*>(lhs)->ply() != static_cast<Move const*>(rhs)->ply()))
				{
					KeyNode const* const* lhsLast	= m_list.begin() + i + 1;
					KeyNode const* const* lhsEnd	= m_list.end();
					KeyNode const* const* rhsLast	= var->m_list.begin() + k + 1;
					KeyNode const* const* rhsEnd	= var->m_list.end();

					while	(	lhsLast < lhsEnd
							&& rhsLast < rhsEnd
							&& (*lhsLast)->type() == (*rhsLast)->type()
							&& (*lhsLast)->key() == (*rhsLast)->key()
							&& *static_cast<Node const*>(*lhsLast) == static_cast<Node const*>(*rhsLast))
					{
						++lhsLast;
						++rhsLast;
					}

					Key const& before	= rhs->endKey();
					Key const& after	= rhsLast == var->m_list.end() ? endKey : (*rhsLast)->startKey();

					nodes.push_back(root->newAction(Action::Replace, level, before, after));
					nodes.insert(nodes.end(), m_list.begin() + i, lhsLast);
					nodes.push_back(root->newAction(Action::Finish, level));
					i = lhsLast - m_list.begin() - 1;
					k = rhsLast - var->m_list.begin() - 1;
				}
				else
				{
					Key const& before	= rhs->endKey();
					Key const& after	= (k == n - 1) ? endKey : var->m_list[k + 1]->startKey();

					nodes.push_back(root->newAction(Action::Replace, level, before, after));
					nodes.push_back(lhs);
					nodes.push_back(root->newAction(Action::Finish, level));
				}
			}

			++i;
			++k;
		}
		else // if (lhsType != rhsType)
		{
			enum { Insert, Remove } action;

			switch (rhsType)
			{
				case TDiagram:		action = Remove; break;
				case TMove:			action = Insert; break;
				case TVariation:	action = (lhsType == TMove) ? Remove : Insert; break;
				default:				//M_ASSERT(!"should not happen");
					return;
			}

			switch (action)
			{
				case Insert:
					nodes.push_back(root->newAction(Action::Insert, level, rhs->startKey()));
					nodes.push_back(lhs);
					nodes.push_back(root->newAction(Action::Finish, level));
					++i;
					break;

				case Remove:
					Key const& after = (k == n - 1) ? endKey : var->m_list[k + 1]->startKey();
					nodes.push_back(root->newAction(Action::Remove, level, rhs->startKey(), after));
					++k;
					break;
			}
		}
	}

	if (i < m)
	{
		nodes.push_back(root->newAction(Action::Insert, level, successor()));
		nodes.insert(nodes.end(), m_list.begin() + i, m_list.end());
		nodes.push_back(root->newAction(Action::Finish, level));
	}

	if (k < n)
		nodes.push_back(root->newAction(Action::Remove, level, var->m_list[k]->startKey(), endKey));
}