1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Support UTF-8 filenames on OS/2 by converting them to and from the local codepage. Ticket 3052. (CVS 5014)

FossilOrigin-Name: cafa8ac2687890355a7faa751d71859eb0fadd01
This commit is contained in:
pweilbacher
2008-04-15 18:50:02 +00:00
parent 1d3a5ac998
commit d190be8539
5 changed files with 104 additions and 20 deletions

View File

@@ -1,5 +1,5 @@
C Increment\sthe\sversion\snumber.\s(CVS\s5013) 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-15T14:37:51 D 2008-04-15T18:50:02
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -118,9 +118,9 @@ F src/mutex_os2.c 2911ea96955ab6cba734cc4ad903fe76f834b39e
F src/mutex_unix.c 466d20378a0645fea64c3f2e2669c33b7802df56 F src/mutex_unix.c 466d20378a0645fea64c3f2e2669c33b7802df56
F src/mutex_w32.c 133698096a2c4e81cd11ea6f4de7891c66f7b9f7 F src/mutex_w32.c 133698096a2c4e81cd11ea6f4de7891c66f7b9f7
F src/os.c d811a3e1a152e03c98d3dd85f2b7aff0d7630cea F src/os.c d811a3e1a152e03c98d3dd85f2b7aff0d7630cea
F src/os.h 497bf5f0f2648461ef65940cfb59ba427430f3fc F src/os.h 2ee8b0dec88f946c5371919ffa0f2fe4ac0de2e6
F src/os_common.h e8b748b2f2ecc8a498e50bfe5d8721f189c19d2a 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_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b
F src/os_test.c 3074b10357ab6175caaab808c780e5e1f94a20b8 F src/os_test.c 3074b10357ab6175caaab808c780e5e1f94a20b8
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
@@ -137,7 +137,7 @@ F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
F src/select.c 5b8824a326a923876827fa8771c5e4e9e3a7faa1 F src/select.c 5b8824a326a923876827fa8771c5e4e9e3a7faa1
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d F src/shell.c be22ec05c8c4a43a95a6ad3b8068542200451e07
F src/sqlite.h.in 824f823b341e9c979f82edebf710c87b74d1b7f5 F src/sqlite.h.in 824f823b341e9c979f82edebf710c87b74d1b7f5
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
F src/sqliteInt.h 625375d9327f0d79bf6f0f7864cc4a0543aec440 F src/sqliteInt.h 625375d9327f0d79bf6f0f7864cc4a0543aec440
@@ -630,7 +630,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P f5fc42e96d36b78797d7fa10b01d22b8501112b1 P a12fa0252c1bc45a116d0123758ef639cc8e451b
R 71b9be4e3d499e4cd475e805a56af0fa R d8de72a548d7f4403c57ee71816098c3
U drh U pweilbacher
Z e324a3cc0d4912a74acebac21239e8ad Z ca8f83b6ee28230fbc93d88b258246a7

View File

@@ -1 +1 @@
a12fa0252c1bc45a116d0123758ef639cc8e451b cafa8ac2687890355a7faa751d71859eb0fadd01

View File

@@ -84,6 +84,7 @@
# define INCL_DOSMODULEMGR # define INCL_DOSMODULEMGR
# define INCL_DOSSEMAPHORES # define INCL_DOSSEMAPHORES
# include <os2.h> # include <os2.h>
# include <uconv.h>
# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
#else #else
# define SQLITE_TEMPNAME_SIZE 200 # define SQLITE_TEMPNAME_SIZE 200

View File

@@ -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 /* 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 ** 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 ){ if( pFile->locktype>=locktype ){
OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype ); OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype );
@@ -553,6 +553,66 @@ static int os2DeviceCharacteristics(sqlite3_file *id){
return 0; 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 ** This vector defines all the methods that can operate on an
** sqlite3_file for os2. ** sqlite3_file for os2.
@@ -597,7 +657,7 @@ static int os2Open(
APIRET rc = NO_ERROR; APIRET rc = NO_ERROR;
ULONG ulAction; ULONG ulAction;
memset(pFile, 0, sizeof(*pFile)); memset( pFile, 0, sizeof(*pFile) );
OSTRACE2( "OPEN want %d\n", flags ); OSTRACE2( "OPEN want %d\n", flags );
@@ -647,7 +707,8 @@ static int os2Open(
ulOpenMode |= OPEN_FLAGS_RANDOM; ulOpenMode |= OPEN_FLAGS_RANDOM;
ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
rc = DosOpen( (PSZ)zName, char *zNameCp = convertUtf8PathToCp( zName );
rc = DosOpen( (PSZ)zNameCp,
&h, &h,
&ulAction, &ulAction,
0L, 0L,
@@ -655,6 +716,7 @@ static int os2Open(
ulOpenFlags, ulOpenFlags,
ulOpenMode, ulOpenMode,
(PEAOP2)NULL ); (PEAOP2)NULL );
free( zNameCp );
if( rc != NO_ERROR ){ if( rc != NO_ERROR ){
OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ); rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode );
@@ -689,7 +751,9 @@ int os2Delete(
){ ){
APIRET rc = NO_ERROR; APIRET rc = NO_ERROR;
SimulateIOError(return SQLITE_IOERR_DELETE); SimulateIOError(return SQLITE_IOERR_DELETE);
rc = DosDelete( (PSZ)zFilename ); char *zFilenameCp = convertUtf8PathToCp( zFilename );
rc = DosDelete( (PSZ)zFilenameCp );
free( zFilenameCp );
OSTRACE2( "DELETE \"%s\"\n", zFilename ); OSTRACE2( "DELETE \"%s\"\n", zFilename );
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
} }
@@ -705,9 +769,11 @@ static int os2Access(
FILESTATUS3 fsts3ConfigInfo; FILESTATUS3 fsts3ConfigInfo;
APIRET rc = NO_ERROR; APIRET rc = NO_ERROR;
memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) );
rc = DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD, char *zFilenameCp = convertUtf8PathToCp( zFilename );
rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
&fsts3ConfigInfo, sizeof(FILESTATUS3) ); &fsts3ConfigInfo, sizeof(FILESTATUS3) );
free( zFilenameCp );
OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
fsts3ConfigInfo.attrFile, flags, rc ); fsts3ConfigInfo.attrFile, flags, rc );
switch( flags ){ switch( flags ){
@@ -739,6 +805,7 @@ static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
int i, j; int i, j;
char zTempPathBuf[3]; char zTempPathBuf[3];
PSZ zTempPath = (PSZ)&zTempPathBuf; PSZ zTempPath = (PSZ)&zTempPathBuf;
char *zTempPathUTF;
if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){
if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){
if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){
@@ -755,8 +822,10 @@ static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
j--; j--;
} }
zTempPath[j] = '\0'; zTempPath[j] = '\0';
zTempPathUTF = convertCpPathToUtf8( zTempPath );
sqlite3_snprintf( nBuf-30, zBuf, sqlite3_snprintf( nBuf-30, zBuf,
"%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath ); "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF );
free( zTempPathUTF );
j = strlen( zBuf ); j = strlen( zBuf );
sqlite3_randomness( 20, &zBuf[j] ); sqlite3_randomness( 20, &zBuf[j] );
for( i = 0; i < 20; i++, j++ ){ for( i = 0; i < 20; i++, j++ ){
@@ -779,7 +848,15 @@ static int os2FullPathname(
int nFull, /* Size of output buffer in bytes */ int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */ 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; return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
} }
@@ -796,7 +873,9 @@ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
UCHAR loadErr[256]; UCHAR loadErr[256];
HMODULE hmod; HMODULE hmod;
APIRET rc; 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; return rc != NO_ERROR ? 0 : (void*)hmod;
} }
/* /*

View File

@@ -12,7 +12,7 @@
** This file contains code to implement the "sqlite" command line ** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases. ** 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 <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -1944,7 +1944,11 @@ int main(int argc, char **argv){
} }
} }
if( i<argc ){ if( i<argc ){
#ifdef OS_OS2
data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
#else
data.zDbFilename = argv[i++]; data.zDbFilename = argv[i++];
#endif
}else{ }else{
#ifndef SQLITE_OMIT_MEMORYDB #ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:"; data.zDbFilename = ":memory:";