예제 #1
0
TEST( PathTools, GetSlash )
{
#if defined( _WIN32 )
	ASSERT_EQ( '\\', Path_GetSlash() );
#else
	ASSERT_EQ( '/', Path_GetSlash() );
#endif
}
예제 #2
0
std::string Path_RemoveTrailingSlash(const std::string & sRawPath, char slash)
{
	if (slash == 0)
		slash = Path_GetSlash();

	std::string sPath = sRawPath;
	std::string::size_type nCurrent = sRawPath.length();
	if (nCurrent == 0)
		return sPath;

	int nLastFound = -1;
	nCurrent--;
	while (nCurrent != 0)
	{
		if (sRawPath[nCurrent] == slash)
		{
			nLastFound = (int)nCurrent;
			nCurrent--;
		}
		else
		{
			break;
		}
	}

	if (nLastFound >= 0)
	{
		sPath.erase(nLastFound, std::string::npos);
	}

	return sPath;
}
예제 #3
0
/** returns just the filename from the provided full or relative path. */
std::string Path_StripDirectory(const std::string & sPath, char slash)
{
	if (slash == 0)
		slash = Path_GetSlash();

	std::string::size_type n = sPath.find_last_of(slash);
	if (n == std::string::npos)
		return sPath;
	else
		return std::string(sPath.begin() + n + 1, sPath.end());
}
예제 #4
0
/** Returns the specified path without its filename */
std::string Path_StripFilename(const std::string& sPath, char slash)
{
	if (slash == 0)
		slash = Path_GetSlash();

	std::string::size_type n = sPath.find_last_of(slash);
	if (n == std::string::npos)
		return sPath;
	else
		return std::string(sPath.begin(), sPath.begin() + n);
}
예제 #5
0
/** Fixes the directory separators for the current platform */
std::string Path_FixSlashes(const std::string & sPath, char slash)
{
	if (slash == 0)
		slash = Path_GetSlash();

	std::string sFixed = sPath;
	for (std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++)
	{
		if (*i == '/' || *i == '\\')
			* i = slash;
	}

	return sFixed;
}
예제 #6
0
/** Jams two paths together with the right kind of slash */
std::string Path_Join(const std::string & first, const std::string & second, char slash)
{
	if (slash == 0)
		slash = Path_GetSlash();

	// only insert a slash if we don't already have one
	std::string::size_type nLen = first.length();
	if (!nLen)
		return second;
#if defined(_WIN32)
	if (first.back() == '\\' || first.back() == '/')
		nLen--;
#else
	char last_char = first[first.length() - 1];
	if (last_char == '\\' || last_char == '/')
		nLen--;
#endif

	return first.substr(0, nLen) + std::string(1, slash) + second;
}
예제 #7
0
/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the
* specified path has a broken number of directories for its number of ..s */
std::string Path_Compact(const std::string & sRawPath, char slash)
{
	if (slash == 0)
		slash = Path_GetSlash();

	std::string sPath = Path_FixSlashes(sRawPath, slash);
	std::string sSlashString(1, slash);

	// strip out all /./
	for (std::string::size_type i = 0; (i + 3) < sPath.length(); )
	{
		if (sPath[i] == slash && sPath[i + 1] == '.' && sPath[i + 2] == slash)
		{
			sPath.replace(i, 3, sSlashString);
		}
		else
		{
			++i;
		}
	}


	// get rid of trailing /. but leave the path separator
	if (sPath.length() > 2)
	{
		std::string::size_type len = sPath.length();
		if (sPath[len - 1] == '.' && sPath[len - 2] == slash)
		{
			// sPath.pop_back();
			sPath[len - 1] = 0;  // for now, at least
		}
	}

	// get rid of leading ./ 
	if (sPath.length() > 2)
	{
		if (sPath[0] == '.' && sPath[1] == slash)
		{
			sPath.replace(0, 2, "");
		}
	}

	// each time we encounter .. back up until we've found the previous directory name
	// then get rid of both
	std::string::size_type i = 0;
	while (i < sPath.length())
	{
		if (i > 0 && sPath.length() - i >= 2
			&& sPath[i] == '.'
			&& sPath[i + 1] == '.'
			&& (i + 2 == sPath.length() || sPath[i + 2] == slash)
			&& sPath[i - 1] == slash)
		{
			// check if we've hit the start of the string and have a bogus path
			if (i == 1)
				return "";

			// find the separator before i-1
			std::string::size_type iDirStart = i - 2;
			while (iDirStart > 0 && sPath[iDirStart - 1] != slash)
				--iDirStart;

			// remove everything from iDirStart to i+2
			sPath.replace(iDirStart, (i - iDirStart) + 3, "");

			// start over
			i = 0;
		}
		else
		{
			++i;
		}
	}

	return sPath;
}