summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Dubois <jand@activestate.com>2006-12-18 13:37:25 -0800
committerSteve Peters <steve@fisharerojo.org>2006-12-20 04:14:06 +0000
commitd684b16258d4be88a6b78f17e48637c1127b0ed7 (patch)
tree56192373b41ee0fe650bdc7677208f0efb500d98
parent35cf1ab6c6ff4f898ef39b9c22313127bcebffc4 (diff)
downloadperl-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.h54
-rw-r--r--win32/vdir.h88
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];