]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Bug fixes from Oleg Oleinick (CVS 195)
authordrh <drh@noemail.net>
Tue, 3 Apr 2001 16:53:21 +0000 (16:53 +0000)
committerdrh <drh@noemail.net>
Tue, 3 Apr 2001 16:53:21 +0000 (16:53 +0000)
FossilOrigin-Name: 1f0197d504fa2bde15b287ac6c0102cacdb1e482

17 files changed:
Makefile.in
VERSION
manifest
manifest.uuid
src/dbbe.h
src/dbbegdbm.c
src/dbbemem.c
src/pager.h [new file with mode: 0644]
src/sqlite.h.in
src/tclsqlite.c
src/test.file [deleted file]
test/dbbe.test
test/lock.test
test/tclsqlite.test [new file with mode: 0644]
tool/lemon.c
tool/lempar.c
www/changes.tcl

index b8d5f839c433ab9f451867289f82f236f4d86a21..113efaa35414b027285c90c91caa69fbbb84c082 100644 (file)
@@ -56,9 +56,8 @@ LIBOBJ = build.o dbbe.o dbbegdbm.o dbbemem.o delete.o expr.o insert.o \
 SRC = \
   $(TOP)/src/build.c \
   $(TOP)/src/dbbe.c \
-  $(TOP)/src/dbbegdbm.c \
-  $(TOP)/src/dbbemem.c \
   $(TOP)/src/dbbe.h \
+  $(TOP)/src/dbbegdbm.c \
   $(TOP)/src/dbbemem.c \
   $(TOP)/src/delete.c \
   $(TOP)/src/expr.c \
diff --git a/VERSION b/VERSION
index adb7b04cb2fa210fbe2ce1b09f9926f7bedea01e..8b54409523334d1445657a06489cc075505909a5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.27
+1.0.28
index c48e1a771f10d7605752a5f7424c7e7553054164..5d1dd7e794a25153e9842105bc7e675c6ce2f62e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,9 +1,9 @@
-C Version\s1.0.27\s(CVS\s476)
-D 2001-03-20T22:15:00
+C Bug\sfixes\sfrom\sOleg\sOleinick\s(CVS\s195)
+D 2001-04-03T16:53:22
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
-F Makefile.in 7efa81e2985b45ba73db27d55b70cc927f5abfd7
+F Makefile.in fd8815aa01a7181f60f786158b7737a35413189e
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
-F VERSION dee81fa1259d8cbb43230e982a9392f11f89859d
+F VERSION 010a68e4026cf015511e2c5acc54815fa374d11b
 F configure 3dc1edb9dcf60215e31ff72b447935ab62211442 x
 F configure.in d892ca33db7e88a055519ce2f36dcb11020e8fff
 F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
@@ -11,9 +11,9 @@ F doc/report1.txt 734cbae63b1310cc643fe5e9e3da1ab55a79b99e
 F src/TODO 38a68a489e56e9fd4a96263e0ff9404a47368ad4
 F src/build.c 7aa5879bf58ea6bbff22c26c59d1130021fa6ca4
 F src/dbbe.c b178f0959f6bac5ef8a109484c1571053f31abe5
-F src/dbbe.h 57d6debb99f6d7a91364b73cf3f0b129058ebbb3
-F src/dbbegdbm.c 84b2bf31d220f1de1cb0507ea051d30128fd681b
-F src/dbbemem.c d0fb86f1e8a52cdb195dc91d07f43765cf48bb95
+F src/dbbe.h 4b33f0cf884dfab49e39a422b2dcaf7a2a0e626c
+F src/dbbegdbm.c c4b2857e242ff8b4e8a5ac2d95e2e35f462ce8eb
+F src/dbbemem.c f0007eff4a00f28126c093f37f8e7dd2fcaa123b
 F src/delete.c 7aa9dcb86d5e98c3eb9dee00a459e0ef9b73fbe3
 F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a
 F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7
@@ -26,17 +26,17 @@ F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
 F src/expr.c 49bc261fdc4f4fb91c74cd668a9a952c00e85931
 F src/insert.c 4bc1cab84f7805d560a1417734a532843e30b762
 F src/main.c 5afe29c425b875acede20f609485866eb5b276f6
+F src/pager.h 889c5cf517ad30704e295540793c893ac843fd5f
 F src/parse.y 25ee4d8efccc4b247c32fe4ab194e3dd8fd5a4ee
 F src/printf.c af0dc65c293427272e1949c7807b1d88f10004fd
 F src/random.c b36c3f57dc80c8f354e6bfbf39cf1e1de021d54a
 F src/select.c faac634ef0c717bc82ca112a4531a257886f2c7a
 F src/shell.c 441e20913cde0bb71281f4027623c623530241cd
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
-F src/sqlite.h.in 7c1a53f020418d89d13ed2fe9c477ff54540755d
+F src/sqlite.h.in 3b446fcbed6005f0ab89632f3356c4708b349e88
 F src/sqliteInt.h 9887d207b98362392668410a11c59b3e334f51a1
 F src/table.c 5be76051a8ed6f6bfa641f4adc52529efa34fbf9
-F src/tclsqlite.c 2a925e1835c348f07dd17c87d95ae9a577833407
-F src/test.file 55ca6286e3e4f4fba5d0448333fa99fc5a404a73
+F src/tclsqlite.c f654b0399ea8a29262637dbe71fdfe7c26bd9032
 F src/tokenize.c c7ad428f38e56342eb2025320480b5ae9ece1b90
 F src/update.c 8365b3922ea098330d1e20862d6e64911e4e03d0
 F src/util.c f4573201fc2b581dbf601c53787349310b7da150
@@ -45,7 +45,7 @@ F src/vdbe.h 031b7dd7d6f94c51dc37cdf26efe43d1619bb672
 F src/where.c 478fde7c930969ca428de2d80b137959d25ee2fb
 F test/all.test 15cac2f6b2d4c55bf896212aff3cc9d6597b0490
 F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
-F test/dbbe.test 03a6940807f8a1e7538897b4c802a7937677e053
+F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c
 F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf
 F test/expr.test 48273bf48a15d226c35829f702af4254c0ff6795
 F test/func.test 02aed8845b98bde1043dda97455de1d37238ebb3
@@ -53,7 +53,7 @@ F test/in.test 2c560c0f55fb777029fd9bb5378f2997582aa603
 F test/index.test ee060ef8912be47ba616e50cce7985259a68d58a
 F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c
 F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
-F test/lock.test d8f0fc54f2a88969368c15490ea82811e2d7dd37
+F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a
 F test/main.test 5b0ed3d586c15b9136b9fd4916dcc95086639387
 F test/select1.test 68ff778c24fc8982e63dda37acb5b0396913adf7
 F test/select2.test 04ac3bd69298f58c7d0883159bab42ab9ad6021c
@@ -63,14 +63,15 @@ F test/select5.test e2b9d51d88cbd6c307c2c05b0ef55fe7ba811ac2
 F test/sort.test d582086c4bb7df3fbf50aa72e69d7e235e9f8e31
 F test/subselect.test bf8b251a92fb091973c1c469ce499dc9648a41d5
 F test/table.test eaa25951c0f18615763cd3dc248ea4bc38739c05
+F test/tclsqlite.test d2aa55926874783b2401f0146e839f773c6796e1
 F test/tester.tcl 01f881142be3bd8713abcea06747652067dafb78
 F test/update.test 72c0c93310483b86dc904a992220c5b84c7ce100
 F test/vacuum.test b95d8119a0a83dc6c4ac63888f8872f06199e065
 F test/where.test bbab5a308055fb6087dc23d600b4ad2b72797397
 F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b
 F tool/gdbmstat.c 56a9033531e5f5a48413f6ec436d5fb0341632c1
-F tool/lemon.c b13a31798574af881753d38f4da7d505929259c3
-F tool/lempar.c a1eec94d6eacc12332368660ec65f3b248853833
+F tool/lemon.c e007bfdbc79a51a4cd7c8a5f81f517cebd121150
+F tool/lempar.c 943b476d44b319eed525e46bb29e15f2c5986b37
 F tool/memleak.awk a0a11dd84bf4582acc81c3c61271021ae49b3f15
 F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
@@ -80,7 +81,7 @@ F www/arch.fig 4f246003b7da23bd63b8b0af0618afb4ee3055c8
 F www/arch.png 8dae0766d42ed3de9ed013c1341a5792bcf633e6
 F www/arch.tcl a40380c1fe0080c43e6cc5c20ed70731511b06be
 F www/c_interface.tcl 11be2d5826eb7d6efd629751d3b483c1ed78ba14
-F www/changes.tcl e01a5257038fafe0302b629d1b278789409029d2
+F www/changes.tcl 1be73dbd1d45471fdef05f627e8332206768f179
 F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
 F www/fileformat.tcl cfb7fba80b7275555281ba2f256c00734bcdd1c9
@@ -91,7 +92,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
 F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
 F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
-P daea156e2430762e683ff5460f9f8bb3204ae168
-R e053fcd301655951022cbe2ddba947b1
+P 833291c22734b2ac2342da84710320eb28f5d8cc
+R b3979afeb1b2a68085466c778c74b02f
 U drh
-Z ad447a72b5a7a06ad29b2399f5aa6480
+Z ceda48d7a4b9b3c738f23f47b38664dd
index c719651356165849dcbd7a98732c0096ccba265e..d89cf8b8ebb4469e209a606a3e2a5a2eba34a91d 100644 (file)
@@ -1 +1 @@
-833291c22734b2ac2342da84710320eb28f5d8cc
\ No newline at end of file
+1f0197d504fa2bde15b287ac6c0102cacdb1e482
\ No newline at end of file
index 6a386adf9af656ca838e9707acf81befb23bc3f6..31c6252f5c506ab5ea4c04f0e6679c0dd127d73a 100644 (file)
@@ -28,7 +28,7 @@
 ** This library was originally designed to support the following
 ** backends: GDBM, NDBM, SDBM, Berkeley DB.
 **
-** $Id: dbbe.h,v 1.11 2001/03/20 22:05:00 drh Exp $
+** $Id: dbbe.h,v 1.12 2001/04/03 16:53:22 drh Exp $
 */
 #ifndef _SQLITE_DBBE_H_
 #define _SQLITE_DBBE_H_
@@ -75,18 +75,19 @@ struct DbbeMethods {
   /* Close the whole database. */
   void (*Close)(Dbbe*);
 
-  /* Open a cursor into particular file of a previously opened database.
-  ** Create the file if it doesn't already exist and writeable!=0.  zName
-  ** is the base name of the file to be opened.  This routine will add
-  ** an appropriate path and extension to the filename to locate the 
+  /* Open a cursor into a particular table of a previously opened database.
+  ** Create the table if it doesn't already exist and writeable!=0.  zName
+  ** is the base name of the table to be opened.  If the database is 
+  ** implement as one file per table, then this routine will add an
+  ** appropriate path and extension to the table name to locate the 
   ** actual file.
   **
-  ** The keyType parameter is TRUE if this table will only be accessed
+  ** The intKeyOnly parameter is TRUE if this table will only be accessed
   ** using integer keys.  This parameter allows the database backend to
   ** use a faster algorithm for the special case of integer keys, if it
   ** wants to.
   **
-  ** If zName is 0 or "", then a temporary file is created that
+  ** If zName is 0 or "", then a temporary table is created that
   ** will be deleted when closed.
   */
   int (*OpenCursor)(Dbbe*, const char *zName, int writeable, 
@@ -165,7 +166,8 @@ struct DbbeMethods {
 struct Dbbe {
   struct DbbeMethods *x; /* Backend-specific methods for database access */
   /* There used to be other information here, but it has since
-  ** been removed.  */
+  ** been removed.  We'll keep the same design, though, in case we
+  ** ever want to add some new fields in the future. */
 };
 
 #endif /* defined(_SQLITE_DBBE_H_) */
index 777c7dacef4c43539946bc6ec5e82163b474b932..8aba06b32f267bec4573662c44eb6924eda8ead3 100644 (file)
@@ -30,7 +30,7 @@
 ** relatively simple to convert to a different database such
 ** as NDBM, SDBM, or BerkeleyDB.
 **
-** $Id: dbbegdbm.c,v 1.4 2001/03/20 22:05:00 drh Exp $
+** $Id: dbbegdbm.c,v 1.5 2001/04/03 16:53:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include <gdbm.h>
@@ -46,6 +46,9 @@
 ** for a self-join, for example) then two DbbeCursor structures are
 ** created but there is only a single BeFile structure with an
 ** nRef of 2.
+**
+** This backend uses a separate disk file for each database table
+** and index.
 */
 typedef struct BeFile BeFile;
 struct BeFile {
@@ -545,7 +548,7 @@ static int sqliteGdbmDelete(DbbeCursor *pCursr, int nKey, char *pKey){
 ** used to implement the GDBM backend.
 */
 static struct DbbeMethods gdbmMethods = {
-  /* n         Close */   sqliteGdbmClose,
+  /*           Close */   sqliteGdbmClose,
   /*      OpenCursor */   sqliteGdbmOpenCursor,
   /*       DropTable */   sqliteGdbmDropTable,
   /* ReorganizeTable */   sqliteGdbmReorganizeTable,
index 6bf1cc0f2f43504c2725ea098a4aa7f1c8a37ec7..86ddcf5706a89e3815f9ad8a23dddabb5511c7ed 100644 (file)
 ** of information to the disk.
 **
 ** This file uses an in-memory hash table as the database backend. 
+** Nothing is ever written to disk using this backend.  All information
+** is forgotten when the program exits.
 **
-** $Id: dbbemem.c,v 1.11 2001/03/20 22:05:00 drh Exp $
+** $Id: dbbemem.c,v 1.12 2001/04/03 16:53:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include <sys/stat.h>
@@ -720,7 +722,7 @@ static int sqliteMemDelete(DbbeCursor *pCursr, int nKey, char *pKey){
 ** used to implement the MEMORY backend.
 */
 static struct DbbeMethods memoryMethods = {
-  /* n         Close */   sqliteMemClose,
+  /*           Close */   sqliteMemClose,
   /*      OpenCursor */   sqliteMemOpenCursor,
   /*       DropTable */   sqliteMemDropTable,
   /* ReorganizeTable */   sqliteMemReorganizeTable,
diff --git a/src/pager.h b/src/pager.h
new file mode 100644 (file)
index 0000000..cec8f4e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+** Copyright (c) 2001 D. Richard Hipp
+**
+** This program is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public
+** License as published by the Free Software Foundation; either
+** version 2 of the License, or (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+** General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public
+** License along with this library; if not, write to the
+** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+** Boston, MA  02111-1307, USA.
+**
+** Author contact information:
+**   drh@hwaci.com
+**   http://www.hwaci.com/drh/
+**
+*************************************************************************
+** This header file defines the interface that the sqlite page cache
+** subsystem.  The page cache subsystem reads and writes a file a page
+** at a time and provides a journal for rollback.
+**
+** @(#) $Id: pager.h,v 1.1 2001/04/03 16:53:22 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** The size of one page
+*/
+#define SQLITE_PAGE_SIZE 1024
+
+/*
+** The type used to represent a page number.  The first page in a file
+** is called page 1.  0 is used to represent "not a page".
+*/
+typedef unsigned int Pgno;
+
+/*
+** Each open file is managed by a separate instance of the "Pager" structure.
+*/
+typedef struct Pager Pager;
+
+int sqlite_pager_open(Pager **ppPager, const char *zFilename);
+int sqlite_pager_close(Pager *pPager);
+int sqlite_pager_get(Pager *pPager, Pgno pgno, void **ppPage);
+int sqlite_pager_unref(void*);
+Pgno sqlite_pager_pagenumber(void*);
+int sqlite_pager_write(void*);
+int sqlite_pager_pagecount(Pager*);
+int sqlite_pager_commit(Pager*);
+int sqlite_pager_rollback(Pager*);
index 1f1980dc1d8acc632a80af69d894cb0bb226d533..59332dcf92339b40aea1b4d57861ee08cc0bff16 100644 (file)
@@ -24,7 +24,7 @@
 ** This header file defines the interface that the sqlite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.9 2001/01/20 19:52:49 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.10 2001/04/03 16:53:22 drh Exp $
 */
 #ifndef _SQLITE_H_
 #define _SQLITE_H_
@@ -142,6 +142,8 @@ int sqlite_exec(
 #define SQLITE_CORRUPT   10   /* The database disk image is malformed */
 #define SQLITE_NOTFOUND  11   /* Table or record not found */
 #define SQLITE_FULL      12   /* Insertion failed because database is full */
+#define SQLITE_CANTOPEN  13   /* Unable to open the database file */
+#define SQLITE_PROTOCOL  14   /* Database lock protocol error */
 
 /* This function causes any pending database operation to abort and
 ** return at its earliest opportunity.  This routine is typically
index 81c9ddb7e2fb6aa78b76a12c7d3dfbe0845cc78b..c88052422074b8ab2be45f618010b07ebc08200f 100644 (file)
@@ -23,7 +23,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.13 2001/01/31 13:28:09 drh Exp $
+** $Id: tclsqlite.c,v 1.14 2001/04/03 16:53:22 drh Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -53,6 +53,7 @@ struct CallbackData {
   char *zArray;             /* The array into which data is written */
   Tcl_Obj *pCode;           /* The code to execute for each row */
   int once;                 /* Set only for the first invocation of callback */
+  int tcl_rc;               /* Return code from TCL script */
 };
 
 /*
@@ -88,7 +89,9 @@ static int DbEvalCallback(
   }
   cbData->once = 0;
   rc = Tcl_EvalObj(cbData->interp, cbData->pCode);
-  return rc!=TCL_OK && rc!=TCL_CONTINUE;
+  if( rc==TCL_CONTINUE ) rc = TCL_OK;
+  cbData->tcl_rc = rc;
+  return rc!=TCL_OK;
 }
 
 /*
@@ -171,7 +174,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   SqliteDb *pDb = (SqliteDb*)cd;
   int choice;
   static char *DB_optStrs[] = {
-     "busy",   "close",  "complete",  "eval",  "timeout"
+     "busy",   "close",  "complete",  "eval",  "timeout", 0
   };
   enum DB_opts {
      DB_BUSY,  DB_CLOSE, DB_COMPLETE, DB_EVAL, DB_TIMEOUT
@@ -278,20 +281,26 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       cbData.once = 1;
       cbData.zArray = Tcl_GetStringFromObj(objv[3], 0);
       cbData.pCode = objv[4];
+      cbData.tcl_rc = TCL_OK;
       zErrMsg = 0;
       Tcl_IncrRefCount(objv[3]);
       Tcl_IncrRefCount(objv[4]);
       rc = sqlite_exec(pDb->db, zSql, DbEvalCallback, &cbData, &zErrMsg);
       Tcl_DecrRefCount(objv[4]);
       Tcl_DecrRefCount(objv[3]);
+      if( cbData.tcl_rc==TCL_BREAK ){ cbData.tcl_rc = TCL_OK; }
     }else{
       Tcl_Obj *pList = Tcl_NewObj();
+      cbData.tcl_rc = TCL_OK;
       rc = sqlite_exec(pDb->db, zSql, DbEvalCallback2, pList, &zErrMsg);
       Tcl_SetObjResult(interp, pList);
     }
     if( zErrMsg ){
       Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
       free(zErrMsg);
+      rc = TCL_ERROR;
+    }else{
+      rc = cbData.tcl_rc;
     }
     Tcl_DecrRefCount(objv[2]);
     return rc;
diff --git a/src/test.file b/src/test.file
deleted file mode 100644 (file)
index 45b983b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-hi
index d30047bc153dbd45bdea3e4ca13b0c09e8732424..c9cd2148c3110de59135960dc27482a501b4a81d 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is exercising the code in dbbe.c.
 #
-# $Id: dbbe.test,v 1.6 2001/03/20 12:55:14 drh Exp $
+# $Id: dbbe.test,v 1.7 2001/04/03 16:53:22 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -134,7 +134,7 @@ do_test dbbe-3.1 {
   sqlite db testdb 0444
   set v [catch {execsql {INSERT INTO t1 VALUES(1)}} msg]
   lappend v $msg
-} {7 {table t1 is readonly}}
+} {1 {table t1 is readonly}}
 
 
 finish_test
index bae3864e25eeea697f86057151483a67f684e3ee..ce93b0e7760f188f1dfb888b6ac196041ca0372a 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is database locks.
 #
-# $Id: lock.test,v 1.7 2001/03/20 12:55:14 drh Exp $
+# $Id: lock.test,v 1.8 2001/04/03 16:53:22 drh Exp $
 
 if {$dbprefix=="gdbm:" && $::tcl_platform(platform)!="windows"} {
 
@@ -60,7 +60,7 @@ do_probtest lock-1.2 {
   #
   set v [catch {execsql {UPDATE big SET f2='xyz' WHERE f1=11}} msg]
   lappend v $msg
-} {5 {table big is locked}}
+} {1 {table big is locked}}
 
 do_probtest lock-1.3 {
   # Try to update the database in a separate process
diff --git a/test/tclsqlite.test b/test/tclsqlite.test
new file mode 100644 (file)
index 0000000..fd1f37a
--- /dev/null
@@ -0,0 +1,80 @@
+# Copyright (c) 1999, 2000 D. Richard Hipp
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA  02111-1307, USA.
+#
+# Author contact information:
+#   drh@hwaci.com
+#   http://www.hwaci.com/drh/
+#
+#***********************************************************************
+# This file implements regression tests for TCL interface to the
+# SQLite library. 
+#
+# Actually, all tests are based on the TCL interface, so the main
+# interface is pretty well tested.  This file contains some addition
+# tests for fringe issues that the main test suite does not cover.
+#
+# $Id: tclsqlite.test,v 1.1 2001/04/03 16:53:22 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Check the error messages generated by tclsqlite
+#
+do_test tcl-1.1 {
+  set v [catch {sqlite bogus} msg]
+  lappend v $msg
+} {1 {wrong # args: should be "sqlite HANDLE FILENAME ?MODE?"}}
+do_test tcl-1.2 {
+  set v [catch {db bogus} msg]
+  lappend v $msg
+} {1 {bad option "bogus": must be busy, close, complete, eval, or timeout}}
+do_test tcl-1.3 {
+  execsql {CREATE TABLE t1(a int, b int)}
+  execsql {INSERT INTO t1 VALUES(10,20)}
+  set v [catch {
+    db eval {SELECT * FROM t1} data {
+      error "The error message"
+    }
+  } msg]
+  lappend v $msg
+} {1 {The error message}}
+do_test tcl-1.4 {
+  set v [catch {
+    db eval {SELECT * FROM t2} data {
+      error "The error message"
+    }
+  } msg]
+  lappend v $msg
+} {1 {no such table: t2}}
+do_test tcl-1.5 {
+  set v [catch {
+    db eval {SELECT * FROM t1} data {
+      break
+    }
+  } msg]
+  lappend v $msg
+} {0 {}}
+do_test tcl-1.6 {
+  set v [catch {
+    db eval {SELECT * FROM t1} data {
+      expr x*
+    }
+  } msg]
+  lappend v $msg
+} {1 {syntax error in expression "x*"}}
+
+finish_test
index e0ea780439609d8cd50d6c3d55d93450c64bab6e..41426caa97204adc5d5132d2146c7ee5e45bc0da 100644 (file)
@@ -3,8 +3,8 @@
 **
 ** This file contains all sources (including headers) to the LEMON
 ** LALR(1) parser generator.  The sources have been combined into a
-** single file to make it easy to include LEMON as part of another
-** program.
+** single file to make it easy to include LEMON in the source tree
+** and Makefile of another program.
 **
 ** This program is free software; you can redistribute it and/or
 ** modify it under the terms of the GNU General Public
@@ -263,6 +263,7 @@ struct lemon {
   char *name;              /* Name of the generated parser */
   char *arg;               /* Declaration of the 3th argument to parser */
   char *tokentype;         /* Type of terminal symbols in the parser stack */
+  char *vartype;           /* The default type of non-terminal symbols */
   char *start;             /* Name of the start symbol for the grammar */
   char *stacksize;         /* Size of the parser stack */
   char *include;           /* Code to put at the start of the C file */
@@ -279,6 +280,8 @@ struct lemon {
   int  extracodeln;        /* Line number for the start of the extra code */
   char *tokendest;         /* Code to execute to destroy token data */
   int  tokendestln;        /* Line number for token destroyer code */
+  char *vardest;           /* Code for the default non-terminal destructor */
+  int  vardestln;          /* Line number for default non-term destructor code*/
   char *filename;          /* Name of the input file */
   char *outname;           /* Name of the current output file */
   char *tokenprefix;       /* A prefix added to token names in the .h file */
@@ -1216,9 +1219,11 @@ char **argv;
   lem.basisflag = basisflag;
   lem.nconflict = 0;
   lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0;
+  lem.vartype = 0;
   lem.stacksize = 0;
   lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest =
      lem.tokenprefix = lem.outname = lem.extracode = 0;
+  lem.vardest = 0;
   lem.tablesize = 0;
   Symbol_new("$");
   lem.errsym = Symbol_new("error");
@@ -1967,6 +1972,9 @@ to follow the previous rule.");
        }else if( strcmp(x,"token_destructor")==0 ){
           psp->declargslot = &psp->gp->tokendest;
           psp->decllnslot = &psp->gp->tokendestln;
+       }else if( strcmp(x,"default_destructor")==0 ){
+          psp->declargslot = &psp->gp->vardest;
+          psp->decllnslot = &psp->gp->vardestln;
        }else if( strcmp(x,"token_prefix")==0 ){
           psp->declargslot = &psp->gp->tokenprefix;
        }else if( strcmp(x,"syntax_error")==0 ){
@@ -1985,6 +1993,8 @@ to follow the previous rule.");
           psp->declargslot = &(psp->gp->arg);
         }else if( strcmp(x,"token_type")==0 ){
           psp->declargslot = &(psp->gp->tokentype);
+        }else if( strcmp(x,"default_type")==0 ){
+          psp->declargslot = &(psp->gp->vartype);
         }else if( strcmp(x,"stack_size")==0 ){
           psp->declargslot = &(psp->gp->stacksize);
         }else if( strcmp(x,"start_symbol")==0 ){
@@ -2210,7 +2220,7 @@ struct lemon *gp;
        }
       }
       if( c==0 ){
-        ErrorMsg(ps.filename,startline,
+        ErrorMsg(ps.filename,ps.tokenlineno,
 "C code starting on this line is not terminated before the end of the file.");
         ps.errorcnt++;
         nextcp = cp;
@@ -2643,6 +2653,8 @@ struct lemon *lemp;
   }
   if( access(buf,004)==0 ){
     tpltname = buf;
+  }else if( access(templatename,004)==0 ){
+    tpltname = templatename;
   }else{
     tpltname = pathsearch(lemp->argv0,templatename,0);
   }
@@ -2697,10 +2709,13 @@ int *lineno;
    cp = lemp->tokendest;
    if( cp==0 ) return;
    fprintf(out,"#line %d \"%s\"\n{",lemp->tokendestln,lemp->filename);
- }else{
+ }else if( sp->destructor ){
    cp = sp->destructor;
-   if( cp==0 ) return;
    fprintf(out,"#line %d \"%s\"\n{",sp->destructorln,lemp->filename);
+ }else if( lemp->vardest ){
+   cp = lemp->vardest;
+   if( cp==0 ) return;
+   fprintf(out,"#line %d \"%s\"\n{",lemp->vardestln,lemp->filename);
  }
  for(; *cp; cp++){
    if( *cp=='$' && cp[1]=='$' ){
@@ -2717,7 +2732,7 @@ int *lineno;
 }
 
 /*
-** Return TRUE (non-zero) if the given symbol has a distructor.
+** Return TRUE (non-zero) if the given symbol has a destructor.
 */
 int has_destructor(sp, lemp)
 struct symbol *sp;
@@ -2727,7 +2742,7 @@ struct lemon *lemp;
   if( sp->type==TERMINAL ){
     ret = lemp->tokendest!=0;
   }else{
-    ret = sp->destructor!=0;
+    ret = lemp->vardest!=0 || sp->destructor!=0;
   }
   return ret;
 }
@@ -2796,7 +2811,7 @@ int *lineno;
  for(i=0; i<rp->nrhs; i++){
    if( rp->rhsalias[i] && !used[i] ){
      ErrorMsg(lemp->filename,rp->ruleline,
-       "Label $%s$ for \"%s(%s)\" is never used.",
+       "Label %s for \"%s(%s)\" is never used.",
        rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
      lemp->errorcnt++;
    }else if( rp->rhsalias[i]==0 ){
@@ -2840,6 +2855,9 @@ int mhflag;                 /* True if generating makeheaders output */
   types = (char**)malloc( arraysize * sizeof(char*) );
   for(i=0; i<arraysize; i++) types[i] = 0;
   maxdtlength = 0;
+  if( lemp->vartype ){
+    maxdtlength = strlen(lemp->vartype);
+  }
   for(i=0; i<lemp->nsymbol; i++){
     int len;
     struct symbol *sp = lemp->symbols[i];
@@ -2855,8 +2873,10 @@ int mhflag;                 /* True if generating makeheaders output */
 
   /* Build a hash table of datatypes. The ".dtnum" field of each symbol
   ** is filled in with the hash index plus 1.  A ".dtnum" value of 0 is
-  ** used for terminal symbols and for nonterminals which don't specify
-  ** a datatype using the %type directive. */
+  ** used for terminal symbols.  If there is no %default_type defined then
+  ** 0 is also used as the .dtnum value for nonterminals which do not specify
+  ** a datatype using the %type directive.
+  */
   for(i=0; i<lemp->nsymbol; i++){
     struct symbol *sp = lemp->symbols[i];
     char *cp;
@@ -2864,11 +2884,12 @@ int mhflag;                 /* True if generating makeheaders output */
       sp->dtnum = arraysize+1;
       continue;
     }
-    if( sp->type!=NONTERMINAL || sp->datatype==0 ){
+    if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){
       sp->dtnum = 0;
       continue;
     }
     cp = sp->datatype;
+    if( cp==0 ) cp = lemp->vartype;
     j = 0;
     while( isspace(*cp) ) cp++;
     while( *cp ) stddt[j++] = *cp++;
@@ -3159,6 +3180,20 @@ int mhflag;     /* Output in makeheaders format if true */
     emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
     fprintf(out,"      break;\n"); lineno++;
   }
+  if( lemp->vardest ){
+    struct symbol *dflt_sp = 0;
+    for(i=0; i<lemp->nsymbol; i++){
+      struct symbol *sp = lemp->symbols[i];
+      if( sp==0 || sp->type==TERMINAL ||
+          sp->index<=0 || sp->destructor!=0 ) continue;
+      fprintf(out,"    case %d:\n",sp->index); lineno++;
+      dflt_sp = sp;
+    }
+    if( dflt_sp!=0 ){
+      emit_destructor_code(out,dflt_sp,lemp,&lineno);
+      fprintf(out,"      break;\n"); lineno++;
+    }
+  }
   tplt_xfer(lemp->name,in,out,&lineno);
 
   /* Generate code which executes whenever the parser stack overflows */
index e5293b1de28364ac57f481cb828fa0044765818c..8b35e86bf86d787f88e26db7e7a104296b9db5a8 100644 (file)
@@ -1,9 +1,5 @@
 /* Driver template for the LEMON parser generator.
 ** Copyright 1991-1995 by D. Richard Hipp.
-*
-* This version is specially modified for use with sqlite.
-* @(#) $Id: lempar.c,v 1.1 2000/05/29 14:26:02 drh Exp $
-*
 **
 ** This library is free software; you can redistribute it and/or
 ** modify it under the terms of the GNU Library General Public
@@ -177,7 +173,6 @@ static char *yyTracePrompt = 0;
 ** Outputs:
 ** None.
 */
-/* SQLITE MODIFICATION: Give the function file scope */
 void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
   yyTraceFILE = TraceFILE;
   yyTracePrompt = zTracePrompt;
@@ -195,6 +190,18 @@ static char *yyTokenName[] = {
 #define YYTRACE(X)
 #endif
 
+/*
+** This function returns the symbolic name associated with a token
+** value.
+*/
+const char *ParseTokenName(int tokenType){
+  if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
+    return yyTokenName[tokenType];
+  }else{
+    return "Unknown";
+  }
+}
+
 /* 
 ** This function allocates a new parser.
 ** The only argument is a pointer to a function which works like
@@ -207,10 +214,9 @@ static char *yyTokenName[] = {
 ** A pointer to a parser.  This pointer is used in subsequent calls
 ** to Parse and ParseFree.
 */
-/* SQLITE MODIFICATION: Give the function file scope */
-void *ParseAlloc(void *(*mallocProc)()){
+void *ParseAlloc(void *(*mallocProc)(int)){
   yyParser *pParser;
-  pParser = (yyParser*)(*mallocProc)( sizeof(yyParser), __FILE__, __LINE__ );
+  pParser = (yyParser*)(*mallocProc)( (int)sizeof(yyParser) );
   if( pParser ){
     pParser->idx = -1;
   }
@@ -277,15 +283,14 @@ static int yy_pop_parser_stack(yyParser *pParser){
 **       from malloc.
 ** </ul>
 */
-/* SQLITE MODIFICATION: Give the function file scope */
 void ParseFree(
-  void *p,               /* The parser to be deleted */
-  void (*freeProc)()     /* Function used to reclaim memory */
+  void *p,                    /* The parser to be deleted */
+  void (*freeProc)(void*)     /* Function used to reclaim memory */
 ){
   yyParser *pParser = (yyParser*)p;
   if( pParser==0 ) return;
   while( pParser->idx>=0 ) yy_pop_parser_stack(pParser);
-  (*freeProc)(pParser, __FILE__, __LINE__);
+  (*freeProc)((void*)pParser);
 }
 
 /*
@@ -366,7 +371,7 @@ static struct {
 %%
 };
 
-static void yy_accept();  /* Forward declaration */
+static void yy_accept(yyParser *  ParseANSIARGDECL);  /* Forward Declaration */
 
 /*
 ** Perform a reduce action and the shift that must immediately
@@ -475,7 +480,6 @@ static void yy_accept(
 ** Outputs:
 ** None.
 */
-/* SQLITE MODIFICATION: Give the function file scope */
 void Parse(
   void *yyp,                   /* The parser */
   int yymajor,                 /* The major token code number */
index 111276c81a1cbff0eecd933ad5944b6ba5229bea..ac8dd670e0d82729f8709054f8c8726a94e04efb 100644 (file)
@@ -17,6 +17,12 @@ proc chng {date desc} {
   puts "<DD><P><UL>$desc</UL></P></DD>"
 }
 
+chng {2001 Apr 3 (1.0.28)} {
+<li>Changes to the "lemon" parser generator to help it work better when
+    compiled using MSVC.</li>
+<li>Bug fixes in the TCL interface identified by Oleg Oleinick.</li>
+}
+
 chng {2001 Mar 20 (1.0.27)} {
 <li>When doing DELETE and UPDATE, the library used to write the record
     numbers of records to be deleted or updated into a temporary file.