/ Check-in [95b7687f]
Login

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

Overview
Comment:Move some test logic out of tclsqlite.c and into auxiliary test_*.c files. This is a work in progress.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tclsqlite-cleanup
Files: files | file ages | folders
SHA3-256: 95b7687fed75b32a62a0c62d397f4f543bf40095e13c22e15938d5dcfd71fcdf
User & Date: drh 2017-10-13 15:06:06
Context
2017-10-13
15:56
When compiling with SQLITE_TEST, extra options are available on the "DB version" command for controlling the internal state of the SqliteDb object, for testing purposes. check-in: bf86478d user: drh tags: tclsqlite-cleanup
15:06
Move some test logic out of tclsqlite.c and into auxiliary test_*.c files. This is a work in progress. check-in: 95b7687f user: drh tags: tclsqlite-cleanup
2017-10-12
20:37
Add the sqlite_dbpage virtual table (enabled using SQLITE_ENABLE_DBPAGE_VTAB). Make that virtual table and dbstat available to the command-line shell. check-in: eaeeb09d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   392    392     $(TOP)/src/test_fs.c \
   393    393     $(TOP)/src/test_func.c \
   394    394     $(TOP)/src/test_hexio.c \
   395    395     $(TOP)/src/test_init.c \
   396    396     $(TOP)/src/test_intarray.c \
   397    397     $(TOP)/src/test_journal.c \
   398    398     $(TOP)/src/test_malloc.c \
          399  +  $(TOP)/src/test_md5.c \
   399    400     $(TOP)/src/test_multiplex.c \
   400    401     $(TOP)/src/test_mutex.c \
   401    402     $(TOP)/src/test_onefile.c \
   402    403     $(TOP)/src/test_osinst.c \
   403    404     $(TOP)/src/test_pcache.c \
   404    405     $(TOP)/src/test_quota.c \
   405    406     $(TOP)/src/test_rtree.c \
   406    407     $(TOP)/src/test_schema.c \
   407    408     $(TOP)/src/test_server.c \
   408    409     $(TOP)/src/test_superlock.c \
   409    410     $(TOP)/src/test_syscall.c \
          411  +  $(TOP)/src/test_tclsh.c \
   410    412     $(TOP)/src/test_tclvar.c \
   411    413     $(TOP)/src/test_thread.c \
   412    414     $(TOP)/src/test_vfs.c \
   413    415     $(TOP)/src/test_windirent.c \
   414    416     $(TOP)/src/test_wsd.c       \
   415    417     $(TOP)/ext/fts3/fts3_term.c \
   416    418     $(TOP)/ext/fts3/fts3_test.c  \

Changes to Makefile.msc.

  1370   1370     $(TOP)\src\test_fs.c \
  1371   1371     $(TOP)\src\test_func.c \
  1372   1372     $(TOP)\src\test_hexio.c \
  1373   1373     $(TOP)\src\test_init.c \
  1374   1374     $(TOP)\src\test_intarray.c \
  1375   1375     $(TOP)\src\test_journal.c \
  1376   1376     $(TOP)\src\test_malloc.c \
         1377  +  $(TOP)\src\test_md5.c \
  1377   1378     $(TOP)\src\test_multiplex.c \
  1378   1379     $(TOP)\src\test_mutex.c \
  1379   1380     $(TOP)\src\test_onefile.c \
  1380   1381     $(TOP)\src\test_osinst.c \
  1381   1382     $(TOP)\src\test_pcache.c \
  1382   1383     $(TOP)\src\test_quota.c \
  1383   1384     $(TOP)\src\test_rtree.c \
  1384   1385     $(TOP)\src\test_schema.c \
  1385   1386     $(TOP)\src\test_server.c \
  1386   1387     $(TOP)\src\test_superlock.c \
  1387   1388     $(TOP)\src\test_syscall.c \
         1389  +  $(TOP)\src\test_tclsh.c \
  1388   1390     $(TOP)\src\test_tclvar.c \
  1389   1391     $(TOP)\src\test_thread.c \
  1390   1392     $(TOP)\src\test_vfs.c \
  1391   1393     $(TOP)\src\test_windirent.c \
  1392   1394     $(TOP)\src\test_wsd.c \
  1393   1395     $(TOP)\ext\fts3\fts3_term.c \
  1394   1396     $(TOP)\ext\fts3\fts3_test.c \

Changes to main.mk.

   304    304     $(TOP)/src/test_fs.c \
   305    305     $(TOP)/src/test_func.c \
   306    306     $(TOP)/src/test_hexio.c \
   307    307     $(TOP)/src/test_init.c \
   308    308     $(TOP)/src/test_intarray.c \
   309    309     $(TOP)/src/test_journal.c \
   310    310     $(TOP)/src/test_malloc.c \
          311  +  $(TOP)/src/test_md5.c \
   311    312     $(TOP)/src/test_multiplex.c \
   312    313     $(TOP)/src/test_mutex.c \
   313    314     $(TOP)/src/test_onefile.c \
   314    315     $(TOP)/src/test_osinst.c \
   315    316     $(TOP)/src/test_pcache.c \
   316    317     $(TOP)/src/test_quota.c \
   317    318     $(TOP)/src/test_rtree.c \
   318    319     $(TOP)/src/test_schema.c \
   319    320     $(TOP)/src/test_server.c \
   320    321     $(TOP)/src/test_sqllog.c \
   321    322     $(TOP)/src/test_superlock.c \
   322    323     $(TOP)/src/test_syscall.c \
          324  +  $(TOP)/src/test_tclsh.c \
   323    325     $(TOP)/src/test_tclvar.c \
   324    326     $(TOP)/src/test_thread.c \
   325    327     $(TOP)/src/test_vfs.c \
   326    328     $(TOP)/src/test_windirent.c \
   327    329     $(TOP)/src/test_wsd.c
   328    330   
   329    331   # Extensions to be statically loaded.

Changes to src/tclsqlite.c.

  3542   3542   #ifndef SQLITE_3_SUFFIX_ONLY
  3543   3543   int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3544   3544   int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3545   3545   int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3546   3546   int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3547   3547   #endif
  3548   3548   
  3549         -#ifdef TCLSH
  3550         -/*****************************************************************************
  3551         -** All of the code that follows is used to build standalone TCL interpreters
  3552         -** that are statically linked with SQLite.  Enable these by compiling
  3553         -** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard
  3554         -** tclsh but with SQLite built in.  An n of 2 generates the SQLite space
  3555         -** analysis program.
         3549  +/*
         3550  +** If the TCLSH macro is defined to be either 1 or 2, then a main()
         3551  +** routine is inserted that starts up a Tcl interpreter.  When TCLSH==1
         3552  +** the interpreter works like an ordinary tclsh.  When TCLSH==2 then the
         3553  +** startup script is supplied by an routine named "tclsh_main_loop()"
         3554  +** that must be linked separately.  The TCLSH==2 technique is used to
         3555  +** generate stand-alone executables based on TCL, such as 
         3556  +** sqlite3_analyzer.exe.
  3556   3557   */
  3557         -
  3558         -#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
  3559         -/*
  3560         - * This code implements the MD5 message-digest algorithm.
  3561         - * The algorithm is due to Ron Rivest.  This code was
  3562         - * written by Colin Plumb in 1993, no copyright is claimed.
  3563         - * This code is in the public domain; do with it what you wish.
  3564         - *
  3565         - * Equivalent code is available from RSA Data Security, Inc.
  3566         - * This code has been tested against that, and is equivalent,
  3567         - * except that you don't need to include two pages of legalese
  3568         - * with every copy.
  3569         - *
  3570         - * To compute the message digest of a chunk of bytes, declare an
  3571         - * MD5Context structure, pass it to MD5Init, call MD5Update as
  3572         - * needed on buffers full of bytes, and then call MD5Final, which
  3573         - * will fill a supplied 16-byte array with the digest.
  3574         - */
  3575         -
  3576         -/*
  3577         - * If compiled on a machine that doesn't have a 32-bit integer,
  3578         - * you just set "uint32" to the appropriate datatype for an
  3579         - * unsigned 32-bit integer.  For example:
  3580         - *
  3581         - *       cc -Duint32='unsigned long' md5.c
  3582         - *
  3583         - */
  3584         -#ifndef uint32
  3585         -#  define uint32 unsigned int
  3586         -#endif
  3587         -
  3588         -struct MD5Context {
  3589         -  int isInit;
  3590         -  uint32 buf[4];
  3591         -  uint32 bits[2];
  3592         -  unsigned char in[64];
  3593         -};
  3594         -typedef struct MD5Context MD5Context;
  3595         -
  3596         -/*
  3597         - * Note: this code is harmless on little-endian machines.
  3598         - */
  3599         -static void byteReverse (unsigned char *buf, unsigned longs){
  3600         -        uint32 t;
  3601         -        do {
  3602         -                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
  3603         -                            ((unsigned)buf[1]<<8 | buf[0]);
  3604         -                *(uint32 *)buf = t;
  3605         -                buf += 4;
  3606         -        } while (--longs);
  3607         -}
  3608         -/* The four core functions - F1 is optimized somewhat */
  3609         -
  3610         -/* #define F1(x, y, z) (x & y | ~x & z) */
  3611         -#define F1(x, y, z) (z ^ (x & (y ^ z)))
  3612         -#define F2(x, y, z) F1(z, x, y)
  3613         -#define F3(x, y, z) (x ^ y ^ z)
  3614         -#define F4(x, y, z) (y ^ (x | ~z))
  3615         -
  3616         -/* This is the central step in the MD5 algorithm. */
  3617         -#define MD5STEP(f, w, x, y, z, data, s) \
  3618         -        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
  3619         -
  3620         -/*
  3621         - * The core of the MD5 algorithm, this alters an existing MD5 hash to
  3622         - * reflect the addition of 16 longwords of new data.  MD5Update blocks
  3623         - * the data and converts bytes into longwords for this routine.
  3624         - */
  3625         -static void MD5Transform(uint32 buf[4], const uint32 in[16]){
  3626         -        register uint32 a, b, c, d;
  3627         -
  3628         -        a = buf[0];
  3629         -        b = buf[1];
  3630         -        c = buf[2];
  3631         -        d = buf[3];
  3632         -
  3633         -        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
  3634         -        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
  3635         -        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
  3636         -        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
  3637         -        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
  3638         -        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
  3639         -        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
  3640         -        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
  3641         -        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
  3642         -        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
  3643         -        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
  3644         -        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
  3645         -        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
  3646         -        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
  3647         -        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
  3648         -        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
  3649         -
  3650         -        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
  3651         -        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
  3652         -        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
  3653         -        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
  3654         -        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
  3655         -        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
  3656         -        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
  3657         -        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
  3658         -        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
  3659         -        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
  3660         -        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
  3661         -        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
  3662         -        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
  3663         -        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
  3664         -        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
  3665         -        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
  3666         -
  3667         -        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
  3668         -        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
  3669         -        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
  3670         -        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
  3671         -        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
  3672         -        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
  3673         -        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
  3674         -        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
  3675         -        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
  3676         -        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
  3677         -        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
  3678         -        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
  3679         -        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
  3680         -        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
  3681         -        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
  3682         -        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
  3683         -
  3684         -        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
  3685         -        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
  3686         -        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
  3687         -        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
  3688         -        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
  3689         -        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
  3690         -        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
  3691         -        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
  3692         -        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
  3693         -        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
  3694         -        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
  3695         -        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
  3696         -        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
  3697         -        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
  3698         -        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
  3699         -        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
  3700         -
  3701         -        buf[0] += a;
  3702         -        buf[1] += b;
  3703         -        buf[2] += c;
  3704         -        buf[3] += d;
  3705         -}
  3706         -
  3707         -/*
  3708         - * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
  3709         - * initialization constants.
  3710         - */
  3711         -static void MD5Init(MD5Context *ctx){
  3712         -        ctx->isInit = 1;
  3713         -        ctx->buf[0] = 0x67452301;
  3714         -        ctx->buf[1] = 0xefcdab89;
  3715         -        ctx->buf[2] = 0x98badcfe;
  3716         -        ctx->buf[3] = 0x10325476;
  3717         -        ctx->bits[0] = 0;
  3718         -        ctx->bits[1] = 0;
  3719         -}
  3720         -
  3721         -/*
  3722         - * Update context to reflect the concatenation of another buffer full
  3723         - * of bytes.
  3724         - */
  3725         -static
  3726         -void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
  3727         -        uint32 t;
  3728         -
  3729         -        /* Update bitcount */
  3730         -
  3731         -        t = ctx->bits[0];
  3732         -        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
  3733         -                ctx->bits[1]++; /* Carry from low to high */
  3734         -        ctx->bits[1] += len >> 29;
  3735         -
  3736         -        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
  3737         -
  3738         -        /* Handle any leading odd-sized chunks */
  3739         -
  3740         -        if ( t ) {
  3741         -                unsigned char *p = (unsigned char *)ctx->in + t;
  3742         -
  3743         -                t = 64-t;
  3744         -                if (len < t) {
  3745         -                        memcpy(p, buf, len);
  3746         -                        return;
  3747         -                }
  3748         -                memcpy(p, buf, t);
  3749         -                byteReverse(ctx->in, 16);
  3750         -                MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3751         -                buf += t;
  3752         -                len -= t;
  3753         -        }
  3754         -
  3755         -        /* Process data in 64-byte chunks */
  3756         -
  3757         -        while (len >= 64) {
  3758         -                memcpy(ctx->in, buf, 64);
  3759         -                byteReverse(ctx->in, 16);
  3760         -                MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3761         -                buf += 64;
  3762         -                len -= 64;
  3763         -        }
  3764         -
  3765         -        /* Handle any remaining bytes of data. */
  3766         -
  3767         -        memcpy(ctx->in, buf, len);
  3768         -}
  3769         -
  3770         -/*
  3771         - * Final wrapup - pad to 64-byte boundary with the bit pattern
  3772         - * 1 0* (64-bit count of bits processed, MSB-first)
  3773         - */
  3774         -static void MD5Final(unsigned char digest[16], MD5Context *ctx){
  3775         -        unsigned count;
  3776         -        unsigned char *p;
  3777         -
  3778         -        /* Compute number of bytes mod 64 */
  3779         -        count = (ctx->bits[0] >> 3) & 0x3F;
  3780         -
  3781         -        /* Set the first char of padding to 0x80.  This is safe since there is
  3782         -           always at least one byte free */
  3783         -        p = ctx->in + count;
  3784         -        *p++ = 0x80;
  3785         -
  3786         -        /* Bytes of padding needed to make 64 bytes */
  3787         -        count = 64 - 1 - count;
  3788         -
  3789         -        /* Pad out to 56 mod 64 */
  3790         -        if (count < 8) {
  3791         -                /* Two lots of padding:  Pad the first block to 64 bytes */
  3792         -                memset(p, 0, count);
  3793         -                byteReverse(ctx->in, 16);
  3794         -                MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3795         -
  3796         -                /* Now fill the next block with 56 bytes */
  3797         -                memset(ctx->in, 0, 56);
  3798         -        } else {
  3799         -                /* Pad block to 56 bytes */
  3800         -                memset(p, 0, count-8);
  3801         -        }
  3802         -        byteReverse(ctx->in, 14);
  3803         -
  3804         -        /* Append length in bits and transform */
  3805         -        memcpy(ctx->in + 14*4, ctx->bits, 8);
  3806         -
  3807         -        MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3808         -        byteReverse((unsigned char *)ctx->buf, 4);
  3809         -        memcpy(digest, ctx->buf, 16);
  3810         -}
  3811         -
  3812         -/*
  3813         -** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
  3814         -*/
  3815         -static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
  3816         -  static char const zEncode[] = "0123456789abcdef";
  3817         -  int i, j;
  3818         -
  3819         -  for(j=i=0; i<16; i++){
  3820         -    int a = digest[i];
  3821         -    zBuf[j++] = zEncode[(a>>4)&0xf];
  3822         -    zBuf[j++] = zEncode[a & 0xf];
  3823         -  }
  3824         -  zBuf[j] = 0;
  3825         -}
  3826         -
  3827         -
  3828         -/*
  3829         -** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
  3830         -** each representing 16 bits of the digest and separated from each
  3831         -** other by a "-" character.
  3832         -*/
  3833         -static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
  3834         -  int i, j;
  3835         -  unsigned int x;
  3836         -  for(i=j=0; i<16; i+=2){
  3837         -    x = digest[i]*256 + digest[i+1];
  3838         -    if( i>0 ) zDigest[j++] = '-';
  3839         -    sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
  3840         -    j += 5;
  3841         -  }
  3842         -  zDigest[j] = 0;
  3843         -}
  3844         -
  3845         -/*
  3846         -** A TCL command for md5.  The argument is the text to be hashed.  The
  3847         -** Result is the hash in base64.
  3848         -*/
  3849         -static int SQLITE_TCLAPI md5_cmd(
  3850         -  void*cd,
  3851         -  Tcl_Interp *interp,
  3852         -  int argc,
  3853         -  const char **argv
  3854         -){
  3855         -  MD5Context ctx;
  3856         -  unsigned char digest[16];
  3857         -  char zBuf[50];
  3858         -  void (*converter)(unsigned char*, char*);
  3859         -
  3860         -  if( argc!=2 ){
  3861         -    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
  3862         -        " TEXT\"", (char*)0);
  3863         -    return TCL_ERROR;
  3864         -  }
  3865         -  MD5Init(&ctx);
  3866         -  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
  3867         -  MD5Final(digest, &ctx);
  3868         -  converter = (void(*)(unsigned char*,char*))cd;
  3869         -  converter(digest, zBuf);
  3870         -  Tcl_AppendResult(interp, zBuf, (char*)0);
  3871         -  return TCL_OK;
  3872         -}
  3873         -
  3874         -/*
  3875         -** A TCL command to take the md5 hash of a file.  The argument is the
  3876         -** name of the file.
  3877         -*/
  3878         -static int SQLITE_TCLAPI md5file_cmd(
  3879         -  void*cd,
  3880         -  Tcl_Interp *interp,
  3881         -  int argc,
  3882         -  const char **argv
  3883         -){
  3884         -  FILE *in;
  3885         -  int ofst;
  3886         -  int amt;
  3887         -  MD5Context ctx;
  3888         -  void (*converter)(unsigned char*, char*);
  3889         -  unsigned char digest[16];
  3890         -  char zBuf[10240];
  3891         -
  3892         -  if( argc!=2 && argc!=4 ){
  3893         -    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
  3894         -        " FILENAME [OFFSET AMT]\"", (char*)0);
  3895         -    return TCL_ERROR;
  3896         -  }
  3897         -  if( argc==4 ){
  3898         -    ofst = atoi(argv[2]);
  3899         -    amt = atoi(argv[3]);
  3900         -  }else{
  3901         -    ofst = 0;
  3902         -    amt = 2147483647;
  3903         -  }
  3904         -  in = fopen(argv[1],"rb");
  3905         -  if( in==0 ){
  3906         -    Tcl_AppendResult(interp,"unable to open file \"", argv[1],
  3907         -         "\" for reading", (char*)0);
  3908         -    return TCL_ERROR;
  3909         -  }
  3910         -  fseek(in, ofst, SEEK_SET);
  3911         -  MD5Init(&ctx);
  3912         -  while( amt>0 ){
  3913         -    int n;
  3914         -    n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
  3915         -    if( n<=0 ) break;
  3916         -    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
  3917         -    amt -= n;
  3918         -  }
  3919         -  fclose(in);
  3920         -  MD5Final(digest, &ctx);
  3921         -  converter = (void(*)(unsigned char*,char*))cd;
  3922         -  converter(digest, zBuf);
  3923         -  Tcl_AppendResult(interp, zBuf, (char*)0);
  3924         -  return TCL_OK;
  3925         -}
  3926         -
  3927         -/*
  3928         -** Register the four new TCL commands for generating MD5 checksums
  3929         -** with the TCL interpreter.
  3930         -*/
  3931         -int Md5_Init(Tcl_Interp *interp){
  3932         -  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
  3933         -                    MD5DigestToBase16, 0);
  3934         -  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
  3935         -                    MD5DigestToBase10x8, 0);
  3936         -  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
  3937         -                    MD5DigestToBase16, 0);
  3938         -  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
  3939         -                    MD5DigestToBase10x8, 0);
  3940         -  return TCL_OK;
  3941         -}
  3942         -#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */
  3943         -
  3944         -#if defined(SQLITE_TEST)
  3945         -/*
  3946         -** During testing, the special md5sum() aggregate function is available.
  3947         -** inside SQLite.  The following routines implement that function.
  3948         -*/
  3949         -static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
  3950         -  MD5Context *p;
  3951         -  int i;
  3952         -  if( argc<1 ) return;
  3953         -  p = sqlite3_aggregate_context(context, sizeof(*p));
  3954         -  if( p==0 ) return;
  3955         -  if( !p->isInit ){
  3956         -    MD5Init(p);
  3957         -  }
  3958         -  for(i=0; i<argc; i++){
  3959         -    const char *zData = (char*)sqlite3_value_text(argv[i]);
  3960         -    if( zData ){
  3961         -      MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
  3962         -    }
  3963         -  }
  3964         -}
  3965         -static void md5finalize(sqlite3_context *context){
  3966         -  MD5Context *p;
  3967         -  unsigned char digest[16];
  3968         -  char zBuf[33];
  3969         -  p = sqlite3_aggregate_context(context, sizeof(*p));
  3970         -  MD5Final(digest,p);
  3971         -  MD5DigestToBase16(digest, zBuf);
  3972         -  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  3973         -}
  3974         -int Md5_Register(
  3975         -  sqlite3 *db,
  3976         -  char **pzErrMsg,
  3977         -  const sqlite3_api_routines *pThunk
  3978         -){
  3979         -  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
  3980         -                                 md5step, md5finalize);
  3981         -  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
  3982         -  return rc;
  3983         -}
  3984         -#endif /* defined(SQLITE_TEST) */
  3985         -
         3558  +#ifdef TCLSH
  3986   3559   
  3987   3560   /*
  3988   3561   ** If the macro TCLSH is one, then put in code this for the
  3989   3562   ** "main" routine that will initialize Tcl and take input from
  3990   3563   ** standard input, or if a file is named on the command line
  3991   3564   ** the TCL interpreter reads and evaluates that file.
  3992   3565   */
................................................................................
  4017   3590     return zMainloop;
  4018   3591   }
  4019   3592   #endif
  4020   3593   #if TCLSH==2
  4021   3594   static const char *tclsh_main_loop(void);
  4022   3595   #endif
  4023   3596   
         3597  +/* The following to TCL commands used for testing must appear in this
         3598  +** file (they cannot be factored out into one of the test_*.c files where
         3599  +** they belong) because they require access to the SqliteDb object.
         3600  +*/
  4024   3601   #ifdef SQLITE_TEST
  4025         -static void init_all(Tcl_Interp *);
  4026         -static int SQLITE_TCLAPI init_all_cmd(
  4027         -  ClientData cd,
  4028         -  Tcl_Interp *interp,
  4029         -  int objc,
  4030         -  Tcl_Obj *CONST objv[]
  4031         -){
  4032         -
  4033         -  Tcl_Interp *slave;
  4034         -  if( objc!=2 ){
  4035         -    Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
  4036         -    return TCL_ERROR;
  4037         -  }
  4038         -
  4039         -  slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
  4040         -  if( !slave ){
  4041         -    return TCL_ERROR;
  4042         -  }
  4043         -
  4044         -  init_all(slave);
  4045         -  return TCL_OK;
  4046         -}
  4047         -
  4048   3602   /*
  4049   3603   ** Tclcmd: db_use_legacy_prepare DB BOOLEAN
  4050   3604   **
  4051   3605   **   The first argument to this command must be a database command created by
  4052   3606   **   [sqlite3]. If the second argument is true, then the handle is configured
  4053   3607   **   to use the sqlite3_prepare_v2() function to prepare statements. If it
  4054   3608   **   is false, sqlite3_prepare().
................................................................................
  4119   3673     }
  4120   3674     Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
  4121   3675   
  4122   3676     return TCL_OK;
  4123   3677   }
  4124   3678   #endif /* SQLITE_TEST */
  4125   3679   
  4126         -/*
  4127         -** Configure the interpreter passed as the first argument to have access
  4128         -** to the commands and linked variables that make up:
  4129         -**
  4130         -**   * the [sqlite3] extension itself,
  4131         -**
  4132         -**   * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
  4133         -**
  4134         -**   * If SQLITE_TEST is set, the various test interfaces used by the Tcl
  4135         -**     test suite.
  4136         -*/
  4137         -static void init_all(Tcl_Interp *interp){
  4138         -  Sqlite3_Init(interp);
  4139         -
  4140         -#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
  4141         -  Md5_Init(interp);
  4142         -#endif
  4143         -
  4144         -#ifdef SQLITE_TEST
  4145         -  {
  4146         -    extern int Sqliteconfig_Init(Tcl_Interp*);
  4147         -    extern int Sqlitetest1_Init(Tcl_Interp*);
  4148         -    extern int Sqlitetest2_Init(Tcl_Interp*);
  4149         -    extern int Sqlitetest3_Init(Tcl_Interp*);
  4150         -    extern int Sqlitetest4_Init(Tcl_Interp*);
  4151         -    extern int Sqlitetest5_Init(Tcl_Interp*);
  4152         -    extern int Sqlitetest6_Init(Tcl_Interp*);
  4153         -    extern int Sqlitetest7_Init(Tcl_Interp*);
  4154         -    extern int Sqlitetest8_Init(Tcl_Interp*);
  4155         -    extern int Sqlitetest9_Init(Tcl_Interp*);
  4156         -    extern int Sqlitetestasync_Init(Tcl_Interp*);
  4157         -    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
  4158         -    extern int Sqlitetest_blob_Init(Tcl_Interp*);
  4159         -    extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
  4160         -    extern int Sqlitetest_func_Init(Tcl_Interp*);
  4161         -    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
  4162         -    extern int Sqlitetest_init_Init(Tcl_Interp*);
  4163         -    extern int Sqlitetest_malloc_Init(Tcl_Interp*);
  4164         -    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
  4165         -    extern int Sqlitetestschema_Init(Tcl_Interp*);
  4166         -    extern int Sqlitetestsse_Init(Tcl_Interp*);
  4167         -    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
  4168         -    extern int Sqlitetestfs_Init(Tcl_Interp*);
  4169         -    extern int SqlitetestThread_Init(Tcl_Interp*);
  4170         -    extern int SqlitetestOnefile_Init();
  4171         -    extern int SqlitetestOsinst_Init(Tcl_Interp*);
  4172         -    extern int Sqlitetestbackup_Init(Tcl_Interp*);
  4173         -    extern int Sqlitetestintarray_Init(Tcl_Interp*);
  4174         -    extern int Sqlitetestvfs_Init(Tcl_Interp *);
  4175         -    extern int Sqlitetestrtree_Init(Tcl_Interp*);
  4176         -    extern int Sqlitequota_Init(Tcl_Interp*);
  4177         -    extern int Sqlitemultiplex_Init(Tcl_Interp*);
  4178         -    extern int SqliteSuperlock_Init(Tcl_Interp*);
  4179         -    extern int SqlitetestSyscall_Init(Tcl_Interp*);
  4180         -#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  4181         -    extern int TestSession_Init(Tcl_Interp*);
  4182         -#endif
  4183         -    extern int Fts5tcl_Init(Tcl_Interp *);
  4184         -    extern int SqliteRbu_Init(Tcl_Interp*);
  4185         -    extern int Sqlitetesttcl_Init(Tcl_Interp*);
  4186         -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  4187         -    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
  4188         -#endif
  4189         -
  4190         -#ifdef SQLITE_ENABLE_ZIPVFS
  4191         -    extern int Zipvfs_Init(Tcl_Interp*);
  4192         -    Zipvfs_Init(interp);
  4193         -#endif
  4194         -
  4195         -    Sqliteconfig_Init(interp);
  4196         -    Sqlitetest1_Init(interp);
  4197         -    Sqlitetest2_Init(interp);
  4198         -    Sqlitetest3_Init(interp);
  4199         -    Sqlitetest4_Init(interp);
  4200         -    Sqlitetest5_Init(interp);
  4201         -    Sqlitetest6_Init(interp);
  4202         -    Sqlitetest7_Init(interp);
  4203         -    Sqlitetest8_Init(interp);
  4204         -    Sqlitetest9_Init(interp);
  4205         -    Sqlitetestasync_Init(interp);
  4206         -    Sqlitetest_autoext_Init(interp);
  4207         -    Sqlitetest_blob_Init(interp);
  4208         -    Sqlitetest_demovfs_Init(interp);
  4209         -    Sqlitetest_func_Init(interp);
  4210         -    Sqlitetest_hexio_Init(interp);
  4211         -    Sqlitetest_init_Init(interp);
  4212         -    Sqlitetest_malloc_Init(interp);
  4213         -    Sqlitetest_mutex_Init(interp);
  4214         -    Sqlitetestschema_Init(interp);
  4215         -    Sqlitetesttclvar_Init(interp);
  4216         -    Sqlitetestfs_Init(interp);
  4217         -    SqlitetestThread_Init(interp);
  4218         -    SqlitetestOnefile_Init();
  4219         -    SqlitetestOsinst_Init(interp);
  4220         -    Sqlitetestbackup_Init(interp);
  4221         -    Sqlitetestintarray_Init(interp);
  4222         -    Sqlitetestvfs_Init(interp);
  4223         -    Sqlitetestrtree_Init(interp);
  4224         -    Sqlitequota_Init(interp);
  4225         -    Sqlitemultiplex_Init(interp);
  4226         -    SqliteSuperlock_Init(interp);
  4227         -    SqlitetestSyscall_Init(interp);
  4228         -#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  4229         -    TestSession_Init(interp);
  4230         -#endif
  4231         -    Fts5tcl_Init(interp);
  4232         -    SqliteRbu_Init(interp);
  4233         -    Sqlitetesttcl_Init(interp);
  4234         -
  4235         -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  4236         -    Sqlitetestfts3_Init(interp);
  4237         -#endif
  4238         -
  4239         -    Tcl_CreateObjCommand(
  4240         -        interp, "load_testfixture_extensions", init_all_cmd, 0, 0
  4241         -    );
  4242         -    Tcl_CreateObjCommand(
  4243         -        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
  4244         -    );
  4245         -    Tcl_CreateObjCommand(
  4246         -        interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
  4247         -    );
  4248         -
  4249         -#ifdef SQLITE_SSE
  4250         -    Sqlitetestsse_Init(interp);
  4251         -#endif
  4252         -  }
  4253         -#endif
  4254         -}
  4255         -
  4256         -/* Needed for the setrlimit() system call on unix */
  4257         -#if defined(unix)
  4258         -#include <sys/resource.h>
  4259         -#endif
  4260         -
  4261   3680   #define TCLSH_MAIN main   /* Needed to fake out mktclapp */
  4262   3681   int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
  4263   3682     Tcl_Interp *interp;
  4264   3683   
  4265   3684   #if !defined(_WIN32_WCE)
  4266   3685     if( getenv("BREAK") ){
  4267   3686       fprintf(stderr,
  4268   3687           "attach debugger to process %d and press any key to continue.\n",
  4269   3688           GETPID());
  4270   3689       fgetc(stdin);
  4271   3690     }
  4272   3691   #endif
  4273         -
  4274         -  /* Since the primary use case for this binary is testing of SQLite,
  4275         -  ** be sure to generate core files if we crash */
  4276         -#if defined(SQLITE_TEST) && defined(unix)
  4277         -  { struct rlimit x;
  4278         -    getrlimit(RLIMIT_CORE, &x);
  4279         -    x.rlim_cur = x.rlim_max;
  4280         -    setrlimit(RLIMIT_CORE, &x);
  4281         -  }
  4282         -#endif /* SQLITE_TEST && unix */
  4283         -
  4284   3692   
  4285   3693     /* Call sqlite3_shutdown() once before doing anything else. This is to
  4286   3694     ** test that sqlite3_shutdown() can be safely called by a process before
  4287   3695     ** sqlite3_initialize() is. */
  4288   3696     sqlite3_shutdown();
  4289   3697   
  4290   3698     Tcl_FindExecutable(argv[0]);
................................................................................
  4291   3699     Tcl_SetSystemEncoding(NULL, "utf-8");
  4292   3700     interp = Tcl_CreateInterp();
  4293   3701   
  4294   3702   #if TCLSH==2
  4295   3703     sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
  4296   3704   #endif
  4297   3705   
  4298         -  init_all(interp);
         3706  +  /* Add extensions */
         3707  +#if !defined(SQLITE_TEST)
         3708  +  /* Normally we only initialize the TCL extension */
         3709  +  Sqlite3_Init(interp);
         3710  +#else
         3711  +  /* For testing, do lots of extra initialization */
         3712  +  {
         3713  +    extern void sqlite3InitTclTestLogic(Tcl_Interp*);
         3714  +    sqlite3InitTclTestLogic(interp);
         3715  +    Tcl_CreateObjCommand(
         3716  +        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
         3717  +    );
         3718  +    Tcl_CreateObjCommand(
         3719  +        interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
         3720  +    );
         3721  +  }
         3722  +#endif /* SQLITE_TEST */
  4299   3723     if( argc>=2 ){
  4300   3724       int i;
  4301   3725       char zArgc[32];
  4302   3726       sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
  4303   3727       Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
  4304   3728       Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
  4305   3729       Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);

Added src/test_md5.c.

            1  +/*
            2  +** 2017-10-13
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains code to implement an MD5 extension to TCL.
           14  +*/
           15  +#include "sqlite3.h"
           16  +#include <stdlib.h>
           17  +#include <string.h>
           18  +#include "sqlite3.h"
           19  +#if defined(INCLUDE_SQLITE_TCL_H)
           20  +# include "sqlite_tcl.h"
           21  +#else
           22  +# include "tcl.h"
           23  +# ifndef SQLITE_TCLAPI
           24  +#  define SQLITE_TCLAPI
           25  +# endif
           26  +#endif
           27  +
           28  +/*
           29  + * This code implements the MD5 message-digest algorithm.
           30  + * The algorithm is due to Ron Rivest.  This code was
           31  + * written by Colin Plumb in 1993, no copyright is claimed.
           32  + * This code is in the public domain; do with it what you wish.
           33  + *
           34  + * Equivalent code is available from RSA Data Security, Inc.
           35  + * This code has been tested against that, and is equivalent,
           36  + * except that you don't need to include two pages of legalese
           37  + * with every copy.
           38  + *
           39  + * To compute the message digest of a chunk of bytes, declare an
           40  + * MD5Context structure, pass it to MD5Init, call MD5Update as
           41  + * needed on buffers full of bytes, and then call MD5Final, which
           42  + * will fill a supplied 16-byte array with the digest.
           43  + */
           44  +
           45  +/*
           46  + * If compiled on a machine that doesn't have a 32-bit integer,
           47  + * you just set "uint32" to the appropriate datatype for an
           48  + * unsigned 32-bit integer.  For example:
           49  + *
           50  + *       cc -Duint32='unsigned long' md5.c
           51  + *
           52  + */
           53  +#ifndef uint32
           54  +#  define uint32 unsigned int
           55  +#endif
           56  +
           57  +struct MD5Context {
           58  +  int isInit;
           59  +  uint32 buf[4];
           60  +  uint32 bits[2];
           61  +  unsigned char in[64];
           62  +};
           63  +typedef struct MD5Context MD5Context;
           64  +
           65  +/*
           66  + * Note: this code is harmless on little-endian machines.
           67  + */
           68  +static void byteReverse (unsigned char *buf, unsigned longs){
           69  +        uint32 t;
           70  +        do {
           71  +                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
           72  +                            ((unsigned)buf[1]<<8 | buf[0]);
           73  +                *(uint32 *)buf = t;
           74  +                buf += 4;
           75  +        } while (--longs);
           76  +}
           77  +/* The four core functions - F1 is optimized somewhat */
           78  +
           79  +/* #define F1(x, y, z) (x & y | ~x & z) */
           80  +#define F1(x, y, z) (z ^ (x & (y ^ z)))
           81  +#define F2(x, y, z) F1(z, x, y)
           82  +#define F3(x, y, z) (x ^ y ^ z)
           83  +#define F4(x, y, z) (y ^ (x | ~z))
           84  +
           85  +/* This is the central step in the MD5 algorithm. */
           86  +#define MD5STEP(f, w, x, y, z, data, s) \
           87  +        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
           88  +
           89  +/*
           90  + * The core of the MD5 algorithm, this alters an existing MD5 hash to
           91  + * reflect the addition of 16 longwords of new data.  MD5Update blocks
           92  + * the data and converts bytes into longwords for this routine.
           93  + */
           94  +static void MD5Transform(uint32 buf[4], const uint32 in[16]){
           95  +        register uint32 a, b, c, d;
           96  +
           97  +        a = buf[0];
           98  +        b = buf[1];
           99  +        c = buf[2];
          100  +        d = buf[3];
          101  +
          102  +        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
          103  +        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
          104  +        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
          105  +        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
          106  +        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
          107  +        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
          108  +        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
          109  +        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
          110  +        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
          111  +        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
          112  +        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
          113  +        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
          114  +        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
          115  +        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
          116  +        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
          117  +        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
          118  +
          119  +        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
          120  +        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
          121  +        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
          122  +        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
          123  +        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
          124  +        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
          125  +        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
          126  +        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
          127  +        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
          128  +        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
          129  +        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
          130  +        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
          131  +        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
          132  +        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
          133  +        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
          134  +        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
          135  +
          136  +        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
          137  +        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
          138  +        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
          139  +        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
          140  +        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
          141  +        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
          142  +        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
          143  +        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
          144  +        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
          145  +        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
          146  +        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
          147  +        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
          148  +        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
          149  +        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
          150  +        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
          151  +        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
          152  +
          153  +        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
          154  +        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
          155  +        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
          156  +        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
          157  +        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
          158  +        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
          159  +        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
          160  +        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
          161  +        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
          162  +        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
          163  +        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
          164  +        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
          165  +        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
          166  +        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
          167  +        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
          168  +        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
          169  +
          170  +        buf[0] += a;
          171  +        buf[1] += b;
          172  +        buf[2] += c;
          173  +        buf[3] += d;
          174  +}
          175  +
          176  +/*
          177  + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
          178  + * initialization constants.
          179  + */
          180  +static void MD5Init(MD5Context *ctx){
          181  +        ctx->isInit = 1;
          182  +        ctx->buf[0] = 0x67452301;
          183  +        ctx->buf[1] = 0xefcdab89;
          184  +        ctx->buf[2] = 0x98badcfe;
          185  +        ctx->buf[3] = 0x10325476;
          186  +        ctx->bits[0] = 0;
          187  +        ctx->bits[1] = 0;
          188  +}
          189  +
          190  +/*
          191  + * Update context to reflect the concatenation of another buffer full
          192  + * of bytes.
          193  + */
          194  +static
          195  +void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
          196  +        uint32 t;
          197  +
          198  +        /* Update bitcount */
          199  +
          200  +        t = ctx->bits[0];
          201  +        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
          202  +                ctx->bits[1]++; /* Carry from low to high */
          203  +        ctx->bits[1] += len >> 29;
          204  +
          205  +        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
          206  +
          207  +        /* Handle any leading odd-sized chunks */
          208  +
          209  +        if ( t ) {
          210  +                unsigned char *p = (unsigned char *)ctx->in + t;
          211  +
          212  +                t = 64-t;
          213  +                if (len < t) {
          214  +                        memcpy(p, buf, len);
          215  +                        return;
          216  +                }
          217  +                memcpy(p, buf, t);
          218  +                byteReverse(ctx->in, 16);
          219  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
          220  +                buf += t;
          221  +                len -= t;
          222  +        }
          223  +
          224  +        /* Process data in 64-byte chunks */
          225  +
          226  +        while (len >= 64) {
          227  +                memcpy(ctx->in, buf, 64);
          228  +                byteReverse(ctx->in, 16);
          229  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
          230  +                buf += 64;
          231  +                len -= 64;
          232  +        }
          233  +
          234  +        /* Handle any remaining bytes of data. */
          235  +
          236  +        memcpy(ctx->in, buf, len);
          237  +}
          238  +
          239  +/*
          240  + * Final wrapup - pad to 64-byte boundary with the bit pattern
          241  + * 1 0* (64-bit count of bits processed, MSB-first)
          242  + */
          243  +static void MD5Final(unsigned char digest[16], MD5Context *ctx){
          244  +        unsigned count;
          245  +        unsigned char *p;
          246  +
          247  +        /* Compute number of bytes mod 64 */
          248  +        count = (ctx->bits[0] >> 3) & 0x3F;
          249  +
          250  +        /* Set the first char of padding to 0x80.  This is safe since there is
          251  +           always at least one byte free */
          252  +        p = ctx->in + count;
          253  +        *p++ = 0x80;
          254  +
          255  +        /* Bytes of padding needed to make 64 bytes */
          256  +        count = 64 - 1 - count;
          257  +
          258  +        /* Pad out to 56 mod 64 */
          259  +        if (count < 8) {
          260  +                /* Two lots of padding:  Pad the first block to 64 bytes */
          261  +                memset(p, 0, count);
          262  +                byteReverse(ctx->in, 16);
          263  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
          264  +
          265  +                /* Now fill the next block with 56 bytes */
          266  +                memset(ctx->in, 0, 56);
          267  +        } else {
          268  +                /* Pad block to 56 bytes */
          269  +                memset(p, 0, count-8);
          270  +        }
          271  +        byteReverse(ctx->in, 14);
          272  +
          273  +        /* Append length in bits and transform */
          274  +        memcpy(ctx->in + 14*4, ctx->bits, 8);
          275  +
          276  +        MD5Transform(ctx->buf, (uint32 *)ctx->in);
          277  +        byteReverse((unsigned char *)ctx->buf, 4);
          278  +        memcpy(digest, ctx->buf, 16);
          279  +}
          280  +
          281  +/*
          282  +** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
          283  +*/
          284  +static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
          285  +  static char const zEncode[] = "0123456789abcdef";
          286  +  int i, j;
          287  +
          288  +  for(j=i=0; i<16; i++){
          289  +    int a = digest[i];
          290  +    zBuf[j++] = zEncode[(a>>4)&0xf];
          291  +    zBuf[j++] = zEncode[a & 0xf];
          292  +  }
          293  +  zBuf[j] = 0;
          294  +}
          295  +
          296  +
          297  +/*
          298  +** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
          299  +** each representing 16 bits of the digest and separated from each
          300  +** other by a "-" character.
          301  +*/
          302  +static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
          303  +  int i, j;
          304  +  unsigned int x;
          305  +  for(i=j=0; i<16; i+=2){
          306  +    x = digest[i]*256 + digest[i+1];
          307  +    if( i>0 ) zDigest[j++] = '-';
          308  +    sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
          309  +    j += 5;
          310  +  }
          311  +  zDigest[j] = 0;
          312  +}
          313  +
          314  +/*
          315  +** A TCL command for md5.  The argument is the text to be hashed.  The
          316  +** Result is the hash in base64.
          317  +*/
          318  +static int SQLITE_TCLAPI md5_cmd(
          319  +  void*cd,
          320  +  Tcl_Interp *interp,
          321  +  int argc,
          322  +  const char **argv
          323  +){
          324  +  MD5Context ctx;
          325  +  unsigned char digest[16];
          326  +  char zBuf[50];
          327  +  void (*converter)(unsigned char*, char*);
          328  +
          329  +  if( argc!=2 ){
          330  +    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
          331  +        " TEXT\"", (char*)0);
          332  +    return TCL_ERROR;
          333  +  }
          334  +  MD5Init(&ctx);
          335  +  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
          336  +  MD5Final(digest, &ctx);
          337  +  converter = (void(*)(unsigned char*,char*))cd;
          338  +  converter(digest, zBuf);
          339  +  Tcl_AppendResult(interp, zBuf, (char*)0);
          340  +  return TCL_OK;
          341  +}
          342  +
          343  +/*
          344  +** A TCL command to take the md5 hash of a file.  The argument is the
          345  +** name of the file.
          346  +*/
          347  +static int SQLITE_TCLAPI md5file_cmd(
          348  +  void*cd,
          349  +  Tcl_Interp *interp,
          350  +  int argc,
          351  +  const char **argv
          352  +){
          353  +  FILE *in;
          354  +  int ofst;
          355  +  int amt;
          356  +  MD5Context ctx;
          357  +  void (*converter)(unsigned char*, char*);
          358  +  unsigned char digest[16];
          359  +  char zBuf[10240];
          360  +
          361  +  if( argc!=2 && argc!=4 ){
          362  +    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
          363  +        " FILENAME [OFFSET AMT]\"", (char*)0);
          364  +    return TCL_ERROR;
          365  +  }
          366  +  if( argc==4 ){
          367  +    ofst = atoi(argv[2]);
          368  +    amt = atoi(argv[3]);
          369  +  }else{
          370  +    ofst = 0;
          371  +    amt = 2147483647;
          372  +  }
          373  +  in = fopen(argv[1],"rb");
          374  +  if( in==0 ){
          375  +    Tcl_AppendResult(interp,"unable to open file \"", argv[1],
          376  +         "\" for reading", (char*)0);
          377  +    return TCL_ERROR;
          378  +  }
          379  +  fseek(in, ofst, SEEK_SET);
          380  +  MD5Init(&ctx);
          381  +  while( amt>0 ){
          382  +    int n;
          383  +    n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
          384  +    if( n<=0 ) break;
          385  +    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
          386  +    amt -= n;
          387  +  }
          388  +  fclose(in);
          389  +  MD5Final(digest, &ctx);
          390  +  converter = (void(*)(unsigned char*,char*))cd;
          391  +  converter(digest, zBuf);
          392  +  Tcl_AppendResult(interp, zBuf, (char*)0);
          393  +  return TCL_OK;
          394  +}
          395  +
          396  +/*
          397  +** Register the four new TCL commands for generating MD5 checksums
          398  +** with the TCL interpreter.
          399  +*/
          400  +int Md5_Init(Tcl_Interp *interp){
          401  +  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
          402  +                    MD5DigestToBase16, 0);
          403  +  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
          404  +                    MD5DigestToBase10x8, 0);
          405  +  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
          406  +                    MD5DigestToBase16, 0);
          407  +  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
          408  +                    MD5DigestToBase10x8, 0);
          409  +  return TCL_OK;
          410  +}
          411  +
          412  +/*
          413  +** During testing, the special md5sum() aggregate function is available.
          414  +** inside SQLite.  The following routines implement that function.
          415  +*/
          416  +static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
          417  +  MD5Context *p;
          418  +  int i;
          419  +  if( argc<1 ) return;
          420  +  p = sqlite3_aggregate_context(context, sizeof(*p));
          421  +  if( p==0 ) return;
          422  +  if( !p->isInit ){
          423  +    MD5Init(p);
          424  +  }
          425  +  for(i=0; i<argc; i++){
          426  +    const char *zData = (char*)sqlite3_value_text(argv[i]);
          427  +    if( zData ){
          428  +      MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
          429  +    }
          430  +  }
          431  +}
          432  +static void md5finalize(sqlite3_context *context){
          433  +  MD5Context *p;
          434  +  unsigned char digest[16];
          435  +  char zBuf[33];
          436  +  p = sqlite3_aggregate_context(context, sizeof(*p));
          437  +  MD5Final(digest,p);
          438  +  MD5DigestToBase16(digest, zBuf);
          439  +  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
          440  +}
          441  +int Md5_Register(
          442  +  sqlite3 *db,
          443  +  char **pzErrMsg,
          444  +  const sqlite3_api_routines *pThunk
          445  +){
          446  +  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
          447  +                                 md5step, md5finalize);
          448  +  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
          449  +  return rc;
          450  +}

Added src/test_tclsh.c.

            1  +/*
            2  +** 2017-10-13
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains extensions to the the "tclsqlite.c" module used for
           14  +** testing.  Basically, all of the other "test_*.c" modules are linked
           15  +** into the enhanced tclsh used for testing (and named "testfixture" or
           16  +** "testfixture.exe") using logic encoded by this file.
           17  +**
           18  +** The code in this file used to be found in tclsqlite3.c, contained within
           19  +** #if SQLITE_TEST ... #endif.  It is factored out into this separate module
           20  +** in an effort to keep the tclsqlite.c file pure.
           21  +*/
           22  +#include "sqlite3.h"
           23  +#if defined(INCLUDE_SQLITE_TCL_H)
           24  +# include "sqlite_tcl.h"
           25  +#else
           26  +# include "tcl.h"
           27  +# ifndef SQLITE_TCLAPI
           28  +#  define SQLITE_TCLAPI
           29  +# endif
           30  +#endif
           31  +
           32  +/* Needed for the setrlimit() system call on unix */
           33  +#if defined(unix)
           34  +#include <sys/resource.h>
           35  +#endif
           36  +
           37  +/* Forward declaration */
           38  +static int SQLITE_TCLAPI load_testfixture_extensions(
           39  +  ClientData cd,
           40  +  Tcl_Interp *interp,
           41  +  int objc,
           42  +  Tcl_Obj *CONST objv[]
           43  +);
           44  +
           45  +/*
           46  +** This routine is the primary export of this file.
           47  +**
           48  +** Configure the interpreter passed as the first argument to have access
           49  +** to the commands and linked variables that make up:
           50  +**
           51  +**   * the [sqlite3] extension itself,
           52  +**
           53  +**   * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
           54  +**
           55  +**   * If SQLITE_TEST is set, the various test interfaces used by the Tcl
           56  +**     test suite.
           57  +*/
           58  +void sqlite3InitTclTestLogic(Tcl_Interp *interp){
           59  +  /* Since the primary use case for this binary is testing of SQLite,
           60  +  ** be sure to generate core files if we crash */
           61  +#if defined(unix)
           62  +  { struct rlimit x;
           63  +    getrlimit(RLIMIT_CORE, &x);
           64  +    x.rlim_cur = x.rlim_max;
           65  +    setrlimit(RLIMIT_CORE, &x);
           66  +  }
           67  +#endif /* unix */
           68  +
           69  +  {
           70  +    extern int Sqlite3_Init(Tcl_Interp*);
           71  +    extern int Sqliteconfig_Init(Tcl_Interp*);
           72  +    extern int Sqlitetest1_Init(Tcl_Interp*);
           73  +    extern int Sqlitetest2_Init(Tcl_Interp*);
           74  +    extern int Sqlitetest3_Init(Tcl_Interp*);
           75  +    extern int Sqlitetest4_Init(Tcl_Interp*);
           76  +    extern int Sqlitetest5_Init(Tcl_Interp*);
           77  +    extern int Sqlitetest6_Init(Tcl_Interp*);
           78  +    extern int Sqlitetest7_Init(Tcl_Interp*);
           79  +    extern int Sqlitetest8_Init(Tcl_Interp*);
           80  +    extern int Sqlitetest9_Init(Tcl_Interp*);
           81  +    extern int Sqlitetestasync_Init(Tcl_Interp*);
           82  +    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
           83  +    extern int Sqlitetest_blob_Init(Tcl_Interp*);
           84  +    extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
           85  +    extern int Sqlitetest_func_Init(Tcl_Interp*);
           86  +    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
           87  +    extern int Sqlitetest_init_Init(Tcl_Interp*);
           88  +    extern int Sqlitetest_malloc_Init(Tcl_Interp*);
           89  +    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
           90  +    extern int Sqlitetestschema_Init(Tcl_Interp*);
           91  +    extern int Sqlitetestsse_Init(Tcl_Interp*);
           92  +    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
           93  +    extern int Sqlitetestfs_Init(Tcl_Interp*);
           94  +    extern int SqlitetestThread_Init(Tcl_Interp*);
           95  +    extern int SqlitetestOnefile_Init();
           96  +    extern int SqlitetestOsinst_Init(Tcl_Interp*);
           97  +    extern int Sqlitetestbackup_Init(Tcl_Interp*);
           98  +    extern int Sqlitetestintarray_Init(Tcl_Interp*);
           99  +    extern int Sqlitetestvfs_Init(Tcl_Interp *);
          100  +    extern int Sqlitetestrtree_Init(Tcl_Interp*);
          101  +    extern int Sqlitequota_Init(Tcl_Interp*);
          102  +    extern int Sqlitemultiplex_Init(Tcl_Interp*);
          103  +    extern int SqliteSuperlock_Init(Tcl_Interp*);
          104  +    extern int SqlitetestSyscall_Init(Tcl_Interp*);
          105  +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
          106  +    extern int TestSession_Init(Tcl_Interp*);
          107  +#endif
          108  +    extern int Md5_Init(Tcl_Interp*);
          109  +    extern int Fts5tcl_Init(Tcl_Interp *);
          110  +    extern int SqliteRbu_Init(Tcl_Interp*);
          111  +    extern int Sqlitetesttcl_Init(Tcl_Interp*);
          112  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
          113  +    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
          114  +#endif
          115  +#ifdef SQLITE_ENABLE_ZIPVFS
          116  +    extern int Zipvfs_Init(Tcl_Interp*);
          117  +#endif
          118  +
          119  +    Sqlite3_Init(interp);
          120  +#ifdef SQLITE_ENABLE_ZIPVFS
          121  +    Zipvfs_Init(interp);
          122  +#endif
          123  +    Md5_Init(interp);
          124  +    Sqliteconfig_Init(interp);
          125  +    Sqlitetest1_Init(interp);
          126  +    Sqlitetest2_Init(interp);
          127  +    Sqlitetest3_Init(interp);
          128  +    Sqlitetest4_Init(interp);
          129  +    Sqlitetest5_Init(interp);
          130  +    Sqlitetest6_Init(interp);
          131  +    Sqlitetest7_Init(interp);
          132  +    Sqlitetest8_Init(interp);
          133  +    Sqlitetest9_Init(interp);
          134  +    Sqlitetestasync_Init(interp);
          135  +    Sqlitetest_autoext_Init(interp);
          136  +    Sqlitetest_blob_Init(interp);
          137  +    Sqlitetest_demovfs_Init(interp);
          138  +    Sqlitetest_func_Init(interp);
          139  +    Sqlitetest_hexio_Init(interp);
          140  +    Sqlitetest_init_Init(interp);
          141  +    Sqlitetest_malloc_Init(interp);
          142  +    Sqlitetest_mutex_Init(interp);
          143  +    Sqlitetestschema_Init(interp);
          144  +    Sqlitetesttclvar_Init(interp);
          145  +    Sqlitetestfs_Init(interp);
          146  +    SqlitetestThread_Init(interp);
          147  +    SqlitetestOnefile_Init();
          148  +    SqlitetestOsinst_Init(interp);
          149  +    Sqlitetestbackup_Init(interp);
          150  +    Sqlitetestintarray_Init(interp);
          151  +    Sqlitetestvfs_Init(interp);
          152  +    Sqlitetestrtree_Init(interp);
          153  +    Sqlitequota_Init(interp);
          154  +    Sqlitemultiplex_Init(interp);
          155  +    SqliteSuperlock_Init(interp);
          156  +    SqlitetestSyscall_Init(interp);
          157  +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
          158  +    TestSession_Init(interp);
          159  +#endif
          160  +    Fts5tcl_Init(interp);
          161  +    SqliteRbu_Init(interp);
          162  +    Sqlitetesttcl_Init(interp);
          163  +
          164  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
          165  +    Sqlitetestfts3_Init(interp);
          166  +#endif
          167  +
          168  +    Tcl_CreateObjCommand(
          169  +        interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
          170  +    );
          171  +  }
          172  +}
          173  +
          174  +/* tclcmd:   load_testfixture_extensions
          175  +*/
          176  +static int SQLITE_TCLAPI load_testfixture_extensions(
          177  +  ClientData cd,
          178  +  Tcl_Interp *interp,
          179  +  int objc,
          180  +  Tcl_Obj *CONST objv[]
          181  +){
          182  +
          183  +  Tcl_Interp *slave;
          184  +  if( objc!=2 ){
          185  +    Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
          186  +    return TCL_ERROR;
          187  +  }
          188  +
          189  +  slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
          190  +  if( !slave ){
          191  +    return TCL_ERROR;
          192  +  }
          193  +
          194  +  sqlite3InitTclTestLogic(slave);
          195  +  return TCL_OK;
          196  +}