Exemple #1
0
INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size)
{
    if (InPath[0] && InPath[1] == _T(':'))
    {
        INT t=0;

        if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
        {
            t = (InPath[0] - _T('0')) +28;
        }

        if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z')))
        {
            t = (InPath[0] - _T('a')) +1;
            InPath[0] = t + _T('A') - 1;
        }

        if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z')))
        {
            t = (InPath[0] - _T('A')) +1;
        }

        return _tgetdcwd(t,OutPath,size) == NULL;
    }

    /* Get current directory */
    return !GetCurrentDirectory(size,OutPath);
}
CL_String CL_PathHelp::make_absolute(
	const CL_String &base_path,
	const CL_String &relative_path,
	PathType path_type)
{
	CL_String base = normalize(base_path, path_type);
	CL_String relative = normalize(relative_path, path_type);
	if (path_type == path_type_file)
	{
		if (!is_absolute(base, path_type_file))
		{
			// make base_path absolute using current drive and directory
#ifdef WIN32
			TCHAR absolute_base[MAX_PATH];
			memset(absolute_base, 0, sizeof(TCHAR) * MAX_PATH);
			if (_tfullpath(absolute_base, CL_StringHelp::utf8_to_ucs2(base).c_str(), MAX_PATH) == 0)
				throw CL_Exception(cl_format("Unable to make base path absolute: %1", base_path));
			base = absolute_base;
#else
			char working_dir[1024];
			memset(working_dir, 0, 1024);
			if (getcwd(working_dir, 1024) == 0)
				throw CL_Exception("Unable to get current working directory!");
			base = add_trailing_slash(working_dir, path_type) + base;
#endif
		}

		CL_String base_location = get_location(base_path, path_type_file);
		CL_String relative_location = get_location(relative_path, path_type_file);
		if (relative_location.empty() || CL_StringHelp::compare(relative_location, base_location, true) == 0)
		{
			if (is_absolute(relative, path_type))
			{
				if (relative_location.empty())
					return base_location + relative;
				else
					return relative;
			}
			CL_String absolute = add_trailing_slash(base, path_type) + relative.substr(relative_location.length());
			return normalize(absolute, path_type);
		}
		else
		{
#ifdef WIN32
			if (is_absolute(relative, path_type))
				return relative;

			if (relative_location.length() == 2 && relative_location[1] == ':')
			{
				int drive = 0;
				if (relative_location[0] >= 'A' && relative_location[0] <= 'Z')
					drive = relative_location[0] - 'A' + 1;
				else if (relative_location[0] >= 'a' && relative_location[0] <= 'z')
					drive = relative_location[0] - 'a' + 1;
				else
					throw CL_Exception(cl_format("Invalid drive: %1", relative_location));
				TCHAR working_dir[MAX_PATH];
				memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH);
				if (_tgetdcwd(drive, working_dir, MAX_PATH) == 0)
					throw CL_Exception(cl_format("Unable to get current working directory for %1!", relative_location));

				return add_trailing_slash(working_dir, path_type) + relative.substr(relative_location.length());
			}
			else
			{
				return relative; // UNC path
			}
#else
			throw CL_Exception("Error in CL_PathHelp::make_absolute");
#endif
		}
	}
	else
	{
		if (is_absolute(relative, path_type))
			return relative;
		CL_String absolute = add_trailing_slash(base, path_type) + relative;
		return normalize(absolute, path_type);
	}
}
CL_String CL_PathHelp::make_relative(
	const CL_String &base_path,
	const CL_String &absolute_path,
	PathType path_type)
{
	CL_String base = add_trailing_slash(normalize(base_path, path_type), path_type);
	CL_String absolute = normalize(absolute_path, path_type);

	if (path_type == path_type_file)
	{
		CL_String base_location = get_location(base, path_type_file);
		CL_String absolute_location = get_location(absolute, path_type_file);

		if (is_relative(base, path_type))
		{
#ifdef WIN32
			if (base_location.length() == 2 && base_location[1] == ':')
			{
				int drive = 0;
				if (base_location[0] >= 'A' && base_location[0] <= 'Z')
					drive = base_location[0] - 'A' + 1;
				else if (base_location[0] >= 'a' && base_location[0] <= 'z')
					drive = base_location[0] - 'a' + 1;
				else
					throw CL_Exception(cl_format("Invalid drive: %1", base_location));
				TCHAR working_dir[MAX_PATH];
				memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH);
				if (_tgetdcwd(drive, working_dir, MAX_PATH) == 0)
					throw CL_Exception(cl_format("Unable to get current working directory for %1!", base_location));

				base = add_trailing_slash(working_dir, path_type) + base;
			}
			else if (base_location.empty())
			{
				TCHAR working_dir[MAX_PATH];
				memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH);
				if (GetCurrentDirectory(MAX_PATH, working_dir) == FALSE)
					throw CL_Exception(cl_format("Unable to get current working directory for %1!", base_location));

				base = add_trailing_slash(working_dir, path_type) + base;
			}
			else
			{
				throw CL_Exception(cl_format("Error in make_relative with base path: %1", base_path));
			}
#else
			char working_dir[1024];
			memset(working_dir, 0, 1024);
			if (getcwd(working_dir, 1024) == 0)
				throw CL_Exception("Unable to get current working directory!");
			base = add_trailing_slash(working_dir, path_type) + base;
#endif
		}
		if (is_relative(absolute, path_type))
		{
#ifdef WIN32
			if (absolute_location.length() == 2 && absolute_location[1] == ':')
			{
				int drive = 0;
				if (absolute_location[0] >= 'A' && absolute_location[0] <= 'Z')
					drive = absolute_location[0] - 'A' + 1;
				else if (absolute_location[0] >= 'a' && absolute_location[0] <= 'z')
					drive = absolute_location[0] - 'a' + 1;
				else
					throw CL_Exception(cl_format("Invalid drive: %1", absolute_location));
				TCHAR working_dir[MAX_PATH];
				memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH);
				if (_tgetdcwd(drive, working_dir, MAX_PATH) == 0)
					throw CL_Exception(cl_format("Unable to get current working directory for %1!", absolute_location));

				absolute = add_trailing_slash(working_dir, path_type) + absolute;
			}
			else if (absolute_location.empty())
			{
				TCHAR working_dir[MAX_PATH];
				memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH);
				if (GetCurrentDirectory(MAX_PATH, working_dir) == FALSE)
					throw CL_Exception(cl_format("Unable to get current working directory for %1!", absolute_location));

				absolute = add_trailing_slash(working_dir, path_type) + absolute;
			}
			else
			{
				throw CL_Exception(cl_format("Error in make_relative with absolute path: %1", absolute_path));
			}
#else
			char working_dir[1024];
			memset(working_dir, 0, 1024);
			if (getcwd(working_dir, 1024) == 0)
				throw CL_Exception("Unable to get current working directory!");
			absolute = add_trailing_slash(working_dir, path_type) + absolute;
#endif
		}

		base_location = get_location(base, path_type_file);
		absolute_location = get_location(absolute, path_type_file);
		if (CL_StringHelp::compare(absolute_location, base_location, true) != 0)
			return absolute_path;
	}

	if (is_relative(base, path_type))
		throw CL_Exception(cl_format("Relative path %1 used as base path for make_relative", base_path));
	if (is_relative(absolute, path_type))
		throw CL_Exception(cl_format("Relative path %1 used as absolute path for make_relative", absolute_path));

	CL_String relative;
	CL_String relative_end;

	bool differs = false;
	CL_String::size_type start_pos = 0, end_pos = 0;
	while (true)
	{
		if (path_type == path_type_file)
		{
			end_pos = base.find_first_of("\\/", start_pos);
		}
		else
		{
			end_pos = base.find('/', start_pos);
		}
		if (end_pos == CL_String::npos)
			break;

		if (!differs)
		{
			CL_String base_element = base.substr(start_pos, end_pos - start_pos + 1);
			CL_String absolute_element = absolute.substr(start_pos, end_pos - start_pos + 1);

			bool same_element = false;
			if (path_type == path_type_file)
			{
#ifdef WIN32
				same_element = (CL_StringHelp::compare(base_element, absolute_element, true) == 0);
#else
				same_element = (base_element == absolute_element);
#endif
			}
			else
			{
				same_element = (base_element == absolute_element);
			}

			if (!same_element)
			{
				relative_end = absolute.substr(start_pos);
				differs = true;
			}
			else
			{
				relative_end = absolute.substr(end_pos+1);
			}
		}

		if (differs)
		{
			if (path_type_file)
			{
#ifdef WIN32
				relative += "..\\";
#else
				relative += "../";
#endif
			}
			else
			{
				relative += "../";
			}
		}

		start_pos = end_pos + 1;
	}

	return relative + relative_end;
}