aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpweilbacher <pweilbacher@noemail.net>2008-04-15 18:50:02 +0000
committerpweilbacher <pweilbacher@noemail.net>2008-04-15 18:50:02 +0000
commitd190be853978155ca7c8442058a87d59bed16c41 (patch)
tree7c74933830c7ccc4d4294a8acbe3540c2da65949 /src
parent1d3a5ac9986fa7096a85fa9db58b4c2840e9b60f (diff)
downloadsqlite-d190be853978155ca7c8442058a87d59bed16c41.tar.gz
sqlite-d190be853978155ca7c8442058a87d59bed16c41.zip
Support UTF-8 filenames on OS/2 by converting them to and from the local codepage. Ticket 3052. (CVS 5014)
FossilOrigin-Name: cafa8ac2687890355a7faa751d71859eb0fadd01
Diffstat (limited to 'src')
-rw-r--r--src/os.h1
-rw-r--r--src/os_os2.c97
-rw-r--r--src/shell.c6
3 files changed, 94 insertions, 10 deletions
diff --git a/src/os.h b/src/os.h
index 77934b840..ac619af61 100644
--- a/src/os.h
+++ b/src/os.h
@@ -84,6 +84,7 @@
# define INCL_DOSMODULEMGR
# define INCL_DOSSEMAPHORES
# include <os2.h>
+# include <uconv.h>
# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
#else
# define SQLITE_TEMPNAME_SIZE 200
diff --git a/src/os_os2.c b/src/os_os2.c
index f183c9ae2..6191fbadd 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 );
@@ -554,6 +554,66 @@ static int os2DeviceCharacteristics(sqlite3_file *id){
}
/*
+** 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 467917960..319c34332 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 <stdlib.h>
#include <string.h>
@@ -1944,7 +1944,11 @@ int main(int argc, char **argv){
}
}
if( i<argc ){
+#ifdef OS_OS2
+ data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
+#else
data.zDbFilename = argv[i++];
+#endif
}else{
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";