diff options
author | Jan Dubois <jand@activestate.com> | 2006-12-18 13:37:25 -0800 |
---|---|---|
committer | Steve Peters <steve@fisharerojo.org> | 2006-12-20 04:14:06 +0000 |
commit | d684b16258d4be88a6b78f17e48637c1127b0ed7 (patch) | |
tree | 56192373b41ee0fe650bdc7677208f0efb500d98 | |
parent | 35cf1ab6c6ff4f898ef39b9c22313127bcebffc4 (diff) | |
download | perl-d684b16258d4be88a6b78f17e48637c1127b0ed7.tar.gz |
Update cwd() to return the "short" pathname if the long one doesn't fit the codepage
Message-ID: <3rteo219or8hqr511e4vg1fnsgvgemb4sh@4ax.com>
p4raw-id: //depot/perl@29598
-rw-r--r-- | win32/perlhost.h | 54 | ||||
-rw-r--r-- | win32/vdir.h | 88 |
2 files changed, 106 insertions, 36 deletions
diff --git a/win32/perlhost.h b/win32/perlhost.h index fe026dde1f..d6e1e0fe33 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -21,6 +21,10 @@ #include "vmem.h" #include "vdir.h" +#ifndef WC_NO_BEST_FIT_CHARS +# define WC_NO_BEST_FIT_CHARS 0x00000400 +#endif + START_EXTERN_C extern char * g_win32_get_privlib(const char *pl); extern char * g_win32_get_sitelib(const char *pl); @@ -2236,20 +2240,52 @@ CPerlHost::FreeLocalEnvironmentStrings(LPSTR lpStr) Safefree(lpStr); } +static char * +get_valid_filename(pTHX_ WCHAR *widename) +{ + char *name; + BOOL use_default = FALSE; + size_t widelen = wcslen(widename)+1; + int len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, widename, widelen, + NULL, 0, NULL, NULL); + Newx(name, len, char); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, widename, widelen, + name, len, NULL, &use_default); + if (use_default) { + WCHAR *shortname; + DWORD shortlen = GetShortPathNameW(widename, NULL, 0); + Newx(shortname, shortlen, WCHAR); + shortlen = GetShortPathNameW(widename, shortname, shortlen)+1; + len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, shortname, shortlen, + NULL, 0, NULL, NULL); + Renew(name, len, char); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, shortname, shortlen, + name, len, NULL, NULL); + Safefree(shortname); + } + return name; +} + char* CPerlHost::GetChildDir(void) { dTHX; - int length; char* ptr; - Newx(ptr, MAX_PATH+1, char); - if(ptr) { - m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr); - length = strlen(ptr); - if (length > 3) { - if ((ptr[length-1] == '\\') || (ptr[length-1] == '/')) - ptr[length-1] = 0; - } + size_t length; + + if (IsWin95()) { + Newx(ptr, MAX_PATH+1, char); + m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr); + } + else { + WCHAR path[MAX_PATH+1]; + m_pvDir->GetCurrentDirectoryW(MAX_PATH+1, path); + ptr = get_valid_filename(aTHX_ path); + } + length = strlen(ptr); + if (length > 3) { + if ((ptr[length-1] == '\\') || (ptr[length-1] == '/')) + ptr[length-1] = 0; } return ptr; } diff --git a/win32/vdir.h b/win32/vdir.h index 10119ead9e..fb80e38679 100644 --- a/win32/vdir.h +++ b/win32/vdir.h @@ -34,47 +34,48 @@ public: inline char* GetCurrentDirectoryA(int dwBufSize, char *lpBuffer) { char* ptr = dirTableA[nDefault]; - while (dwBufSize--) + while (--dwBufSize) { if ((*lpBuffer++ = *ptr++) == '\0') break; } - return lpBuffer; + *lpBuffer = '\0'; + return /* unused */ NULL; }; inline WCHAR* GetCurrentDirectoryW(int dwBufSize, WCHAR *lpBuffer) { WCHAR* ptr = dirTableW[nDefault]; - while (dwBufSize--) + while (--dwBufSize) { if ((*lpBuffer++ = *ptr++) == '\0') break; } - return lpBuffer; + *lpBuffer = '\0'; + return /* unused */ NULL; }; - DWORD CalculateEnvironmentSpace(void); LPSTR BuildEnvironmentSpace(LPSTR lpStr); protected: int SetDirA(char const *pPath, int index); + int SetDirW(WCHAR const *pPath, int index); void FromEnvA(char *pEnv, int index); + void FromEnvW(WCHAR *pEnv, int index); + inline const char *GetDefaultDirA(void) { return dirTableA[nDefault]; }; - inline void SetDefaultDirA(char const *pPath, int index) { SetDirA(pPath, index); nDefault = index; }; - int SetDirW(WCHAR const *pPath, int index); inline const WCHAR *GetDefaultDirW(void) { return dirTableW[nDefault]; }; - inline void SetDefaultDirW(WCHAR const *pPath, int index) { SetDirW(pPath, index); @@ -134,9 +135,6 @@ VDir::VDir(int bManageDir /* = 1 */) void VDir::Init(VDir* pDir, VMem *p) { int index; - DWORD driveBits; - int nSave; - char szBuffer[MAX_PATH*driveCount]; pMem = p; if (pDir) { @@ -146,23 +144,47 @@ void VDir::Init(VDir* pDir, VMem *p) nDefault = pDir->GetDefault(); } else { - nSave = bManageDirectory; + int bSave = bManageDirectory; + DWORD driveBits = GetLogicalDrives(); + OSVERSIONINFO osver; + + memset(&osver, 0, sizeof(osver)); + osver.dwOSVersionInfoSize = sizeof(osver); + GetVersionEx(&osver); + bManageDirectory = 0; - driveBits = GetLogicalDrives(); - if (GetLogicalDriveStrings(sizeof(szBuffer), szBuffer)) { - char* pEnv = (char*)GetEnvironmentStrings(); - char* ptr = szBuffer; - for (index = 0; index < driveCount; ++index) { - if (driveBits & (1<<index)) { - ptr += SetDirA(ptr, index) + 1; - FromEnvA(pEnv, index); - } - } - FreeEnvironmentStrings(pEnv); - } - SetDefaultA("."); - bManageDirectory = nSave; - } + if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + char szBuffer[MAX_PATH*driveCount]; + if (GetLogicalDriveStringsA(sizeof(szBuffer), szBuffer)) { + char* pEnv = (char*)GetEnvironmentStringsA(); + char* ptr = szBuffer; + for (index = 0; index < driveCount; ++index) { + if (driveBits & (1<<index)) { + ptr += SetDirA(ptr, index) + 1; + FromEnvA(pEnv, index); + } + } + FreeEnvironmentStringsA(pEnv); + } + SetDefaultA("."); + } + else { /* Windows NT or later */ + WCHAR szBuffer[MAX_PATH*driveCount]; + if (GetLogicalDriveStringsW(sizeof(szBuffer), szBuffer)) { + WCHAR* pEnv = GetEnvironmentStringsW(); + WCHAR* ptr = szBuffer; + for (index = 0; index < driveCount; ++index) { + if (driveBits & (1<<index)) { + ptr += SetDirW(ptr, index) + 1; + FromEnvW(pEnv, index); + } + } + FreeEnvironmentStringsW(pEnv); + } + SetDefaultW(L"."); + } + bManageDirectory = bSave; + } } int VDir::SetDirA(char const *pPath, int index) @@ -211,6 +233,18 @@ void VDir::FromEnvA(char *pEnv, int index) } } +void VDir::FromEnvW(WCHAR *pEnv, int index) +{ /* gets the directory for index from the environment variable. */ + while (*pEnv != '\0') { + if ((pEnv[0] == '=') && (DriveIndex((char)pEnv[1]) == index)) { + SetDirW(&pEnv[4], index); + break; + } + else + pEnv += wcslen(pEnv)+1; + } +} + void VDir::SetDefaultA(char const *pDefault) { char szBuffer[MAX_PATH+1]; |