Index: third_party/sqlite/misc.patch |
=================================================================== |
--- third_party/sqlite/misc.patch (revision 26826) |
+++ third_party/sqlite/misc.patch (working copy) |
@@ -792,3 +792,789 @@ |
fuzz.test |
fuzz3.test |
fuzz_malloc.test |
+Index: src/os_symbian.cc |
+=================================================================== |
+--- src/os_symbian.cc 1969-12-31 16:00:00.000000000 -0800 |
++++ src/os_symbian.cc 2009-07-01 12:08:37.000000000 -0700 |
+@@ -0,0 +1,579 @@ |
++// Copyright 2008, Google Inc. |
++// |
++// Redistribution and use in source and binary forms, with or without |
++// modification, are permitted provided that the following conditions are met: |
++// |
++// 1. Redistributions of source code must retain the above copyright notice, |
++// this list of conditions and the following disclaimer. |
++// 2. Redistributions in binary form must reproduce the above copyright notice, |
++// this list of conditions and the following disclaimer in the documentation |
++// and/or other materials provided with the distribution. |
++// 3. Neither the name of Google Inc. nor the names of its contributors may be |
++// used to endorse or promote products derived from this software without |
++// specific prior written permission. |
++// |
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
++// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
++// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
++// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
++// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
++// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
++// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
++// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
++// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
++ |
++// This file contains code that is specific to Symbian. |
++// Differently from the rest of SQLite, it is implemented in C++ as this is |
++// the native language of the OS and all interfaces we need to use are C++. |
++// |
++// This file follows the Gears code style guidelines. |
++ |
++#ifdef OS_SYMBIAN |
++#include <coemain.h> |
++#include <e32math.h> |
++#include <f32file.h> |
++#include <utf.h> |
++ |
++extern "C" { |
++#include "sqliteInt.h" |
++#include "os_common.h" |
++} |
++ |
++const TInt kFileLockAttempts = 3; |
++ |
++// The global file system session. |
++RFs g_fs_session; |
++ |
++static TInt UTF8ToUTF16(const char *in, TDes *out16) { |
++ assert(in); |
++ TPtrC8 in_des(reinterpret_cast<const unsigned char*>(in)); |
++ return CnvUtfConverter::ConvertToUnicodeFromUtf8(*out16, in_des); |
++} |
++ |
++static TInt UTF16ToUTF8(const TDesC16& in16, TDes8 *out8) { |
++ return CnvUtfConverter::ConvertFromUnicodeToUtf8(*out8, in16); |
++} |
++ |
++// The SymbianFile structure is a subclass of sqlite3_file* specific to the |
++// Symbian portability layer. |
++struct SymbianFile { |
++ const sqlite3_io_methods *methods; |
++ RFile handle; // The file handle |
++ TUint8 lock_type; // Type of lock currently held on this file |
++ TUint16 shared_lock_byte; // Randomly chosen byte used as a shared lock |
++}; |
++ |
++static SymbianFile* ConvertToSymbianFile(sqlite3_file* const id) { |
++ assert(id); |
++ return reinterpret_cast<SymbianFile*>(id); |
++} |
++ |
++static int SymbianClose(sqlite3_file *id) { |
++ SymbianFile *file_id = ConvertToSymbianFile(id); |
++ file_id->handle.Close(); |
++ OpenCounter(-1); |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianRead(sqlite3_file *id, |
++ void *buffer, |
++ int amount, |
++ sqlite3_int64 offset) { |
++ assert(buffer); |
++ assert(amount >=0); |
++ assert(offset >=0); |
++ |
++ SymbianFile* file_id = ConvertToSymbianFile(id); |
++ TPtr8 dest(static_cast<unsigned char*>(buffer), amount); |
++ |
++ if (KErrNone == file_id->handle.Read(offset, dest, amount)) { |
++ if (dest.Length() == amount) { |
++ return SQLITE_OK; |
++ } else { |
++ return SQLITE_IOERR_SHORT_READ; |
++ } |
++ } else { |
++ return SQLITE_IOERR; |
++ } |
++} |
++ |
++static int SymbianWrite(sqlite3_file *id, |
++ const void *buffer, |
++ int amount, |
++ sqlite3_int64 offset) { |
++ assert(buffer); |
++ assert(amount >=0); |
++ assert(offset >=0); |
++ |
++ SymbianFile *file_id = ConvertToSymbianFile(id); |
++ TPtrC8 src(static_cast<const unsigned char*>(buffer), amount); |
++ if (file_id->handle.Write(offset, src) != KErrNone) { |
++ return SQLITE_IOERR_WRITE; |
++ } |
++ |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianTruncate(sqlite3_file *id, sqlite3_int64 bytes) { |
++ assert(bytes >=0); |
++ |
++ SymbianFile *file_id = ConvertToSymbianFile(id); |
++ if (file_id->handle.SetSize(bytes) != KErrNone) { |
++ return SQLITE_IOERR; |
++ } |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianSync(sqlite3_file *id, int /*flags*/) { |
++ SymbianFile *file_id = ConvertToSymbianFile(id); |
++ if (file_id->handle.Flush() != KErrNone) { |
++ return SQLITE_IOERR; |
++ } else { |
++ return SQLITE_OK; |
++ } |
++} |
++ |
++static int SymbianFileSize(sqlite3_file *id, sqlite3_int64 *size) { |
++ assert(size); |
++ |
++ SymbianFile *file_id = ConvertToSymbianFile(id); |
++ TInt size_tmp; |
++ if (file_id->handle.Size(size_tmp) != KErrNone) { |
++ return SQLITE_IOERR; |
++ } |
++ *size = size_tmp; |
++ return SQLITE_OK; |
++} |
++ |
++// File lock/unlock functions; see os_win.c for a description |
++// of the algorithm used. |
++static int GetReadLock(SymbianFile *file) { |
++ file->shared_lock_byte = Math::Random() % (SHARED_SIZE - 1); |
++ return file->handle.Lock(SHARED_FIRST + file->shared_lock_byte, 1); |
++} |
++ |
++static int UnlockReadLock(SymbianFile *file) { |
++ return file->handle.UnLock(SHARED_FIRST + file->shared_lock_byte, 1); |
++} |
++ |
++static int SymbianLock(sqlite3_file *id, int lock_type) { |
++ SymbianFile *file = ConvertToSymbianFile(id); |
++ if (file->lock_type >= lock_type) { |
++ return SQLITE_OK; |
++ } |
++ |
++ // Make sure the locking sequence is correct |
++ assert(file->lock_type != NO_LOCK || lock_type == SHARED_LOCK); |
++ assert(lock_type != PENDING_LOCK); |
++ assert(lock_type != RESERVED_LOCK || file->lock_type == SHARED_LOCK); |
++ |
++ // Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or |
++ // a SHARED lock. If we are acquiring a SHARED lock, the acquisition of |
++ // the PENDING_LOCK byte is temporary. |
++ int new_lock_type = file->lock_type; |
++ int got_pending_lock = 0; |
++ int res = KErrNone; |
++ if (file->lock_type == NO_LOCK || |
++ (lock_type == EXCLUSIVE_LOCK && file->lock_type == RESERVED_LOCK)) { |
++ int count = kFileLockAttempts; |
++ while (count-- > 0 && |
++ (res = file->handle.Lock(PENDING_BYTE, 1)) != KErrNone ) { |
++ // Try 3 times to get the pending lock. The pending lock might be |
++ // held by another reader process who will release it momentarily. |
++ OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); |
++ User::After(1000); |
++ } |
++ got_pending_lock = (res == KErrNone? 1 : 0); |
++ } |
++ |
++ // Acquire a shared lock |
++ if (lock_type == SHARED_LOCK && res == KErrNone) { |
++ assert(file->lock_type == NO_LOCK); |
++ res = GetReadLock(file); |
++ if (res == KErrNone) { |
++ new_lock_type = SHARED_LOCK; |
++ } |
++ } |
++ |
++ // Acquire a RESERVED lock |
++ if (lock_type == RESERVED_LOCK && res == KErrNone) { |
++ assert(file->lock_type == SHARED_LOCK); |
++ res = file->handle.Lock(RESERVED_BYTE, 1); |
++ if (res == KErrNone) { |
++ new_lock_type = RESERVED_LOCK; |
++ } |
++ } |
++ |
++ // Acquire a PENDING lock |
++ if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { |
++ new_lock_type = PENDING_LOCK; |
++ got_pending_lock = 0; |
++ } |
++ |
++ // Acquire an EXCLUSIVE lock |
++ if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { |
++ assert(file->lock_type >= SHARED_LOCK); |
++ res = UnlockReadLock(file); |
++ OSTRACE2("unreadlock = %d\n", res); |
++ res = file->handle.Lock(SHARED_FIRST, SHARED_SIZE); |
++ if (res == KErrNone) { |
++ new_lock_type = EXCLUSIVE_LOCK; |
++ } else { |
++ OSTRACE2("error-code = %d\n", GetLastError()); |
++ GetReadLock(file); |
++ } |
++ } |
++ |
++ // If we are holding a PENDING lock that ought to be released, then |
++ // release it now. |
++ if (got_pending_lock && lock_type == SHARED_LOCK) { |
++ file->handle.UnLock(PENDING_BYTE, 1); |
++ } |
++ |
++ // Update the state of the lock held in the file descriptor, then |
++ // return the appropriate result code. |
++ file->lock_type = new_lock_type; |
++ if (res == KErrNone) { |
++ return SQLITE_OK; |
++ } else { |
++ OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", file->handle, |
++ lock_type, new_lock_type); |
++ return SQLITE_BUSY; |
++ } |
++} |
++ |
++static int SymbianUnlock(sqlite3_file *id, int lock_type) { |
++ int type; |
++ int rc = SQLITE_OK; |
++ SymbianFile *file = ConvertToSymbianFile(id); |
++ assert(lock_type <= SHARED_LOCK); |
++ OSTRACE5("UNLOCK %d to %d was %d(%d)\n", file->handle, lock_type, |
++ file->lock_type, file->shared_lock_byte); |
++ type = file->lock_type; |
++ if (type >= EXCLUSIVE_LOCK) { |
++ file->handle.UnLock(SHARED_FIRST, SHARED_SIZE); |
++ if (lock_type == SHARED_LOCK && GetReadLock(file) != KErrNone) { |
++ // This should never happen. We should always be able to |
++ // reacquire the read lock |
++ rc = SQLITE_IOERR_UNLOCK; |
++ } |
++ } |
++ if (type >= RESERVED_LOCK) { |
++ file->handle.UnLock(RESERVED_BYTE, 1); |
++ } |
++ if (lock_type == NO_LOCK && type >= SHARED_LOCK) { |
++ UnlockReadLock(file); |
++ } |
++ if (type >= PENDING_LOCK) { |
++ file->handle.UnLock(PENDING_BYTE, 1); |
++ } |
++ file->lock_type = lock_type; |
++ return rc; |
++} |
++ |
++static int SymbianCheckReservedLock(sqlite3_file *id, int *result) { |
++ int rc; |
++ SymbianFile *file = ConvertToSymbianFile(id); |
++ if (file->lock_type >= RESERVED_LOCK) { |
++ rc = 1; |
++ OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); |
++ } else { |
++ rc = file->handle.Lock(RESERVED_BYTE, 1); |
++ if (rc == KErrNone) { |
++ file->handle.UnLock(RESERVED_BYTE, 1); |
++ } |
++ rc = !rc; |
++ OSTRACE3("TEST WR-LOCK %d %d (remote)\n", file->handle, rc); |
++ } |
++ *result = rc; |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianFileControl(sqlite3_file */*id*/, |
++ int /*op*/, |
++ void */*arg*/) { |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianSectorSize(sqlite3_file */*id*/) { |
++ return SQLITE_DEFAULT_SECTOR_SIZE; |
++} |
++ |
++static int SymbianDeviceCharacteristics(sqlite3_file */*id*/) { |
++ return 0; |
++} |
++ |
++/* |
++** This vector defines all the methods that can operate on a |
++** sqlite3_file for Symbian. |
++*/ |
++static const sqlite3_io_methods SymbianIoMethod = { |
++ 1, // iVersion |
++ SymbianClose, |
++ SymbianRead, |
++ SymbianWrite, |
++ SymbianTruncate, |
++ SymbianSync, |
++ SymbianFileSize, |
++ SymbianLock, |
++ SymbianUnlock, |
++ SymbianCheckReservedLock, |
++ SymbianFileControl, |
++ SymbianSectorSize, |
++ SymbianDeviceCharacteristics |
++}; |
++ |
++// ============================================================================ |
++// vfs methods begin here |
++// ============================================================================ |
++static int SymbianOpen(sqlite3_vfs */*vfs*/, |
++ const char *name, |
++ sqlite3_file *id, |
++ int flags, |
++ int *out_flags) { |
++ TUint desired_access; |
++ TUint share_mode; |
++ TInt err = KErrNone; |
++ TFileName name_utf16; |
++ SymbianFile *file = ConvertToSymbianFile(id); |
++ |
++ if (out_flags) { |
++ *out_flags = flags; |
++ } |
++ |
++ // if the name is NULL we have to open a temporary file. |
++ if (!name) { |
++ TPath private_path; |
++ TFileName file_name; |
++ if (g_fs_session.PrivatePath(private_path) != KErrNone) { |
++ return SQLITE_CANTOPEN; |
++ } |
++ if (file->handle.Temp(g_fs_session, |
++ private_path, |
++ file_name, |
++ EFileWrite) != |
++ KErrNone) { |
++ return SQLITE_CANTOPEN; |
++ } |
++ file->methods = &SymbianIoMethod; |
++ file->lock_type = NO_LOCK; |
++ file->shared_lock_byte = 0; |
++ OpenCounter(+1); |
++ return SQLITE_OK; |
++ } |
++ |
++ if (UTF8ToUTF16(name, &name_utf16) != KErrNone) |
++ return SQLITE_CANTOPEN; |
++ |
++ if (flags & SQLITE_OPEN_READWRITE) { |
++ desired_access = EFileWrite; |
++ } else { |
++ desired_access = EFileRead; |
++ } |
++ if (flags & SQLITE_OPEN_MAIN_DB) { |
++ share_mode = EFileShareReadersOrWriters; |
++ } else { |
++ share_mode = 0; |
++ } |
++ |
++ if (flags & SQLITE_OPEN_CREATE) { |
++ err = file->handle.Create(g_fs_session, |
++ name_utf16, |
++ desired_access | share_mode); |
++ if (err != KErrNone && err != KErrAlreadyExists) { |
++ return SQLITE_CANTOPEN; |
++ } |
++ } |
++ |
++ if (err != KErrNone) { |
++ err = file->handle.Open(g_fs_session, |
++ name_utf16, |
++ desired_access | share_mode); |
++ if (err != KErrNone && flags & SQLITE_OPEN_READWRITE) { |
++ if (out_flags) { |
++ *out_flags = (flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE; |
++ } |
++ desired_access = EFileRead; |
++ err = file->handle.Open(g_fs_session, |
++ name_utf16, |
++ desired_access | share_mode); |
++ } |
++ if (err != KErrNone) { |
++ return SQLITE_CANTOPEN; |
++ } |
++ } |
++ file->methods = &SymbianIoMethod; |
++ file->lock_type = NO_LOCK; |
++ file->shared_lock_byte = 0; |
++ OpenCounter(+1); |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianDelete(sqlite3_vfs */*vfs*/, |
++ const char *file_name, |
++ int /*sync_dir*/) { |
++ assert(file_name); |
++ TFileName file_name_utf16; |
++ |
++ if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { |
++ return SQLITE_ERROR; |
++ } |
++ |
++ TInt result = g_fs_session.Delete(file_name_utf16); |
++ return (result == KErrNone || result == KErrPathNotFound)? |
++ SQLITE_OK : SQLITE_IOERR_DELETE; |
++} |
++ |
++static int SymbianAccess(sqlite3_vfs */*vfs*/, |
++ const char *file_name, |
++ int flags, |
++ int *result) { |
++ assert(file_name); |
++ TEntry entry; |
++ TFileName file_name_utf16; |
++ |
++ if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { |
++ return SQLITE_ERROR; |
++ } |
++ |
++ if (g_fs_session.Entry(file_name_utf16, entry) != KErrNone) { |
++ *result = 0; |
++ return SQLITE_OK; |
++ } |
++ |
++ switch (flags) { |
++ case SQLITE_ACCESS_READ: |
++ case SQLITE_ACCESS_EXISTS: |
++ *result = !entry.IsDir(); |
++ break; |
++ case SQLITE_ACCESS_READWRITE: |
++ *result = !entry.IsDir() && !entry.IsReadOnly(); |
++ break; |
++ default: |
++ return SQLITE_ERROR; |
++ } |
++ |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianFullPathname(sqlite3_vfs */*vfs*/, |
++ const char *relative, |
++ int full_len, |
++ char *full) { |
++ assert(relative); |
++ assert(full); |
++ |
++ TParse parse; |
++ TPath relative_utf16; |
++ TPath base_path; |
++ TPtr8 full_utf8(reinterpret_cast<unsigned char*>(full), full_len); |
++ |
++ g_fs_session.PrivatePath(base_path); |
++ |
++ if (UTF8ToUTF16(relative, &relative_utf16) != KErrNone) { |
++ return SQLITE_ERROR; |
++ } |
++ |
++ if (parse.Set(relative_utf16, &base_path, NULL) != KErrNone) { |
++ return SQLITE_ERROR; |
++ } |
++ |
++ TDesC full_utf16(parse.FullName()); |
++ if (UTF16ToUTF8(relative_utf16, &full_utf8) != KErrNone) { |
++ return SQLITE_ERROR; |
++ } |
++ |
++ full_utf8.PtrZ(); |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianRandomness(sqlite3_vfs */*vfs*/, int buf_len, char *buffer) { |
++ assert(buffer); |
++ TInt64 seed = User::TickCount(); |
++ for (TInt i = 0; i < buf_len; i++) { |
++ buffer[i] = Math::Rand(seed) % 255; |
++ } |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianSleep(sqlite3_vfs */*vfs*/, int microsec) { |
++ User::After(microsec); |
++ return SQLITE_OK; |
++} |
++ |
++int SymbianCurrentTime(sqlite3_vfs */*vfs*/, double *now) { |
++ _LIT(kEpoch, "19700101:000000.000000"); |
++ assert(now); |
++ TTime time; |
++ TTime epoch_time(kEpoch); |
++ TTimeIntervalSeconds interval; |
++ |
++ time.HomeTime(); |
++ // calculate seconds elapsed since 1-1-1970 |
++ time.SecondsFrom(epoch_time, interval); |
++ |
++ // Julian date @ 1-1-1970 = 2440587.5 |
++ // seconds per day = 86400.0 |
++ *now = interval.Int()/86400.0 + 2440587.5; |
++ return SQLITE_OK; |
++} |
++ |
++static int SymbianGetLastError(sqlite3_vfs */*vfs*/, |
++ int /*buf_len*/, |
++ char */*buf*/) { |
++ assert(buf[0] == '\0'); |
++ return 0; |
++} |
++ |
++// Interfaces for opening a shared library, finding entry points |
++// within the shared library, and closing the shared library. |
++// TODO(marcogelmi): implement. |
++#define SymbianDlOpen 0 |
++#define SymbianDlError 0 |
++#define SymbianDlSym 0 |
++#define SymbianDlClose 0 |
++ |
++// Initialize and deinitialize the operating system interface. |
++int sqlite3_os_init(void) { |
++ static sqlite3_vfs symbian_vfs = { |
++ 1, // iVersion |
++ sizeof(SymbianFile), // szOsFile |
++ KMaxPath, // mxPathname |
++ 0, // pNext |
++ "symbian", // name |
++ 0, // pAppData |
++ |
++ SymbianOpen, // xOpen |
++ SymbianDelete, // xDelete |
++ SymbianAccess, // xAccess |
++ SymbianFullPathname, // xFullPathname |
++ SymbianDlOpen, // xDlOpen |
++ SymbianDlError, // xDlError |
++ SymbianDlSym, // xDlSym |
++ SymbianDlClose, // xDlClose |
++ SymbianRandomness, // xRandomness |
++ SymbianSleep, // xSleep |
++ SymbianCurrentTime, // xCurrentTime |
++ SymbianGetLastError // xGetLastError |
++ }; |
++ |
++ if (g_fs_session.Connect() != KErrNone) { |
++ return SQLITE_ERROR; |
++ } |
++ |
++ if (g_fs_session.ShareAuto() != KErrNone) { |
++ g_fs_session.Close(); |
++ return SQLITE_ERROR; |
++ } |
++ |
++ sqlite3_vfs_register(&symbian_vfs, 1); |
++ return SQLITE_OK; |
++} |
++ |
++int sqlite3_os_end(void) { |
++ g_fs_session.Close(); |
++ return SQLITE_OK; |
++} |
++ |
++#endif /* OS_SYMBIAN*/ |
+Index: src/shell_icu_linux.c |
+=================================================================== |
+--- src/shell_icu_linux.c 1969-12-31 16:00:00.000000000 -0800 |
++++ src/shell_icu_linux.c 2009-09-17 13:48:49.000000000 -0700 |
+@@ -0,0 +1,26 @@ |
++/* Copyright 2007 Google Inc. All Rights Reserved. |
++**/ |
++ |
++#include <limits.h> |
++#include <unistd.h> |
++#include "unicode/udata.h" |
++ |
++/* |
++** This function attempts to load the ICU data tables from a data file. |
++** Returns 0 on failure, nonzero on success. |
++** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. |
++*/ |
++int sqlite_shell_init_icu() { |
++ char bin_dir[PATH_MAX + 1]; |
++ int bin_dir_size = readlink("/proc/self/exe", bin_dir, PATH_MAX); |
++ if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) |
++ return 0; |
++ bin_dir[bin_dir_size] = 0;; |
++ |
++ u_setDataDirectory(bin_dir); |
++ // Only look for the packaged data file; |
++ // the default behavior is to look for individual files. |
++ UErrorCode err = U_ZERO_ERROR; |
++ udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); |
++ return err == U_ZERO_ERROR; |
++} |
+Index: src/shell_icu_win.c |
+=================================================================== |
+--- src/shell_icu_win.c 1969-12-31 16:00:00.000000000 -0800 |
++++ src/shell_icu_win.c 2009-09-09 12:29:11.000000000 -0700 |
+@@ -0,0 +1,34 @@ |
++/* Copyright 2007 Google Inc. All Rights Reserved. |
++**/ |
++ |
++#include <windows.h> |
++#include "unicode/udata.h" |
++ |
++/* |
++** This function attempts to load the ICU data tables from a DLL. |
++** Returns 0 on failure, nonzero on success. |
++** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. |
++*/ |
++ |
++#define ICU_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" |
++int sqlite_shell_init_icu() { |
++ HMODULE module; |
++ FARPROC addr; |
++ UErrorCode err; |
++ |
++ wchar_t dll_name[12]; |
++ wsprintf(dll_name, L"icudt%2S.dll", U_ICU_VERSION_SHORT); |
++ dll_name[11] = L'\0'; |
++ module = LoadLibrary(dll_name); |
++ if (!module) |
++ return 0; |
++ |
++ addr = GetProcAddress(module, ICU_DATA_SYMBOL); |
++ if (!addr) |
++ return 0; |
++ |
++ err = U_ZERO_ERROR; |
++ udata_setCommonData(addr, &err); |
++ |
++ return 1; |
++} |
+Index: test/fts.test |
+=================================================================== |
+--- test/fts.test 1969-12-31 16:00:00.000000000 -0800 |
++++ test/fts.test 2009-07-01 12:08:39.000000000 -0700 |
+@@ -0,0 +1,61 @@ |
++# |
++# May you do good and not evil. |
++# May you find forgiveness for yourself and forgive others. |
++# May you share freely, never taking more than you give. |
++# |
++#*********************************************************************** |
++# This file runs the fts tests. |
++# |
++# $Id$ |
++ |
++proc lshift {lvar} { |
++ upvar $lvar l |
++ set ret [lindex $l 0] |
++ set l [lrange $l 1 end] |
++ return $ret |
++} |
++while {[set arg [lshift argv]] != ""} { |
++ switch -- $arg { |
++ -sharedpagercache { |
++ sqlite3_enable_shared_cache 1 |
++ } |
++ default { |
++ set argv [linsert $argv 0 $arg] |
++ break |
++ } |
++ } |
++} |
++ |
++set testdir [file dirname $argv0] |
++source $testdir/tester.tcl |
++rename finish_test really_finish_test |
++proc finish_test {} {} |
++set ISQUICK 1 |
++ |
++set EXCLUDE { |
++ fts.test |
++ fts1.test |
++ fts2.test |
++} |
++ |
++if {[sqlite3 -has-codec]} { |
++ # lappend EXCLUDE \ |
++ # conflict.test |
++} |
++ |
++foreach testfile [lsort -dictionary [glob $testdir/fts*.test]] { |
++ set tail [file tail $testfile] |
++ puts "test: $tail" |
++ if {[lsearch -exact $EXCLUDE $tail]>=0} continue |
++ source $testfile |
++ catch {db close} |
++ if {$sqlite_open_file_count>0} { |
++ puts "$tail did not close all files: $sqlite_open_file_count" |
++ incr nErr |
++ lappend ::failList $tail |
++ } |
++} |
++source $testdir/misuse.test |
++ |
++set sqlite_open_file_count 0 |
++really_finish_test |
+Index: test/fts1.test |
+=================================================================== |
+--- test/fts1.test 1969-12-31 16:00:00.000000000 -0800 |
++++ test/fts1.test 2009-07-01 12:08:39.000000000 -0700 |
+@@ -0,0 +1,61 @@ |
++# |
++# May you do good and not evil. |
++# May you find forgiveness for yourself and forgive others. |
++# May you share freely, never taking more than you give. |
++# |
++#*********************************************************************** |
++# This file runs the fts tests. |
++# |
++# $Id$ |
++ |
++proc lshift {lvar} { |
++ upvar $lvar l |
++ set ret [lindex $l 0] |
++ set l [lrange $l 1 end] |
++ return $ret |
++} |
++while {[set arg [lshift argv]] != ""} { |
++ switch -- $arg { |
++ -sharedpagercache { |
++ sqlite3_enable_shared_cache 1 |
++ } |
++ default { |
++ set argv [linsert $argv 0 $arg] |
++ break |
++ } |
++ } |
++} |
++ |
++set testdir [file dirname $argv0] |
++source $testdir/tester.tcl |
++rename finish_test really_finish_test |
++proc finish_test {} {} |
++set ISQUICK 1 |
++ |
++set EXCLUDE { |
++ fts.test |
++ fts1.test |
++ fts2.test |
++} |
++ |
++if {[sqlite3 -has-codec]} { |
++ # lappend EXCLUDE \ |
++ # conflict.test |
++} |
++ |
++foreach testfile [lsort -dictionary [glob $testdir/fts1*.test]] { |
++ set tail [file tail $testfile] |
++ puts "test: $tail" |
++ if {[lsearch -exact $EXCLUDE $tail]>=0} continue |
++ source $testfile |
++ catch {db close} |
++ if {$sqlite_open_file_count>0} { |
++ puts "$tail did not close all files: $sqlite_open_file_count" |
++ incr nErr |
++ lappend ::failList $tail |
++ } |
++} |
++source $testdir/misuse.test |
++ |
++set sqlite_open_file_count 0 |
++really_finish_test |