Index: main.mk ================================================================== --- main.mk +++ main.mk @@ -63,12 +63,10 @@ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \ where.o utf.o legacy.o vtab.o -LIBOBJ += icu.o - # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ $(TOP)/src/analyze.c \ @@ -141,12 +139,10 @@ $(TOP)/ext/fts2/fts2_hash.c \ $(TOP)/ext/fts2/fts2_hash.h \ $(TOP)/ext/fts2/fts2_porter.c \ $(TOP)/ext/fts2/fts2_tokenizer.h \ $(TOP)/ext/fts2/fts2_tokenizer1.c -SRC += \ - $(TOP)/ext/icu/icu.c # Generated source code files # SRC += \ keywordhash.h \ Index: src/printf.c ================================================================== --- src/printf.c +++ src/printf.c @@ -835,10 +835,14 @@ */ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ char *z; va_list ap; + if( n<=0 ){ + return zBuf; + } + zBuf[0] = 0; va_start(ap,zFormat); z = base_vprintf(0, 0, zBuf, n, zFormat, ap); va_end(ap); return z; } Index: src/test1.c ================================================================== --- src/test1.c +++ src/test1.c @@ -11,11 +11,11 @@ ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.248 2007/05/07 09:32:45 danielk1977 Exp $ +** $Id: test1.c,v 1.249 2007/05/07 11:24:30 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include @@ -423,10 +423,37 @@ zStr = sqlite3MPrintf("%s%n", argv[1], &n); sqliteFree(zStr); Tcl_SetObjResult(interp, Tcl_NewIntObj(n)); return TCL_OK; } + +/* +** Usage: sqlite3_snprintf_int SIZE FORMAT INT +** +** Test the of sqlite3_snprintf() routine. SIZE is the size of the +** output buffer in bytes. The maximum size is 100. FORMAT is the +** format string. INT is a single integer argument. The FORMAT +** string must require no more than this one integer argument. If +** You pass in a format string that requires more than one argument, +** bad things will happen. +*/ +static int test_snprintf_int( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + char zStr[100]; + int n = atoi(argv[1]); + if( n>sizeof(zStr) ) n = sizeof(zStr); + const char *zFormat = argv[2]; + int a1 = atoi(argv[3]); + strcpy(zStr, "abcdefghijklmnopqrstuvwxyz"); + sqlite3_snprintf(n, zStr, zFormat, a1); + Tcl_AppendResult(interp, zStr, 0); + return TCL_OK; +} /* ** Usage: sqlite3_get_table_printf DB FORMAT STRING ** ** Invoke the sqlite3_get_table_printf() interface using the open database @@ -4607,10 +4634,11 @@ { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, { "sqlite3_mprintf_hexdouble", (Tcl_CmdProc*)sqlite3_mprintf_hexdouble}, { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, { "sqlite3_mprintf_n_test", (Tcl_CmdProc*)test_mprintf_n }, + { "sqlite3_snprintf_int", (Tcl_CmdProc*)test_snprintf_int }, { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, { "sqlite3_exec", (Tcl_CmdProc*)test_exec }, { "sqlite3_exec_nr", (Tcl_CmdProc*)test_exec_nr }, { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, Index: test/printf.test ================================================================== --- test/printf.test +++ test/printf.test @@ -9,11 +9,11 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the sqlite_*_printf() interface. # -# $Id: printf.test,v 1.22 2007/03/31 15:02:50 drh Exp $ +# $Id: printf.test,v 1.23 2007/05/07 11:24:31 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl set n 1 @@ -266,7 +266,16 @@ } 5 do_test printf-14.3 { sqlite3_mprintf_str {abc-%T-123} 0 0 {not used} } {abc-} +do_test printf-15.1 { + sqlite3_snprintf_int 5 {12345} 0 +} {1234} +do_test printf-15.2 { + sqlite3_snprintf_int 5 {} 0 +} {} +do_test printf-15.3 { + sqlite3_snprintf_int 0 {} 0 +} {abcdefghijklmnopqrstuvwxyz} finish_test Index: www/capi3ref.tcl ================================================================== --- www/capi3ref.tcl +++ www/capi3ref.tcl @@ -1,6 +1,6 @@ -set rcsid {$Id: capi3ref.tcl,v 1.56 2007/04/27 17:16:22 drh Exp $} +set rcsid {$Id: capi3ref.tcl,v 1.57 2007/05/07 11:24:31 drh Exp $} source common.tcl header {C/C++ Interface For SQLite Version 3} puts {

C/C++ Interface For SQLite Version 3

} @@ -1131,10 +1131,37 @@ This second example is an SQL syntax error. As a general rule you should always use %q instead of %s when inserting text into a string literal. } {} + +api {} { +char *sqlite3_snprintf(int bufSize, char *buf, const char *zFormat, ...); +} { + This routine works like "sprintf()", writing a formatted string into + the buf[]. However, no more than bufSize characters will be written + into buf[]. This routine returns a pointer to buf[]. If bufSize is + greater than zero, then buf[] is guaranteed to be zero-terminated. + + This routine uses the same extended formatting options as + sqlite3_mprintf() and sqlite3_vmprintf(). + + Note these differences with the snprintf() function found in many + standard libraries: (1) sqlite3_snprintf() returns a pointer to the + buffer rather than the number of characters written. (It would, + arguably, be more useful to return the number of characters written, + but we discovered that after the interface had been published and + are unwilling to break backwards compatibility.) (2) The order + of the bufSize and buf parameter is reversed from snprintf(). + And (3) sqlite3_snprintf() always writes a zero-terminator if bufSize + is positive. + + Please do not use the return value of this routine. We may + decide to make the minor compatibility break and change this routine + to return the number of characters written rather than a pointer to + the buffer in a future minor version increment. +} api {} { int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */