From: pweilbacher Date: Tue, 15 Apr 2008 18:50:02 +0000 (+0000) Subject: Support UTF-8 filenames on OS/2 by converting them to and from the local codepage... X-Git-Tag: version-3.6.10~1163 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d190be853978155ca7c8442058a87d59bed16c41;p=thirdparty%2Fsqlite.git Support UTF-8 filenames on OS/2 by converting them to and from the local codepage. Ticket 3052. (CVS 5014) FossilOrigin-Name: cafa8ac2687890355a7faa751d71859eb0fadd01 --- diff --git a/manifest b/manifest index fcfbc77062..5b8822c9a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increment\sthe\sversion\snumber.\s(CVS\s5013) -D 2008-04-15T14:37:51 +C Support\sUTF-8\sfilenames\son\sOS/2\sby\sconverting\sthem\sto\sand\sfrom\sthe\slocal\scodepage.\sTicket\s3052.\s(CVS\s5014) +D 2008-04-15T18:50:02 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -118,9 +118,9 @@ F src/mutex_os2.c 2911ea96955ab6cba734cc4ad903fe76f834b39e F src/mutex_unix.c 466d20378a0645fea64c3f2e2669c33b7802df56 F src/mutex_w32.c 133698096a2c4e81cd11ea6f4de7891c66f7b9f7 F src/os.c d811a3e1a152e03c98d3dd85f2b7aff0d7630cea -F src/os.h 497bf5f0f2648461ef65940cfb59ba427430f3fc +F src/os.h 2ee8b0dec88f946c5371919ffa0f2fe4ac0de2e6 F src/os_common.h e8b748b2f2ecc8a498e50bfe5d8721f189c19d2a -F src/os_os2.c 85c443333761d5b58f041489a7b21ae918993e4f +F src/os_os2.c 7a918c400ee9ed879b50fedc61e74985b285f2b0 F src/os_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b F src/os_test.c 3074b10357ab6175caaab808c780e5e1f94a20b8 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 @@ -137,7 +137,7 @@ F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a F src/select.c 5b8824a326a923876827fa8771c5e4e9e3a7faa1 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 -F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d +F src/shell.c be22ec05c8c4a43a95a6ad3b8068542200451e07 F src/sqlite.h.in 824f823b341e9c979f82edebf710c87b74d1b7f5 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3 F src/sqliteInt.h 625375d9327f0d79bf6f0f7864cc4a0543aec440 @@ -630,7 +630,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P f5fc42e96d36b78797d7fa10b01d22b8501112b1 -R 71b9be4e3d499e4cd475e805a56af0fa -U drh -Z e324a3cc0d4912a74acebac21239e8ad +P a12fa0252c1bc45a116d0123758ef639cc8e451b +R d8de72a548d7f4403c57ee71816098c3 +U pweilbacher +Z ca8f83b6ee28230fbc93d88b258246a7 diff --git a/manifest.uuid b/manifest.uuid index 61b70ba8cc..9f8444a80b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a12fa0252c1bc45a116d0123758ef639cc8e451b \ No newline at end of file +cafa8ac2687890355a7faa751d71859eb0fadd01 \ No newline at end of file diff --git a/src/os.h b/src/os.h index 77934b840d..ac619af61c 100644 --- a/src/os.h +++ b/src/os.h @@ -84,6 +84,7 @@ # define INCL_DOSMODULEMGR # define INCL_DOSSEMAPHORES # include +# include # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) #else # define SQLITE_TEMPNAME_SIZE 200 diff --git a/src/os_os2.c b/src/os_os2.c index f183c9ae2a..6191fbadd9 100644 --- a/src/os_os2.c +++ b/src/os_os2.c @@ -291,7 +291,7 @@ int os2Lock( sqlite3_file *id, int locktype ){ /* If there is already a lock of this type or more restrictive on the ** os2File, do nothing. Don't use the end_lock: exit path, as - ** sqlite3OsEnterMutex() hasn't been called yet. + ** sqlite3_mutex_enter() hasn't been called yet. */ if( pFile->locktype>=locktype ){ OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype ); @@ -553,6 +553,66 @@ static int os2DeviceCharacteristics(sqlite3_file *id){ return 0; } +/* +** Helper function to convert UTF-8 filenames to local OS/2 codepage. +** The two-step process: first convert the incoming UTF-8 string +** into UCS-2 and then from UCS-2 to the current codepage. +** The returned char pointer has to be freed. +*/ +char *convertUtf8PathToCp(const char *in) +{ + UconvObject uconv; + UniChar ucsUtf8Cp[12], + tempPath[CCHMAXPATH]; + char *out; + int rc = 0; + + out = (char *)calloc(CCHMAXPATH, 1); + + /* determine string for the conversion of UTF-8 which is CP1208 */ + rc = UniMapCpToUcsCp(1208, ucsUtf8Cp, 12); + rc = UniCreateUconvObject(ucsUtf8Cp, &uconv); + rc = UniStrToUcs(uconv, tempPath, (char *)in, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + /* conversion for current codepage which can be used for paths */ + rc = UniCreateUconvObject((UniChar *)L"@path=yes", &uconv); + rc = UniStrFromUcs(uconv, out, tempPath, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + return out; +} + +/* +** Helper function to convert filenames from local codepage to UTF-8. +** The two-step process: first convert the incoming codepage-specific +** string into UCS-2 and then from UCS-2 to the codepage of UTF-8. +** The returned char pointer has to be freed. +*/ +char *convertCpPathToUtf8(const char *in) +{ + UconvObject uconv; + UniChar ucsUtf8Cp[12], + tempPath[CCHMAXPATH]; + char *out; + int rc = 0; + + out = (char *)calloc(CCHMAXPATH, 1); + + /* conversion for current codepage which can be used for paths */ + rc = UniCreateUconvObject((UniChar *)L"@path=yes", &uconv); + rc = UniStrToUcs(uconv, tempPath, (char *)in, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + /* determine string for the conversion of UTF-8 which is CP1208 */ + rc = UniMapCpToUcsCp(1208, ucsUtf8Cp, 12); + rc = UniCreateUconvObject(ucsUtf8Cp, &uconv); + rc = UniStrFromUcs(uconv, out, tempPath, CCHMAXPATH); + rc = UniFreeUconvObject(uconv); + + return out; +} + /* ** This vector defines all the methods that can operate on an ** sqlite3_file for os2. @@ -597,7 +657,7 @@ static int os2Open( APIRET rc = NO_ERROR; ULONG ulAction; - memset(pFile, 0, sizeof(*pFile)); + memset( pFile, 0, sizeof(*pFile) ); OSTRACE2( "OPEN want %d\n", flags ); @@ -647,7 +707,8 @@ static int os2Open( ulOpenMode |= OPEN_FLAGS_RANDOM; ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; - rc = DosOpen( (PSZ)zName, + char *zNameCp = convertUtf8PathToCp( zName ); + rc = DosOpen( (PSZ)zNameCp, &h, &ulAction, 0L, @@ -655,6 +716,7 @@ static int os2Open( ulOpenFlags, ulOpenMode, (PEAOP2)NULL ); + free( zNameCp ); if( rc != NO_ERROR ){ OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ); @@ -689,7 +751,9 @@ int os2Delete( ){ APIRET rc = NO_ERROR; SimulateIOError(return SQLITE_IOERR_DELETE); - rc = DosDelete( (PSZ)zFilename ); + char *zFilenameCp = convertUtf8PathToCp( zFilename ); + rc = DosDelete( (PSZ)zFilenameCp ); + free( zFilenameCp ); OSTRACE2( "DELETE \"%s\"\n", zFilename ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } @@ -705,9 +769,11 @@ static int os2Access( FILESTATUS3 fsts3ConfigInfo; APIRET rc = NO_ERROR; - memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); - rc = DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD, + memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) ); + char *zFilenameCp = convertUtf8PathToCp( zFilename ); + rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) ); + free( zFilenameCp ); OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", fsts3ConfigInfo.attrFile, flags, rc ); switch( flags ){ @@ -739,6 +805,7 @@ static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ int i, j; char zTempPathBuf[3]; PSZ zTempPath = (PSZ)&zTempPathBuf; + char *zTempPathUTF; if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ @@ -755,8 +822,10 @@ static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ j--; } zTempPath[j] = '\0'; + zTempPathUTF = convertCpPathToUtf8( zTempPath ); sqlite3_snprintf( nBuf-30, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath ); + "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF ); + free( zTempPathUTF ); j = strlen( zBuf ); sqlite3_randomness( 20, &zBuf[j] ); for( i = 0; i < 20; i++, j++ ){ @@ -779,7 +848,15 @@ static int os2FullPathname( int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ - APIRET rc = DosQueryPathInfo( zRelative, FIL_QUERYFULLNAME, zFull, nFull ); + char *zRelativeCp = convertUtf8PathToCp( zRelative ); + char zFullCp[CCHMAXPATH]; + char *zFullUTF; + APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp, + CCHMAXPATH ); + free( zRelativeCp ); + zFullUTF = convertCpPathToUtf8( zFullCp ); + sqlite3_snprintf( nFull, zFull, zFullUTF ); + free( zFullUTF ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } @@ -796,7 +873,9 @@ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ UCHAR loadErr[256]; HMODULE hmod; APIRET rc; - rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilename, &hmod); + char *zFilenameCp = convertUtf8PathToCp(zFilename); + rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilenameCp, &hmod); + free(zFilenameCp); return rc != NO_ERROR ? 0 : (void*)hmod; } /* diff --git a/src/shell.c b/src/shell.c index 467917960d..319c343327 100644 --- a/src/shell.c +++ b/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.176 2008/03/04 17:45:01 mlcreech Exp $ +** $Id: shell.c,v 1.177 2008/04/15 18:50:02 pweilbacher Exp $ */ #include #include @@ -1944,7 +1944,11 @@ int main(int argc, char **argv){ } } if( i