mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Use a built-in atof() function instead of the one from the library to
avoid problems with locale. Ticket #305. (CVS 1144) FossilOrigin-Name: 4d9edbc50f7dee64edbadad2e2dc4f93d8248b3b
This commit is contained in:
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
|||||||
C Optimizations\sto\sthe\sLEMON\sparser\stemplate.\s(CVS\s1143)
|
C Use\sa\sbuilt-in\satof()\sfunction\sinstead\sof\sthe\sone\sfrom\sthe\slibrary\sto\navoid\sproblems\swith\slocale.\s\sTicket\s#305.\s(CVS\s1144)
|
||||||
D 2003-12-22T14:53:20
|
D 2003-12-23T02:17:35
|
||||||
F Makefile.in 0515ff9218ad8d5a8f6220f0494b8ef94c67013b
|
F Makefile.in 0515ff9218ad8d5a8f6220f0494b8ef94c67013b
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -28,11 +28,11 @@ F src/btree.h 9b7c09f1e64274d7bb74a57bbfc63778f67b1048
|
|||||||
F src/btree_rb.c e4084b6a12270674b0cd7034655f55e6a2639c78
|
F src/btree_rb.c e4084b6a12270674b0cd7034655f55e6a2639c78
|
||||||
F src/build.c a7493c433de5b552f9535d8fa7ed80aaf135491e
|
F src/build.c a7493c433de5b552f9535d8fa7ed80aaf135491e
|
||||||
F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73
|
F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73
|
||||||
F src/date.c acb75ff7849ca923837a9d3ef6b2d3e111a32fb0
|
F src/date.c ec36ce6f044fbc6c837c5bc52e71cdba0ea2746e
|
||||||
F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
|
F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
|
||||||
F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544
|
F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544
|
||||||
F src/expr.c a14401a54e5923f3e52b6d04a83813d150f43f33
|
F src/expr.c a14401a54e5923f3e52b6d04a83813d150f43f33
|
||||||
F src/func.c 82a749b9a03ae9834a90854464f93e29f902799b
|
F src/func.c b6ad8e786b5a0a9e2a80f617bdd5c0eb124ba652
|
||||||
F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
|
F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
|
||||||
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
||||||
F src/insert.c 01f66866f35c986eab4a57373ca689a3255ef2df
|
F src/insert.c 01f66866f35c986eab4a57373ca689a3255ef2df
|
||||||
@ -44,26 +44,26 @@ F src/pager.c ca24fced1ca4c2b8ea519d5fe8ec69a2d846276f
|
|||||||
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
|
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
|
||||||
F src/parse.y c65aa6c5508763806ac9734b0589b93480ec7e7a
|
F src/parse.y c65aa6c5508763806ac9734b0589b93480ec7e7a
|
||||||
F src/pragma.c deec7342741e371f3042adaee53fcc324c5dd1d4
|
F src/pragma.c deec7342741e371f3042adaee53fcc324c5dd1d4
|
||||||
F src/printf.c 12e45d482ac8abcc6f786fc99e5bed7dd9a51af0
|
F src/printf.c 09fac1bc6bb6f2ca4ac6589bee6e656dcc0499d1
|
||||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||||
F src/select.c d79ac60ba1595ff3c94b12892e87098329776482
|
F src/select.c d79ac60ba1595ff3c94b12892e87098329776482
|
||||||
F src/shell.c 3b067edc098c45caca164bcad1fa79192c3ec5ae
|
F src/shell.c 3b067edc098c45caca164bcad1fa79192c3ec5ae
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in e6cfff01fafc8a82ce82cd8c932af421dc9adb54
|
F src/sqlite.h.in e6cfff01fafc8a82ce82cd8c932af421dc9adb54
|
||||||
F src/sqliteInt.h f8549cf426920e43efb105a08484768cdb73c808
|
F src/sqliteInt.h a70744a84caec6d48017143ea5b9f945867e539e
|
||||||
F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
|
F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
|
||||||
F src/tclsqlite.c dcd18d1f0d51ac4863d1f9059f614f903bc1fffe
|
F src/tclsqlite.c dcd18d1f0d51ac4863d1f9059f614f903bc1fffe
|
||||||
F src/test1.c f9d5816610f7ec4168ab7b098d5207a5708712b6
|
F src/test1.c ba47a3e50379a1356acbc9a3388ad5eced85b740
|
||||||
F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
|
F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
|
||||||
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
|
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
|
||||||
F src/test4.c dcbbbb382626fd466a7c46907f74db35fc8bad64
|
F src/test4.c dcbbbb382626fd466a7c46907f74db35fc8bad64
|
||||||
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
||||||
F src/tokenize.c d10e7f0b4d8634f6f37237b4e65314e3e5a3a34b
|
F src/tokenize.c 5597df1fd76d6947e7da824856ac1910e2055729
|
||||||
F src/trigger.c ce83e017b407d046e909d05373d7f8ee70f9f7f9
|
F src/trigger.c ce83e017b407d046e909d05373d7f8ee70f9f7f9
|
||||||
F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
|
F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
|
||||||
F src/util.c cc95dd360fac09a059b2ab98e4c333d1a2308db5
|
F src/util.c 48631b7f7b2f3874fb3aa60396e18619933e9386
|
||||||
F src/vacuum.c 77485a64a6e4e358170f150fff681c1624a092b0
|
F src/vacuum.c 77485a64a6e4e358170f150fff681c1624a092b0
|
||||||
F src/vdbe.c 46068de5569a9ddb7d97f396f7acec1b02281f29
|
F src/vdbe.c a16a084ca40edeec3a2e490d6f672fc84f851dd9
|
||||||
F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43
|
F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43
|
||||||
F src/vdbeInt.h 2824bf88895b901b3a8c9e44527c67530e1c0dcb
|
F src/vdbeInt.h 2824bf88895b901b3a8c9e44527c67530e1c0dcb
|
||||||
F src/vdbeaux.c 877ae44ab42f43d38e8cd989087627508a4c98dd
|
F src/vdbeaux.c 877ae44ab42f43d38e8cd989087627508a4c98dd
|
||||||
@ -88,7 +88,7 @@ F test/date.test 17619ff81d5b813092915927c50923e265e85bd8
|
|||||||
F test/delete.test 92256384f1801760180ded129f7427884cf28886
|
F test/delete.test 92256384f1801760180ded129f7427884cf28886
|
||||||
F test/expr.test c4cc292d601019c2f2ce95093caaa5d10284b105
|
F test/expr.test c4cc292d601019c2f2ce95093caaa5d10284b105
|
||||||
F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
|
F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
|
||||||
F test/format3.test b05cb2968841553698290f2833f72894f156024e
|
F test/format3.test 149cc166c97923fa60def047e90dd3fb32bba916
|
||||||
F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4
|
F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4
|
||||||
F test/in.test 22de8a3eb27265aab723adc513bea0e76bef70c6
|
F test/in.test 22de8a3eb27265aab723adc513bea0e76bef70c6
|
||||||
F test/index.test 9295deefbdb6dedbe01be8905f0c448fe5bd4079
|
F test/index.test 9295deefbdb6dedbe01be8905f0c448fe5bd4079
|
||||||
@ -106,7 +106,7 @@ F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90
|
|||||||
F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af
|
F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af
|
||||||
F test/misc1.test 0b98d493b0cf55cb5f53e1f3df8107c166eecb5a
|
F test/misc1.test 0b98d493b0cf55cb5f53e1f3df8107c166eecb5a
|
||||||
F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be
|
F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be
|
||||||
F test/misc3.test 24b3b3fb96e52c129c70b5ad73c10237a2f3b859
|
F test/misc3.test cfece884d4e552400bb630efb6deda973a97eda2
|
||||||
F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
|
F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
|
||||||
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
||||||
F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
|
F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
|
||||||
@ -179,7 +179,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
|
|||||||
F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
||||||
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
||||||
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
||||||
P 952924084aac4a7fa84a7cb7aaac869d35db1896
|
P 06db29df8f0c1cd29e696537e622f0c5456056f5
|
||||||
R 7ab32ac7ee9a5574dd03ea51da394001
|
R 9d798a5665b47753acb63650cff0e583
|
||||||
U drh
|
U drh
|
||||||
Z bb57c31f5dd8de3fdff4945aa0883461
|
Z 5b1d9472f20aec057f316ff1b43aed10
|
||||||
|
@ -1 +1 @@
|
|||||||
06db29df8f0c1cd29e696537e622f0c5456056f5
|
4d9edbc50f7dee64edbadad2e2dc4f93d8248b3b
|
@ -16,7 +16,7 @@
|
|||||||
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
|
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
|
||||||
** All other code has file scope.
|
** All other code has file scope.
|
||||||
**
|
**
|
||||||
** $Id: date.c,v 1.1 2003/11/01 01:53:54 drh Exp $
|
** $Id: date.c,v 1.2 2003/12/23 02:17:35 drh Exp $
|
||||||
**
|
**
|
||||||
** NOTES:
|
** NOTES:
|
||||||
**
|
**
|
||||||
@ -322,7 +322,7 @@ static int parseDateOrTime(const char *zDate, DateTime *p){
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}else if( sqliteIsNumber(zDate) ){
|
}else if( sqliteIsNumber(zDate) ){
|
||||||
p->rJD = atof(zDate);
|
p->rJD = sqliteAtoF(zDate);
|
||||||
p->validJD = 1;
|
p->validJD = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||||
** All other code has file scope.
|
** All other code has file scope.
|
||||||
**
|
**
|
||||||
** $Id: func.c,v 1.33 2003/11/01 01:53:54 drh Exp $
|
** $Id: func.c,v 1.34 2003/12/23 02:17:35 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -149,7 +149,7 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){
|
|||||||
n = argc==2 ? atoi(argv[1]) : 0;
|
n = argc==2 ? atoi(argv[1]) : 0;
|
||||||
if( n>30 ) n = 30;
|
if( n>30 ) n = 30;
|
||||||
if( n<0 ) n = 0;
|
if( n<0 ) n = 0;
|
||||||
r = atof(argv[0]);
|
r = sqliteAtoF(argv[0]);
|
||||||
sprintf(zBuf,"%.*f",n,r);
|
sprintf(zBuf,"%.*f",n,r);
|
||||||
sqlite_set_result_string(context, zBuf, -1);
|
sqlite_set_result_string(context, zBuf, -1);
|
||||||
}
|
}
|
||||||
@ -397,7 +397,7 @@ static void sumStep(sqlite_func *context, int argc, const char **argv){
|
|||||||
if( argc<1 ) return;
|
if( argc<1 ) return;
|
||||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||||
if( p && argv[0] ){
|
if( p && argv[0] ){
|
||||||
p->sum += atof(argv[0]);
|
p->sum += sqliteAtoF(argv[0]);
|
||||||
p->cnt++;
|
p->cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ static void stdDevStep(sqlite_func *context, int argc, const char **argv){
|
|||||||
if( argc<1 ) return;
|
if( argc<1 ) return;
|
||||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||||
if( p && argv[0] ){
|
if( p && argv[0] ){
|
||||||
x = atof(argv[0]);
|
x = sqliteAtoF(argv[0]);
|
||||||
p->sum += x;
|
p->sum += x;
|
||||||
p->sum2 += x*x;
|
p->sum2 += x*x;
|
||||||
p->cnt++;
|
p->cnt++;
|
||||||
|
41
src/printf.c
41
src/printf.c
@ -758,6 +758,47 @@ char *sqlite_vmprintf(const char *zFormat, va_list ap){
|
|||||||
return zNew;
|
return zNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function implements the callback from vxprintf.
|
||||||
|
**
|
||||||
|
** This routine add nNewChar characters of text in zNewText to
|
||||||
|
** the sgMprintf structure pointed to by "arg". Unlike mout() above,
|
||||||
|
** this routine does not allocate new space when the buffer fills.
|
||||||
|
** It just truncates.
|
||||||
|
*/
|
||||||
|
static void sout(void *arg, char *zNewText, int nNewChar){
|
||||||
|
struct sgMprintf *pM = (struct sgMprintf*)arg;
|
||||||
|
if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
|
||||||
|
nNewChar = pM->nAlloc - pM->nChar - 1;
|
||||||
|
if( nNewChar<=0 ) return;
|
||||||
|
}
|
||||||
|
memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
|
||||||
|
pM->nChar += nNewChar;
|
||||||
|
pM->zText[pM->nChar] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** sqlite_sprintf() works like sprintf() except that it ignores the
|
||||||
|
** current locale settings. This is important for SQLite because we
|
||||||
|
** are not able to use a "," as the decimal point in place of "." as
|
||||||
|
** specified by some locales.
|
||||||
|
*/
|
||||||
|
int sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
|
||||||
|
va_list ap;
|
||||||
|
struct sgMprintf sMprintf;
|
||||||
|
|
||||||
|
sMprintf.nChar = 0;
|
||||||
|
sMprintf.nAlloc = n;
|
||||||
|
sMprintf.zText = zBuf;
|
||||||
|
sMprintf.zBase = zBuf;
|
||||||
|
va_start(ap,zFormat);
|
||||||
|
vxprintf(sout,&sMprintf,zFormat,ap);
|
||||||
|
va_end(ap);
|
||||||
|
return sMprintf.nChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The following four routines implement the varargs versions of the
|
** The following four routines implement the varargs versions of the
|
||||||
** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h
|
** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.204 2003/12/07 00:24:35 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.205 2003/12/23 02:17:35 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
@ -1203,3 +1203,5 @@ int sqliteFixSelect(DbFixer*, Select*);
|
|||||||
int sqliteFixExpr(DbFixer*, Expr*);
|
int sqliteFixExpr(DbFixer*, Expr*);
|
||||||
int sqliteFixExprList(DbFixer*, ExprList*);
|
int sqliteFixExprList(DbFixer*, ExprList*);
|
||||||
int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
|
int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
|
||||||
|
double sqliteAtoF(const char *z);
|
||||||
|
int sqlite_snprintf(int,char*,const char*,...);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.28 2003/09/06 22:18:08 drh Exp $
|
** $Id: test1.c,v 1.29 2003/12/23 02:17:35 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@ -552,7 +552,7 @@ static void testFunc(sqlite_func *context, int argc, const char **argv){
|
|||||||
}else if( sqliteStrICmp(argv[0],"int")==0 ){
|
}else if( sqliteStrICmp(argv[0],"int")==0 ){
|
||||||
sqlite_set_result_int(context, atoi(argv[1]));
|
sqlite_set_result_int(context, atoi(argv[1]));
|
||||||
}else if( sqliteStrICmp(argv[0],"double")==0 ){
|
}else if( sqliteStrICmp(argv[0],"double")==0 ){
|
||||||
sqlite_set_result_double(context, atof(argv[1]));
|
sqlite_set_result_double(context, sqliteAtoF(argv[1]));
|
||||||
}else{
|
}else{
|
||||||
sqlite_set_result_error(context,"first argument should be one of: "
|
sqlite_set_result_error(context,"first argument should be one of: "
|
||||||
"string int double", -1);
|
"string int double", -1);
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
** individual tokens and sends those tokens one-by-one over to the
|
** individual tokens and sends those tokens one-by-one over to the
|
||||||
** parser for analysis.
|
** parser for analysis.
|
||||||
**
|
**
|
||||||
** $Id: tokenize.c,v 1.65 2003/12/06 21:43:56 drh Exp $
|
** $Id: tokenize.c,v 1.66 2003/12/23 02:17:35 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -155,10 +155,11 @@ static Keyword *apHashTable[KEY_HASH_SIZE];
|
|||||||
int sqliteKeywordCode(const char *z, int n){
|
int sqliteKeywordCode(const char *z, int n){
|
||||||
int h;
|
int h;
|
||||||
Keyword *p;
|
Keyword *p;
|
||||||
if( aKeywordTable[0].len==0 ){
|
static char needInit = 1;
|
||||||
|
if( needInit ){
|
||||||
/* Initialize the keyword hash table */
|
/* Initialize the keyword hash table */
|
||||||
sqliteOsEnterMutex();
|
sqliteOsEnterMutex();
|
||||||
if( aKeywordTable[0].len==0 ){
|
if( needInit ){
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
|
n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
|
||||||
@ -169,6 +170,7 @@ int sqliteKeywordCode(const char *z, int n){
|
|||||||
aKeywordTable[i].pNext = apHashTable[h];
|
aKeywordTable[i].pNext = apHashTable[h];
|
||||||
apHashTable[h] = &aKeywordTable[i];
|
apHashTable[h] = &aKeywordTable[i];
|
||||||
}
|
}
|
||||||
|
needInit = 0;
|
||||||
}
|
}
|
||||||
sqliteOsLeaveMutex();
|
sqliteOsLeaveMutex();
|
||||||
}
|
}
|
||||||
|
73
src/util.c
73
src/util.c
@ -14,7 +14,7 @@
|
|||||||
** This file contains functions for allocating memory, comparing
|
** This file contains functions for allocating memory, comparing
|
||||||
** strings, and stuff like that.
|
** strings, and stuff like that.
|
||||||
**
|
**
|
||||||
** $Id: util.c,v 1.68 2003/10/22 22:15:28 drh Exp $
|
** $Id: util.c,v 1.69 2003/12/23 02:17:35 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -650,6 +650,69 @@ int sqliteIsNumber(const char *z){
|
|||||||
return *z==0;
|
return *z==0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The string z[] is an ascii representation of a real number.
|
||||||
|
** Convert this string to a double.
|
||||||
|
**
|
||||||
|
** This routine assumes that z[] really is a valid number. If it
|
||||||
|
** is not, the result is undefined.
|
||||||
|
**
|
||||||
|
** This routine is used instead of the library atof() function because
|
||||||
|
** the library atof() might want to use "," as the decimal point instead
|
||||||
|
** of "." depending on how locale is set. But that would cause problems
|
||||||
|
** for SQL. So this routine always uses "." regardless of locale.
|
||||||
|
*/
|
||||||
|
double sqliteAtoF(const char *z){
|
||||||
|
int sign = 1;
|
||||||
|
double v1 = 0.0;
|
||||||
|
if( *z=='-' ){
|
||||||
|
sign = -1;
|
||||||
|
z++;
|
||||||
|
}else if( *z=='+' ){
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
while( isdigit(*z) ){
|
||||||
|
v1 = v1*10.0 + (*z - '0');
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
if( *z=='.' ){
|
||||||
|
double divisor = 1.0;
|
||||||
|
z++;
|
||||||
|
while( isdigit(*z) ){
|
||||||
|
v1 = v1*10.0 + (*z - '0');
|
||||||
|
divisor *= 10.0;
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
v1 /= divisor;
|
||||||
|
}
|
||||||
|
if( *z=='e' || *z=='E' ){
|
||||||
|
int esign = 1;
|
||||||
|
int eval = 0;
|
||||||
|
double scale = 1.0;
|
||||||
|
z++;
|
||||||
|
if( *z=='-' ){
|
||||||
|
esign = -1;
|
||||||
|
z++;
|
||||||
|
}else if( *z=='+' ){
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
while( isdigit(*z) ){
|
||||||
|
eval = eval*10 + *z - '0';
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
|
||||||
|
while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
|
||||||
|
while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
|
||||||
|
while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
|
||||||
|
if( esign<0 ){
|
||||||
|
v1 /= scale;
|
||||||
|
}else{
|
||||||
|
v1 *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sign<0 ? -v1 : v1;
|
||||||
|
}
|
||||||
|
|
||||||
/* This comparison routine is what we use for comparison operations
|
/* This comparison routine is what we use for comparison operations
|
||||||
** between numeric values in an SQL expression. "Numeric" is a little
|
** between numeric values in an SQL expression. "Numeric" is a little
|
||||||
** bit misleading here. What we mean is that the strings have a
|
** bit misleading here. What we mean is that the strings have a
|
||||||
@ -678,8 +741,8 @@ int sqliteCompare(const char *atext, const char *btext){
|
|||||||
result = -1;
|
result = -1;
|
||||||
}else{
|
}else{
|
||||||
double rA, rB;
|
double rA, rB;
|
||||||
rA = atof(atext);
|
rA = sqliteAtoF(atext);
|
||||||
rB = atof(btext);
|
rB = sqliteAtoF(btext);
|
||||||
if( rA<rB ){
|
if( rA<rB ){
|
||||||
result = -1;
|
result = -1;
|
||||||
}else if( rA>rB ){
|
}else if( rA>rB ){
|
||||||
@ -771,8 +834,8 @@ int sqliteSortCompare(const char *a, const char *b){
|
|||||||
res = -1;
|
res = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rA = atof(&a[1]);
|
rA = sqliteAtoF(&a[1]);
|
||||||
rB = atof(&b[1]);
|
rB = sqliteAtoF(&b[1]);
|
||||||
if( rA<rB ){
|
if( rA<rB ){
|
||||||
res = -1;
|
res = -1;
|
||||||
break;
|
break;
|
||||||
|
16
src/vdbe.c
16
src/vdbe.c
@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.245 2003/12/10 01:31:21 drh Exp $
|
** $Id: vdbe.c,v 1.246 2003/12/23 02:17:35 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -187,9 +187,9 @@ static int hardStringify(Vdbe *p, int i){
|
|||||||
Stack *pStack = &p->aStack[i];
|
Stack *pStack = &p->aStack[i];
|
||||||
int fg = pStack->flags;
|
int fg = pStack->flags;
|
||||||
if( fg & STK_Real ){
|
if( fg & STK_Real ){
|
||||||
sprintf(pStack->z,"%.15g",pStack->r);
|
sqlite_snprintf(sizeof(pStack->z),pStack->z,"%.15g",pStack->r);
|
||||||
}else if( fg & STK_Int ){
|
}else if( fg & STK_Int ){
|
||||||
sprintf(pStack->z,"%d",pStack->i);
|
sqlite_snprintf(sizeof(pStack->z),pStack->z,"%d",pStack->i);
|
||||||
}else{
|
}else{
|
||||||
pStack->z[0] = 0;
|
pStack->z[0] = 0;
|
||||||
}
|
}
|
||||||
@ -321,7 +321,7 @@ static void hardIntegerify(Vdbe *p, int i){
|
|||||||
if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); }
|
if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); }
|
||||||
static void hardRealify(Vdbe *p, int i){
|
static void hardRealify(Vdbe *p, int i){
|
||||||
if( p->aStack[i].flags & STK_Str ){
|
if( p->aStack[i].flags & STK_Str ){
|
||||||
p->aStack[i].r = atof(p->zStack[i]);
|
p->aStack[i].r = sqliteAtoF(p->zStack[i]);
|
||||||
}else if( p->aStack[i].flags & STK_Int ){
|
}else if( p->aStack[i].flags & STK_Int ){
|
||||||
p->aStack[i].r = p->aStack[i].i;
|
p->aStack[i].r = p->aStack[i].i;
|
||||||
}else{
|
}else{
|
||||||
@ -2091,7 +2091,7 @@ case OP_MakeKey: {
|
|||||||
if( (flags & (STK_Real|STK_Int))==STK_Int ){
|
if( (flags & (STK_Real|STK_Int))==STK_Int ){
|
||||||
aStack[i].r = aStack[i].i;
|
aStack[i].r = aStack[i].i;
|
||||||
}else if( (flags & (STK_Real|STK_Int))==0 ){
|
}else if( (flags & (STK_Real|STK_Int))==0 ){
|
||||||
aStack[i].r = atof(zStack[i]);
|
aStack[i].r = sqliteAtoF(zStack[i]);
|
||||||
}
|
}
|
||||||
Release(p, i);
|
Release(p, i);
|
||||||
z = aStack[i].z;
|
z = aStack[i].z;
|
||||||
@ -4668,7 +4668,7 @@ case OP_Vacuum: {
|
|||||||
/* An other opcode is illegal...
|
/* An other opcode is illegal...
|
||||||
*/
|
*/
|
||||||
default: {
|
default: {
|
||||||
sprintf(zBuf,"%d",pOp->opcode);
|
sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
|
||||||
sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
|
sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
|
||||||
rc = SQLITE_INTERNAL;
|
rc = SQLITE_INTERNAL;
|
||||||
break;
|
break;
|
||||||
@ -4809,7 +4809,7 @@ abort_due_to_interrupt:
|
|||||||
** operands than are currently available on the stack.
|
** operands than are currently available on the stack.
|
||||||
*/
|
*/
|
||||||
not_enough_stack:
|
not_enough_stack:
|
||||||
sprintf(zBuf,"%d",pc);
|
sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc);
|
||||||
sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0);
|
sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0);
|
||||||
rc = SQLITE_INTERNAL;
|
rc = SQLITE_INTERNAL;
|
||||||
goto vdbe_halt;
|
goto vdbe_halt;
|
||||||
@ -4818,7 +4818,7 @@ not_enough_stack:
|
|||||||
*/
|
*/
|
||||||
VERIFY(
|
VERIFY(
|
||||||
bad_instruction:
|
bad_instruction:
|
||||||
sprintf(zBuf,"%d",pc);
|
sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc);
|
||||||
sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0);
|
sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0);
|
||||||
rc = SQLITE_INTERNAL;
|
rc = SQLITE_INTERNAL;
|
||||||
goto vdbe_halt;
|
goto vdbe_halt;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# focus of this file is testing the the library is able to correctly
|
# focus of this file is testing the the library is able to correctly
|
||||||
# handle file-format 3 (version 2.6.x) databases.
|
# handle file-format 3 (version 2.6.x) databases.
|
||||||
#
|
#
|
||||||
# $Id: format3.test,v 1.3 2003/06/03 01:47:12 drh Exp $
|
# $Id: format3.test,v 1.4 2003/12/23 02:17:35 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -686,7 +686,7 @@ do_test format3-11.2 {
|
|||||||
execsql {SELECT '0'==0.0}
|
execsql {SELECT '0'==0.0}
|
||||||
} {1}
|
} {1}
|
||||||
do_test format3-11.3 {
|
do_test format3-11.3 {
|
||||||
execsql {SELECT '12345678901234567890'=='12345678901234567891'}
|
execsql {SELECT '123456789012345678901'=='123456789012345678900'}
|
||||||
} {1}
|
} {1}
|
||||||
do_test format3-11.4 {
|
do_test format3-11.4 {
|
||||||
execsql {
|
execsql {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# This file implements tests for miscellanous features that were
|
# This file implements tests for miscellanous features that were
|
||||||
# left out of other test files.
|
# left out of other test files.
|
||||||
#
|
#
|
||||||
# $Id: misc3.test,v 1.1 2003/12/17 23:57:36 drh Exp $
|
# $Id: misc3.test,v 1.2 2003/12/23 02:17:35 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -68,4 +68,35 @@ do_test misc3-1.2 {
|
|||||||
}
|
}
|
||||||
} ok
|
} ok
|
||||||
|
|
||||||
|
# Tests of the sqliteAtoF() function in util.c
|
||||||
|
#
|
||||||
|
do_test misc3-2.1 {
|
||||||
|
execsql {SELECT 2e-25*0.5e25}
|
||||||
|
} 1
|
||||||
|
do_test misc3-2.2 {
|
||||||
|
execsql {SELECT 2.0e-25*000000.500000000000000000000000000000e+00025}
|
||||||
|
} 1
|
||||||
|
do_test misc3-2.3 {
|
||||||
|
execsql {SELECT 000000000002e-0000000025*0.5e25}
|
||||||
|
} 1
|
||||||
|
do_test misc3-2.4 {
|
||||||
|
execsql {SELECT 2e-25*0.5e250}
|
||||||
|
} 1e+225
|
||||||
|
do_test misc3-2.5 {
|
||||||
|
execsql {SELECT 2.0e-250*0.5e25}
|
||||||
|
} 1e-225
|
||||||
|
do_test misc3-2.6 {
|
||||||
|
execsql {SELECT '-2.0e-127' * '-0.5e27'}
|
||||||
|
} 1e-100
|
||||||
|
do_test misc3-2.7 {
|
||||||
|
execsql {SELECT '+2.0e-127' * '-0.5e27'}
|
||||||
|
} -1e-100
|
||||||
|
do_test misc3-2.8 {
|
||||||
|
execsql {SELECT 2.0e-27 * '+0.5e+127'}
|
||||||
|
} 1e+100
|
||||||
|
do_test misc3-2.9 {
|
||||||
|
execsql {SELECT 2.0e-27 * '+0.000005e+132'}
|
||||||
|
} 1e+100
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user