]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Use the unicode API to win32 where available.
authordrh <drh@noemail.net>
Mon, 5 Sep 2005 19:08:29 +0000 (19:08 +0000)
committerdrh <drh@noemail.net>
Mon, 5 Sep 2005 19:08:29 +0000 (19:08 +0000)
Tickets #1407, #1396, #1331, #1243, #1206 (CVS 2656)

FossilOrigin-Name: 3ec58c673ae4cf0695ea0c287cc9bcbdcdb1a200

manifest
manifest.uuid
src/os_win.c
src/test1.c

index 5c1e0ad09431d2279ec37b09f0b45121ce7e5b4e..21bb9756607fdd97a49fc97e15af7fbd5930d79d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sover-aggressive\soptimization\sof\sORDER\sBY\sas\sreported\son\sthe\smailing\slist.\s(CVS\s2655)
-D 2005-09-01T17:47:51
+C Use\sthe\sunicode\sAPI\sto\swin32\swhere\savailable.\r\nTickets\s#1407,\s#1396,\s#1331,\s#1243,\s#1206\s(CVS\s2656)
+D 2005-09-05T19:08:29
 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -54,7 +54,7 @@ F src/os_test.c 91e5f22dd89491e5e1554820e715805f43fa4ece
 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
 F src/os_unix.c b4c4592589113db088662ef7570967ec36022b5d
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
-F src/os_win.c fe7b99cfcfb61d9bf54493ddf5857885a657fb89
+F src/os_win.c 8b80f418aefd2ceabe3580f680f5dcc244cf2344
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c cd9896287a8fd33cc267bd0c2b69c421a4808169
 F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164
@@ -69,7 +69,7 @@ F src/sqlite.h.in d6561d51025d08de4f455607f3f9f9aa76e855d5
 F src/sqliteInt.h 845ff6f8019f80baafb1bdbb8ef80fcd04d9d0f9
 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
 F src/tclsqlite.c ac94682f9e601dd373912c46414a5a842db2089a
-F src/test1.c ca4b959ce0a966ede87727cd8d3f5905743dfd4e
+F src/test1.c 006fafaa3456d20db37951b94c9d9becac64568e
 F src/test2.c 792f203be69fea88668fa221321194f0a28dfdfa
 F src/test3.c f4e6a16a602091696619a1171bda25c0e3df49f7
 F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f
@@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 81259a01f1e85ba50a1d017b1282bf841b16f0a5
-R 9230534585e06aeccca811dde76702e9
+P efbb4bc83cd86b6a26d58c5818c58c2e3edaab18
+R d11951b0db345c53b16225d15ddfa80a
 U drh
-Z 91850feb3a4a5d6eb41e5886f9a1b320
+Z ce91eee65efcee02daeb83c44469f09e
index 21e59d0f358aaeb7d8deaa9c39f6ecb817db07e9..6799ed3610a2eb5023ff9941c78b700395733034 100644 (file)
@@ -1 +1 @@
-efbb4bc83cd86b6a26d58c5818c58c2e3edaab18
\ No newline at end of file
+3ec58c673ae4cf0695ea0c287cc9bcbdcdb1a200
\ No newline at end of file
index ea2ca26089cd5930563a0b853826a69a04bdd6c5..4e98a25f2a21bc768713b575ee55bd66b14667ba 100644 (file)
 */
 #ifndef SQLITE_OMIT_DISKIO
 
+/*
+** The following variable is (normally) set once and never changes
+** thereafter.  It records whether the operating system is Win95
+** or WinNT.
+**
+** 0:   Operating system unknown.
+** 1:   Operating system is Win95.
+** 2:   Operating system is WinNT.
+**
+** In order to facilitate testing on a WinNT system, the test fixture
+** can manually set this value to 1 to emulate Win98 behavior.
+*/
+int sqlite3_os_type = 0;
+
+/*
+** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
+** Return false (zero) for Win95, Win98, or WinME.
+**
+** Here is an interesting observation:  Win95, Win98, and WinME lack
+** the LockFileEx() API.  But we can still statically link against that
+** API as long as we don't call it win running Win95/98/ME.  A call to
+** this routine is used to determine if the host is Win95/98/ME or
+** WinNT/2K/XP so that we will know whether or not we can safely call
+** the LockFileEx() API.
+*/
+static int isNT(void){
+  if( sqlite3_os_type==0 ){
+    OSVERSIONINFO sInfo;
+    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+    GetVersionEx(&sInfo);
+    sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
+  }
+  return sqlite3_os_type==2;
+}
+
+/*
+** Convert a UTF-8 string to UTF-32.  Space to hold the returned string
+** is obtained from sqliteMalloc.
+*/
+static WCHAR *utf8ToUnicode(const char *zFilename){
+  int nByte;
+  WCHAR *zWideFilename;
+
+  if( !isNT() ){
+    return 0;
+  }
+  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
+  zWideFilename = sqliteMalloc( nByte );
+  if( zWideFilename==0 ){
+    return 0;
+  }
+  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
+  if( nByte==0 ){
+    sqliteFree(zWideFilename);
+    zWideFilename = 0;
+  }
+  return zWideFilename;
+}
+
+/*
+** Convert UTF-32 to UTF-8.  Space to hold the returned string is
+** obtained from sqliteMalloc().
+*/
+static char *unicodeToUtf8(const WCHAR *zWideFilename){
+  int nByte;
+  char *zFilename;
+
+  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
+  zFilename = sqliteMalloc( nByte );
+  if( zFilename==0 ){
+    return 0;
+  }
+  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
+                              0, 0);
+  if( nByte == 0 ){
+    sqliteFree(zFilename);
+    zFilename = 0;
+  }
+  return zFilename;
+}
+
+
 /*
 ** Delete the named file
 */
 int sqlite3OsDelete(const char *zFilename){
-  DeleteFileA(zFilename);
+  WCHAR *zWide = utf8ToUnicode(zFilename);
+  if( zWide ){
+    DeleteFileW(zWide);
+    sqliteFree(zWide);
+  }else{
+    DeleteFileA(zFilename);
+  }
   TRACE2("DELETE \"%s\"\n", zFilename);
   return SQLITE_OK;
 }
@@ -54,7 +142,15 @@ int sqlite3OsDelete(const char *zFilename){
 ** Return TRUE if the named file exists.
 */
 int sqlite3OsFileExists(const char *zFilename){
-  return GetFileAttributesA(zFilename) != 0xffffffff;
+  int exists = 0;
+  WCHAR *zWide = utf8ToUnicode(zFilename);
+  if( zWide ){
+    exists = GetFileAttributesW(zWide) != 0xffffffff;
+    sqliteFree(zWide);
+  }else{
+    exists = GetFileAttributesA(zFilename) != 0xffffffff;
+  }
+  return exists;
 }
 
 /*
@@ -76,30 +172,60 @@ int sqlite3OsOpenReadWrite(
   int *pReadonly
 ){
   HANDLE h;
+  WCHAR *zWide = utf8ToUnicode(zFilename);
   assert( !id->isOpen );
-  h = CreateFileA(zFilename,
-     GENERIC_READ | GENERIC_WRITE,
-     FILE_SHARE_READ | FILE_SHARE_WRITE,
-     NULL,
-     OPEN_ALWAYS,
-     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-     NULL
-  );
-  if( h==INVALID_HANDLE_VALUE ){
-    h = CreateFileA(zFilename,
-       GENERIC_READ,
-       FILE_SHARE_READ,
+  if( zWide ){
+    h = CreateFileW(zWide,
+       GENERIC_READ | GENERIC_WRITE,
+       FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
        NULL
     );
     if( h==INVALID_HANDLE_VALUE ){
-      return SQLITE_CANTOPEN;
+      h = CreateFileW(zWide,
+         GENERIC_READ,
+         FILE_SHARE_READ,
+         NULL,
+         OPEN_ALWAYS,
+         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+         NULL
+      );
+      if( h==INVALID_HANDLE_VALUE ){
+        sqliteFree(zWide);
+        return SQLITE_CANTOPEN;
+      }
+      *pReadonly = 1;
+    }else{
+      *pReadonly = 0;
     }
-    *pReadonly = 1;
+    sqliteFree(zWide);
   }else{
-    *pReadonly = 0;
+    h = CreateFileA(zFilename,
+       GENERIC_READ | GENERIC_WRITE,
+       FILE_SHARE_READ | FILE_SHARE_WRITE,
+       NULL,
+       OPEN_ALWAYS,
+       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+       NULL
+    );
+    if( h==INVALID_HANDLE_VALUE ){
+      h = CreateFileA(zFilename,
+         GENERIC_READ,
+         FILE_SHARE_READ,
+         NULL,
+         OPEN_ALWAYS,
+         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+         NULL
+      );
+      if( h==INVALID_HANDLE_VALUE ){
+        return SQLITE_CANTOPEN;
+      }
+      *pReadonly = 1;
+    }else{
+      *pReadonly = 0;
+    }
   }
   id->h = h;
   id->locktype = NO_LOCK;
@@ -128,6 +254,7 @@ int sqlite3OsOpenReadWrite(
 int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
   HANDLE h;
   int fileflags;
+  WCHAR *zWide = utf8ToUnicode(zFilename);
   assert( !id->isOpen );
   if( delFlag ){
     fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
@@ -135,14 +262,26 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
   }else{
     fileflags = FILE_FLAG_RANDOM_ACCESS;
   }
-  h = CreateFileA(zFilename,
-     GENERIC_READ | GENERIC_WRITE,
-     0,
-     NULL,
-     CREATE_ALWAYS,
-     fileflags,
-     NULL
-  );
+  if( zWide ){
+    h = CreateFileW(zWide,
+       GENERIC_READ | GENERIC_WRITE,
+       0,
+       NULL,
+       CREATE_ALWAYS,
+       fileflags,
+       NULL
+    );
+    sqliteFree(zWide);
+  }else{
+    h = CreateFileA(zFilename,
+       GENERIC_READ | GENERIC_WRITE,
+       0,
+       NULL,
+       CREATE_ALWAYS,
+       fileflags,
+       NULL
+    );
+  }
   if( h==INVALID_HANDLE_VALUE ){
     return SQLITE_CANTOPEN;
   }
@@ -164,15 +303,28 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
 */
 int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
   HANDLE h;
+  WCHAR *zWide = utf8ToUnicode(zFilename);
   assert( !id->isOpen );
-  h = CreateFileA(zFilename,
-     GENERIC_READ,
-     0,
-     NULL,
-     OPEN_EXISTING,
-     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-     NULL
-  );
+  if( zWide ){
+    h = CreateFileW(zWide,
+       GENERIC_READ,
+       0,
+       NULL,
+       OPEN_EXISTING,
+       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+       NULL
+    );
+    sqliteFree(zWide);
+  }else{
+    h = CreateFileA(zFilename,
+       GENERIC_READ,
+       0,
+       NULL,
+       OPEN_EXISTING,
+       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+       NULL
+    );
+  }
   if( h==INVALID_HANDLE_VALUE ){
     return SQLITE_CANTOPEN;
   }
@@ -229,6 +381,16 @@ int sqlite3OsTempFileName(char *zBuf){
   if( sqlite3_temp_directory ){
     strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
     zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
+  }else if( isNT() ){
+    char *zMulti;
+    WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
+    GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
+    zMulti = unicodeToUtf8(zWidePath);
+    if( zMulti ){
+      memcpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
+      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
+      sqliteFree(zMulti);
+    }
   }else{
     GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
   }
@@ -364,28 +526,6 @@ int sqlite3OsFileSize(OsFile *id, i64 *pSize){
   return SQLITE_OK;
 }
 
-/*
-** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
-** Return false (zero) for Win95, Win98, or WinME.
-**
-** Here is an interesting observation:  Win95, Win98, and WinME lack
-** the LockFileEx() API.  But we can still statically link against that
-** API as long as we don't call it win running Win95/98/ME.  A call to
-** this routine is used to determine if the host is Win95/98/ME or
-** WinNT/2K/XP so that we will know whether or not we can safely call
-** the LockFileEx() API.
-*/
-static int isNT(void){
-  static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
-  if( osType==0 ){
-    OSVERSIONINFO sInfo;
-    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-    GetVersionEx(&sInfo);
-    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
-  }
-  return osType==2;
-}
-
 /*
 ** Acquire a reader lock.
 ** Different API routines are called depending on whether or not this
@@ -426,11 +566,18 @@ static int unlockReadLock(OsFile *id){
 ** Check that a given pathname is a directory and is writable 
 **
 */
-int sqlite3OsIsDirWritable(char *zBuf){
+int sqlite3OsIsDirWritable(char *zDirname){
   int fileAttr;
-  if(! zBuf ) return 0;
-  if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;
-  fileAttr = GetFileAttributesA(zBuf);
+  WCHAR *zWide;
+  if( zDirname==0 ) return 0;
+  if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
+  zWide = utf8ToUnicode(zDirname);
+  if( zWide ){
+    fileAttr = GetFileAttributesW(zWide);
+    sqliteFree(zWide);
+  }else{
+    fileAttr = GetFileAttributesA(zDirname);
+  }
   if( fileAttr == 0xffffffff ) return 0;
   if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
     return 0;
@@ -641,6 +788,7 @@ int sqlite3OsUnlock(OsFile *id, int locktype){
 char *sqlite3OsFullPathname(const char *zRelative){
   char *zNotUsed;
   char *zFull;
+  WCHAR *zWide;
   int nByte;
 #ifdef __CYGWIN__
   nByte = strlen(zRelative) + MAX_PATH + 1001;
@@ -648,10 +796,22 @@ char *sqlite3OsFullPathname(const char *zRelative){
   if( zFull==0 ) return 0;
   if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
 #else
-  nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
-  zFull = sqliteMalloc( nByte );
-  if( zFull==0 ) return 0;
-  GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
+  zWide = utf8ToUnicode(zRelative);
+  if( zWide ){
+    WCHAR *zTemp, *zNotUsedW;
+    nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
+    zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
+    if( zTemp==0 ) return 0;
+    GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
+    sqliteFree(zWide);
+    zFull = unicodeToUtf8(zTemp);
+    sqliteFree(zTemp);
+  }else{
+    nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
+    zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
+    if( zFull==0 ) return 0;
+    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
+  }
 #endif
   return zFull;
 }
index 3b555a39efdff4967c74372d2ffa1997fc14597b..37345a080cd072806bf2718581f82d6d2349992a 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.158 2005/09/01 12:16:29 drh Exp $
+** $Id: test1.c,v 1.159 2005/09/05 19:08:29 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -3157,6 +3157,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
   extern int sqlite3_memMax;
   extern char sqlite3_query_plan[];
   extern int sqlite3_like_count;
+#if OS_WIN
+  extern int sqlite3_os_type;
+#endif
 #ifdef SQLITE_DEBUG
   extern int sqlite3_vdbe_addop_trace;
 #endif
@@ -3185,6 +3188,10 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
       (char*)&sqlite3_os_trace, TCL_LINK_INT);
   Tcl_LinkVar(interp, "sqlite_where_trace",
       (char*)&sqlite3_where_trace, TCL_LINK_INT);
+#if OS_WIN
+  Tcl_LinkVar(interp, "sqlite_os_type",
+      (char*)&sqlite3_os_type, TCL_LINK_INT);
+#endif
 #ifdef SQLITE_DEBUG
   Tcl_LinkVar(interp, "sqlite_addop_trace",
       (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT);