/ Check-in [c92b0fe1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Cherry-pick [555fc07]: Changes to the thread routines to disable them when threading is turned off using sqlite3_config(). Also merge all recent trunk changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: c92b0fe1371e7c20a5fbdf5fa96e30da14c40880
User & Date: drh 2012-08-21 17:36:44
Context
2014-03-13
15:41
Merge latest trunk changes into this branch. check-in: d17231b6 user: dan tags: threads
2012-08-21
17:36
Cherry-pick [555fc07]: Changes to the thread routines to disable them when threading is turned off using sqlite3_config(). Also merge all recent trunk changes. check-in: c92b0fe1 user: drh tags: threads
13:08
Update the spellfix virtual table so that all OOM errors are reported out to the application. ERROR: A single edit was missed in spellfix1 which means that this particular check-in won't build "make test". Closed-Leaf check-in: c2cf4985 user: drh tags: mistake
2012-08-16
11:24
Update the threads branch to include all the latest trunk changes. check-in: f4125771 user: drh tags: threads
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.msc.

    72     72   # for the platform the compilation process is taking place on.  If it is not
    73     73   # defined, simply define it to have the same value as the CC macro.  When
    74     74   # cross-compiling, it is suggested that this macro be modified via the command
    75     75   # line (since nmake itself does not provide a built-in method to guess it).
    76     76   # For example, to use the x86 compiler when cross-compiling for x64, a command
    77     77   # line similar to the following could be used (all on one line):
    78     78   #
    79         -#     nmake /f Makefile.msc
           79  +#     nmake /f Makefile.msc sqlite3.dll
    80     80   #           "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
    81     81   #           USE_NATIVE_LIBPATHS=1
    82     82   #
    83     83   !IFDEF NCC
    84     84   NCC = $(NCC:\\=\)
    85     85   !ELSE
    86     86   NCC = $(CC)

Changes to ext/fts3/fts3.c.

  4432   4432     int nToken = 0;
  4433   4433     int nOr = 0;
  4434   4434   
  4435   4435     /* Allocate a MultiSegReader for each token in the expression. */
  4436   4436     fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc);
  4437   4437   
  4438   4438     /* Determine which, if any, tokens in the expression should be deferred. */
         4439  +#ifndef SQLITE_DISABLE_FTS4_DEFERRED
  4439   4440     if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
  4440   4441       Fts3TokenAndCost *aTC;
  4441   4442       Fts3Expr **apOr;
  4442   4443       aTC = (Fts3TokenAndCost *)sqlite3_malloc(
  4443   4444           sizeof(Fts3TokenAndCost) * nToken
  4444   4445         + sizeof(Fts3Expr *) * nOr * 2
  4445   4446       );
................................................................................
  4462   4463             rc = fts3EvalSelectDeferred(pCsr, apOr[ii], aTC, nToken);
  4463   4464           }
  4464   4465         }
  4465   4466   
  4466   4467         sqlite3_free(aTC);
  4467   4468       }
  4468   4469     }
         4470  +#endif
  4469   4471   
  4470   4472     fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
  4471   4473     return rc;
  4472   4474   }
  4473   4475   
  4474   4476   /*
  4475   4477   ** Invalidate the current position list for phrase pPhrase.
................................................................................
  4845   4847           bHit = (
  4846   4848               fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc)
  4847   4849            && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc)
  4848   4850           );
  4849   4851           break;
  4850   4852   
  4851   4853         default: {
         4854  +#ifndef SQLITE_DISABLE_FTS4_DEFERRED
  4852   4855           if( pCsr->pDeferred 
  4853   4856            && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
  4854   4857           ){
  4855   4858             Fts3Phrase *pPhrase = pExpr->pPhrase;
  4856   4859             assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 );
  4857   4860             if( pExpr->bDeferred ){
  4858   4861               fts3EvalInvalidatePoslist(pPhrase);
  4859   4862             }
  4860   4863             *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
  4861   4864             bHit = (pPhrase->doclist.pList!=0);
  4862   4865             pExpr->iDocid = pCsr->iPrevId;
  4863         -        }else{
         4866  +        }else
         4867  +#endif
         4868  +        {
  4864   4869             bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId);
  4865   4870           }
  4866   4871           break;
  4867   4872         }
  4868   4873       }
  4869   4874     }
  4870   4875     return bHit;

Changes to ext/fts3/fts3Int.h.

   423    423   int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **);
   424    424   int sqlite3Fts3ReadLock(Fts3Table *);
   425    425   int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*);
   426    426   
   427    427   int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
   428    428   int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);
   429    429   
          430  +#ifndef SQLITE_DISABLE_FTS4_DEFERRED
   430    431   void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
   431    432   int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
   432    433   int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
   433    434   void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *);
          435  +int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
          436  +#else
          437  +# define sqlite3Fts3FreeDeferredTokens(x)
          438  +# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK
          439  +# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK
          440  +# define sqlite3Fts3FreeDeferredDoclists(x)
          441  +# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK
          442  +#endif
          443  +
   434    444   void sqlite3Fts3SegmentsClose(Fts3Table *);
   435    445   int sqlite3Fts3MaxLevel(Fts3Table *, int *);
   436    446   
   437    447   /* Special values interpreted by sqlite3SegReaderCursor() */
   438    448   #define FTS3_SEGCURSOR_PENDING        -1
   439    449   #define FTS3_SEGCURSOR_ALL            -2
   440    450   
................................................................................
   535    545       Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
   536    546   int sqlite3Fts3MsrIncrNext(
   537    547       Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
   538    548   int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); 
   539    549   int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
   540    550   int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
   541    551   
   542         -int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
   543         -
   544    552   /* fts3_unicode2.c (functions generated by parsing unicode text files) */
   545    553   #ifdef SQLITE_ENABLE_FTS4_UNICODE61
   546    554   int sqlite3FtsUnicodeFold(int, int);
   547    555   int sqlite3FtsUnicodeIsalnum(int);
   548    556   int sqlite3FtsUnicodeIsdiacritic(int);
   549    557   #endif
   550    558   
   551    559   #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
   552    560   #endif /* _FTSINT_H */

Changes to ext/fts3/fts3_write.c.

  5042   5042     }else{
  5043   5043       rc = SQLITE_ERROR;
  5044   5044     }
  5045   5045   
  5046   5046     return rc;
  5047   5047   }
  5048   5048   
         5049  +#ifndef SQLITE_DISABLE_FTS4_DEFERRED
  5049   5050   /*
  5050   5051   ** Delete all cached deferred doclists. Deferred doclists are cached
  5051   5052   ** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
  5052   5053   */
  5053   5054   void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){
  5054   5055     Fts3DeferredToken *pDef;
  5055   5056     for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){
................................................................................
  5179   5180     pCsr->pDeferred = pDeferred;
  5180   5181   
  5181   5182     assert( pToken->pDeferred==0 );
  5182   5183     pToken->pDeferred = pDeferred;
  5183   5184   
  5184   5185     return SQLITE_OK;
  5185   5186   }
         5187  +#endif
  5186   5188   
  5187   5189   /*
  5188   5190   ** SQLite value pRowid contains the rowid of a row that may or may not be
  5189   5191   ** present in the FTS3 table. If it is, delete it and adjust the contents
  5190   5192   ** of subsiduary data structures accordingly.
  5191   5193   */
  5192   5194   static int fts3DeleteByRowid(

Changes to src/btree.c.

  1457   1457           /* Start of free block is off the page */
  1458   1458           return SQLITE_CORRUPT_BKPT; 
  1459   1459         }
  1460   1460         next = get2byte(&data[pc]);
  1461   1461         size = get2byte(&data[pc+2]);
  1462   1462         if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
  1463   1463           /* Free blocks must be in ascending order. And the last byte of
  1464         -	** the free-block must lie on the database page.  */
         1464  +        ** the free-block must lie on the database page.  */
  1465   1465           return SQLITE_CORRUPT_BKPT; 
  1466   1466         }
  1467   1467         nFree = nFree + size;
  1468   1468         pc = next;
  1469   1469       }
  1470   1470   
  1471   1471       /* At this point, nFree contains the sum of the offset to the start
................................................................................
  2631   2631             btreeInvokeBusyHandler(pBt) );
  2632   2632   
  2633   2633     if( rc==SQLITE_OK ){
  2634   2634       if( p->inTrans==TRANS_NONE ){
  2635   2635         pBt->nTransaction++;
  2636   2636   #ifndef SQLITE_OMIT_SHARED_CACHE
  2637   2637         if( p->sharable ){
  2638         -	assert( p->lock.pBtree==p && p->lock.iTable==1 );
         2638  +        assert( p->lock.pBtree==p && p->lock.iTable==1 );
  2639   2639           p->lock.eLock = READ_LOCK;
  2640   2640           p->lock.pNext = pBt->pLock;
  2641   2641           pBt->pLock = &p->lock;
  2642   2642         }
  2643   2643   #endif
  2644   2644       }
  2645   2645       p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);

Changes to src/build.c.

   530    530     /* Delete all indices associated with this table. */
   531    531     for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
   532    532       pNext = pIndex->pNext;
   533    533       assert( pIndex->pSchema==pTable->pSchema );
   534    534       if( !db || db->pnBytesFreed==0 ){
   535    535         char *zName = pIndex->zName; 
   536    536         TESTONLY ( Index *pOld = ) sqlite3HashInsert(
   537         -	  &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
          537  +         &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
   538    538         );
   539    539         assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
   540    540         assert( pOld==pIndex || pOld==0 );
   541    541       }
   542    542       freeIndex(db, pIndex);
   543    543     }
   544    544   

Changes to src/mem1.c.

   227    227     sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
   228    228     if( cpuCount>1 ){
   229    229       /* defer MT decisions to system malloc */
   230    230       _sqliteZone_ = malloc_default_zone();
   231    231     }else{
   232    232       /* only 1 core, use our own zone to contention over global locks, 
   233    233       ** e.g. we have our own dedicated locks */
   234         -    bool success;		
          234  +    bool success;
   235    235       malloc_zone_t* newzone = malloc_create_zone(4096, 0);
   236    236       malloc_set_zone_name(newzone, "Sqlite_Heap");
   237    237       do{
   238    238         success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
   239    239                                    (void * volatile *)&_sqliteZone_);
   240    240       }while(!_sqliteZone_);
   241         -    if( !success ){	
          241  +    if( !success ){
   242    242         /* somebody registered a zone first */
   243    243         malloc_destroy_zone(newzone);
   244    244       }
   245    245     }
   246    246   #endif
   247    247     UNUSED_PARAMETER(NotUsed);
   248    248     return SQLITE_OK;

Changes to src/os_unix.c.

   711    711       /* random NFS retry error, unless during file system support 
   712    712        * introspection, in which it actually means what it says */
   713    713       return SQLITE_BUSY;
   714    714       
   715    715     case EACCES: 
   716    716       /* EACCES is like EAGAIN during locking operations, but not any other time*/
   717    717       if( (sqliteIOErr == SQLITE_IOERR_LOCK) || 
   718         -	(sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
   719         -	(sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
   720         -	(sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
          718  +        (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
          719  +        (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
          720  +        (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
   721    721         return SQLITE_BUSY;
   722    722       }
   723    723       /* else fall through */
   724    724     case EPERM: 
   725    725       return SQLITE_PERM;
   726    726       
   727    727     /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And
................................................................................
  1760   1760         lock.l_type = F_UNLCK;
  1761   1761         lock.l_whence = SEEK_SET;
  1762   1762         lock.l_start = lock.l_len = 0L;
  1763   1763         if( unixFileLock(pFile, &lock)==0 ){
  1764   1764           pInode->eFileLock = NO_LOCK;
  1765   1765         }else{
  1766   1766           rc = SQLITE_IOERR_UNLOCK;
  1767         -	pFile->lastErrno = errno;
         1767  +        pFile->lastErrno = errno;
  1768   1768           pInode->eFileLock = NO_LOCK;
  1769   1769           pFile->eFileLock = NO_LOCK;
  1770   1770         }
  1771   1771       }
  1772   1772   
  1773   1773       /* Decrement the count of locks against this same file.  When the
  1774   1774       ** count reaches zero, close any other file descriptors whose close
................................................................................
  1776   1776       */
  1777   1777       pInode->nLock--;
  1778   1778       assert( pInode->nLock>=0 );
  1779   1779       if( pInode->nLock==0 ){
  1780   1780         closePendingFds(pFile);
  1781   1781       }
  1782   1782     }
  1783         -	
         1783  +
  1784   1784   end_unlock:
  1785   1785     unixLeaveMutex();
  1786   1786     if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
  1787   1787     return rc;
  1788   1788   }
  1789   1789   
  1790   1790   /*
................................................................................
  2043   2043   static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
  2044   2044     unixFile *pFile = (unixFile*)id;
  2045   2045     char *zLockFile = (char *)pFile->lockingContext;
  2046   2046     int rc;
  2047   2047   
  2048   2048     assert( pFile );
  2049   2049     OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
  2050         -	   pFile->eFileLock, getpid()));
         2050  +           pFile->eFileLock, getpid()));
  2051   2051     assert( eFileLock<=SHARED_LOCK );
  2052   2052     
  2053   2053     /* no-op if possible */
  2054   2054     if( pFile->eFileLock==eFileLock ){
  2055   2055       return SQLITE_OK;
  2056   2056     }
  2057   2057   
................................................................................
  2430   2430   static int semUnlock(sqlite3_file *id, int eFileLock) {
  2431   2431     unixFile *pFile = (unixFile*)id;
  2432   2432     sem_t *pSem = pFile->pInode->pSem;
  2433   2433   
  2434   2434     assert( pFile );
  2435   2435     assert( pSem );
  2436   2436     OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
  2437         -	   pFile->eFileLock, getpid()));
         2437  +           pFile->eFileLock, getpid()));
  2438   2438     assert( eFileLock<=SHARED_LOCK );
  2439   2439     
  2440   2440     /* no-op if possible */
  2441   2441     if( pFile->eFileLock==eFileLock ){
  2442   2442       return SQLITE_OK;
  2443   2443     }
  2444   2444     
................................................................................
  3020   3020   #else
  3021   3021       newOffset = lseek(id->h, offset, SEEK_SET);
  3022   3022       SimulateIOError( newOffset-- );
  3023   3023       if( newOffset!=offset ){
  3024   3024         if( newOffset == -1 ){
  3025   3025           ((unixFile*)id)->lastErrno = errno;
  3026   3026         }else{
  3027         -        ((unixFile*)id)->lastErrno = 0;			
         3027  +        ((unixFile*)id)->lastErrno = 0;
  3028   3028         }
  3029   3029         return -1;
  3030   3030       }
  3031   3031       got = osRead(id->h, pBuf, cnt);
  3032   3032   #endif
  3033   3033       if( got==cnt ) break;
  3034   3034       if( got<0 ){
................................................................................
  3108   3108     do{
  3109   3109       newOffset = lseek(id->h, offset, SEEK_SET);
  3110   3110       SimulateIOError( newOffset-- );
  3111   3111       if( newOffset!=offset ){
  3112   3112         if( newOffset == -1 ){
  3113   3113           ((unixFile*)id)->lastErrno = errno;
  3114   3114         }else{
  3115         -        ((unixFile*)id)->lastErrno = 0;			
         3115  +        ((unixFile*)id)->lastErrno = 0;
  3116   3116         }
  3117   3117         return -1;
  3118   3118       }
  3119   3119       got = osWrite(id->h, pBuf, cnt);
  3120   3120     }while( got<0 && errno==EINTR );
  3121   3121   #endif
  3122   3122     TIMER_END;
................................................................................
  5622   5622   ** as POSIX read & write locks over fixed set of locations (via fsctl),
  5623   5623   ** on AFP and SMB only exclusive byte-range locks are available via fsctl
  5624   5624   ** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
  5625   5625   ** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
  5626   5626   ** address in the shared range is taken for a SHARED lock, the entire
  5627   5627   ** shared range is taken for an EXCLUSIVE lock):
  5628   5628   **
  5629         -**      PENDING_BYTE        0x40000000		   	
         5629  +**      PENDING_BYTE        0x40000000
  5630   5630   **      RESERVED_BYTE       0x40000001
  5631   5631   **      SHARED_RANGE        0x40000002 -> 0x40000200
  5632   5632   **
  5633   5633   ** This works well on the local file system, but shows a nearly 100x
  5634   5634   ** slowdown in read performance on AFP because the AFP client disables
  5635   5635   ** the read cache when byte-range locks are present.  Enabling the read
  5636   5636   ** cache exposes a cache coherency problem that is present on all OS X

Changes to src/os_win.c.

    42     42   # define FILE_FLAG_MASK          (0xFF3C0000)
    43     43   #endif
    44     44   
    45     45   #ifndef FILE_ATTRIBUTE_MASK
    46     46   # define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
    47     47   #endif
    48     48   
           49  +#ifndef SQLITE_OMIT_WAL
    49     50   /* Forward references */
    50     51   typedef struct winShm winShm;           /* A connection to shared-memory */
    51     52   typedef struct winShmNode winShmNode;   /* A region of shared-memory */
           53  +#endif
    52     54   
    53     55   /*
    54     56   ** WinCE lacks native support for file locking so we have to fake it
    55     57   ** with some code of our own.
    56     58   */
    57     59   #if SQLITE_OS_WINCE
    58     60   typedef struct winceLock {
................................................................................
    72     74     const sqlite3_io_methods *pMethod; /*** Must be first ***/
    73     75     sqlite3_vfs *pVfs;      /* The VFS used to open this file */
    74     76     HANDLE h;               /* Handle for accessing the file */
    75     77     u8 locktype;            /* Type of lock currently held on this file */
    76     78     short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
    77     79     u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
    78     80     DWORD lastErrno;        /* The Windows errno from the last I/O error */
           81  +#ifndef SQLITE_OMIT_WAL
    79     82     winShm *pShm;           /* Instance of shared memory on this file */
           83  +#endif
    80     84     const char *zPath;      /* Full pathname of this file */
    81     85     int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
    82     86   #if SQLITE_OS_WINCE
    83     87     LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
    84     88     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
    85     89     HANDLE hShared;         /* Shared memory segment used for locking */
    86     90     winceLock local;        /* Locks obtained by this instance of winFile */
................................................................................
  1933   1937   */
  1934   1938   #define MX_CLOSE_ATTEMPT 3
  1935   1939   static int winClose(sqlite3_file *id){
  1936   1940     int rc, cnt = 0;
  1937   1941     winFile *pFile = (winFile*)id;
  1938   1942   
  1939   1943     assert( id!=0 );
         1944  +#ifndef SQLITE_OMIT_WAL
  1940   1945     assert( pFile->pShm==0 );
         1946  +#endif
  1941   1947     OSTRACE(("CLOSE %d\n", pFile->h));
  1942   1948     do{
  1943   1949       rc = osCloseHandle(pFile->h);
  1944   1950       /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
  1945   1951     }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
  1946   1952   #if SQLITE_OS_WINCE
  1947   1953   #define WINCE_DELETION_ATTEMPTS 3
................................................................................
  3683   3689     }
  3684   3690   
  3685   3691     memset(pFile, 0, sizeof(*pFile));
  3686   3692     pFile->pMethod = &winIoMethod;
  3687   3693     pFile->h = h;
  3688   3694     pFile->lastErrno = NO_ERROR;
  3689   3695     pFile->pVfs = pVfs;
         3696  +#ifndef SQLITE_OMIT_WAL
  3690   3697     pFile->pShm = 0;
         3698  +#endif
  3691   3699     pFile->zPath = zName;
  3692   3700     if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
  3693   3701       pFile->ctrlFlags |= WINFILE_PSOW;
  3694   3702     }
  3695   3703   
  3696   3704   #if SQLITE_OS_WINCE
  3697   3705     if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB

Changes to src/sqlite.h.in.

  3150   3150   ** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
  3151   3151   **
  3152   3152   ** ^The third argument is the value to bind to the parameter.
  3153   3153   **
  3154   3154   ** ^(In those routines that have a fourth argument, its value is the
  3155   3155   ** number of bytes in the parameter.  To be clear: the value is the
  3156   3156   ** number of <u>bytes</u> in the value, not the number of characters.)^
  3157         -** ^If the fourth parameter is negative, the length of the string is
         3157  +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
         3158  +** is negative, then the length of the string is
  3158   3159   ** the number of bytes up to the first zero terminator.
         3160  +** If the fourth parameter to sqlite3_bind_blob() is negative, then
         3161  +** the behavior is undefined.
  3159   3162   ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
  3160   3163   ** or sqlite3_bind_text16() then that parameter must be the byte offset
  3161   3164   ** where the NUL terminator would occur assuming the string were NUL
  3162   3165   ** terminated.  If any NUL characters occur at byte offsets less than 
  3163   3166   ** the value of the fourth parameter then the resulting string value will
  3164   3167   ** contain embedded NULs.  The result of expressions involving strings
  3165   3168   ** with embedded NULs is undefined.

Changes to src/test1.c.

  5924   5924     int objc,
  5925   5925     Tcl_Obj *CONST objv[]
  5926   5926   ){
  5927   5927     int i;
  5928   5928     sqlite3 *db;
  5929   5929     const char *zOpt;
  5930   5930     int onoff;
  5931         -  int mask;
         5931  +  int mask = 0;
  5932   5932     static const struct {
  5933   5933       const char *zOptName;
  5934   5934       int mask;
  5935   5935     } aOpt[] = {
  5936   5936       { "all",              SQLITE_OptMask        },
  5937   5937       { "query-flattener",  SQLITE_QueryFlattener },
  5938   5938       { "column-cache",     SQLITE_ColumnCache    },

Changes to src/test_config.c.

   314    314   #endif
   315    315   
   316    316   #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_ENABLE_FTS4_UNICODE61)
   317    317     Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY);
   318    318   #else
   319    319     Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY);
   320    320   #endif
          321  +
          322  +#ifdef SQLITE_DISABLE_FTS4_DEFERRED
          323  +  Tcl_SetVar2(interp, "sqlite_options", "fts4_deferred", "0", TCL_GLOBAL_ONLY);
          324  +#else
          325  +  Tcl_SetVar2(interp, "sqlite_options", "fts4_deferred", "1", TCL_GLOBAL_ONLY);
          326  +#endif
   321    327   
   322    328   #ifdef SQLITE_OMIT_GET_TABLE
   323    329     Tcl_SetVar2(interp, "sqlite_options", "gettable", "0", TCL_GLOBAL_ONLY);
   324    330   #else
   325    331     Tcl_SetVar2(interp, "sqlite_options", "gettable", "1", TCL_GLOBAL_ONLY);
   326    332   #endif
   327    333   

Changes to src/test_multiplex.c.

   498    498     const char *zName,         /* Name of file to be opened */
   499    499     sqlite3_file *pConn,       /* Fill in this file descriptor */
   500    500     int flags,                 /* Flags to control the opening */
   501    501     int *pOutFlags             /* Flags showing results of opening */
   502    502   ){
   503    503     int rc = SQLITE_OK;                  /* Result code */
   504    504     multiplexConn *pMultiplexOpen;       /* The new multiplex file descriptor */
   505         -  multiplexGroup *pGroup;              /* Corresponding multiplexGroup object */
          505  +  multiplexGroup *pGroup = 0;          /* Corresponding multiplexGroup object */
   506    506     sqlite3_file *pSubOpen = 0;                    /* Real file descriptor */
   507    507     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   508         -  int nName;
   509         -  int sz;
          508  +  int nName = 0;
          509  +  int sz = 0;
   510    510     char *zToFree = 0;
   511    511   
   512    512     UNUSED_PARAMETER(pVfs);
   513    513     memset(pConn, 0, pVfs->szOsFile);
   514    514     assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
   515    515   
   516    516     /* We need to create a group structure and manage

Changes to src/test_spellfix.c.

   655    655     sqlite3 *db,            /* Load from this database */
   656    656     const char *zTable      /* Name of the table from which to load */
   657    657   ){
   658    658     sqlite3_stmt *pStmt;
   659    659     int rc, rc2;
   660    660     char *zSql;
   661    661     int iLangPrev = -9999;
   662         -  EditDist3Lang *pLang;
          662  +  EditDist3Lang *pLang = 0;
   663    663   
   664    664     zSql = sqlite3_mprintf("SELECT iLang, cFrom, cTo, iCost"
   665    665                            " FROM \"%w\" WHERE iLang>=0 ORDER BY iLang", zTable);
   666    666     if( zSql==0 ) return SQLITE_NOMEM;
   667    667     rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
   668    668     sqlite3_free(zSql);
   669    669     if( rc ) return rc;
................................................................................
   676    676       int nTo = zTo ? sqlite3_column_bytes(pStmt, 2) : 0;
   677    677       int iCost = sqlite3_column_int(pStmt, 3);
   678    678   
   679    679       assert( zFrom!=0 || nFrom==0 );
   680    680       assert( zTo!=0 || nTo==0 );
   681    681       if( nFrom>100 || nTo>100 ) continue;
   682    682       if( iCost<0 ) continue;
   683         -    if( iLang!=iLangPrev ){
          683  +    if( pLang==0 || iLang!=iLangPrev ){
   684    684         EditDist3Lang *pNew;
   685    685         pNew = sqlite3_realloc(p->a, (p->nLang+1)*sizeof(p->a[0]));
   686    686         if( pNew==0 ){ rc = SQLITE_NOMEM; break; }
   687    687         p->a = pNew;
   688    688         pLang = &p->a[p->nLang];
   689    689         p->nLang++;
   690    690         pLang->iLang = iLang;
................................................................................
   859    859   */
   860    860   static void updateCost(
   861    861     unsigned int *m,
   862    862     int i,
   863    863     int j,
   864    864     int iCost
   865    865   ){
   866         -  int b;
          866  +  assert( iCost>=0 );
   867    867     if( iCost<10000 ){
   868         -    b = m[j] + iCost;
          868  +    unsigned int b = m[j] + iCost;
   869    869       if( b<m[i] ) m[i] = b;
   870    870     }
   871    871   }
   872    872   
   873    873   /* Compute the edit distance between two strings.
   874    874   **
   875    875   ** If an error occurs, return a negative number which is the error code.
................................................................................
  2504   2504   
  2505   2505   
  2506   2506   /*
  2507   2507   ** Advance a cursor to its next row of output
  2508   2508   */
  2509   2509   static int spellfix1Next(sqlite3_vtab_cursor *cur){
  2510   2510     spellfix1_cursor *pCur = (spellfix1_cursor *)cur;
         2511  +  int rc = SQLITE_OK;
  2511   2512     if( pCur->iRow < pCur->nRow ){
  2512   2513       if( pCur->pFullScan ){
  2513         -      int rc = sqlite3_step(pCur->pFullScan);
         2514  +      rc = sqlite3_step(pCur->pFullScan);
  2514   2515         if( rc!=SQLITE_ROW ) pCur->iRow = pCur->nRow;
         2516  +      if( rc==SQLITE_ROW || rc==SQLITE_DONE ) rc = SQLITE_OK;
  2515   2517       }else{
  2516   2518         pCur->iRow++;
  2517   2519       }
  2518   2520     }
  2519         -  return SQLITE_OK;
         2521  +  return rc;
  2520   2522   }
  2521   2523   
  2522   2524   /*
  2523   2525   ** Return TRUE if we are at the end-of-file
  2524   2526   */
  2525   2527   static int spellfix1Eof(sqlite3_vtab_cursor *cur){
  2526   2528     spellfix1_cursor *pCur = (spellfix1_cursor *)cur;
................................................................................
  2769   2771     spellfix1Rename,         /* xRename */
  2770   2772   };
  2771   2773   
  2772   2774   /*
  2773   2775   ** Register the various functions and the virtual table.
  2774   2776   */
  2775   2777   static int spellfix1Register(sqlite3 *db){
  2776         -  int nErr = 0;
         2778  +  int rc = SQLITE_OK;
  2777   2779     int i;
  2778         -  nErr += sqlite3_create_function(db, "spellfix1_translit", 1, SQLITE_UTF8, 0,
         2780  +  rc = sqlite3_create_function(db, "spellfix1_translit", 1, SQLITE_UTF8, 0,
  2779   2781                                     transliterateSqlFunc, 0, 0);
  2780         -  nErr += sqlite3_create_function(db, "spellfix1_editdist", 2, SQLITE_UTF8, 0,
         2782  +  if( rc==SQLITE_OK ){
         2783  +    rc = sqlite3_create_function(db, "spellfix1_editdist", 2, SQLITE_UTF8, 0,
  2781   2784                                     editdistSqlFunc, 0, 0);
  2782         -  nErr += sqlite3_create_function(db, "spellfix1_phonehash", 1, SQLITE_UTF8, 0,
         2785  +  }
         2786  +  if( rc==SQLITE_OK ){
         2787  +    rc = sqlite3_create_function(db, "spellfix1_phonehash", 1, SQLITE_UTF8, 0,
  2783   2788                                     phoneticHashSqlFunc, 0, 0);
  2784         -  nErr += sqlite3_create_function(db, "spellfix1_scriptcode", 1, SQLITE_UTF8, 0,
         2789  +  }
         2790  +  if( rc==SQLITE_OK ){
         2791  +    rc = sqlite3_create_function(db, "spellfix1_scriptcode", 1, SQLITE_UTF8, 0,
  2785   2792                                     scriptCodeSqlFunc, 0, 0);
  2786         -  nErr += sqlite3_create_module(db, "spellfix1", &spellfix1Module, 0);
  2787         -  nErr += editDist3Install(db);
         2793  +  }
         2794  +  if( rc==SQLITE_OK ){
         2795  +    rc = sqlite3_create_module(db, "spellfix1", &spellfix1Module, 0);
         2796  +  }
         2797  +  if( rc==SQLITE_OK ){
         2798  +    rc = editDist3Install(db);
         2799  +  }
  2788   2800   
  2789   2801     /* Verify sanity of the translit[] table */
  2790   2802     for(i=0; i<sizeof(translit)/sizeof(translit[0])-1; i++){
  2791   2803       assert( translit[i].cFrom<translit[i+1].cFrom );
  2792   2804     }
  2793   2805   
  2794         -  return nErr ? SQLITE_ERROR : SQLITE_OK;
         2806  +  return rc;
  2795   2807   }
  2796   2808   
  2797   2809   #if SQLITE_CORE || defined(SQLITE_TEST)
  2798   2810   /*
  2799   2811   ** Register the spellfix1 virtual table and its associated functions.
  2800   2812   */
  2801   2813   int sqlite3Spellfix1Register(sqlite3 *db){

Changes to src/threads.c.

    32     32   
    33     33   #define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
    34     34   #include <pthread.h>
    35     35   
    36     36   /* A running thread */
    37     37   struct SQLiteThread {
    38     38     pthread_t tid;
           39  +  int done;
           40  +  void *pOut;
    39     41   };
    40     42   
    41     43   /* Create a new thread */
    42     44   int sqlite3ThreadCreate(
    43     45     SQLiteThread **ppThread,  /* OUT: Write the thread object here */
    44     46     void *(*xTask)(void*),    /* Routine to run in a separate thread */
    45     47     void *pIn                 /* Argument passed into xTask() */
................................................................................
    48     50     int rc;
    49     51   
    50     52     assert( ppThread!=0 );
    51     53     assert( xTask!=0 );
    52     54     *ppThread = 0;
    53     55     p = sqlite3Malloc(sizeof(*p));
    54     56     if( p==0 ) return SQLITE_NOMEM;
    55         -  rc = pthread_create(&p->tid, 0, xTask, pIn);
    56         -  if( rc ){
    57         -    sqlite3_free(p);
    58         -    return SQLITE_ERROR;
           57  +  memset(p, 0, sizeof(*p));
           58  +  if( sqlite3GlobalConfig.bCoreMutex==0
           59  +    || pthread_create(&p->tid, 0, xTask, pIn)!=0 
           60  +  ){
           61  +    p->done = 1;
           62  +    p->pOut = xTask(pIn);
    59     63     }
    60     64     *ppThread = p;
    61     65     return SQLITE_OK;
    62     66   }
    63     67   
    64     68   /* Get the results of the thread */
    65     69   int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
    66     70     int rc;
    67     71   
    68     72     assert( ppOut!=0 );
    69     73     if( p==0 ) return SQLITE_NOMEM;
    70         -  rc = pthread_join(p->tid, ppOut);
           74  +  if( p->done ){
           75  +    *ppOut = p->pOut;
           76  +    rc = SQLITE_OK;
           77  +  }else{
           78  +    rc = pthread_join(p->tid, ppOut);
           79  +  }
    71     80     sqlite3_free(p);
    72     81     return rc ? SQLITE_ERROR : SQLITE_OK;
    73     82   }
    74     83   
    75     84   #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
    76     85   /******************************** End Unix Pthreads *************************/
    77     86   
................................................................................
   111    120     SQLiteThread *p;
   112    121   
   113    122     assert( ppThread!=0 );
   114    123     assert( xTask!=0 );
   115    124     *ppThread = 0;
   116    125     p = sqlite3Malloc(sizeof(*p));
   117    126     if( p==0 ) return SQLITE_NOMEM;
   118         -  p->xTask = xTask; p->pIn = pIn;
   119         -  p->tid = _beginthread(sqlite3ThreadProc, 0, p);
   120         -  if( p->tid==(uintptr_t)-1 ){
   121         -    sqlite3_free(p);
   122         -    return SQLITE_ERROR;
          127  +  if( sqlite3GlobalConfig.bCoreMutex==0 ){
          128  +    memset(p, 0, sizeof(*p));
          129  +  }else{
          130  +    p->xTask = xTask;
          131  +    p->pIn = pIn;
          132  +    p->tid = _beginthread(sqlite3ThreadProc, 0, p);
          133  +    if( p->tid==(uintptr_t)-1 ){
          134  +      memset(p, 0, sizeof(*p));
          135  +    }
          136  +  }
          137  +  if( p->xTask==0 ){
          138  +    p->pResult = xTask(pIn);
   123    139     }
   124    140     *ppThread = p;
   125    141     return SQLITE_OK;
   126    142   }
   127    143   
   128    144   /* Get the results of the thread */
   129    145   int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
   130    146     DWORD rc;
   131    147   
   132    148     assert( ppOut!=0 );
   133    149     if( p==0 ) return SQLITE_NOMEM;
   134         -  rc = sqlite3Win32Wait((HANDLE)p->tid);
   135         -  assert( rc!=WAIT_IO_COMPLETION );
          150  +  if( p->xTask==0 ){
          151  +    rc = WAIT_OBJECT_O;
          152  +  }else{
          153  +    rc = sqlite3Win32Wait((HANDLE)p->tid);
          154  +    assert( rc!=WAIT_IO_COMPLETION );
          155  +  }
   136    156     if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
   137    157     sqlite3_free(p);
   138    158     return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
   139    159   }
   140    160   
   141    161   #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
   142    162   /******************************** End Win32 Threads *************************/

Changes to test/fts3auto.test.

    63     63     set tbl   [lindex $args [expr $nArg-2]]
    64     64     set match [lindex $args [expr $nArg-1]]
    65     65     set deferred [list]
    66     66   
    67     67     foreach {k v} [lrange $args 0 [expr $nArg-3]] {
    68     68       switch -- $k {
    69     69         -deferred {
    70         -        set deferred $v
           70  +        ifcapable fts4_deferred { set deferred $v }
    71     71         }
    72     72         default {
    73     73           error "bad option \"$k\": must be -deferred"
    74     74         }
    75     75       }
    76     76     }
    77     77   
................................................................................
   505    505       INSERT INTO t1(docid, x) VALUES(6, 'c a b');
   506    506     }
   507    507   
   508    508     set limit [fts3_make_deferrable t1 c]
   509    509   
   510    510     do_fts3query_test 3.$tn.2.1 t1 {a OR c}
   511    511   
   512         -  do_test 3.$tn.3 { 
   513         -    fts3_zero_long_segments t1 $limit 
   514         -  } {1}
          512  +  ifcapable fts4_deferred {
          513  +    do_test 3.$tn.3 { fts3_zero_long_segments t1 $limit } {1}
          514  +  }
   515    515   
   516    516     foreach {tn2 expr def} {
   517    517       1     {a NEAR c}            {}
   518    518       2     {a AND c}             c
   519    519       3     {"a c"}               c
   520    520       4     {"c a"}               c
   521    521       5     {"a c" NEAR/1 g}      {}
................................................................................
   546    546     do_fts3query_test 4.$tn.1.3 t1 {one NEAR/1 five}
   547    547     do_fts3query_test 4.$tn.1.4 t1 {one NEAR/2 five}
   548    548     do_fts3query_test 4.$tn.1.5 t1 {one NEAR/3 five}
   549    549   
   550    550     do_test 4.$tn.2 { 
   551    551       set limit [fts3_make_deferrable t1 five]
   552    552       execsql { INSERT INTO t1(t1) VALUES('optimize') }
   553         -    expr {[fts3_zero_long_segments t1 $limit]>0}
          553  +    ifcapable fts4_deferred {
          554  +      expr {[fts3_zero_long_segments t1 $limit]>0}
          555  +    } else {
          556  +      expr 1
          557  +    }
   554    558     } {1}
   555    559   
   556    560     do_fts3query_test 4.$tn.3.1 -deferred five t1 {one AND five}
   557    561     do_fts3query_test 4.$tn.3.2 -deferred five t1 {one NEAR five}
   558    562     do_fts3query_test 4.$tn.3.3 -deferred five t1 {one NEAR/1 five}
   559    563     do_fts3query_test 4.$tn.3.4 -deferred five t1 {one NEAR/2 five}
   560    564   

Changes to test/fts3defer.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   
    12     12   set testdir [file dirname $argv0]
    13     13   source $testdir/tester.tcl
    14     14   source $testdir/malloc_common.tcl
    15     15   
    16         -ifcapable !fts3 {
           16  +ifcapable !fts3||!fts4_deferred {
    17     17     finish_test
    18     18     return
    19     19   }
    20     20   
    21     21   set sqlite_fts3_enable_parentheses 1
    22     22   
    23     23   set fts3_simple_deferred_tokens_only 1

Changes to test/fts3defer2.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/malloc_common.tcl
    16         -ifcapable !fts3 { finish_test ; return }
           16  +ifcapable !fts3||!fts4_deferred {
           17  +  finish_test 
           18  +  return
           19  +}
    17     20   
    18     21   set testprefix fts3defer2
    19     22   
    20     23   proc mit {blob} {
    21     24     set scan(littleEndian) i*
    22     25     set scan(bigEndian) I*
    23     26     binary scan $blob $scan($::tcl_platform(byteOrder)) r

Changes to test/fts3matchinfo.test.

   271    271   
   272    272   do_matchinfo_test 4.3.2 t5 {t5 MATCH 'a b'}         { s {2} }
   273    273   do_matchinfo_test 4.3.3 t5 {t5 MATCH 'a b a'}       { s {3} }
   274    274   do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'}       { s {3 1} }
   275    275   do_matchinfo_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
   276    276   do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'}      { s {1 2 1 1} }
   277    277   
   278         -do_execsql_test 4.4.0 {
   279         -  INSERT INTO t5(t5) VALUES('optimize');
   280         -  UPDATE t5_segments 
   281         -  SET block = zeroblob(length(block)) 
   282         -  WHERE length(block)>10000;
          278  +do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') }
          279  +
          280  +ifcapable fts4_deferred {
          281  +  do_execsql_test 4.4.0.2 {
          282  +    UPDATE t5_segments 
          283  +    SET block = zeroblob(length(block)) 
          284  +    WHERE length(block)>10000;
          285  +  }
   283    286   }
   284    287   
   285    288   do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'}         { s {2} }
   286    289   do_matchinfo_test 4.4.1 t5 {t5 MATCH 'a a'}         { s {2 1} }
   287    290   do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'}         { s {2} }
   288    291   do_matchinfo_test 4.4.3 t5 {t5 MATCH 'a b a'}       { s {3} }
   289    292   do_matchinfo_test 4.4.4 t5 {t5 MATCH 'a a a'}       { s {3 1} }

Changes to test/fts4aa.test.

  1651   1651     }
  1652   1652   } {}
  1653   1653   do_test fts4aa-1.8 {
  1654   1654     db eval {
  1655   1655       SELECT docid FROM t1_docsize EXCEPT SELECT docid FROM t1
  1656   1656     }
  1657   1657   } {}
  1658         -do_test fts4aa-1.9 {
  1659         -  # Note: Token 'in' is being deferred in the following query. 
  1660         -  db eval {
  1661         -    SELECT docid, mit(matchinfo(t1, 'pcxnal')) FROM t1
  1662         -     WHERE t1 MATCH 'joseph died in egypt'
  1663         -     ORDER BY docid;
  1664         -  }
  1665         -} {1050026 {4 1 1 1 1 1 1 1 2 1 1 1 1 1 1 23 23}}
         1658  +ifcapable fts4_deferred {
         1659  +  do_test fts4aa-1.9 {
         1660  +    # Note: Token 'in' is being deferred in the following query. 
         1661  +    db eval {
         1662  +      SELECT docid, mit(matchinfo(t1, 'pcxnal')) FROM t1
         1663  +       WHERE t1 MATCH 'joseph died in egypt'
         1664  +       ORDER BY docid;
         1665  +    }
         1666  +  } {1050026 {4 1 1 1 1 1 1 1 2 1 1 1 1 1 1 23 23}}
         1667  +}
  1666   1668   
  1667   1669   # Should get the same search results from FTS3
  1668   1670   #
  1669   1671   do_test fts4aa-2.0 {
  1670   1672     db eval {
  1671   1673       DROP TABLE t1;
  1672   1674       CREATE VIRTUAL TABLE t1 USING fts3(words, tokenize porter);

Changes to test/releasetest.tcl.

   147    147       -DSQLITE_DEBUG=1 
   148    148       -DSQLITE_PREFER_PROXY_LOCKING=1
   149    149     }
   150    150     "Extra-Robustness" {
   151    151       -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
   152    152       -DSQLITE_MAX_ATTACHED=62
   153    153     }
          154  +  "Devkit" {
          155  +    -DSQLITE_DEFAULT_FILE_FORMAT=4
          156  +    -DSQLITE_MAX_ATTACHED=30
          157  +    -DSQLITE_ENABLE_COLUMN_METADATA
          158  +    -DSQLITE_ENABLE_FTS4
          159  +    -DSQLITE_ENABLE_FTS4_PARENTHESIS
          160  +    -DSQLITE_DISABLE_FTS4_DEFERRED
          161  +    -DSQLITE_ENABLE_RTREE
          162  +  }
   154    163   }
   155    164   
   156    165   array set ::Platforms {
   157    166     Linux-x86_64 {
   158    167       "Debug-One"               "checksymbols test"
   159    168       "Secure-Delete"           test
   160    169       "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
................................................................................
   162    171       "Extra-Robustness"        test
   163    172       "Device-Two"              test
   164    173       "Ftrapv"                  test
   165    174       "Default"                 "threadtest test"
   166    175       "Device-One"              fulltest
   167    176     }
   168    177     Linux-i686 {
          178  +    "Devkit"                  test
   169    179       "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
   170    180       "Device-One"              test
   171    181       "Device-Two"              test
   172    182       "Default"                 "threadtest fulltest"
   173    183     }
   174    184     Darwin-i386 {
   175    185       "Locking-Style"           test

Added tool/checkSpacing.c.

            1  +/*
            2  +** This program checks for formatting problems in source code:
            3  +**
            4  +**    *  Any use of tab characters
            5  +**    *  White space at the end of a line
            6  +**    *  Blank lines at the end of a file
            7  +**
            8  +** Any violations are reported.
            9  +*/
           10  +#include <stdio.h>
           11  +#include <stdlib.h>
           12  +#include <string.h>
           13  +
           14  +#define CR_OK      0x001
           15  +#define WSEOL_OK   0x002
           16  +
           17  +static void checkSpacing(const char *zFile, unsigned flags){
           18  +  FILE *in = fopen(zFile, "rb");
           19  +  int i;
           20  +  int seenSpace;
           21  +  int seenTab;
           22  +  int ln = 0;
           23  +  int lastNonspace = 0;
           24  +  char zLine[2000];
           25  +  if( in==0 ){
           26  +    printf("cannot open %s\n", zFile);
           27  +    return;
           28  +  }
           29  +  while( fgets(zLine, sizeof(zLine), in) ){
           30  +    seenSpace = 0;
           31  +    seenTab = 0;
           32  +    ln++;
           33  +    for(i=0; zLine[i]; i++){
           34  +      if( zLine[i]=='\t' && seenTab==0 ){
           35  +        printf("%s:%d: tab (\\t) character\n", zFile, ln);
           36  +        seenTab = 1;
           37  +      }else if( zLine[i]=='\r' ){
           38  +        if( (flags & CR_OK)==0 ){
           39  +          printf("%s:%d: carriage-return (\\r) character\n", zFile, ln);
           40  +        }
           41  +      }else if( zLine[i]==' ' ){
           42  +        seenSpace = 1;
           43  +      }else if( zLine[i]!='\n' ){
           44  +        lastNonspace = ln;
           45  +        seenSpace = 0;
           46  +      }
           47  +    }
           48  +    if( seenSpace && (flags & WSEOL_OK)==0 ){
           49  +      printf("%s:%d: whitespace at end-of-line\n", zFile, ln);
           50  +    }
           51  +  }
           52  +  fclose(in);
           53  +  if( lastNonspace<ln ){
           54  +    printf("%s:%d: blank lines at end of file (%d)\n",
           55  +        zFile, ln, ln - lastNonspace);
           56  +  }
           57  +}
           58  +
           59  +int main(int argc, char **argv){
           60  +  int i;
           61  +  unsigned flags = WSEOL_OK;
           62  +  for(i=1; i<argc; i++){
           63  +    const char *z = argv[i];
           64  +    if( z[0]=='-' ){
           65  +      while( z[0]=='-' ) z++;
           66  +      if( strcmp(z,"crok")==0 ){
           67  +        flags |= CR_OK;
           68  +      }else if( strcmp(z, "wseol")==0 ){
           69  +        flags &= ~WSEOL_OK;
           70  +      }else if( strcmp(z, "help")==0 ){
           71  +        printf("Usage: %s [options] FILE ...\n", argv[0]);
           72  +        printf("  --crok      Do not report on carriage-returns\n");
           73  +        printf("  --wseol     Complain about whitespace at end-of-line\n");
           74  +        printf("  --help      This message\n");
           75  +      }else{
           76  +        printf("unknown command-line option: [%s]\n", argv[i]);
           77  +        printf("use --help for additional information\n");
           78  +      }
           79  +    }else{
           80  +      checkSpacing(argv[i], flags);
           81  +    }
           82  +  }
           83  +  return 0;
           84  +}

Changes to tool/lemon.c.

    11     11   #include <string.h>
    12     12   #include <ctype.h>
    13     13   #include <stdlib.h>
    14     14   #include <assert.h>
    15     15   
    16     16   #ifndef __WIN32__
    17     17   #   if defined(_WIN32) || defined(WIN32)
    18         -#	define __WIN32__
           18  +#       define __WIN32__
    19     19   #   endif
    20     20   #endif
    21     21   
    22     22   #ifdef __WIN32__
    23     23   #ifdef __cplusplus
    24     24   extern "C" {
    25     25   #endif
................................................................................
   649    649               if( sp->subsym[j]->prec>=0 ){
   650    650                 rp->precsym = sp->subsym[j];
   651    651                 break;
   652    652               }
   653    653             }
   654    654           }else if( sp->prec>=0 ){
   655    655             rp->precsym = rp->rhs[i];
   656         -	}
          656  +        }
   657    657         }
   658    658       }
   659    659     }
   660    660     return;
   661    661   }
   662    662   
   663    663   /* Find all nonterminals which will generate the empty string.
................................................................................
   707    707             progress += SetAdd(s1->firstset,s2->index);
   708    708             break;
   709    709           }else if( s2->type==MULTITERMINAL ){
   710    710             for(j=0; j<s2->nsubsym; j++){
   711    711               progress += SetAdd(s1->firstset,s2->subsym[j]->index);
   712    712             }
   713    713             break;
   714         -	}else if( s1==s2 ){
          714  +        }else if( s1==s2 ){
   715    715             if( s1->lambda==LEMON_FALSE ) break;
   716         -	}else{
          716  +        }else{
   717    717             progress += SetUnion(s1->firstset,s2->firstset);
   718    718             if( s2->lambda==LEMON_FALSE ) break;
   719         -	}
          719  +        }
   720    720         }
   721    721       }
   722    722     }while( progress );
   723    723     return;
   724    724   }
   725    725   
   726    726   /* Compute all LR(0) states for the grammar.  Links
................................................................................
   955    955         for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
   956    956           if( cfp->status==COMPLETE ) continue;
   957    957           for(plp=cfp->fplp; plp; plp=plp->next){
   958    958             change = SetUnion(plp->cfp->fws,cfp->fws);
   959    959             if( change ){
   960    960               plp->cfp->status = INCOMPLETE;
   961    961               progress = 1;
   962         -	  }
   963         -	}
          962  +          }
          963  +        }
   964    964           cfp->status = COMPLETE;
   965    965         }
   966    966       }
   967    967     }while( progress );
   968    968   }
   969    969   
   970    970   static int resolve_conflict(struct action *,struct action *);
................................................................................
   989    989         if( cfp->rp->nrhs==cfp->dot ){        /* Is dot at extreme right? */
   990    990           for(j=0; j<lemp->nterminal; j++){
   991    991             if( SetFind(cfp->fws,j) ){
   992    992               /* Add a reduce action to the state "stp" which will reduce by the
   993    993               ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
   994    994               Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
   995    995             }
   996         -	}
          996  +        }
   997    997         }
   998    998       }
   999    999     }
  1000   1000   
  1001   1001     /* Add the accepting token */
  1002   1002     if( lemp->start ){
  1003   1003       sp = Symbol_find(lemp->start);
................................................................................
  1258   1258               break;
  1259   1259             }else if( xsp->type==MULTITERMINAL ){
  1260   1260               int k;
  1261   1261               for(k=0; k<xsp->nsubsym; k++){
  1262   1262                 SetAdd(newcfp->fws, xsp->subsym[k]->index);
  1263   1263               }
  1264   1264               break;
  1265         -	  }else{
         1265  +          }else{
  1266   1266               SetUnion(newcfp->fws,xsp->firstset);
  1267   1267               if( xsp->lambda==LEMON_FALSE ) break;
  1268         -	  }
  1269         -	}
         1268  +          }
         1269  +        }
  1270   1270           if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
  1271   1271         }
  1272   1272       }
  1273   1273     }
  1274   1274     return;
  1275   1275   }
  1276   1276   
................................................................................
  1992   1992           psp->state = WAITING_FOR_ARROW;
  1993   1993         }else if( x[0]=='{' ){
  1994   1994           if( psp->prevrule==0 ){
  1995   1995             ErrorMsg(psp->filename,psp->tokenlineno,
  1996   1996   "There is no prior rule upon which to attach the code \
  1997   1997   fragment which begins on this line.");
  1998   1998             psp->errorcnt++;
  1999         -	}else if( psp->prevrule->code!=0 ){
         1999  +        }else if( psp->prevrule->code!=0 ){
  2000   2000             ErrorMsg(psp->filename,psp->tokenlineno,
  2001   2001   "Code fragment beginning on this line is not the first \
  2002   2002   to follow the previous rule.");
  2003   2003             psp->errorcnt++;
  2004   2004           }else{
  2005   2005             psp->prevrule->line = psp->tokenlineno;
  2006   2006             psp->prevrule->code = &x[1];
  2007         -	}
         2007  +        }
  2008   2008         }else if( x[0]=='[' ){
  2009   2009           psp->state = PRECEDENCE_MARK_1;
  2010   2010         }else{
  2011   2011           ErrorMsg(psp->filename,psp->tokenlineno,
  2012   2012             "Token \"%s\" should be either \"%%\" or a nonterminal name.",
  2013   2013             x);
  2014   2014           psp->errorcnt++;
................................................................................
  2093   2093           rp = (struct rule *)calloc( sizeof(struct rule) + 
  2094   2094                sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
  2095   2095           if( rp==0 ){
  2096   2096             ErrorMsg(psp->filename,psp->tokenlineno,
  2097   2097               "Can't allocate enough memory for this rule.");
  2098   2098             psp->errorcnt++;
  2099   2099             psp->prevrule = 0;
  2100         -	}else{
         2100  +        }else{
  2101   2101             int i;
  2102   2102             rp->ruleline = psp->tokenlineno;
  2103   2103             rp->rhs = (struct symbol**)&rp[1];
  2104   2104             rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
  2105   2105             for(i=0; i<psp->nrhs; i++){
  2106   2106               rp->rhs[i] = psp->rhs[i];
  2107   2107               rp->rhsalias[i] = psp->alias[i];
  2108         -	  }
         2108  +          }
  2109   2109             rp->lhs = psp->lhs;
  2110   2110             rp->lhsalias = psp->lhsalias;
  2111   2111             rp->nrhs = psp->nrhs;
  2112   2112             rp->code = 0;
  2113   2113             rp->precsym = 0;
  2114   2114             rp->index = psp->gp->nrule++;
  2115   2115             rp->nextlhs = rp->lhs->rule;
  2116   2116             rp->lhs->rule = rp;
  2117   2117             rp->next = 0;
  2118   2118             if( psp->firstrule==0 ){
  2119   2119               psp->firstrule = psp->lastrule = rp;
  2120         -	  }else{
         2120  +          }else{
  2121   2121               psp->lastrule->next = rp;
  2122   2122               psp->lastrule = rp;
  2123         -	  }
         2123  +          }
  2124   2124             psp->prevrule = rp;
  2125         -	}
         2125  +        }
  2126   2126           psp->state = WAITING_FOR_DECL_OR_RULE;
  2127   2127         }else if( isalpha(x[0]) ){
  2128   2128           if( psp->nrhs>=MAXRHS ){
  2129   2129             ErrorMsg(psp->filename,psp->tokenlineno,
  2130   2130               "Too many symbols on RHS of rule beginning at \"%s\".",
  2131   2131               x);
  2132   2132             psp->errorcnt++;
  2133   2133             psp->state = RESYNC_AFTER_RULE_ERROR;
  2134         -	}else{
         2134  +        }else{
  2135   2135             psp->rhs[psp->nrhs] = Symbol_new(x);
  2136   2136             psp->alias[psp->nrhs] = 0;
  2137   2137             psp->nrhs++;
  2138         -	}
         2138  +        }
  2139   2139         }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
  2140   2140           struct symbol *msp = psp->rhs[psp->nrhs-1];
  2141   2141           if( msp->type!=MULTITERMINAL ){
  2142   2142             struct symbol *origsp = msp;
  2143   2143             msp = (struct symbol *) calloc(1,sizeof(*msp));
  2144   2144             memset(msp, 0, sizeof(*msp));
  2145   2145             msp->type = MULTITERMINAL;
................................................................................
  2195   2195           psp->declargslot = 0;
  2196   2196           psp->decllinenoslot = 0;
  2197   2197           psp->insertLineMacro = 1;
  2198   2198           psp->state = WAITING_FOR_DECL_ARG;
  2199   2199           if( strcmp(x,"name")==0 ){
  2200   2200             psp->declargslot = &(psp->gp->name);
  2201   2201             psp->insertLineMacro = 0;
  2202         -	}else if( strcmp(x,"include")==0 ){
         2202  +        }else if( strcmp(x,"include")==0 ){
  2203   2203             psp->declargslot = &(psp->gp->include);
  2204         -	}else if( strcmp(x,"code")==0 ){
         2204  +        }else if( strcmp(x,"code")==0 ){
  2205   2205             psp->declargslot = &(psp->gp->extracode);
  2206         -	}else if( strcmp(x,"token_destructor")==0 ){
         2206  +        }else if( strcmp(x,"token_destructor")==0 ){
  2207   2207             psp->declargslot = &psp->gp->tokendest;
  2208         -	}else if( strcmp(x,"default_destructor")==0 ){
         2208  +        }else if( strcmp(x,"default_destructor")==0 ){
  2209   2209             psp->declargslot = &psp->gp->vardest;
  2210         -	}else if( strcmp(x,"token_prefix")==0 ){
         2210  +        }else if( strcmp(x,"token_prefix")==0 ){
  2211   2211             psp->declargslot = &psp->gp->tokenprefix;
  2212   2212             psp->insertLineMacro = 0;
  2213         -	}else if( strcmp(x,"syntax_error")==0 ){
         2213  +        }else if( strcmp(x,"syntax_error")==0 ){
  2214   2214             psp->declargslot = &(psp->gp->error);
  2215         -	}else if( strcmp(x,"parse_accept")==0 ){
         2215  +        }else if( strcmp(x,"parse_accept")==0 ){
  2216   2216             psp->declargslot = &(psp->gp->accept);
  2217         -	}else if( strcmp(x,"parse_failure")==0 ){
         2217  +        }else if( strcmp(x,"parse_failure")==0 ){
  2218   2218             psp->declargslot = &(psp->gp->failure);
  2219         -	}else if( strcmp(x,"stack_overflow")==0 ){
         2219  +        }else if( strcmp(x,"stack_overflow")==0 ){
  2220   2220             psp->declargslot = &(psp->gp->overflow);
  2221   2221           }else if( strcmp(x,"extra_argument")==0 ){
  2222   2222             psp->declargslot = &(psp->gp->arg);
  2223   2223             psp->insertLineMacro = 0;
  2224   2224           }else if( strcmp(x,"token_type")==0 ){
  2225   2225             psp->declargslot = &(psp->gp->tokentype);
  2226   2226             psp->insertLineMacro = 0;
................................................................................
  2241   2241             psp->preccounter++;
  2242   2242             psp->declassoc = RIGHT;
  2243   2243             psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
  2244   2244           }else if( strcmp(x,"nonassoc")==0 ){
  2245   2245             psp->preccounter++;
  2246   2246             psp->declassoc = NONE;
  2247   2247             psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
  2248         -	}else if( strcmp(x,"destructor")==0 ){
         2248  +        }else if( strcmp(x,"destructor")==0 ){
  2249   2249             psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL;
  2250         -	}else if( strcmp(x,"type")==0 ){
         2250  +        }else if( strcmp(x,"type")==0 ){
  2251   2251             psp->state = WAITING_FOR_DATATYPE_SYMBOL;
  2252   2252           }else if( strcmp(x,"fallback")==0 ){
  2253   2253             psp->fallback = 0;
  2254   2254             psp->state = WAITING_FOR_FALLBACK_ID;
  2255   2255           }else if( strcmp(x,"wildcard")==0 ){
  2256   2256             psp->state = WAITING_FOR_WILDCARD_ID;
  2257   2257           }else{
  2258   2258             ErrorMsg(psp->filename,psp->tokenlineno,
  2259   2259               "Unknown declaration keyword: \"%%%s\".",x);
  2260   2260             psp->errorcnt++;
  2261   2261             psp->state = RESYNC_AFTER_DECL_ERROR;
  2262         -	}
         2262  +        }
  2263   2263         }else{
  2264   2264           ErrorMsg(psp->filename,psp->tokenlineno,
  2265   2265             "Illegal declaration keyword: \"%s\".",x);
  2266   2266           psp->errorcnt++;
  2267   2267           psp->state = RESYNC_AFTER_DECL_ERROR;
  2268   2268         }
  2269   2269         break;
................................................................................
  2310   2310         }else if( isupper(x[0]) ){
  2311   2311           struct symbol *sp;
  2312   2312           sp = Symbol_new(x);
  2313   2313           if( sp->prec>=0 ){
  2314   2314             ErrorMsg(psp->filename,psp->tokenlineno,
  2315   2315               "Symbol \"%s\" has already be given a precedence.",x);
  2316   2316             psp->errorcnt++;
  2317         -	}else{
         2317  +        }else{
  2318   2318             sp->prec = psp->preccounter;
  2319   2319             sp->assoc = psp->declassoc;
  2320         -	}
         2320  +        }
  2321   2321         }else{
  2322   2322           ErrorMsg(psp->filename,psp->tokenlineno,
  2323   2323             "Can't assign a precedence to \"%s\".",x);
  2324   2324           psp->errorcnt++;
  2325   2325         }
  2326   2326         break;
  2327   2327       case WAITING_FOR_DECL_ARG:
................................................................................
  2583   2583             int prevc;
  2584   2584             cp = &cp[2];
  2585   2585             prevc = 0;
  2586   2586             while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){
  2587   2587               if( c=='\n' ) lineno++;
  2588   2588               prevc = c;
  2589   2589               cp++;
  2590         -	  }
  2591         -	}else if( c=='/' && cp[1]=='/' ){  /* Skip C++ style comments too */
         2590  +          }
         2591  +        }else if( c=='/' && cp[1]=='/' ){  /* Skip C++ style comments too */
  2592   2592             cp = &cp[2];
  2593   2593             while( (c= *cp)!=0 && c!='\n' ) cp++;
  2594   2594             if( c ) lineno++;
  2595         -	}else if( c=='\'' || c=='\"' ){    /* String a character literals */
         2595  +        }else if( c=='\'' || c=='\"' ){    /* String a character literals */
  2596   2596             int startchar, prevc;
  2597   2597             startchar = c;
  2598   2598             prevc = 0;
  2599   2599             for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){
  2600   2600               if( c=='\n' ) lineno++;
  2601   2601               if( prevc=='\\' ) prevc = 0;
  2602   2602               else              prevc = c;
  2603         -	  }
  2604         -	}
         2603  +          }
         2604  +        }
  2605   2605         }
  2606   2606         if( c==0 ){
  2607   2607           ErrorMsg(ps.filename,ps.tokenlineno,
  2608   2608   "C code starting on this line is not terminated before the end of the file.");
  2609   2609           ps.errorcnt++;
  2610   2610           nextcp = cp;
  2611   2611         }else{