diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 2b5b0641e2..82463d5d9c 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,45 @@ The license applies to all entries newer than 2009-04-28. */ +2012-03-29 03:45 UTC+0200 Viktor Szakats (harbour syenar.net) + * src/rtl/fstemp.c + * hb_fsCreateTempEx(): changed to have only one return point + ! hb_fsCreateTempEx(): do not call hb_fsNameConv() before + calling hb_fsCreateEx(). Latter does this since a few + commits, causing a regression here. + ! low level hb_fsTempName() fixed to use HB_FSNAMECONV() + instead of HB_TCHAR_*() macros. This is slightly inappropriate + for 'prefix' parameter, but will do for now. + ! low level hb_fsTempName() fixed to convert back result + to _SET_OSCODEPAGE. This fixes caller hb_fsCreateTemp() + which passes the value to hb_fsCreateEx(). + ! hb_fsTempDir(): fixed to convert result to _SET_OSCODEPAGE. + ; NOTE: These are supposed to fix some recent and not so recent + oddities with HB_FCREATETEMP[EX]() and HB_DIRTEMP() + functions when used with non-ASCII chars, especially + on Windows. Tests done only on Windows, please review + and test, also on other platforms, non-UNICODE mode. + Regressions are possible. + Oddly, HB_FCREATETEMP() won't work well without properly + set _SET_OSCODEPAGE, probably something requiring further + fixes (and/or internal unicode support?). + ; NOTE: As a loose rule of thumb, each Harbour high-level (.prg) + and low-level (.c) public APIs should expect and return + strings in _SET_CODEPAGE, while applying FSCONV transformations + on input filenames, and converting to/from _SET_OSCODEPAGE + when interfacing with OS-level FS APIs (_SET_OSCODEPAGE + should be ignored if OS-level FS APIs are capable of + handling unicode, f.e. in Windows default build mode). + Currently, low-level code uses a mixture of different + methods to achieve this, HB_TCHAR_* macros and equivalent + APIs, HB_FSNAMECONV(), hb_osDecodeCP()/hb_osEncodeCP(), + hb_fsNameConv(), Str API. + + * contrib/hbmzip/mzip.c + + Changed to use HB_FSNAMECONV() instead of HB_TCHAR_*() macros. + + ; review me! + 2012-03-29 00:06 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * harbour/src/vm/itemapi.c % removed redundant trailing 0 setting diff --git a/harbour/contrib/hbmzip/mzip.c b/harbour/contrib/hbmzip/mzip.c index 7d0451f79d..262b48f759 100644 --- a/harbour/contrib/hbmzip/mzip.c +++ b/harbour/contrib/hbmzip/mzip.c @@ -76,6 +76,7 @@ #endif #elif defined( HB_OS_WIN ) #include + #include "hbwinuni.h" #elif defined( HB_OS_OS2 ) #define INCL_DOSFILEMGR #define INCL_ERRORS @@ -707,8 +708,8 @@ static int hb_zipStoreFile( zipFile hZip, const char * szFileName, const char * #if defined( HB_OS_WIN ) { - char * pszFree; - LPTSTR lpFileName = HB_TCHAR_CONVTO( hb_fsNameConv( szFileName, &pszFree ) ); + LPTSTR lpFileNameFree; + LPTSTR lpFileName = HB_FSNAMECONV( szFileName, &lpFileNameFree ); DWORD attr = GetFileAttributes( lpFileName ); if( attr != INVALID_FILE_ATTRIBUTES ) @@ -721,10 +722,8 @@ static int hb_zipStoreFile( zipFile hZip, const char * szFileName, const char * else fError = HB_TRUE; - HB_TCHAR_FREE( lpFileName ); - - if( pszFree ) - hb_xfree( pszFree ); + if( lpFileNameFree ) + hb_xfree( lpFileNameFree ); } #elif defined( HB_OS_UNIX ) { @@ -793,7 +792,7 @@ static int hb_zipStoreFile( zipFile hZip, const char * szFileName, const char * # endif { ulExtAttr = attr & ( HB_FA_READONLY | HB_FA_HIDDEN | HB_FA_SYSTEM | - HB_FA_DIRECTORY | HB_FA_ARCHIVE ); + HB_FA_DIRECTORY | HB_FA_ARCHIVE ); ulExtAttr = hb_translateExtAttr( szFileName, ulExtAttr ); } @@ -1116,15 +1115,13 @@ static int hb_unzipExtractCurrentFile( unzFile hUnzip, const char * szFileName, #if defined( HB_OS_WIN ) { - char * pszFree; - LPTSTR lpFileName = HB_TCHAR_CONVTO( hb_fsNameConv( szName, &pszFree ) ); + LPTSTR lpFileNameFree; + LPTSTR lpFileName = HB_FSNAMECONV( szName, &lpFileNameFree ); SetFileAttributes( ( LPCTSTR ) lpFileName, ufi.external_fa & 0xFF ); - HB_TCHAR_FREE( lpFileName ); - - if( pszFree ) - hb_xfree( pszFree ); + if( lpFileNameFree ) + hb_xfree( lpFileNameFree ); } #elif defined( HB_OS_UNIX ) || defined( __DJGPP__ ) { diff --git a/harbour/src/rtl/fstemp.c b/harbour/src/rtl/fstemp.c index 6bf2f6b83e..aca6a72eca 100644 --- a/harbour/src/rtl/fstemp.c +++ b/harbour/src/rtl/fstemp.c @@ -73,6 +73,7 @@ #if defined( HB_OS_WIN ) #include + #include "hbwinuni.h" #endif #if ( defined( HB_OS_LINUX ) && ( !defined( __WATCOMC__ ) || __WATCOMC__ >= 1280 ) ) || \ @@ -171,7 +172,10 @@ HB_FHANDLE hb_fsCreateTempEx( char * pszName, const char * pszDir, const char * iLen = ( int ) strlen( pszName ); if( iLen > ( HB_PATH_MAX - 1 ) - 6 ) - return FS_ERROR; + { + fd = FS_ERROR; + break; + } #if defined( HB_HAS_MKSTEMP ) if( hb_setGetFileCase() != HB_SET_CASE_LOWER && @@ -221,16 +225,15 @@ HB_FHANDLE hb_fsCreateTempEx( char * pszName, const char * pszDir, const char * pszName[ iLen ] = '\0'; if( pszExt ) hb_strncat( pszName, pszExt, HB_PATH_MAX - 1 ); - hb_fsNameConv( pszName, NULL ); fd = hb_fsCreateEx( pszName, ulAttr, FO_EXCLUSIVE | FO_EXCL ); } if( fd != ( HB_FHANDLE ) FS_ERROR ) - return fd; + break; } while( --iAttemptLeft ); - return FS_ERROR; + return fd; } /* NOTE: The buffer must be at least HB_PATH_MAX chars long */ @@ -240,16 +243,22 @@ static HB_BOOL hb_fsTempName( char * pszBuffer, const char * pszDir, const char { HB_BOOL fResult; + pszBuffer[ 0 ] = '\0'; + hb_vmUnlock(); #if defined( HB_OS_WIN ) { - LPTSTR lpPrefix = pszPrefix ? HB_TCHAR_CONVTO( pszPrefix ) : NULL; + LPTSTR lpPrefix, lpPrefixFree = NULL; + LPTSTR lpDir, lpDirFree = NULL; + TCHAR lpBuffer[ HB_PATH_MAX ]; TCHAR lpTempDir[ HB_PATH_MAX ]; + lpPrefix = pszPrefix ? HB_FSNAMECONV( pszPrefix, &lpPrefixFree ) : NULL; + if( pszDir && pszDir[ 0 ] != '\0' ) - HB_TCHAR_COPYTO( lpTempDir, pszDir, HB_PATH_MAX - 1 ); + lpDir = HB_FSNAMECONV( pszDir, &lpDirFree ); else { if( ! GetTempPath( HB_PATH_MAX, lpTempDir ) ) @@ -257,16 +266,19 @@ static HB_BOOL hb_fsTempName( char * pszBuffer, const char * pszDir, const char hb_fsSetIOError( HB_FALSE, 0 ); return HB_FALSE; } + lpTempDir[ HB_PATH_MAX - 1 ] = TEXT( '\0' ); + lpDir = lpTempDir; } - lpTempDir[ HB_PATH_MAX - 1 ] = TEXT( '\0' ); - fResult = GetTempFileName( lpTempDir, lpPrefix ? lpPrefix : TEXT( "hb" ), 0, lpBuffer ); + fResult = GetTempFileName( lpDir, lpPrefix ? lpPrefix : TEXT( "hb" ), 0, lpBuffer ); if( fResult ) HB_TCHAR_COPYFROM( pszBuffer, lpBuffer, HB_PATH_MAX - 1 ); - if( lpPrefix ) - HB_TCHAR_FREE( lpPrefix ); + if( lpPrefixFree ) + hb_xfree( lpPrefixFree ); + if( lpDirFree ) + hb_xfree( lpDirFree ); } #else @@ -278,7 +290,6 @@ static HB_BOOL hb_fsTempName( char * pszBuffer, const char * pszDir, const char passed buffer. It will be needed to fix HB_PATH_MAX - 1 to be at least this large. */ - pszBuffer[ 0 ] = '\0'; fResult = ( tmpnam( pszBuffer ) != NULL ); # if defined( __DJGPP__ ) @@ -295,6 +306,21 @@ static HB_BOOL hb_fsTempName( char * pszBuffer, const char * pszDir, const char hb_fsSetIOError( fResult, 0 ); hb_vmLock(); + /* Convert from OS codepage */ + if( fResult ) + { + char * pszFree = NULL; + const char * pszResult; + HB_SIZE nLen = strlen( pszBuffer ); + + pszResult = hb_osDecodeCP( pszBuffer, &pszFree, &nLen ); + + if( pszResult != pszBuffer ) + hb_strncpy( pszBuffer, pszResult, HB_PATH_MAX - 1 ); + if( pszFree ) + hb_xfree( pszFree ); + } + return fResult; } @@ -448,6 +474,20 @@ HB_ERRCODE hb_fsTempDir( char * pszTempDir ) } #endif + /* Convert from OS codepage */ + { + char * pszFree = NULL; + const char * pszResult; + HB_SIZE nLen = strlen( pszTempDir ); + + pszResult = hb_osDecodeCP( pszTempDir, &pszFree, &nLen ); + + if( pszResult != pszTempDir ) + hb_strncpy( pszTempDir, pszResult, HB_PATH_MAX - 1 ); + if( pszFree ) + hb_xfree( pszFree ); + } + return nResult; }