/ Check-in [ef26ea5c]
Login

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

Overview
Comment:Continuing work on adding full support for the SQLITE_OMIT_WSD compile-time option. (CVS 5658)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ef26ea5c46d3915d206f8ff7f82a24f4c8955f1f
User & Date: drh 2008-09-02 00:52:52
Context
2008-09-02
09:38
Modify pcache.c to work with OMIT_WSD. (CVS 5659) check-in: 44def90d user: danielk1977 tags: trunk
00:52
Continuing work on adding full support for the SQLITE_OMIT_WSD compile-time option. (CVS 5658) check-in: ef26ea5c user: drh tags: trunk
2008-09-01
22:15
Add define for INVALID_FILE_ATTRIBUTES if it is not already defined, as some older Windows compilers do not define it. (CVS 5657) check-in: e0461f87 user: shane tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.505 2008/09/01 18:34:20 danielk1977 Exp $
           12  +** $Id: btree.c,v 1.506 2008/09/02 00:52:52 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
    41     41   ** A flag to indicate whether or not shared cache is enabled.  Also,
    42     42   ** a list of BtShared objects that are eligible for participation
    43     43   ** in shared cache.  The variables have file scope during normal builds,
    44     44   ** but the test harness needs to access these variables so we make them
    45     45   ** global for test builds.
    46     46   */
    47     47   #ifdef SQLITE_TEST
    48         -BtShared *sqlite3SharedCacheList = 0;
    49         -int sqlite3SharedCacheEnabled = 0;
           48  +BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
           49  +SQLITE_WSD int sqlite3SharedCacheEnabled = 0;
    50     50   #else
    51         -static BtShared *sqlite3SharedCacheList = 0;
    52         -static int sqlite3SharedCacheEnabled = 0;
           51  +static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
           52  +static SQLITE_WSD int sqlite3SharedCacheEnabled = 0;
    53     53   #endif
    54     54   #endif /* SQLITE_OMIT_SHARED_CACHE */
    55     55   
    56     56   #ifndef SQLITE_OMIT_SHARED_CACHE
    57     57   /*
    58     58   ** Enable or disable the shared pager and schema features.
    59     59   **
    60     60   ** This routine has no effect on existing database connections.
    61     61   ** The shared cache setting effects only future calls to
    62     62   ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
    63     63   */
    64     64   int sqlite3_enable_shared_cache(int enable){
    65         -  sqlite3SharedCacheEnabled = enable;
           65  +  GLOBAL(int,sqlite3SharedCacheEnabled) = enable;
    66     66     return SQLITE_OK;
    67     67   }
    68     68   #endif
    69     69   
    70     70   
    71     71   /*
    72     72   ** Forward declaration
................................................................................
  1228   1228     ** If this Btree is a candidate for shared cache, try to find an
  1229   1229     ** existing BtShared object that we can share with
  1230   1230     */
  1231   1231     if( isMemdb==0
  1232   1232      && (db->flags & SQLITE_Vtab)==0
  1233   1233      && zFilename && zFilename[0]
  1234   1234     ){
  1235         -    if( sqlite3SharedCacheEnabled ){
         1235  +    if( GLOBAL(int,sqlite3SharedCacheEnabled) ){
  1236   1236         int nFullPathname = pVfs->mxPathname+1;
  1237   1237         char *zFullPathname = sqlite3Malloc(nFullPathname);
  1238   1238         sqlite3_mutex *mutexShared;
  1239   1239         p->sharable = 1;
  1240   1240         db->flags |= SQLITE_SharedCache;
  1241   1241         if( !zFullPathname ){
  1242   1242           sqlite3_free(p);
  1243   1243           return SQLITE_NOMEM;
  1244   1244         }
  1245   1245         sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
  1246   1246         mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1247   1247         sqlite3_mutex_enter(mutexShared);
  1248         -      for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
         1248  +      for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
  1249   1249           assert( pBt->nRef>0 );
  1250   1250           if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
  1251   1251                    && sqlite3PagerVfs(pBt->pPager)==pVfs ){
  1252   1252             p->pBt = pBt;
  1253   1253             pBt->nRef++;
  1254   1254             break;
  1255   1255           }
................................................................................
  1345   1345           if( pBt->mutex==0 ){
  1346   1346             rc = SQLITE_NOMEM;
  1347   1347             db->mallocFailed = 0;
  1348   1348             goto btree_open_out;
  1349   1349           }
  1350   1350         }
  1351   1351         sqlite3_mutex_enter(mutexShared);
  1352         -      pBt->pNext = sqlite3SharedCacheList;
  1353         -      sqlite3SharedCacheList = pBt;
         1352  +      pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList);
         1353  +      GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt;
  1354   1354         sqlite3_mutex_leave(mutexShared);
  1355   1355       }
  1356   1356   #endif
  1357   1357     }
  1358   1358   
  1359   1359   #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  1360   1360     /* If the new Btree uses a sharable pBtShared, then link the new
................................................................................
  1414   1414     int removed = 0;
  1415   1415   
  1416   1416     assert( sqlite3_mutex_notheld(pBt->mutex) );
  1417   1417     pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1418   1418     sqlite3_mutex_enter(pMaster);
  1419   1419     pBt->nRef--;
  1420   1420     if( pBt->nRef<=0 ){
  1421         -    if( sqlite3SharedCacheList==pBt ){
  1422         -      sqlite3SharedCacheList = pBt->pNext;
         1421  +    if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
         1422  +      GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
  1423   1423       }else{
  1424         -      pList = sqlite3SharedCacheList;
         1424  +      pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
  1425   1425         while( ALWAYS(pList) && pList->pNext!=pBt ){
  1426   1426           pList=pList->pNext;
  1427   1427         }
  1428   1428         if( ALWAYS(pList) ){
  1429   1429           pList->pNext = pBt->pNext;
  1430   1430         }
  1431   1431       }

Changes to src/fault.c.

     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13         -** $Id: fault.c,v 1.10 2008/06/22 12:37:58 drh Exp $
           13  +** $Id: fault.c,v 1.11 2008/09/02 00:52:52 drh Exp $
    14     14   */
    15     15   
    16     16   /*
    17     17   ** This file contains code to support the concept of "benign" 
    18     18   ** malloc failures (when the xMalloc() or xRealloc() method of the
    19     19   ** sqlite3_mem_methods structure fails to allocate a block of memory
    20     20   ** and returns 0). 
................................................................................
    31     31   #include "sqliteInt.h"
    32     32   
    33     33   #ifndef SQLITE_OMIT_BUILTIN_TEST
    34     34   
    35     35   /*
    36     36   ** Global variables.
    37     37   */
    38         -static struct BenignMallocHooks {
           38  +typedef struct BenignMallocHooks BenignMallocHooks;
           39  +static SQLITE_WSD struct BenignMallocHooks {
    39     40     void (*xBenignBegin)(void);
    40     41     void (*xBenignEnd)(void);
    41         -} hooks;
           42  +} sqlite3Hooks = { 0, 0 };
           43  +
           44  +/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
           45  +** structure.  If writable static data is unsupported on the target,
           46  +** we have to locate the state vector at run-time.  In the more common
           47  +** case where writable static data is supported, wsdHooks can refer directly
           48  +** to the "sqlite3Hooks" state vector declared above.
           49  +*/
           50  +#ifdef SQLITE_OMIT_WSD
           51  +# define wsdHooksInit \
           52  +  BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
           53  +# define wsdHooks x[0]
           54  +#else
           55  +# define wsdHooksInit
           56  +# define wsdHooks sqlite3Hooks
           57  +#endif
           58  +
    42     59   
    43     60   /*
    44     61   ** Register hooks to call when sqlite3BeginBenignMalloc() and
    45     62   ** sqlite3EndBenignMalloc() are called, respectively.
    46     63   */
    47     64   void sqlite3BenignMallocHooks(
    48     65     void (*xBenignBegin)(void),
    49     66     void (*xBenignEnd)(void)
    50     67   ){
    51         -  hooks.xBenignBegin = xBenignBegin;
    52         -  hooks.xBenignEnd = xBenignEnd;
           68  +  wsdHooksInit;
           69  +  wsdHooks.xBenignBegin = xBenignBegin;
           70  +  wsdHooks.xBenignEnd = xBenignEnd;
    53     71   }
    54     72   
    55     73   /*
    56     74   ** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
    57     75   ** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
    58     76   ** indicates that subsequent malloc failures are non-benign.
    59     77   */
    60     78   void sqlite3BeginBenignMalloc(void){
    61         -  if( hooks.xBenignBegin ){
    62         -    hooks.xBenignBegin();
           79  +  wsdHooksInit;
           80  +  if( wsdHooks.xBenignBegin ){
           81  +    wsdHooks.xBenignBegin();
    63     82     }
    64     83   }
    65     84   void sqlite3EndBenignMalloc(void){
    66         -  if( hooks.xBenignEnd ){
    67         -    hooks.xBenignEnd();
           85  +  wsdHooksInit;
           86  +  if( wsdHooks.xBenignEnd ){
           87  +    wsdHooks.xBenignEnd();
    68     88     }
    69     89   }
    70     90   
    71     91   #endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */

Changes to src/loadext.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to dynamically load extensions into
    13     13   ** the SQLite library.
    14     14   **
    15         -** $Id: loadext.c,v 1.53 2008/08/02 03:50:39 drh Exp $
           15  +** $Id: loadext.c,v 1.54 2008/09/02 00:52:52 drh Exp $
    16     16   */
    17     17   
    18     18   #ifndef SQLITE_CORE
    19     19     #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
    20     20   #endif
    21     21   #include "sqlite3ext.h"
    22     22   #include "sqliteInt.h"
................................................................................
   462    462   /*
   463    463   ** The following object holds the list of automatically loaded
   464    464   ** extensions.
   465    465   **
   466    466   ** This list is shared across threads.  The SQLITE_MUTEX_STATIC_MASTER
   467    467   ** mutex must be held while accessing this list.
   468    468   */
   469         -static struct {
          469  +typedef struct sqlite3ExtType sqlite3ExtType;
          470  +static SQLITE_WSD struct sqlite3ExtType {
   470    471     int nExt;        /* Number of entries in aExt[] */          
   471    472     void **aExt;     /* Pointers to the extension init functions */
   472         -} autoext = { 0, 0 };
          473  +} sqlite3Autoext = { 0, 0 };
          474  +
          475  +/* The "wsdAutoext" macro will resolve to the autoextension
          476  +** state vector.  If writable static data is unsupported on the target,
          477  +** we have to locate the state vector at run-time.  In the more common
          478  +** case where writable static data is supported, wsdStat can refer directly
          479  +** to the "sqlite3Autoext" state vector declared above.
          480  +*/
          481  +#ifdef SQLITE_OMIT_WSD
          482  +# define wsdAutoextInit \
          483  +  sqlite3ExtType *x = &GLOBAL(sqlite3ExtType,sqlite3Autoext)
          484  +# define wsdAutoext x[0]
          485  +#else
          486  +# define wsdAutoextInit
          487  +# define wsdAutoext sqlite3Autoext
          488  +#endif
   473    489   
   474    490   
   475    491   /*
   476    492   ** Register a statically linked extension that is automatically
   477    493   ** loaded by every new database connection.
   478    494   */
   479    495   int sqlite3_auto_extension(void *xInit){
................................................................................
   485    501     }else
   486    502   #endif
   487    503     {
   488    504       int i;
   489    505   #ifndef SQLITE_MUTEX_NOOP
   490    506       sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   491    507   #endif
          508  +    wsdAutoextInit;
   492    509       sqlite3_mutex_enter(mutex);
   493         -    for(i=0; i<autoext.nExt; i++){
   494         -      if( autoext.aExt[i]==xInit ) break;
          510  +    for(i=0; i<wsdAutoext.nExt; i++){
          511  +      if( wsdAutoext.aExt[i]==xInit ) break;
   495    512       }
   496         -    if( i==autoext.nExt ){
   497         -      int nByte = (autoext.nExt+1)*sizeof(autoext.aExt[0]);
          513  +    if( i==wsdAutoext.nExt ){
          514  +      int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
   498    515         void **aNew;
   499         -      aNew = sqlite3_realloc(autoext.aExt, nByte);
          516  +      aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
   500    517         if( aNew==0 ){
   501    518           rc = SQLITE_NOMEM;
   502    519         }else{
   503         -        autoext.aExt = aNew;
   504         -        autoext.aExt[autoext.nExt] = xInit;
   505         -        autoext.nExt++;
          520  +        wsdAutoext.aExt = aNew;
          521  +        wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
          522  +        wsdAutoext.nExt++;
   506    523         }
   507    524       }
   508    525       sqlite3_mutex_leave(mutex);
   509    526       assert( (rc&0xff)==rc );
   510    527       return rc;
   511    528     }
   512    529   }
................................................................................
   518    535   #ifndef SQLITE_OMIT_AUTOINIT
   519    536     if( sqlite3_initialize()==SQLITE_OK )
   520    537   #endif
   521    538     {
   522    539   #ifndef SQLITE_MUTEX_NOOP
   523    540       sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   524    541   #endif
          542  +    wsdAutoextInit;
   525    543       sqlite3_mutex_enter(mutex);
   526         -    sqlite3_free(autoext.aExt);
   527         -    autoext.aExt = 0;
   528         -    autoext.nExt = 0;
          544  +    sqlite3_free(wsdAutoext.aExt);
          545  +    wsdAutoext.aExt = 0;
          546  +    wsdAutoext.nExt = 0;
   529    547       sqlite3_mutex_leave(mutex);
   530    548     }
   531    549   }
   532    550   
   533    551   /*
   534    552   ** Load all automatic extensions.
   535    553   */
   536    554   int sqlite3AutoLoadExtensions(sqlite3 *db){
   537    555     int i;
   538    556     int go = 1;
   539    557     int rc = SQLITE_OK;
   540    558     int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   541    559   
   542         -  if( autoext.nExt==0 ){
          560  +  wsdAutoextInit;
          561  +  if( wsdAutoext.nExt==0 ){
   543    562       /* Common case: early out without every having to acquire a mutex */
   544    563       return SQLITE_OK;
   545    564     }
   546    565     for(i=0; go; i++){
   547    566       char *zErrmsg = 0;
   548    567   #ifndef SQLITE_MUTEX_NOOP
   549    568       sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   550    569   #endif
   551    570       sqlite3_mutex_enter(mutex);
   552         -    if( i>=autoext.nExt ){
          571  +    if( i>=wsdAutoext.nExt ){
   553    572         xInit = 0;
   554    573         go = 0;
   555    574       }else{
   556    575         xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
   557         -              autoext.aExt[i];
          576  +              wsdAutoext.aExt[i];
   558    577       }
   559    578       sqlite3_mutex_leave(mutex);
   560    579       if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){
   561    580         sqlite3Error(db, SQLITE_ERROR,
   562    581               "automatic extension loading failed: %s", zErrmsg);
   563    582         go = 0;
   564    583         rc = SQLITE_ERROR;
   565    584         sqlite3_free(zErrmsg);
   566    585       }
   567    586     }
   568    587     return rc;
   569    588   }

Changes to src/pragma.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the PRAGMA command.
    13     13   **
    14         -** $Id: pragma.c,v 1.184 2008/08/20 16:34:24 danielk1977 Exp $
           14  +** $Id: pragma.c,v 1.185 2008/09/02 00:52:52 drh Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include <ctype.h>
    18     18   
    19     19   /* Ignore this whole file if pragmas are disabled
    20     20   */
    21     21   #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
   662    662           sqlite3VdbeSetNumCols(v, 1);
   663    663           sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
   664    664               "temp_store_directory", P4_STATIC);
   665    665           sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
   666    666           sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
   667    667         }
   668    668       }else{
          669  +#ifndef SQLITE_OMIT_WSD
   669    670         if( zRight[0] ){
   670    671           int res;
   671    672           sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
   672    673           if( res==0 ){
   673    674             sqlite3ErrorMsg(pParse, "not a writable directory");
   674    675             goto pragma_out;
   675    676           }
................................................................................
   682    683         }
   683    684         sqlite3_free(sqlite3_temp_directory);
   684    685         if( zRight[0] ){
   685    686           sqlite3_temp_directory = sqlite3DbStrDup(0, zRight);
   686    687         }else{
   687    688           sqlite3_temp_directory = 0;
   688    689         }
          690  +#endif /* SQLITE_OMIT_WSD */
   689    691       }
   690    692     }else
   691    693   
   692    694     /*
   693    695     **   PRAGMA [database.]synchronous
   694    696     **   PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
   695    697     **

Changes to src/random.c.

    11     11   *************************************************************************
    12     12   ** This file contains code to implement a pseudo-random number
    13     13   ** generator (PRNG) for SQLite.
    14     14   **
    15     15   ** Random numbers are used by some of the database backends in order
    16     16   ** to generate random integer keys for tables or random filenames.
    17     17   **
    18         -** $Id: random.c,v 1.25 2008/06/19 01:03:18 drh Exp $
           18  +** $Id: random.c,v 1.26 2008/09/02 00:52:52 drh Exp $
    19     19   */
    20     20   #include "sqliteInt.h"
    21     21   
    22     22   
    23     23   /* All threads share a single random number generator.
    24     24   ** This structure is the current state of the generator.
    25     25   */
    26         -static struct sqlite3PrngType {
           26  +static SQLITE_WSD struct sqlite3PrngType {
    27     27     unsigned char isInit;          /* True if initialized */
    28     28     unsigned char i, j;            /* State variables */
    29     29     unsigned char s[256];          /* State variables */
    30         -} sqlite3Prng;
           30  +} sqlite3Prng = { 0, };
    31     31   
    32     32   /*
    33     33   ** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
    34     34   ** must be held while executing this routine.
    35     35   **
    36     36   ** Why not just use a library random generator like lrand48() for this?
    37     37   ** Because the OP_NewRowid opcode in the VDBE depends on having a very
................................................................................
    44     44   **
    45     45   ** (Later):  Actually, OP_NewRowid does not depend on a good source of
    46     46   ** randomness any more.  But we will leave this code in all the same.
    47     47   */
    48     48   static int randomByte(void){
    49     49     unsigned char t;
    50     50   
           51  +
           52  +  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
           53  +  ** state vector.  If writable static data is unsupported on the target,
           54  +  ** we have to locate the state vector at run-time.  In the more common
           55  +  ** case where writable static data is supported, wsdPrng can refer directly
           56  +  ** to the "sqlite3Prng" state vector declared above.
           57  +  */
           58  +#ifdef SQLITE_OMIT_WSD
           59  +  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
           60  +# define wsdPrng p[0]
           61  +#else
           62  +# define wsdPrng sqlite3Prng
           63  +#endif
           64  +
    51     65   
    52     66     /* Initialize the state of the random number generator once,
    53     67     ** the first time this routine is called.  The seed value does
    54     68     ** not need to contain a lot of randomness since we are not
    55     69     ** trying to do secure encryption or anything like that...
    56     70     **
    57     71     ** Nothing in this file or anywhere else in SQLite does any kind of
    58     72     ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
    59     73     ** number generator) not as an encryption device.
    60     74     */
    61         -  if( !sqlite3Prng.isInit ){
           75  +  if( !wsdPrng.isInit ){
    62     76       int i;
    63     77       char k[256];
    64         -    sqlite3Prng.j = 0;
    65         -    sqlite3Prng.i = 0;
           78  +    wsdPrng.j = 0;
           79  +    wsdPrng.i = 0;
    66     80       sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
    67     81       for(i=0; i<256; i++){
    68         -      sqlite3Prng.s[i] = i;
           82  +      wsdPrng.s[i] = i;
    69     83       }
    70     84       for(i=0; i<256; i++){
    71         -      sqlite3Prng.j += sqlite3Prng.s[i] + k[i];
    72         -      t = sqlite3Prng.s[sqlite3Prng.j];
    73         -      sqlite3Prng.s[sqlite3Prng.j] = sqlite3Prng.s[i];
    74         -      sqlite3Prng.s[i] = t;
           85  +      wsdPrng.j += wsdPrng.s[i] + k[i];
           86  +      t = wsdPrng.s[wsdPrng.j];
           87  +      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
           88  +      wsdPrng.s[i] = t;
    75     89       }
    76         -    sqlite3Prng.isInit = 1;
           90  +    wsdPrng.isInit = 1;
    77     91     }
    78     92   
    79     93     /* Generate and return single random byte
    80     94     */
    81         -  sqlite3Prng.i++;
    82         -  t = sqlite3Prng.s[sqlite3Prng.i];
    83         -  sqlite3Prng.j += t;
    84         -  sqlite3Prng.s[sqlite3Prng.i] = sqlite3Prng.s[sqlite3Prng.j];
    85         -  sqlite3Prng.s[sqlite3Prng.j] = t;
    86         -  t += sqlite3Prng.s[sqlite3Prng.i];
    87         -  return sqlite3Prng.s[t];
           95  +  wsdPrng.i++;
           96  +  t = wsdPrng.s[wsdPrng.i];
           97  +  wsdPrng.j += t;
           98  +  wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
           99  +  wsdPrng.s[wsdPrng.j] = t;
          100  +  t += wsdPrng.s[wsdPrng.i];
          101  +  return wsdPrng.s[t];
    88    102   }
    89    103   
    90    104   /*
    91    105   ** Return N random bytes.
    92    106   */
    93    107   void sqlite3_randomness(int N, void *pBuf){
    94    108     unsigned char *zBuf = pBuf;
................................................................................
   101    115     }
   102    116     sqlite3_mutex_leave(mutex);
   103    117   }
   104    118   
   105    119   #ifndef SQLITE_OMIT_BUILTIN_TEST
   106    120   /*
   107    121   ** For testing purposes, we sometimes want to preserve the state of
   108         -** PRNG and restore the PRNG to its saved state at a later time.
          122  +** PRNG and restore the PRNG to its saved state at a later time, or
          123  +** to reset the PRNG to its initial state.  These routines accomplish
          124  +** those tasks.
          125  +**
   109    126   ** The sqlite3_test_control() interface calls these routines to
   110    127   ** control the PRNG.
   111    128   */
   112         -static struct sqlite3PrngType sqlite3SavedPrng;
          129  +static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng = { 0, };
   113    130   void sqlite3PrngSaveState(void){
   114         -  memcpy(&sqlite3SavedPrng, &sqlite3Prng, sizeof(sqlite3Prng));
          131  +  memcpy(
          132  +    &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
          133  +    &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
          134  +    sizeof(sqlite3Prng)
          135  +  );
   115    136   }
   116    137   void sqlite3PrngRestoreState(void){
   117         -  memcpy(&sqlite3Prng, &sqlite3SavedPrng, sizeof(sqlite3Prng));
          138  +  memcpy(
          139  +    &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
          140  +    &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
          141  +    sizeof(sqlite3Prng)
          142  +  );
   118    143   }
   119    144   void sqlite3PrngResetState(void){
   120         -  sqlite3Prng.isInit = 0;
          145  +  GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
   121    146   }
   122    147   #endif /* SQLITE_OMIT_BUILTIN_TEST */

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.767 2008/09/01 21:59:43 shane Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.768 2008/09/02 00:52:52 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
   437    437   
   438    438   /*
   439    439   ** The following value as a destructor means to use sqlite3DbFree().
   440    440   ** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT.
   441    441   */
   442    442   #define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3DbFree)
   443    443   
          444  +/*
          445  +** When SQLITE_OMIT_WSD is defined, it means that the target platform does
          446  +** not support Writable Static Data (WSD) such as global and static variables.
          447  +** All variables must either be on the stack or dynamically allocated from
          448  +** the heap.  When WSD is unsupported, the variable declarations scattered
          449  +** throughout the SQLite code must become constants instead.  The SQLITE_WSD
          450  +** macro is used for this purpose.  And instead of referencing the variable
          451  +** directly, we use its constant as a key to lookup the run-time allocated
          452  +** buffer that holds real variable.  The constant is also the initializer
          453  +** for the run-time allocated buffer.
          454  +**
          455  +** In the usually case where WSD is supported, the SQLITE_WSD and GLOBAL
          456  +** macros become no-ops and have zero performance impact.
          457  +*/
   444    458   #ifdef SQLITE_OMIT_WSD
   445    459     #define SQLITE_WSD const
   446    460     #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
   447    461     #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
   448    462   #else
   449    463     #define SQLITE_WSD 
   450    464     #define GLOBAL(t,v) v

Changes to src/status.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This module implements the sqlite3_status() interface and related
    14     14   ** functionality.
    15     15   **
    16         -** $Id: status.c,v 1.8 2008/08/12 15:21:12 drh Exp $
           16  +** $Id: status.c,v 1.9 2008/09/02 00:52:52 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   
    20     20   /*
    21     21   ** Variables in which to record status information.
    22     22   */
    23         -static struct {
           23  +typedef struct sqlite3StatType sqlite3StatType;
           24  +static SQLITE_WSD struct sqlite3StatType {
    24     25     int nowValue[9];         /* Current value */
    25     26     int mxValue[9];          /* Maximum value */
    26         -} sqlite3Stat;
           27  +} sqlite3Stat = { {0,}, {0,} };
           28  +
    27     29   
           30  +/* The "wsdStat" macro will resolve to the status information
           31  +** state vector.  If writable static data is unsupported on the target,
           32  +** we have to locate the state vector at run-time.  In the more common
           33  +** case where writable static data is supported, wsdStat can refer directly
           34  +** to the "sqlite3Stat" state vector declared above.
           35  +*/
           36  +#ifdef SQLITE_OMIT_WSD
           37  +# define wsdStatInit  sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
           38  +# define wsdStat x[0]
           39  +#else
           40  +# define wsdStatInit
           41  +# define wsdStat sqlite3Stat
           42  +#endif
    28     43   
    29     44   /*
    30     45   ** Return the current value of a status parameter.
    31     46   */
    32     47   int sqlite3StatusValue(int op){
    33         -  assert( op>=0 && op<ArraySize(sqlite3Stat.nowValue) );
    34         -  return sqlite3Stat.nowValue[op];
           48  +  wsdStatInit;
           49  +  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
           50  +  return wsdStat.nowValue[op];
    35     51   }
    36     52   
    37     53   /*
    38     54   ** Add N to the value of a status record.  It is assumed that the
    39     55   ** caller holds appropriate locks.
    40     56   */
    41     57   void sqlite3StatusAdd(int op, int N){
    42         -  assert( op>=0 && op<ArraySize(sqlite3Stat.nowValue) );
    43         -  sqlite3Stat.nowValue[op] += N;
    44         -  if( sqlite3Stat.nowValue[op]>sqlite3Stat.mxValue[op] ){
    45         -    sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op];
           58  +  wsdStatInit;
           59  +  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
           60  +  wsdStat.nowValue[op] += N;
           61  +  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
           62  +    wsdStat.mxValue[op] = wsdStat.nowValue[op];
    46     63     }
    47     64   }
    48     65   
    49     66   /*
    50     67   ** Set the value of a status to X.
    51     68   */
    52     69   void sqlite3StatusSet(int op, int X){
    53         -  assert( op>=0 && op<ArraySize(sqlite3Stat.nowValue) );
    54         -  sqlite3Stat.nowValue[op] = X;
    55         -  if( sqlite3Stat.nowValue[op]>sqlite3Stat.mxValue[op] ){
    56         -    sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op];
           70  +  wsdStatInit;
           71  +  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
           72  +  wsdStat.nowValue[op] = X;
           73  +  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
           74  +    wsdStat.mxValue[op] = wsdStat.nowValue[op];
    57     75     }
    58     76   }
    59     77   
    60     78   /*
    61     79   ** Query status information.
    62     80   **
    63     81   ** This implementation assumes that reading or writing an aligned
    64     82   ** 32-bit integer is an atomic operation.  If that assumption is not true,
    65     83   ** then this routine is not threadsafe.
    66     84   */
    67     85   int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
    68         -  if( op<0 || op>=ArraySize(sqlite3Stat.nowValue) ){
           86  +  wsdStatInit;
           87  +  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
    69     88       return SQLITE_MISUSE;
    70     89     }
    71         -  *pCurrent = sqlite3Stat.nowValue[op];
    72         -  *pHighwater = sqlite3Stat.mxValue[op];
           90  +  *pCurrent = wsdStat.nowValue[op];
           91  +  *pHighwater = wsdStat.mxValue[op];
    73     92     if( resetFlag ){
    74         -    sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op];
           93  +    wsdStat.mxValue[op] = wsdStat.nowValue[op];
    75     94     }
    76     95     return SQLITE_OK;
    77     96   }
    78     97   
    79     98   /*
    80     99   ** Query status information for a single database connection
    81    100   */

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.322 2008/08/30 13:25:11 danielk1977 Exp $
           16  +** $Id: test1.c,v 1.323 2008/09/02 00:52:52 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
    22     22   
    23     23   /*
................................................................................
  1383   1383     int ret = 0;
  1384   1384     extern int sqlite3SharedCacheEnabled;
  1385   1385   
  1386   1386     if( objc!=2 && objc!=1 ){
  1387   1387       Tcl_WrongNumArgs(interp, 1, objv, "?BOOLEAN?");
  1388   1388       return TCL_ERROR;
  1389   1389     }
  1390         -  ret = sqlite3SharedCacheEnabled;
         1390  +  ret = GLOBAL(int, sqlite3SharedCacheEnabled);
  1391   1391   
  1392   1392     if( objc==2 ){
  1393   1393       if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
  1394   1394         return TCL_ERROR;
  1395   1395       }
  1396   1396       rc = sqlite3_enable_shared_cache(enable);
  1397   1397       if( rc!=SQLITE_OK ){

Changes to src/test_btree.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test_btree.c,v 1.6 2008/07/15 00:27:35 drh Exp $
           16  +** $Id: test_btree.c,v 1.7 2008/09/02 00:52:52 drh Exp $
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   #include <tcl.h>
    20     20   
    21     21   /*
    22     22   ** Usage: sqlite3_shared_cache_report
    23     23   **
................................................................................
    30     30     int objc,
    31     31     Tcl_Obj *CONST objv[]
    32     32   ){
    33     33   #ifndef SQLITE_OMIT_SHARED_CACHE
    34     34     extern BtShared *sqlite3SharedCacheList;
    35     35     BtShared *pBt;
    36     36     Tcl_Obj *pRet = Tcl_NewObj();
    37         -  for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
           37  +  for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
    38     38       const char *zFile = sqlite3PagerFilename(pBt->pPager);
    39     39       Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
    40     40       Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
    41     41     }
    42     42     Tcl_SetObjResult(interp, pRet);
    43     43   #endif
    44     44     return TCL_OK;

Changes to src/test_config.c.

    12     12   ** 
    13     13   ** This file contains code used for testing the SQLite system.
    14     14   ** None of the code in this file goes into a deliverable build.
    15     15   ** 
    16     16   ** The focus of this file is providing the TCL testing layer
    17     17   ** access to compile-time constants.
    18     18   **
    19         -** $Id: test_config.c,v 1.33 2008/07/31 02:05:05 shane Exp $
           19  +** $Id: test_config.c,v 1.34 2008/09/02 00:52:52 drh Exp $
    20     20   */
    21     21   
    22     22   #include "sqliteLimit.h"
    23     23   
    24     24   #include "sqliteInt.h"
    25     25   #include "tcl.h"
    26     26   #include <stdlib.h>
................................................................................
   432    432   #endif
   433    433   
   434    434   #ifdef SQLITE_OMIT_VIRTUALTABLE
   435    435     Tcl_SetVar2(interp, "sqlite_options", "vtab", "0", TCL_GLOBAL_ONLY);
   436    436   #else
   437    437     Tcl_SetVar2(interp, "sqlite_options", "vtab", "1", TCL_GLOBAL_ONLY);
   438    438   #endif
          439  +
          440  +#ifdef SQLITE_OMIT_WSD
          441  +  Tcl_SetVar2(interp, "sqlite_options", "wsd", "0", TCL_GLOBAL_ONLY);
          442  +#else
          443  +  Tcl_SetVar2(interp, "sqlite_options", "wsd", "1", TCL_GLOBAL_ONLY);
          444  +#endif
   439    445   
   440    446   #ifdef SQLITE_SECURE_DELETE
   441    447     Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "1", TCL_GLOBAL_ONLY);
   442    448   #else
   443    449     Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY);
   444    450   #endif
   445    451   

Changes to test/pragma.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests for the PRAGMA command.
    14     14   #
    15         -# $Id: pragma.test,v 1.65 2008/08/20 16:34:24 danielk1977 Exp $
           15  +# $Id: pragma.test,v 1.66 2008/09/02 00:52:52 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Test organization:
    21     21   #
    22     22   # pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
................................................................................
   921    921   }
   922    922   
   923    923   do_test pragma-9.4 {
   924    924     execsql {
   925    925       PRAGMA temp_store_directory;
   926    926     }
   927    927   } {}
   928         -do_test pragma-9.5 {
   929         -  set pwd [string map {' ''} [pwd]]
   930         -  execsql "
   931         -    PRAGMA temp_store_directory='$pwd';
   932         -  "
   933         -} {}
   934         -do_test pragma-9.6 {
   935         -  execsql { 
   936         -    PRAGMA temp_store_directory;
   937         -  }
   938         -} [list [pwd]]
   939         -do_test pragma-9.7 {
   940         -  catchsql { 
   941         -    PRAGMA temp_store_directory='/NON/EXISTENT/PATH/FOOBAR';
   942         -  }
   943         -} {1 {not a writable directory}}
   944         -do_test pragma-9.8 {
   945         -  execsql { 
   946         -    PRAGMA temp_store_directory='';
   947         -  }
   948         -} {}
   949         -if {![info exists TEMP_STORE] || $TEMP_STORE<=1} {
   950         -  ifcapable tempdb {
   951         -    do_test pragma-9.9 {
   952         -      execsql { 
   953         -        PRAGMA temp_store_directory;
   954         -        PRAGMA temp_store=FILE;
   955         -        CREATE TEMP TABLE temp_store_directory_test(a integer);
   956         -        INSERT INTO temp_store_directory_test values (2);
   957         -        SELECT * FROM temp_store_directory_test;
   958         -      }
   959         -    } {2}
   960         -    do_test pragma-9.10 {
   961         -      catchsql "
   962         -        PRAGMA temp_store_directory='$pwd';
   963         -        SELECT * FROM temp_store_directory_test;
   964         -      "
   965         -    } {1 {no such table: temp_store_directory_test}}
   966         -  }
   967         -}  
          928  +ifcapable wsd {
          929  +  do_test pragma-9.5 {
          930  +    set pwd [string map {' ''} [pwd]]
          931  +    execsql "
          932  +      PRAGMA temp_store_directory='$pwd';
          933  +    "
          934  +  } {}
          935  +  do_test pragma-9.6 {
          936  +    execsql { 
          937  +      PRAGMA temp_store_directory;
          938  +    }
          939  +  } [list [pwd]]
          940  +  do_test pragma-9.7 {
          941  +    catchsql { 
          942  +      PRAGMA temp_store_directory='/NON/EXISTENT/PATH/FOOBAR';
          943  +    }
          944  +  } {1 {not a writable directory}}
          945  +  do_test pragma-9.8 {
          946  +    execsql { 
          947  +      PRAGMA temp_store_directory='';
          948  +    }
          949  +  } {}
          950  +  if {![info exists TEMP_STORE] || $TEMP_STORE<=1} {
          951  +    ifcapable tempdb {
          952  +      do_test pragma-9.9 {
          953  +        execsql { 
          954  +          PRAGMA temp_store_directory;
          955  +          PRAGMA temp_store=FILE;
          956  +          CREATE TEMP TABLE temp_store_directory_test(a integer);
          957  +          INSERT INTO temp_store_directory_test values (2);
          958  +          SELECT * FROM temp_store_directory_test;
          959  +        }
          960  +      } {2}
          961  +      do_test pragma-9.10 {
          962  +        catchsql "
          963  +          PRAGMA temp_store_directory='$pwd';
          964  +          SELECT * FROM temp_store_directory_test;
          965  +        "
          966  +      } {1 {no such table: temp_store_directory_test}}
          967  +    }
          968  +  }
          969  +}
   968    970   do_test pragma-9.11 {
   969    971     execsql {
   970    972       PRAGMA temp_store = 0;
   971    973       PRAGMA temp_store;
   972    974     }
   973    975   } {0}
   974    976   do_test pragma-9.12 {