/ Check-in [2d8f7beb]
Login

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

Overview
Comment:Test coverage improvements on printf. (CVS 5385)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2d8f7bebf0f13f3a95f1e2163e35d43229cabfea
User & Date: drh 2008-07-09 16:51:51
Context
2008-07-10
00:32
Remove unused code. Test coverage enhancements. Modify the algorithm used to select column names for VIEWs of joins so that the constructed column names omits the underlying table names. (CVS 5386) check-in: 636cd723 user: drh tags: trunk
2008-07-09
16:51
Test coverage improvements on printf. (CVS 5385) check-in: 2d8f7beb user: drh tags: trunk
14:47
Add a test case to join.test. No code changes, no bugs found. (CVS 5384) check-in: 417aa158 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/printf.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
...
481
482
483
484
485
486
487

488
489

490
491
492
493
494
495
496
497
...
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
...
606
607
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
...
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
/*
** The "printf" code that follows dates from the 1980's.  It is in
** the public domain.  The original comments are included here for
** completeness.  They are very out-of-date but might be useful as
** an historical reference.  Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
** $Id: printf.c,v 1.88 2008/07/08 19:34:07 drh Exp $
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
** found in the standard C library.  The following enhancements are
** supported:
**
................................................................................
#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
#define etSIZE        5 /* Return number of characters processed so far. %n */
#define etSTRING      6 /* Strings. %s */
#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
#define etPERCENT     8 /* Percent symbol. %% */
#define etCHARX       9 /* Characters. %c */
/* The rest are extensions, not normally found in printf() */
#define etCHARLIT    10 /* Literal characters.  %' */
#define etSQLESCAPE  11 /* Strings with '\'' doubled.  %q */
#define etSQLESCAPE2 12 /* Strings with '\'' doubled and enclosed in '',
                          NULL pointers replaced by SQL NULL.  %Q */
#define etTOKEN      13 /* a pointer to a Token structure */
#define etSRCLIST    14 /* a pointer to a SrcList */
#define etPOINTER    15 /* The %p conversion */
#define etSQLESCAPE3 16 /* %w -> Strings with '\"' doubled */
#define etORDINAL    17 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */


/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;

................................................................................
          *(--bufpt) = '0';                             /* Zero pad */
        }
        if( prefix ) *(--bufpt) = prefix;               /* Add sign */
        if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
          const char *pre;
          char x;
          pre = &aPrefix[infop->prefix];
          if( *bufpt!=pre[0] ){
            for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
          }
        }
        length = &buf[etBUFSIZE-1]-bufpt;
        break;
      case etFLOAT:
      case etEXP:
      case etGENERIC:
        realvalue = va_arg(ap,double);
................................................................................
          length = 3;
          break;
        }
        if( realvalue>0.0 ){
          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }

          while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }

          if( exp>350 || exp<-350 ){
            if( prefix=='-' ){
              bufpt = "-Inf";
            }else if( prefix=='+' ){
              bufpt = "+Inf";
            }else{
              bufpt = "Inf";
            }
................................................................................
        }
        /* The decimal point */
        if( flag_dp ){
          *(bufpt++) = '.';
        }
        /* "0" digits after the decimal point but before the first
        ** significant digit of the number */
        for(e2++; e2<0 && precision>0; precision--, e2++){

          *(bufpt++) = '0';
        }
        /* Significant digits after the decimal point */
        while( (precision--)>0 ){
          *(bufpt++) = et_getdigit(&realvalue,&nsd);
        }
        /* Remove trailing zeros and the "." if no digits follow the "." */
................................................................................
              *(bufpt++) = '0';
            }else{
              *(--bufpt) = 0;
            }
          }
        }
        /* Add the "eNNN" suffix */
        if( flag_exp || (xtype==etEXP && exp) ){
          *(bufpt++) = aDigits[infop->charset];
          if( exp<0 ){
            *(bufpt++) = '-'; exp = -exp;
          }else{
            *(bufpt++) = '+';
          }
          if( exp>=100 ){
................................................................................
        length = width = 0;
        break;
      case etPERCENT:
        buf[0] = '%';
        bufpt = buf;
        length = 1;
        break;
      case etCHARLIT:
      case etCHARX:
        c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);

        if( precision>=0 ){
          for(idx=1; idx<precision; idx++) buf[idx] = c;
          length = precision;
        }else{
          length =1;
        }
        bufpt = buf;
................................................................................
        length = j;
        /* The precision is ignored on %q and %Q */
        /* if( precision>=0 && precision<length ) length = precision; */
        break;
      }
      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);
        if( pToken && pToken->z ){
          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);







|







 







<
|
|

|
|
|
|
|







 







<
|
<







 







>
|
|
>
|







 







|
>







 







|







 







<

<
>







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
...
439
440
441
442
443
444
445

446

447
448
449
450
451
452
453
...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
...
606
607
608
609
610
611
612

613

614
615
616
617
618
619
620
621
...
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
/*
** The "printf" code that follows dates from the 1980's.  It is in
** the public domain.  The original comments are included here for
** completeness.  They are very out-of-date but might be useful as
** an historical reference.  Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
** $Id: printf.c,v 1.89 2008/07/09 16:51:51 drh Exp $
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
** found in the standard C library.  The following enhancements are
** supported:
**
................................................................................
#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
#define etSIZE        5 /* Return number of characters processed so far. %n */
#define etSTRING      6 /* Strings. %s */
#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
#define etPERCENT     8 /* Percent symbol. %% */
#define etCHARX       9 /* Characters. %c */
/* The rest are extensions, not normally found in printf() */

#define etSQLESCAPE  10 /* Strings with '\'' doubled.  %q */
#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
                          NULL pointers replaced by SQL NULL.  %Q */
#define etTOKEN      12 /* a pointer to a Token structure */
#define etSRCLIST    13 /* a pointer to a SrcList */
#define etPOINTER    14 /* The %p conversion */
#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
#define etORDINAL    16 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */


/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;

................................................................................
          *(--bufpt) = '0';                             /* Zero pad */
        }
        if( prefix ) *(--bufpt) = prefix;               /* Add sign */
        if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
          const char *pre;
          char x;
          pre = &aPrefix[infop->prefix];

          for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;

        }
        length = &buf[etBUFSIZE-1]-bufpt;
        break;
      case etFLOAT:
      case etEXP:
      case etGENERIC:
        realvalue = va_arg(ap,double);
................................................................................
          length = 3;
          break;
        }
        if( realvalue>0.0 ){
          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
          if( realvalue>0.0 ){
            while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
            while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
          }
          if( exp>350 ){
            if( prefix=='-' ){
              bufpt = "-Inf";
            }else if( prefix=='+' ){
              bufpt = "+Inf";
            }else{
              bufpt = "Inf";
            }
................................................................................
        }
        /* The decimal point */
        if( flag_dp ){
          *(bufpt++) = '.';
        }
        /* "0" digits after the decimal point but before the first
        ** significant digit of the number */
        for(e2++; e2<0; precision--, e2++){
          assert( precision>0 );
          *(bufpt++) = '0';
        }
        /* Significant digits after the decimal point */
        while( (precision--)>0 ){
          *(bufpt++) = et_getdigit(&realvalue,&nsd);
        }
        /* Remove trailing zeros and the "." if no digits follow the "." */
................................................................................
              *(bufpt++) = '0';
            }else{
              *(--bufpt) = 0;
            }
          }
        }
        /* Add the "eNNN" suffix */
        if( flag_exp || xtype==etEXP ){
          *(bufpt++) = aDigits[infop->charset];
          if( exp<0 ){
            *(bufpt++) = '-'; exp = -exp;
          }else{
            *(bufpt++) = '+';
          }
          if( exp>=100 ){
................................................................................
        length = width = 0;
        break;
      case etPERCENT:
        buf[0] = '%';
        bufpt = buf;
        length = 1;
        break;

      case etCHARX:

        c = buf[0] = va_arg(ap,int);
        if( precision>=0 ){
          for(idx=1; idx<precision; idx++) buf[idx] = c;
          length = precision;
        }else{
          length =1;
        }
        bufpt = buf;
................................................................................
        length = j;
        /* The precision is ignored on %q and %Q */
        /* if( precision>=0 && precision<length ) length = precision; */
        break;
      }
      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);
        if( pToken ){
          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);

Changes to src/test_malloc.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1057
1058
1059
1060
1061
1062
1063


1064
1065
1066
1067
1068
1069
1070
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.34 2008/07/09 13:28:54 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

................................................................................
      break;
    }
  }
  if( i>=ArraySize(aOp) ){
    if( Tcl_GetIntFromObj(interp, objv[1], &op) ) return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[2], &resetFlag) ) return TCL_ERROR;


  rc = sqlite3_status(op, &iValue, &mxValue, resetFlag);
  pResult = Tcl_NewObj();
  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;







|







 







>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.35 2008/07/09 16:51:51 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

................................................................................
      break;
    }
  }
  if( i>=ArraySize(aOp) ){
    if( Tcl_GetIntFromObj(interp, objv[1], &op) ) return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[2], &resetFlag) ) return TCL_ERROR;
  iValue = 0;
  mxValue = 0;
  rc = sqlite3_status(op, &iValue, &mxValue, resetFlag);
  pResult = Tcl_NewObj();
  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
  Tcl_SetObjResult(interp, pResult);
  return TCL_OK;

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.179 2008/07/08 23:40:20 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRow);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
      sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol);
    }
    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
    if( pParse->nErr ) goto update_cleanup;
    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRow, regRowid);
    sqlite3ReleaseTempReg(pParse, regRowid);
    sqlite3ReleaseTempReg(pParse, regRow);

    sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
    sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
  }







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.180 2008/07/09 16:51:51 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRow);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
      sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol);
    }
    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
    /* if( pParse->nErr ) goto update_cleanup; */
    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRow, regRowid);
    sqlite3ReleaseTempReg(pParse, regRowid);
    sqlite3ReleaseTempReg(pParse, regRow);

    sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
    sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
  }

Changes to src/vdbemem.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
*************************************************************************
**
** This file contains code use to manipulate "Mem" structure.  A "Mem"
** stores a single value in the VDBE.  Mem is an opaque structure visible
** only within the VDBE.  Interface routines refer to a Mem using the
** name sqlite_value
**
** $Id: vdbemem.c,v 1.117 2008/07/08 22:28:49 shane Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
................................................................................
  assert( 1 >=
    ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
    (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + 
    ((pMem->flags&MEM_Ephem) ? 1 : 0) + 
    ((pMem->flags&MEM_Static) ? 1 : 0)
  );

  if( !pMem->zMalloc || sqlite3MallocSize(pMem->zMalloc)<n ){
    n = (n>32?n:32);
    if( preserve && pMem->z==pMem->zMalloc ){
      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
      if( !pMem->z ){
        pMem->flags = MEM_Null;
      }
      preserve = 0;
    }else{







|







 







|
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
*************************************************************************
**
** This file contains code use to manipulate "Mem" structure.  A "Mem"
** stores a single value in the VDBE.  Mem is an opaque structure visible
** only within the VDBE.  Interface routines refer to a Mem using the
** name sqlite_value
**
** $Id: vdbemem.c,v 1.118 2008/07/09 16:51:51 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
................................................................................
  assert( 1 >=
    ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
    (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + 
    ((pMem->flags&MEM_Ephem) ? 1 : 0) + 
    ((pMem->flags&MEM_Static) ? 1 : 0)
  );

  if( n<32 ) n = 32;
  if( sqlite3MallocSize(pMem->zMalloc)<n ){
    if( preserve && pMem->z==pMem->zMalloc ){
      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
      if( !pMem->z ){
        pMem->flags = MEM_Null;
      }
      preserve = 0;
    }else{

Changes to test/misc7.test.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
441
442
443
444
445
446
447











448
449
450
451
452
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# $Id: misc7.test,v 1.19 2008/03/15 14:53:05 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test misc7-1-misuse {
  c_misuse_test
} {}
................................................................................
    FROM
      (SELECT table_1.col_10 AS col_10 FROM table_1),
      (SELECT table_1.col_10, table_2.col_9 AS qcol_9
         FROM table_1, table_2
        GROUP BY table_1.col_10, qcol_9);
  }
} {}












db close
file delete -force test.db

finish_test







|







 







>
>
>
>
>
>
>
>
>
>
>





6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# $Id: misc7.test,v 1.20 2008/07/09 16:51:52 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test misc7-1-misuse {
  c_misuse_test
} {}
................................................................................
    FROM
      (SELECT table_1.col_10 AS col_10 FROM table_1),
      (SELECT table_1.col_10, table_2.col_9 AS qcol_9
         FROM table_1, table_2
        GROUP BY table_1.col_10, qcol_9);
  }
} {}

# Testing boundary conditions on sqlite3_status()
#
do_test misc7-19.1 {
  sqlite3_status -1 0
} {21 0 0}
do_test misc7-19.2 {
  sqlite3_status 1000 0
} {21 0 0}



db close
file delete -force test.db

finish_test

Changes to test/printf.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
3396
3397
3398
3399
3400
3401
3402



























3403



















3404
3405
3406
3407
3408
3409
3410
....
3611
3612
3613
3614
3615
3616
3617












3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite_*_printf() interface.
#
# $Id: printf.test,v 1.29 2008/07/08 02:24:03 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


do_test printf-1.1.1 {
  sqlite3_mprintf_int {abc: %d %x %o :xyz}\
................................................................................
} {abc: 3 2 (0.00) :xyz}
do_test printf-2.8.14.8 {
  sqlite3_mprintf_double {abc: %d %d (%3.2e) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 (3.39e-110) :xyz}
do_test printf-2.8.14.9 {
  sqlite3_mprintf_double {abc: %d %d (%3.2g) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 (3.4e-110) :xyz}
















































do_test printf-3.1 {
  sqlite3_mprintf_str {A String: (%*.*s)} 10 10 {This is the string}
} [format {A String: (%*.*s)} 10 10 {This is the string}]
do_test printf-3.2 {
  sqlite3_mprintf_str {A String: (%*.*s)} 10 5 {This is the string}
} [format {A String: (%*.*s)} 10 5 {This is the string}]
................................................................................
} 5
do_test printf-14.3 {
  sqlite3_mprintf_str {abc-%T-123} 0 0 {not used}
} {abc-}
do_test printf-14.4 {
  sqlite3_mprintf_str {abc-%#} 0 0 {not used}
} {abc-}













for {set i 2} {$i<200} {incr i} {
  set res [string repeat { } [expr {$i-1}]]x
  do_test printf-14.10.$i "
    sqlite3_mprintf_str {%*.*s} $i 500 x
  " $res
}

do_test printf-15.1 {
  sqlite3_snprintf_int 5 {12345} 0
} {1234}







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>



|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
....
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite_*_printf() interface.
#
# $Id: printf.test,v 1.30 2008/07/09 16:51:52 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


do_test printf-1.1.1 {
  sqlite3_mprintf_int {abc: %d %x %o :xyz}\
................................................................................
} {abc: 3 2 (0.00) :xyz}
do_test printf-2.8.14.8 {
  sqlite3_mprintf_double {abc: %d %d (%3.2e) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 (3.39e-110) :xyz}
do_test printf-2.8.14.9 {
  sqlite3_mprintf_double {abc: %d %d (%3.2g) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 (3.4e-110) :xyz}
do_test printf-2.8.15.1 {
  sqlite3_mprintf_double {abc: (% *.*f) :xyz} 3 2 3.38826392e-110
} {abc: ( 0.00) :xyz}
do_test printf-2.8.15.2 {
  sqlite3_mprintf_double {abc: (% *.*e) :xyz} 3 2 3.38826392e-110
} {abc: ( 3.39e-110) :xyz}
do_test printf-2.8.15.3 {
  sqlite3_mprintf_double {abc: (% *.*g) :xyz} 3 2 3.38826392e-110
} {abc: ( 3.4e-110) :xyz}
do_test printf-2.8.15.4 {
  sqlite3_mprintf_double {abc: %d %d (% g) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 ( 3.38826e-110) :xyz}
do_test printf-2.8.15.5 {
  sqlite3_mprintf_double {abc: %d %d (% #g) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 ( 3.38826e-110) :xyz}
do_test printf-2.8.15.6 {
  sqlite3_mprintf_double {abc: %d %d (%0 10g) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 ( 3.38826e-110) :xyz}
do_test printf-2.8.15.7 {
  sqlite3_mprintf_double {abc: %d %d (% 3.2f) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 ( 0.00) :xyz}
do_test printf-2.8.15.8 {
  sqlite3_mprintf_double {abc: %d %d (% 3.2e) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 ( 3.39e-110) :xyz}
do_test printf-2.8.15.9 {
  sqlite3_mprintf_double {abc: %d %d (% 3.2g) :xyz} 3 2 3.38826392e-110
} {abc: 3 2 ( 3.4e-110) :xyz}

do_test printf-2.9.1 {
  sqlite3_mprintf_double {abc: %d %d (%5.0g) :xyz} 0 0 1.234
} {abc: 0 0 (    1) :xyz}
do_test printf-2.9.2 {
  sqlite3_mprintf_double {abc: %d %d (%+5.0g) :xyz} 0 0 1.234
} {abc: 0 0 (   +1) :xyz}
do_test printf-2.9.3 {
  sqlite3_mprintf_double {abc: %d %d (%+-5.0g) :xyz} 0 0 1.234
} {abc: 0 0 (+1   ) :xyz}

do_test printf-2.10.1 {
  sqlite3_mprintf_double {abc: %d %d (%-010.5f) :xyz} 0 0 1.234
} {abc: 0 0 (1.23400   ) :xyz}
do_test printf-2.10.2 {
  sqlite3_mprintf_double {abc: %d %d (%010.5f) :xyz} 0 0 1.234
} {abc: 0 0 (0001.23400) :xyz}
do_test printf-2.10.3 {
  sqlite3_mprintf_double {abc: %d %d (%+010.5f) :xyz} 0 0 1.234
} {abc: 0 0 (+001.23400) :xyz}

do_test printf-3.1 {
  sqlite3_mprintf_str {A String: (%*.*s)} 10 10 {This is the string}
} [format {A String: (%*.*s)} 10 10 {This is the string}]
do_test printf-3.2 {
  sqlite3_mprintf_str {A String: (%*.*s)} 10 5 {This is the string}
} [format {A String: (%*.*s)} 10 5 {This is the string}]
................................................................................
} 5
do_test printf-14.3 {
  sqlite3_mprintf_str {abc-%T-123} 0 0 {not used}
} {abc-}
do_test printf-14.4 {
  sqlite3_mprintf_str {abc-%#} 0 0 {not used}
} {abc-}
do_test printf-14.5 {
  sqlite3_mprintf_str {abc-%*.*s-xyz} 10 -10 {a_very_long_string}
} {abc-a_very_lon-xyz}
do_test printf-14.6 {
  sqlite3_mprintf_str {abc-%5.10/} 0 0 {not used}
} {abc-}
do_test printf-14.7 {
  sqlite3_mprintf_str {abc-%05.5d} 123 0 {not used}
} {abc-00123}
do_test printf-14.8 {
  sqlite3_mprintf_str {abc-%05.5d} 1234567 0 {not used}
} {abc-1234567}

for {set i 2} {$i<200} {incr i} {
  set res [string repeat { } [expr {$i-1}]]x
  do_test printf-14.90.$i "
    sqlite3_mprintf_str {%*.*s} $i 500 x
  " $res
}

do_test printf-15.1 {
  sqlite3_snprintf_int 5 {12345} 0
} {1234}

Changes to test/tester.tcl.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
282
283
284
285
286
287
288










289
290
291
292
293
294
295
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.129 2008/07/08 12:07:33 danielk1977 Exp $

#
# What for user input before continuing.  This gives an opportunity
# to connect profiling tools to the process.
#
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[regexp {^-+pause$} [lindex $argv $i] all value]} {
................................................................................
    puts "soft-heap-limit set to $heaplimit"
  }
  sqlite3_soft_heap_limit 0
  incr nTest
  puts "$nErr errors out of $nTest tests"
  if {$nErr>0} {
    puts "Failures on these tests: $::failList"










  }
  if {[llength $omitList]>0} {
    puts "Omitted test cases:"
    set prec {}
    foreach {rec} [lsort $omitList] {
      if {$rec==$prec} continue
      set prec $rec







|







 







>
>
>
>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.130 2008/07/09 16:51:52 drh Exp $

#
# What for user input before continuing.  This gives an opportunity
# to connect profiling tools to the process.
#
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[regexp {^-+pause$} [lindex $argv $i] all value]} {
................................................................................
    puts "soft-heap-limit set to $heaplimit"
  }
  sqlite3_soft_heap_limit 0
  incr nTest
  puts "$nErr errors out of $nTest tests"
  if {$nErr>0} {
    puts "Failures on these tests: $::failList"
  }
  set failsafe [lindex [sqlite3_status SQLITE_STATUS_FAILSAFE 1] 1]
  if {$failsafe} {
    puts "Failsafe error code [format 0x%08x $failsafe]"
    incr nErr
  }
  set fs2 [lindex [sqlite3_status SQLITE_STATUS_FAILSAFE 0] 1]
  if {$fs2} {
    puts "Failsafe failed to reset"
    incr nErr
  }
  if {[llength $omitList]>0} {
    puts "Omitted test cases:"
    set prec {}
    foreach {rec} [lsort $omitList] {
      if {$rec==$prec} continue
      set prec $rec