Commit 0bfa31ee authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Implemented _wfullpath.

parent 10f0d0ed
......@@ -512,6 +512,171 @@ void _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT_wchar
}
/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
static void wmsvcrt_fln_fix(MSVCRT_wchar_t *path)
{
int dir_flag = 0, root_flag = 0;
MSVCRT_wchar_t *r, *p, *q, *s;
MSVCRT_wchar_t szbsdot[] = { '\\', '.', 0 };
/* Skip drive */
if (NULL == (r = strrchrW(path, ':')))
r = path;
else
++r;
/* Ignore leading slashes */
while ('\\' == *r)
if ('\\' == r[1])
strcpyW(r, &r[1]);
else
{
root_flag = 1;
++r;
}
p = r; /* Change "\\" to "\" */
while (NULL != (p = strchrW(p, '\\')))
if ('\\' == p[1])
strcpyW(p, &p[1]);
else
++p;
while ('.' == *r) /* Scrunch leading ".\" */
{
if ('.' == r[1])
{
/* Ignore leading ".." */
for (p = (r += 2); *p && (*p != '\\'); ++p)
;
}
else
{
for (p = r + 1 ;*p && (*p != '\\'); ++p)
;
}
strcpyW(r, p + ((*p) ? 1 : 0));
}
while ('\\' == path[strlenW(path)-1]) /* Strip last '\\' */
{
dir_flag = 1;
path[strlenW(path)-1] = '\0';
}
s = r;
/* Look for "\." in path */
while (NULL != (p = strstrW(s, szbsdot)))
{
if ('.' == p[2])
{
/* Execute this section if ".." found */
q = p - 1;
while (q > r) /* Backup one level */
{
if (*q == '\\')
break;
--q;
}
if (q > r)
{
strcpyW(q, p + 3);
s = q;
}
else if ('.' != *q)
{
strcpyW(q + ((*q == '\\') ? 1 : 0),
p + 3 + ((*(p + 3)) ? 1 : 0));
s = q;
}
else s = ++p;
}
else
{
/* Execute this section if "." found */
q = p + 2;
for ( ;*q && (*q != '\\'); ++q)
;
strcpyW (p, q);
}
}
if (root_flag) /* Embedded ".." could have bubbled up to root */
{
for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
;
if (r != p)
strcpyW(r, p);
}
if (dir_flag)
{
MSVCRT_wchar_t szbs[] = { '\\', 0 };
strcatW(path, szbs);
}
}
/*********************************************************************
* _wfullpath (MSVCRT.@)
*/
MSVCRT_wchar_t *_wfullpath(MSVCRT_wchar_t * absPath, const MSVCRT_wchar_t* relPath, unsigned int size)
{
MSVCRT_wchar_t drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
MSVCRT_wchar_t res[MAX_PATH];
size_t len;
MSVCRT_wchar_t szbs[] = { '\\', 0 };
res[0] = '\0';
if (!relPath || !*relPath)
return _wgetcwd(absPath, size);
if (size < 4)
{
*MSVCRT__errno() = MSVCRT_ERANGE;
return NULL;
}
TRACE(":resolving relative path '%s'\n",debugstr_w(relPath));
_wsplitpath(relPath, drive, dir, file, ext);
/* Get Directory and drive into 'res' */
if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
{
/* Relative or no directory given */
_wgetdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 : 0, res, MAX_PATH);
strcatW(res,szbs);
if (dir[0])
strcatW(res,dir);
if (drive[0])
res[0] = drive[0]; /* If given a drive, preserve the letter case */
}
else
{
strcpyW(res,drive);
strcatW(res,dir);
}
strcatW(res,szbs);
strcatW(res, file);
strcatW(res, ext);
wmsvcrt_fln_fix(res);
len = strlenW(res);
if (len >= MAX_PATH || len >= (size_t)size)
return NULL; /* FIXME: errno? */
if (!absPath)
return _wcsdup(res);
strcpyW(absPath,res);
return absPath;
}
/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
static void msvcrt_fln_fix(char *path)
{
int dir_flag = 0, root_flag = 0;
......
......@@ -521,7 +521,7 @@
@ cdecl _wfopen(wstr wstr)
@ stub _wfreopen #(wstr wstr ptr)
@ cdecl _wfsopen(wstr wstr long)
@ stub _wfullpath #(ptr wstr long)
@ cdecl _wfullpath(ptr wstr long)
@ cdecl _wgetcwd(wstr long)
@ cdecl _wgetdcwd(long wstr long)
@ cdecl _wgetenv(wstr)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment