/ Check-in [c4be8d99]
Login

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

Overview
Comment:Modifications to crash-test infrastructure. (CVS 3695)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c4be8d9949fc7b5e1bed757423c5195f38069048
User & Date: danielk1977 2007-03-17 10:26:59
Context
2007-03-17
10:28
Add crash2.test, for robustness testing with variable disk block size. (CVS 3696) check-in: b0f8203d user: danielk1977 tags: trunk
10:26
Modifications to crash-test infrastructure. (CVS 3695) check-in: c4be8d99 user: danielk1977 tags: trunk
07:22
Combine the two very similar definitions of (crashsql) in the test scripts. (CVS 3694) check-in: eaf434d5 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.414 2007/03/13 16:32:25 danielk1977 Exp $
           25  +** $Id: build.c,v 1.415 2007/03/17 10:26:59 danielk1977 Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.

Changes to src/test6.c.

    34     34     int nMaxWrite;           /* Largest offset written to. */
    35     35     char *zName;             /* File name */
    36     36     OsFile *pBase;           /* The real file */
    37     37     crashFile *pNext;        /* Next in a list of them all */
    38     38   };
    39     39   
    40     40   /*
    41         -** Size of a simulated disk block
           41  +** Size of a simulated disk block. Default is 512 bytes.
    42     42   */
    43         -#define BLOCKSIZE 512
           43  +static int BLOCKSIZE = 512;
    44     44   #define BLOCK_OFFSET(x) ((x) * BLOCKSIZE)
    45     45   
    46     46   
    47     47   /*
    48     48   ** The following variables control when a simulated crash occurs.
    49     49   **
    50     50   ** If iCrashDelay is non-zero, then zCrashFile contains (full path) name of
................................................................................
    54     54   **
    55     55   ** In other words, a crash occurs the iCrashDelay'th time zCrashFile is
    56     56   ** synced.
    57     57   */
    58     58   static int iCrashDelay = 0;
    59     59   static char zCrashFile[500];
    60     60   
           61  +/*
           62  +** A list of all open files.
           63  +*/
           64  +static crashFile *pAllFiles = 0;
           65  +
    61     66   /*
    62     67   ** Set the value of the two crash parameters.
    63     68   */
    64     69   static void setCrashParams(int iDelay, char const *zFile){
    65     70     sqlite3OsEnterMutex();
    66     71     assert( strlen(zFile)<sizeof(zCrashFile) );
    67     72     strcpy(zCrashFile, zFile);
    68     73     iCrashDelay = iDelay;
    69     74     sqlite3OsLeaveMutex();
    70     75   }
           76  +
           77  +/*
           78  +** Set the value of the simulated disk block size.
           79  +*/
           80  +static void setBlocksize(int iBlockSize){
           81  +  sqlite3OsEnterMutex();
           82  +  assert( !pAllFiles );
           83  +  BLOCKSIZE = iBlockSize;
           84  +  sqlite3OsLeaveMutex();
           85  +}
    71     86   
    72     87   /*
    73     88   ** File zPath is being sync()ed. Return non-zero if this should
    74     89   ** cause a crash.
    75     90   */
    76     91   static int crashRequired(char const *zPath){
    77     92     int r;
................................................................................
    90    105         r = 1;
    91    106       }
    92    107     }
    93    108     sqlite3OsLeaveMutex();
    94    109     return r;
    95    110   }
    96    111   
    97         -/*
    98         -** A list of all open files.
    99         -*/
   100         -static crashFile *pAllFiles = 0;
   101         -
   102    112   /* Forward reference */
   103    113   static void initFile(OsFile **pId, char const *zName, OsFile *pBase);
   104    114   
   105    115   /*
   106    116   ** Undo the work done by initFile. Delete the OsFile structure
   107    117   ** and unlink the structure from the pAllFiles list.
   108    118   */
................................................................................
   506    516     pFile->pNext = pAllFiles;
   507    517     pAllFiles = pFile;
   508    518     *pId = (OsFile*)pFile;
   509    519   }
   510    520   
   511    521   
   512    522   /*
   513         -** tclcmd:   sqlite_crashparams DELAY CRASHFILE
          523  +** tclcmd:   sqlite_crashparams DELAY CRASHFILE ?BLOCKSIZE?
   514    524   **
   515    525   ** This procedure implements a TCL command that enables crash testing
   516    526   ** in testfixture.  Once enabled, crash testing cannot be disabled.
   517    527   */
   518    528   static int crashParamsObjCmd(
   519    529     void * clientData,
   520    530     Tcl_Interp *interp,
   521    531     int objc,
   522    532     Tcl_Obj *CONST objv[]
   523    533   ){
   524         -  int delay;
          534  +  int iDelay;
   525    535     const char *zFile;
   526    536     int nFile;
   527         -  if( objc!=3 ){
   528         -    Tcl_WrongNumArgs(interp, 1, objv, "DELAY CRASHFILE");
          537  +
          538  +  if( objc!=3 && objc!=4 ){
          539  +    Tcl_WrongNumArgs(interp, 1, objv, "DELAY CRASHFILE ?BLOCKSIZE?");
   529    540       return TCL_ERROR;
   530    541     }
   531         -  if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR;
          542  +  if( Tcl_GetIntFromObj(interp, objv[1], &iDelay) ) return TCL_ERROR;
   532    543     zFile = Tcl_GetStringFromObj(objv[2], &nFile);
   533    544     if( nFile>=sizeof(zCrashFile)-1 ){
   534    545       Tcl_AppendResult(interp, "crash file name too big", 0);
   535    546       return TCL_ERROR;
   536    547     }
   537         -  setCrashParams(delay, zFile);
          548  +  setCrashParams(iDelay, zFile);
          549  +  if( objc==4 ){
          550  +    int iBlockSize = 0;
          551  +    if( Tcl_GetIntFromObj(interp, objv[3], &iBlockSize) ) return TCL_ERROR;
          552  +    if( pAllFiles ){
          553  +      char *zErr = "Cannot modify blocksize after opening files";
          554  +      Tcl_SetResult(interp, zErr, TCL_STATIC);
          555  +      return TCL_ERROR;
          556  +    }
          557  +    setBlocksize(iBlockSize);
          558  +  }
   538    559     sqlite3CrashTestEnable = 1;
   539    560     return TCL_OK;
   540    561   }
   541    562   
   542    563   #endif /* SQLITE_OMIT_DISKIO */
   543    564   
   544    565   /*

Changes to test/all.test.

     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file runs all tests.
    12     12   #
    13         -# $Id: all.test,v 1.36 2006/11/23 21:09:11 drh Exp $
           13  +# $Id: all.test,v 1.37 2007/03/17 10:26:59 danielk1977 Exp $
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   rename finish_test really_finish_test
    18     18   proc finish_test {} {memleak_check}
    19     19   
    20     20   if {[file exists ./sqlite_test_count]} {
................................................................................
    47     47   #
    48     48   set LeakList {}
    49     49   
    50     50   set EXCLUDE {
    51     51     all.test
    52     52     async.test
    53     53     crash.test
           54  +  crash2.test
    54     55     autovacuum_crash.test
    55     56     quick.test
    56     57     malloc.test
    57     58     misuse.test
    58     59     memleak.test
    59     60     speed1.test
    60     61   }

Changes to test/crash.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # The focus of this file is testing the ability of the database to
    14     14   # uses its rollback journal to recover intact (no database corruption)
    15     15   # from a power failure during the middle of a COMMIT.  The OS interface
    16         -# modules are overloaded in a separate instance of testfixture using
    17         -# the modified I/O routines found in test6.c.  These routines allow us
    18         -# to simulate the kind of file damage that occurs after a power failure.
           16  +# modules are overloaded using the modified I/O routines found in test6.c.  
           17  +# These routines allow us to simulate the kind of file damage that 
           18  +# occurs after a power failure.
    19     19   #
    20         -# $Id: crash.test,v 1.22 2007/03/17 07:22:43 danielk1977 Exp $
           20  +# $Id: crash.test,v 1.23 2007/03/17 10:26:59 danielk1977 Exp $
    21     21   
    22     22   set testdir [file dirname $argv0]
    23     23   source $testdir/tester.tcl
    24     24   
    25     25   ifcapable !crashtest {
    26     26     finish_test
    27     27     return
................................................................................
    64     64       INSERT INTO abc VALUES(1, 2, 3);
    65     65       INSERT INTO abc VALUES(4, 5, 6);
    66     66     }
    67     67     set ::sig [signature]
    68     68     expr 0
    69     69   } {0}
    70     70   do_test crash-1.2 {
    71         -  crashsql 1 test.db-journal {
           71  +  crashsql -delay 1 -file test.db-journal {
    72     72       DELETE FROM abc WHERE a = 1;
    73     73     }
    74     74   } {1 {child process exited abnormally}}
    75     75   do_test crash-1.3 {
    76     76     signature
    77     77   } $::sig
    78     78   do_test crash-1.4 {
    79         -  crashsql 1 test.db {
           79  +  crashsql -delay 1 -file test.db {
    80     80       DELETE FROM abc WHERE a = 1;
    81     81     }
    82     82   } {1 {child process exited abnormally}}
    83     83   do_test crash-1.5 {
    84     84     signature
    85     85   } $::sig
    86     86   do_test crash-1.6 {
    87         -  crashsql 2 test.db-journal {
           87  +  crashsql -delay 2 -file test.db-journal {
    88     88       DELETE FROM abc WHERE a = 1;
    89     89     }
    90     90   } {1 {child process exited abnormally}}
    91     91   do_test crash-1.7 {
    92     92     catchsql {
    93     93       SELECT * FROM abc;
    94     94     }
    95     95   } {0 {1 2 3 4 5 6}}
    96     96   
    97     97   do_test crash-1.8 {
    98         -  crashsql 3 test.db-journal {
           98  +  crashsql -delay 3 -file test.db-journal {
    99     99       DELETE FROM abc WHERE a = 1;
   100    100     }
   101    101   } {0 {}}
   102    102   do_test crash-1.9 {
   103    103     catchsql {
   104    104       SELECT * FROM abc;
   105    105     }
   106    106   } {0 {4 5 6}}
   107    107   do_test crash-1.10 {
   108         -  crashsql 2 test.db {
          108  +  crashsql -delay 2 -file test.db {
   109    109       DELETE FROM abc WHERE a = 4;
   110    110     }
   111    111   } {0 {}}
   112    112   do_test crash-1.11 {
   113    113     catchsql {
   114    114       SELECT * FROM abc;
   115    115     }
................................................................................
   139    139     set ::sig [signature]
   140    140     execsql { SELECT sum(a), sum(b), sum(c) from abc }
   141    141   } {499500 999000 1498500}
   142    142   do_test crash-2.2 {
   143    143     expr ([file size test.db] / 1024)>16
   144    144   } {1}
   145    145   do_test crash-2.3 {
   146         -  crashsql 2 test.db-journal {
          146  +  crashsql -delay 2 -file test.db-journal {
   147    147       DELETE FROM abc WHERE a < 800;
   148    148     }
   149    149   } {1 {child process exited abnormally}}
   150    150   do_test crash-2.4 {
   151    151     signature
   152    152   } $sig
   153    153   do_test crash-2.5 {
   154         -  crashsql 1 test.db {
          154  +  crashsql -delay 1 -file test.db {
   155    155       DELETE FROM abc WHERE a<800;
   156    156     }
   157    157   } {1 {child process exited abnormally}}
   158    158   do_test crash-2.6 {
   159    159     signature
   160    160   } $sig
   161    161   
................................................................................
   181    181       INSERT INTO abc SELECT * FROM abc;
   182    182     }
   183    183     expr ([file size test.db] / 1024) > 450
   184    184   } {1}
   185    185   for {set i 1} {$i < $repeats} {incr i} {
   186    186     set sig [signature]
   187    187     do_test crash-3.$i.1 {
   188         -     crashsql [expr $i%5 + 1] test.db-journal "
          188  +     crashsql -delay [expr $i%5 + 1] -file test.db-journal "
   189    189          BEGIN;
   190    190          SELECT random() FROM abc LIMIT $i;
   191    191          INSERT INTO abc VALUES(randstr(10,10), 0, 0);
   192    192          DELETE FROM abc WHERE random()%10!=0;
   193    193          COMMIT;
   194    194        "
   195    195     } {1 {child process exited abnormally}}
................................................................................
   220    220     expr ([file size test2.db] / 1024) > 450
   221    221   } {1}
   222    222   
   223    223   for {set i 1} {$i<$repeats} {incr i} {
   224    224     set sig [signature]
   225    225     set sig2 [signature2]
   226    226     do_test crash-4.1.$i.1 {
   227         -     set c [crashsql $i test.db-journal "
          227  +     set c [crashsql -delay $i -file test.db-journal "
   228    228          ATTACH 'test2.db' AS aux;
   229    229          BEGIN;
   230    230          SELECT random() FROM abc LIMIT $i;
   231    231          INSERT INTO abc VALUES(randstr(10,10), 0, 0);
   232    232          DELETE FROM abc WHERE random()%10!=0;
   233    233          INSERT INTO abc2 VALUES(randstr(10,10), 0, 0);
   234    234          DELETE FROM abc2 WHERE random()%10!=0;
................................................................................
   245    245   } 
   246    246   set i 0
   247    247   while {[incr i]} {
   248    248     set sig [signature]
   249    249     set sig2 [signature2]
   250    250     set ::fin 0
   251    251     do_test crash-4.2.$i.1 {
   252         -     set c [crashsql $i test2.db-journal "
          252  +     set c [crashsql -delay $i -file test2.db-journal "
   253    253          ATTACH 'test2.db' AS aux;
   254    254          BEGIN;
   255    255          SELECT random() FROM abc LIMIT $i;
   256    256          INSERT INTO abc VALUES(randstr(10,10), 0, 0);
   257    257          DELETE FROM abc WHERE random()%10!=0;
   258    258          INSERT INTO abc2 VALUES(randstr(10,10), 0, 0);
   259    259          DELETE FROM abc2 WHERE random()%10!=0;
................................................................................
   273    273       signature2
   274    274     } $sig2
   275    275   } 
   276    276   for {set i 1} {$i < 5} {incr i} {
   277    277     set sig [signature]
   278    278     set sig2 [signature2]
   279    279     do_test crash-4.3.$i.1 {
   280         -     crashsql 1 test.db-mj* "
          280  +     crashsql -delay 1 -file test.db-mj* "
   281    281          ATTACH 'test2.db' AS aux;
   282    282          BEGIN;
   283    283          SELECT random() FROM abc LIMIT $i;
   284    284          INSERT INTO abc VALUES(randstr(10,10), 0, 0);
   285    285          DELETE FROM abc WHERE random()%10!=0;
   286    286          INSERT INTO abc2 VALUES(randstr(10,10), 0, 0);
   287    287          DELETE FROM abc2 WHERE random()%10!=0;
................................................................................
   336    336   #    is sync()hronized.
   337    337   # 6: Commit. A crash occurs during the sync of the journal file.
   338    338   #
   339    339   # End result: Before the bug was fixed, data has been written to page 4 of the
   340    340   # database file and the journal file does not contain trustworthy rollback
   341    341   # data for this page.
   342    342   #
   343         -  crashsql 1 test.db-journal {
          343  +  crashsql -delay 1 -file test.db-journal {
   344    344       BEGIN;                                             -- 1
   345    345       DELETE FROM abc WHERE oid = 1;                     -- 2
   346    346       INSERT INTO abc VALUES(randstr(1500,1500), 0, 0);  -- 3
   347    347       CREATE TABLE abc2(a, b, c);                        -- 4
   348    348       SELECT * FROM abc;                                 -- 5
   349    349       COMMIT;                                            -- 6
   350    350     }
................................................................................
   357    357   #--------------------------------------------------------------------------
   358    358   # The following test cases - crash-6.* - test that a DROP TABLE operation
   359    359   # is correctly rolled back in the event of a crash while the database file
   360    360   # is being written. This is mainly to test that all pages are written to the
   361    361   # journal file before truncation in an auto-vacuum database.
   362    362   #
   363    363   do_test crash-6.1 {
   364         -  crashsql 1 test.db {
          364  +  crashsql -delay 1 -file test.db {
   365    365       DROP TABLE abc;
   366    366     }
   367    367   } {1 {child process exited abnormally}}
   368    368   do_test crash-6.2 {
   369    369     signature
   370    370   } $sig
   371    371   
   372    372   #--------------------------------------------------------------------------
   373    373   # These test cases test the case where the master journal file name is 
   374    374   # corrupted slightly so that the corruption has to be detected by the
   375    375   # checksum.
   376    376   do_test crash-7.1 {
   377         -  crashsql 1 test.db {
          377  +  crashsql -delay 1 -file test.db {
   378    378       ATTACH 'test2.db' AS aux;
   379    379       BEGIN;
   380    380       INSERT INTO abc VALUES(randstr(1500,1500), 0, 0);
   381    381       INSERT INTO abc2 VALUES(randstr(1500,1500), 0, 0);
   382    382       COMMIT;
   383    383     }
   384    384   

Changes to test/ioerr.test.

    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing for correct handling of I/O errors
    13     13   # such as writes failing because the disk is full.
    14     14   # 
    15     15   # The tests in this file use special facilities that are only
    16     16   # available in the SQLite test fixture.
    17     17   #
    18         -# $Id: ioerr.test,v 1.30 2007/03/15 12:17:43 drh Exp $
           18  +# $Id: ioerr.test,v 1.31 2007/03/17 10:26:59 danielk1977 Exp $
    19     19   
    20     20   set testdir [file dirname $argv0]
    21     21   source $testdir/tester.tcl
    22     22   
    23     23   
    24     24   # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error
    25     25   # on the 8th IO operation in the SQL script below doesn't report an error.
................................................................................
   137    137     if {![catch {sqlite3 -has_codec} r] && !$r} {
   138    138       do_ioerr_test ioerr-6 -tclprep {
   139    139         execsql {
   140    140           ATTACH 'test2.db' as aux;
   141    141           CREATE TABLE tx(a, b);
   142    142           CREATE TABLE aux.ty(a, b);
   143    143         }
   144         -      set rc [crashsql 2 test2.db-journal {
          144  +      set rc [crashsql -delay 2 -file test2.db-journal {
   145    145           ATTACH 'test2.db' as aux;
   146    146           PRAGMA cache_size = 10;
   147    147           BEGIN;
   148    148           CREATE TABLE aux.t2(a, b, c);
   149    149           CREATE TABLE t1(a, b, c);
   150    150           COMMIT;
   151    151         }]

Changes to test/malloc.test.

    10     10   #***********************************************************************
    11     11   # This file attempts to check the library in an out-of-memory situation.
    12     12   # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
    13     13   # command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
    14     14   # special feature is used to see what happens in the library if a malloc
    15     15   # were to really fail due to an out-of-memory situation.
    16     16   #
    17         -# $Id: malloc.test,v 1.36 2006/10/18 23:26:39 drh Exp $
           17  +# $Id: malloc.test,v 1.37 2007/03/17 10:26:59 danielk1977 Exp $
    18     18   
    19     19   set testdir [file dirname $argv0]
    20     20   source $testdir/tester.tcl
    21     21   
    22     22   # Only run these tests if memory debugging is turned on.
    23     23   #
    24     24   if {[info command sqlite_malloc_stat]==""} {
................................................................................
   355    355     sqlite3_finalize $::STMT
   356    356   } 
   357    357   
   358    358   # Test malloc errors when replaying two hot journals from a 2-file 
   359    359   # transaction.
   360    360   ifcapable crashtest {
   361    361     do_malloc_test 13 -tclprep {
   362         -    set rc [crashsql 1 test2.db {
          362  +    set rc [crashsql -delay 1 -file test2.db {
   363    363         ATTACH 'test2.db' as aux;
   364    364         PRAGMA cache_size = 10;
   365    365         BEGIN;
   366    366         CREATE TABLE aux.t2(a, b, c);
   367    367         CREATE TABLE t1(a, b, c);
   368    368         COMMIT;
   369    369       }]

Changes to test/quick.test.

     2      2   #    May you do good and not evil.
     3      3   #    May you find forgiveness for yourself and forgive others.
     4      4   #    May you share freely, never taking more than you give.
     5      5   #
     6      6   #***********************************************************************
     7      7   # This file runs all tests.
     8      8   #
     9         -# $Id: quick.test,v 1.47 2006/11/23 21:09:11 drh Exp $
            9  +# $Id: quick.test,v 1.48 2007/03/17 10:26:59 danielk1977 Exp $
    10     10   
    11     11   proc lshift {lvar} {
    12     12     upvar $lvar l
    13     13     set ret [lindex $l 0]
    14     14     set l [lrange $l 1 end]
    15     15     return $ret
    16     16   }
................................................................................
    39     39     btree2.test
    40     40     btree3.test
    41     41     btree4.test
    42     42     btree5.test
    43     43     btree6.test
    44     44     corrupt.test
    45     45     crash.test
           46  +  crash2.test
    46     47     loadext.test
    47     48     malloc.test
    48     49     malloc2.test
    49     50     malloc3.test
    50     51     memleak.test
    51     52     misuse.test
    52     53     quick.test

Changes to test/tester.tcl.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements some common TCL routines used for regression
    12     12   # testing the SQLite library
    13     13   #
    14         -# $Id: tester.tcl,v 1.74 2007/03/17 07:22:43 danielk1977 Exp $
           14  +# $Id: tester.tcl,v 1.75 2007/03/17 10:26:59 danielk1977 Exp $
    15     15   
    16     16   # Make sure tclsqlite3 was compiled correctly.  Abort now with an
    17     17   # error message if not.
    18     18   #
    19     19   if {[sqlite3 -tcl-uses-utf]} {
    20     20     if {"\u1234"=="u1234"} {
    21     21       puts stderr "***** BUILD PROBLEM *****"
................................................................................
   305    305   #
   306    306   # The return value is a list of two elements. The first element is a
   307    307   # boolean, indicating whether or not the process actually crashed or
   308    308   # reported some other error. The second element in the returned list is the
   309    309   # error message. This is "child process exited abnormally" if the crash
   310    310   # occured.
   311    311   #
   312         -proc crashsql {crashdelay crashfile sql} {
          312  +#   crashsql -delay CRASHDELAY -file CRASHFILE ?-blocksize BLOCKSIZE $sql
          313  +#
          314  +proc crashsql {args} {
   313    315     if {$::tcl_platform(platform)!="unix"} {
   314    316       error "crashsql should only be used on unix"
   315    317     }
          318  +
          319  +  set blocksize ""
          320  +  set crashdelay 1
          321  +  set crashfile ""
          322  +  set sql [lindex $args end]
          323  +  
          324  +  for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
          325  +    set z [lindex $args $ii]
          326  +    set n [string length $z]
          327  +    set z2 [lindex $args [expr $ii+1]]
          328  +
          329  +    if     {$n>1 && [string first $z -delay]==0}     {set crashdelay $z2} \
          330  +    elseif {$n>1 && [string first $z -file]==0}      {set crashfile $z2}  \
          331  +    elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize $z2}  \
          332  +    else   { error "Unrecognized option: $z" }
          333  +  }
          334  +
          335  +  if {$crashfile eq ""} {
          336  +    error "Compulsory option -file missing"
          337  +  }
          338  +
   316    339     set cfile [file join [pwd] $crashfile]
   317    340   
   318    341     set f [open crash.tcl w]
   319         -  puts $f "sqlite3_crashparams $crashdelay $cfile"
          342  +  puts $f "sqlite3_crashparams $crashdelay $cfile $blocksize"
   320    343     puts $f "set sqlite_pending_byte $::sqlite_pending_byte"
   321    344     puts $f "sqlite3 db test.db"
   322    345   
   323    346     # This block sets the cache size of the main database to 10
   324    347     # pages. This is done in case the build is configured to omit
   325    348     # "PRAGMA cache_size".
   326    349     puts $f {db eval {SELECT * FROM sqlite_master;}}

Changes to www/capi3ref.tcl.

     1         -set rcsid {$Id: capi3ref.tcl,v 1.52 2007/02/20 15:21:05 drh Exp $}
            1  +set rcsid {$Id: capi3ref.tcl,v 1.53 2007/03/17 10:26:59 danielk1977 Exp $}
     2      2   source common.tcl
     3      3   header {C/C++ Interface For SQLite Version 3}
     4      4   puts {
     5         -<h2>C/C++ Interface For SQLite Version 3</h2>
            5  +<h2 class=pdf_section>C/C++ Interface For SQLite Version 3</h2>
     6      6   }
     7      7   
     8      8   proc api {name prototype desc {notused x}} {
     9      9     global apilist specialname
    10     10     if {$name==""} {
    11     11       regsub -all {sqlite3_[a-z0-9_]+\(} $prototype \
    12     12         {[lappend name [string trimright & (]]} x1
................................................................................
  1718   1718     incr i
  1719   1719   }
  1720   1720   #parray n_to_name
  1721   1721   #parray n_to_idx
  1722   1722   #parray name_to_idx
  1723   1723   #parray sname
  1724   1724   incr n -1
         1725  +puts "<DIV class=pdf_ignore>"
  1725   1726   puts {<table width="100%" cellpadding="5"><tr>}
  1726   1727   set nrow [expr {($n+2)/3}]
  1727   1728   set i 0
  1728   1729   for {set j 0} {$j<3} {incr j} {
  1729   1730     if {$j>0} {puts {<td width="10"></td>}}
  1730   1731     puts {<td valign="top">}
  1731   1732     set limit [expr {$i+$nrow}]
................................................................................
  1736   1737       puts "<li><a href=\"#$name\">$display</a></li>"
  1737   1738       incr i
  1738   1739     }
  1739   1740     puts {</ul></td>}
  1740   1741   }
  1741   1742   puts "</table>"
  1742   1743   puts "<!-- $n entries.  $nrow rows in 3 columns -->"
         1744  +puts "</DIV>"
  1743   1745   
  1744   1746   proc resolve_name {ignore_list name} {
  1745   1747     global name_to_idx
  1746   1748     if {![info exists name_to_idx($name)] || [lsearch $ignore_list $name]>=0} {
  1747   1749       return $name
  1748   1750     } else {
  1749   1751       return "<a href=\"#$name\">$name</a>"
................................................................................
  1752   1754   
  1753   1755   foreach name [lsort [array names name_to_idx]] {
  1754   1756     set i $name_to_idx($name)
  1755   1757     if {[info exists done($i)]} continue
  1756   1758     set done($i) 1
  1757   1759     foreach {namelist prototype desc} [lindex $apilist $i] break
  1758   1760     foreach name $namelist {
  1759         -    puts "<a name=\"$name\">"
         1761  +    puts "<a name=\"$name\"></a>"
  1760   1762     }
  1761   1763     puts "<p><hr></p>"
  1762   1764     puts "<blockquote><pre>"
  1763   1765     regsub "^( *\n)+" $prototype {} p2
  1764   1766     regsub "(\n *)+\$" $p2 {} p3
  1765   1767     puts $p3
  1766   1768     puts "</pre></blockquote>"
................................................................................
  1769   1771     foreach x $specialname {
  1770   1772       regsub -all $x $d2 "\[resolve_name $name &\]" d2
  1771   1773     }
  1772   1774     regsub -all "\n( *\n)+" [subst $d2] "</p>\n\n<p>" d3
  1773   1775     puts "<p>$d3</p>"
  1774   1776   }
  1775   1777   
         1778  +puts "<DIV class=pdf_ignore>"
  1776   1779   footer $rcsid
         1780  +puts "</DIV>"