Fossil SCM

Merge updates from trunk.

mistachkin 2016-11-02 19:12 openssl-1.1 merge
Commit 25285f06f2a02cd7a3314a627b04dc2ffe9993ca
125 files changed +1 -1 +1 -1 +1 +21 -8 +3 -3 +11 -5 +18 -3 +14 -4 +65 -7 +207 -18 +1 -2 +11 -11 +57 -37 +30 -6 +91 -48 +63 -12 +1 -1 +4 -7 +19 -4 +8 -7 +1 -1 +1 -1 +19 -1 +79 -4 +2 +2 +2 +4 -4 +1 -1 +4 +1 -1 +1 -1 +24 -16 +1277 -1181 +28 -7 +42 -31 +4 -7 +1 +1 +52 -16 +84 -1 +36 -18 +14 -8 +3 -2 +37 -12 +48 -16 +1 -1 +57 +8 -8 +105 -17 +1 -1 +55 -17 +12 -3 +31 +2 +3 +1 -1 +1 +2 +113 +4 -1 +1 -1 +2 -6 +68 +126 -18 +2 -2 +14 -4 +2 -2 +12 -12 +39 -3 +1 +1 -1 +1 -1 +2 +2 +2 +2 +2 +2 +11 -11 +5 -5 +11 -11 +4 -4 +1 -1 +31 -2 +9 -9 +3 -3 +13 -8 +7 -7 +2 -2 +4 +1 -1 +9 -9 +9 -9 +1 -1 +5 -1 +3 -3 +5 -5 +33 -33 +19 -19 +2 -2 +11 -11 +2 -2 +54 -15 +13 -13 +48 -60 +1 -1 +5 -5 +3 -3 +10 -10 +26 -26 +13 -13 +12 -12 +3 -3 +6 -6 +21 -21 +3 -3 +10 -10 +3 -3 +9 -9 +28 -5 +5 -5 +1 -2 +3 -2 +4 -4
~ Dockerfile ~ VERSION ~ auto.def ~ src/add.c ~ src/allrepo.c ~ src/blob.c ~ src/branch.c ~ src/checkin.c ~ src/checkout.c ~ src/db.c ~ src/delta.c ~ src/deltacmd.c ~ src/diff.c ~ src/diffcmd.c ~ src/export.c ~ src/file.c ~ src/finfo.c ~ src/fusefs.c ~ src/graph.c ~ src/import.c ~ src/info.c ~ src/json_branch.c ~ src/json_wiki.c ~ src/main.c ~ src/main.mk ~ src/makemake.tcl ~ src/makemake.tcl ~ src/merge3.c ~ src/mkindex.c ~ src/mkversion.c ~ src/search.c ~ src/setup.c ~ src/shell.c ~ src/sqlite3.c ~ src/sqlite3.h ~ src/stash.c ~ src/stat.c ~ src/style.c ~ src/tag.c ~ src/tar.c ~ src/th_main.c ~ src/timeline.c ~ src/tkt.c ~ src/undo.c ~ src/unversioned.c ~ src/user.c ~ src/utf8.c ~ src/util.c ~ src/vfile.c ~ src/winhttp.c ~ src/xfer.c ~ src/zip.c ~ test/delta1.test ~ test/diff.test ~ test/fake-editor.tcl ~ test/graph-test-1.wiki ~ test/json.test ~ test/merge2.test ~ test/mv-rm.test ~ test/set-manifest.test ~ test/settings-repo.test ~ test/settings.test ~ test/stash.test ~ test/symlinks.test ~ test/tester.tcl ~ test/th1-docs.test ~ test/th1-hooks.test ~ test/th1-repo.test ~ test/th1-tcl.test ~ test/th1.test ~ test/unversioned.test ~ win/Makefile.PellesCGMake ~ win/Makefile.dmc ~ win/Makefile.mingw ~ win/Makefile.mingw ~ win/Makefile.mingw.mistachkin ~ win/Makefile.mingw.mistachkin ~ win/Makefile.msc ~ win/Makefile.msc ~ www/aboutcgi.wiki ~ www/adding_code.wiki ~ www/antibot.wiki ~ www/blame.wiki ~ www/bugtheory.wiki ~ www/changes.wiki ~ www/checkin_names.wiki ~ www/childprojects.wiki ~ www/concepts.wiki ~ www/contribute.wiki ~ www/custom_ticket.wiki ~ www/customskin.md ~ www/delta_encoder_algorithm.wiki ~ www/delta_format.wiki ~ www/embeddeddoc.wiki ~ www/encryptedrepos.wiki ~ www/env-opts.md ~ www/event.wiki ~ www/faq.wiki ~ www/fileformat.wiki ~ www/fiveminutes.wiki ~ www/foss-cklist.wiki ~ www/fossil-from-msvc.wiki ~ www/index.wiki ~ www/inout.wiki ~ www/makefile.wiki ~ www/mkdownload.tcl ~ www/newrepo.wiki ~ www/pop.wiki ~ www/private.wiki ~ www/qandc.wiki ~ www/quickstart.wiki ~ www/quotes.wiki ~ www/reviews.wiki ~ www/selfcheck.wiki ~ www/selfhost.wiki ~ www/server.wiki ~ www/settings.wiki ~ www/shunning.wiki ~ www/stats.wiki ~ www/sync.wiki ~ www/th1.md ~ www/theory1.wiki ~ www/webui.wiki ~ www/whyusefossil.wiki ~ www/wikitheory.wiki
+1 -1
--- Dockerfile
+++ Dockerfile
@@ -1,9 +1,9 @@
11
###
22
# Dockerfile for Fossil
33
###
4
-FROM fedora:23
4
+FROM fedora:24
55
66
### Now install some additional parts we will need for the build
77
RUN dnf update -y && dnf install -y gcc make zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
88
99
### If you want to build "trunk", change the next line accordingly.
1010
--- Dockerfile
+++ Dockerfile
@@ -1,9 +1,9 @@
1 ###
2 # Dockerfile for Fossil
3 ###
4 FROM fedora:23
5
6 ### Now install some additional parts we will need for the build
7 RUN dnf update -y && dnf install -y gcc make zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
8
9 ### If you want to build "trunk", change the next line accordingly.
10
--- Dockerfile
+++ Dockerfile
@@ -1,9 +1,9 @@
1 ###
2 # Dockerfile for Fossil
3 ###
4 FROM fedora:24
5
6 ### Now install some additional parts we will need for the build
7 RUN dnf update -y && dnf install -y gcc make zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
8
9 ### If you want to build "trunk", change the next line accordingly.
10
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-1.36
1
+1.37
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.36
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.37
2
+1
--- auto.def
+++ auto.def
@@ -479,10 +479,11 @@
479479
cc-check-function-in-lib sin m
480480
481481
# Check for the FuseFS library
482482
if {[opt-bool fusefs]} {
483483
if {[cc-check-function-in-lib fuse_mount fuse]} {
484
+ define-append EXTRA_CFLAGS -DFOSSIL_HAVE_FUSEFS
484485
define FOSSIL_HAVE_FUSEFS 1
485486
define-append LIBS -lfuse
486487
msg-result "FuseFS support enabled"
487488
}
488489
}
489490
--- auto.def
+++ auto.def
@@ -479,10 +479,11 @@
479 cc-check-function-in-lib sin m
480
481 # Check for the FuseFS library
482 if {[opt-bool fusefs]} {
483 if {[cc-check-function-in-lib fuse_mount fuse]} {
 
484 define FOSSIL_HAVE_FUSEFS 1
485 define-append LIBS -lfuse
486 msg-result "FuseFS support enabled"
487 }
488 }
489
--- auto.def
+++ auto.def
@@ -479,10 +479,11 @@
479 cc-check-function-in-lib sin m
480
481 # Check for the FuseFS library
482 if {[opt-bool fusefs]} {
483 if {[cc-check-function-in-lib fuse_mount fuse]} {
484 define-append EXTRA_CFLAGS -DFOSSIL_HAVE_FUSEFS
485 define FOSSIL_HAVE_FUSEFS 1
486 define-append LIBS -lfuse
487 msg-result "FuseFS support enabled"
488 }
489 }
490
+21 -8
--- src/add.c
+++ src/add.c
@@ -71,29 +71,42 @@
7171
".fos-journal",
7272
".fos-wal",
7373
".fos-shm",
7474
};
7575
76
- /* Names of auxiliary files generated by SQLite when the "manifest"
77
- ** property is enabled
76
+ /* Possible names of auxiliary files generated when the "manifest" property
77
+ ** is used
7878
*/
79
- static const char *const azManifest[] = {
80
- "manifest",
81
- "manifest.uuid",
79
+ static const struct {
80
+ const char *fname;
81
+ int flg;
82
+ }aManifestflags[] = {
83
+ { "manifest", MFESTFLG_RAW },
84
+ { "manifest.uuid", MFESTFLG_UUID },
85
+ { "manifest.tags", MFESTFLG_TAGS }
8286
};
87
+ static const char *azManifests[3];
8388
8489
/*
8590
** Names of repository files, if they exist in the checkout.
8691
*/
8792
static const char *azRepo[4] = { 0, 0, 0, 0 };
8893
8994
/* Cached setting "manifest" */
9095
static int cachedManifest = -1;
96
+ static int numManifests;
9197
9298
if( cachedManifest == -1 ){
99
+ int i;
93100
Blob repo;
94
- cachedManifest = db_get_boolean("manifest",0);
101
+ cachedManifest = db_get_manifest_setting();
102
+ numManifests = 0;
103
+ for(i=0; i<count(aManifestflags); i++){
104
+ if( cachedManifest&aManifestflags[i].flg ) {
105
+ azManifests[numManifests++] = aManifestflags[i].fname;
106
+ }
107
+ }
95108
blob_zero(&repo);
96109
if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
97110
const char *zRepo = blob_str(&repo);
98111
azRepo[0] = zRepo;
99112
azRepo[1] = mprintf("%s-journal", zRepo);
@@ -104,12 +117,12 @@
104117
105118
if( N<0 ) return 0;
106119
if( N<count(azName) ) return azName[N];
107120
N -= count(azName);
108121
if( cachedManifest ){
109
- if( N<count(azManifest) ) return azManifest[N];
110
- N -= count(azManifest);
122
+ if( N<numManifests ) return azManifests[N];
123
+ N -= numManifests;
111124
}
112125
if( !omitRepo && N<count(azRepo) ) return azRepo[N];
113126
return 0;
114127
}
115128
116129
--- src/add.c
+++ src/add.c
@@ -71,29 +71,42 @@
71 ".fos-journal",
72 ".fos-wal",
73 ".fos-shm",
74 };
75
76 /* Names of auxiliary files generated by SQLite when the "manifest"
77 ** property is enabled
78 */
79 static const char *const azManifest[] = {
80 "manifest",
81 "manifest.uuid",
 
 
 
 
82 };
 
83
84 /*
85 ** Names of repository files, if they exist in the checkout.
86 */
87 static const char *azRepo[4] = { 0, 0, 0, 0 };
88
89 /* Cached setting "manifest" */
90 static int cachedManifest = -1;
 
91
92 if( cachedManifest == -1 ){
 
93 Blob repo;
94 cachedManifest = db_get_boolean("manifest",0);
 
 
 
 
 
 
95 blob_zero(&repo);
96 if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
97 const char *zRepo = blob_str(&repo);
98 azRepo[0] = zRepo;
99 azRepo[1] = mprintf("%s-journal", zRepo);
@@ -104,12 +117,12 @@
104
105 if( N<0 ) return 0;
106 if( N<count(azName) ) return azName[N];
107 N -= count(azName);
108 if( cachedManifest ){
109 if( N<count(azManifest) ) return azManifest[N];
110 N -= count(azManifest);
111 }
112 if( !omitRepo && N<count(azRepo) ) return azRepo[N];
113 return 0;
114 }
115
116
--- src/add.c
+++ src/add.c
@@ -71,29 +71,42 @@
71 ".fos-journal",
72 ".fos-wal",
73 ".fos-shm",
74 };
75
76 /* Possible names of auxiliary files generated when the "manifest" property
77 ** is used
78 */
79 static const struct {
80 const char *fname;
81 int flg;
82 }aManifestflags[] = {
83 { "manifest", MFESTFLG_RAW },
84 { "manifest.uuid", MFESTFLG_UUID },
85 { "manifest.tags", MFESTFLG_TAGS }
86 };
87 static const char *azManifests[3];
88
89 /*
90 ** Names of repository files, if they exist in the checkout.
91 */
92 static const char *azRepo[4] = { 0, 0, 0, 0 };
93
94 /* Cached setting "manifest" */
95 static int cachedManifest = -1;
96 static int numManifests;
97
98 if( cachedManifest == -1 ){
99 int i;
100 Blob repo;
101 cachedManifest = db_get_manifest_setting();
102 numManifests = 0;
103 for(i=0; i<count(aManifestflags); i++){
104 if( cachedManifest&aManifestflags[i].flg ) {
105 azManifests[numManifests++] = aManifestflags[i].fname;
106 }
107 }
108 blob_zero(&repo);
109 if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
110 const char *zRepo = blob_str(&repo);
111 azRepo[0] = zRepo;
112 azRepo[1] = mprintf("%s-journal", zRepo);
@@ -104,12 +117,12 @@
117
118 if( N<0 ) return 0;
119 if( N<count(azName) ) return azName[N];
120 N -= count(azName);
121 if( cachedManifest ){
122 if( N<numManifests ) return azManifests[N];
123 N -= numManifests;
124 }
125 if( !omitRepo && N<count(azRepo) ) return azRepo[N];
126 return 0;
127 }
128
129
+3 -3
--- src/allrepo.c
+++ src/allrepo.c
@@ -173,11 +173,10 @@
173173
int useCheckouts = 0;
174174
int quiet = 0;
175175
int dryRunFlag = 0;
176176
int showFile = find_option("showfile",0,0)!=0;
177177
int stopOnError = find_option("dontstop",0,0)==0;
178
- int rc;
179178
int nToDel = 0;
180179
int showLabel = 0;
181180
182181
dryRunFlag = find_option("dry-run","n",0)!=0;
183182
if( !dryRunFlag ){
@@ -375,22 +374,23 @@
375374
" FROM global_config"
376375
" WHERE substr(name, 1, 5)=='repo:'"
377376
" ORDER BY 1"
378377
);
379378
}
380
- db_multi_exec("CREATE TEMP TABLE todel(x TEXT)");
379
+ db_multi_exec("CREATE TEMP TABLE toDel(x TEXT)");
381380
db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
382381
while( db_step(&q)==SQLITE_ROW ){
382
+ int rc;
383383
const char *zFilename = db_column_text(&q, 0);
384384
#if !USE_SEE
385385
if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
386386
#endif
387387
if( file_access(zFilename, F_OK)
388388
|| !file_is_canonical(zFilename)
389389
|| (useCheckouts && file_isdir(zFilename)!=1)
390390
){
391
- db_multi_exec("INSERT INTO todel VALUES(%Q)", db_column_text(&q, 1));
391
+ db_multi_exec("INSERT INTO toDel VALUES(%Q)", db_column_text(&q, 1));
392392
nToDel++;
393393
continue;
394394
}
395395
if( zCmd[0]=='l' ){
396396
fossil_print("%s\n", zFilename);
397397
--- src/allrepo.c
+++ src/allrepo.c
@@ -173,11 +173,10 @@
173 int useCheckouts = 0;
174 int quiet = 0;
175 int dryRunFlag = 0;
176 int showFile = find_option("showfile",0,0)!=0;
177 int stopOnError = find_option("dontstop",0,0)==0;
178 int rc;
179 int nToDel = 0;
180 int showLabel = 0;
181
182 dryRunFlag = find_option("dry-run","n",0)!=0;
183 if( !dryRunFlag ){
@@ -375,22 +374,23 @@
375 " FROM global_config"
376 " WHERE substr(name, 1, 5)=='repo:'"
377 " ORDER BY 1"
378 );
379 }
380 db_multi_exec("CREATE TEMP TABLE todel(x TEXT)");
381 db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
382 while( db_step(&q)==SQLITE_ROW ){
 
383 const char *zFilename = db_column_text(&q, 0);
384 #if !USE_SEE
385 if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
386 #endif
387 if( file_access(zFilename, F_OK)
388 || !file_is_canonical(zFilename)
389 || (useCheckouts && file_isdir(zFilename)!=1)
390 ){
391 db_multi_exec("INSERT INTO todel VALUES(%Q)", db_column_text(&q, 1));
392 nToDel++;
393 continue;
394 }
395 if( zCmd[0]=='l' ){
396 fossil_print("%s\n", zFilename);
397
--- src/allrepo.c
+++ src/allrepo.c
@@ -173,11 +173,10 @@
173 int useCheckouts = 0;
174 int quiet = 0;
175 int dryRunFlag = 0;
176 int showFile = find_option("showfile",0,0)!=0;
177 int stopOnError = find_option("dontstop",0,0)==0;
 
178 int nToDel = 0;
179 int showLabel = 0;
180
181 dryRunFlag = find_option("dry-run","n",0)!=0;
182 if( !dryRunFlag ){
@@ -375,22 +374,23 @@
374 " FROM global_config"
375 " WHERE substr(name, 1, 5)=='repo:'"
376 " ORDER BY 1"
377 );
378 }
379 db_multi_exec("CREATE TEMP TABLE toDel(x TEXT)");
380 db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
381 while( db_step(&q)==SQLITE_ROW ){
382 int rc;
383 const char *zFilename = db_column_text(&q, 0);
384 #if !USE_SEE
385 if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
386 #endif
387 if( file_access(zFilename, F_OK)
388 || !file_is_canonical(zFilename)
389 || (useCheckouts && file_isdir(zFilename)!=1)
390 ){
391 db_multi_exec("INSERT INTO toDel VALUES(%Q)", db_column_text(&q, 1));
392 nToDel++;
393 continue;
394 }
395 if( zCmd[0]=='l' ){
396 fossil_print("%s\n", zFilename);
397
+11 -5
--- src/blob.c
+++ src/blob.c
@@ -851,27 +851,33 @@
851851
int blob_write_to_file(Blob *pBlob, const char *zFilename){
852852
FILE *out;
853853
int nWrote;
854854
855855
if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
856
- nWrote = blob_size(pBlob);
856
+ blob_is_init(pBlob);
857857
#if defined(_WIN32)
858
- if( fossil_utf8_to_console(blob_buffer(pBlob), nWrote, 0) >= 0 ){
859
- return nWrote;
860
- }
858
+ nWrote = fossil_utf8_to_console(blob_buffer(pBlob), blob_size(pBlob), 0);
859
+ if( nWrote>=0 ) return nWrote;
861860
fflush(stdout);
862861
_setmode(_fileno(stdout), _O_BINARY);
863862
#endif
864
- fwrite(blob_buffer(pBlob), 1, nWrote, stdout);
863
+ nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), stdout);
865864
#if defined(_WIN32)
866865
fflush(stdout);
867866
_setmode(_fileno(stdout), _O_TEXT);
868867
#endif
869868
}else{
870869
file_mkfolder(zFilename, 1, 0);
871870
out = fossil_fopen(zFilename, "wb");
872871
if( out==0 ){
872
+#if _WIN32
873
+ const char *zReserved = file_is_win_reserved(zFilename);
874
+ if( zReserved ){
875
+ fossil_fatal("cannot open \"%s\" because \"%s\" is "
876
+ "a reserved name on Windows", zFilename, zReserved);
877
+ }
878
+#endif
873879
fossil_fatal_recursive("unable to open file \"%s\" for writing",
874880
zFilename);
875881
return 0;
876882
}
877883
blob_is_init(pBlob);
878884
--- src/blob.c
+++ src/blob.c
@@ -851,27 +851,33 @@
851 int blob_write_to_file(Blob *pBlob, const char *zFilename){
852 FILE *out;
853 int nWrote;
854
855 if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
856 nWrote = blob_size(pBlob);
857 #if defined(_WIN32)
858 if( fossil_utf8_to_console(blob_buffer(pBlob), nWrote, 0) >= 0 ){
859 return nWrote;
860 }
861 fflush(stdout);
862 _setmode(_fileno(stdout), _O_BINARY);
863 #endif
864 fwrite(blob_buffer(pBlob), 1, nWrote, stdout);
865 #if defined(_WIN32)
866 fflush(stdout);
867 _setmode(_fileno(stdout), _O_TEXT);
868 #endif
869 }else{
870 file_mkfolder(zFilename, 1, 0);
871 out = fossil_fopen(zFilename, "wb");
872 if( out==0 ){
 
 
 
 
 
 
 
873 fossil_fatal_recursive("unable to open file \"%s\" for writing",
874 zFilename);
875 return 0;
876 }
877 blob_is_init(pBlob);
878
--- src/blob.c
+++ src/blob.c
@@ -851,27 +851,33 @@
851 int blob_write_to_file(Blob *pBlob, const char *zFilename){
852 FILE *out;
853 int nWrote;
854
855 if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
856 blob_is_init(pBlob);
857 #if defined(_WIN32)
858 nWrote = fossil_utf8_to_console(blob_buffer(pBlob), blob_size(pBlob), 0);
859 if( nWrote>=0 ) return nWrote;
 
860 fflush(stdout);
861 _setmode(_fileno(stdout), _O_BINARY);
862 #endif
863 nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), stdout);
864 #if defined(_WIN32)
865 fflush(stdout);
866 _setmode(_fileno(stdout), _O_TEXT);
867 #endif
868 }else{
869 file_mkfolder(zFilename, 1, 0);
870 out = fossil_fopen(zFilename, "wb");
871 if( out==0 ){
872 #if _WIN32
873 const char *zReserved = file_is_win_reserved(zFilename);
874 if( zReserved ){
875 fossil_fatal("cannot open \"%s\" because \"%s\" is "
876 "a reserved name on Windows", zFilename, zReserved);
877 }
878 #endif
879 fossil_fatal_recursive("unable to open file \"%s\" for writing",
880 zFilename);
881 return 0;
882 }
883 blob_is_init(pBlob);
884
+18 -3
--- src/branch.c
+++ src/branch.c
@@ -154,11 +154,11 @@
154154
if( brid==0 ){
155155
fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
156156
}
157157
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
158158
if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
159
- fossil_fatal("%s\n", g.zErrMsg);
159
+ fossil_fatal("%s", g.zErrMsg);
160160
}
161161
assert( blob_is_reset(&branch) );
162162
content_deltify(rootid, brid, 0);
163163
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
164164
fossil_print("New branch: %s\n", zUuid);
@@ -323,11 +323,12 @@
323323
@ WHERE plink.pid=event.objid
324324
@ AND tagxref.rid=plink.cid
325325
@ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
326326
@ AND tagtype>0),
327327
@ count(*),
328
-@ (SELECT uuid FROM blob WHERE rid=tagxref.rid)
328
+@ (SELECT uuid FROM blob WHERE rid=tagxref.rid),
329
+@ event.bgcolor
329330
@ FROM tagxref, tag, event
330331
@ WHERE tagxref.tagid=tag.tagid
331332
@ AND tagxref.tagtype>0
332333
@ AND tag.tagname='branch'
333334
@ AND event.objid=tagxref.rid
@@ -344,14 +345,16 @@
344345
** if there are no query parameters.
345346
*/
346347
static void new_brlist_page(void){
347348
Stmt q;
348349
double rNow;
350
+ int show_colors = PB("colors");
349351
login_check_credentials();
350352
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
351353
style_header("Branches");
352354
style_adunit_config(ADUNIT_RIGHT_OK);
355
+ style_submenu_binary("colors", "Color", "B/W", 0);
353356
login_anonymous_available();
354357
355358
db_prepare(&q, brlistQuery/*works-like:""*/);
356359
rNow = db_double(0.0, "SELECT julianday('now')");
357360
@ <div class="brlist"><table id="branchlisttable">
@@ -367,14 +370,26 @@
367370
double rMtime = db_column_double(&q, 1);
368371
int isClosed = db_column_int(&q, 2);
369372
const char *zMergeTo = db_column_text(&q, 3);
370373
int nCkin = db_column_int(&q, 4);
371374
const char *zLastCkin = db_column_text(&q, 5);
375
+ const char *zBgClr = db_column_text(&q, 6);
372376
char *zAge = human_readable_age(rNow - rMtime);
373377
sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
374378
if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
375
- @ <tr>
379
+ if( zBgClr == 0 ){
380
+ if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){
381
+ zBgClr = 0;
382
+ }else{
383
+ zBgClr = hash_color(zBranch);
384
+ }
385
+ }
386
+ if( zBgClr && zBgClr[0] && show_colors ){
387
+ @ <tr style="background-color:%s(zBgClr)">
388
+ }else{
389
+ @ <tr>
390
+ }
376391
@ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
377392
@ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
378393
@ <td>%d(nCkin)</td>
379394
fossil_free(zAge);
380395
@ <td>%s(isClosed?"closed":"")</td>
381396
--- src/branch.c
+++ src/branch.c
@@ -154,11 +154,11 @@
154 if( brid==0 ){
155 fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
156 }
157 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
158 if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
159 fossil_fatal("%s\n", g.zErrMsg);
160 }
161 assert( blob_is_reset(&branch) );
162 content_deltify(rootid, brid, 0);
163 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
164 fossil_print("New branch: %s\n", zUuid);
@@ -323,11 +323,12 @@
323 @ WHERE plink.pid=event.objid
324 @ AND tagxref.rid=plink.cid
325 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
326 @ AND tagtype>0),
327 @ count(*),
328 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid)
 
329 @ FROM tagxref, tag, event
330 @ WHERE tagxref.tagid=tag.tagid
331 @ AND tagxref.tagtype>0
332 @ AND tag.tagname='branch'
333 @ AND event.objid=tagxref.rid
@@ -344,14 +345,16 @@
344 ** if there are no query parameters.
345 */
346 static void new_brlist_page(void){
347 Stmt q;
348 double rNow;
 
349 login_check_credentials();
350 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
351 style_header("Branches");
352 style_adunit_config(ADUNIT_RIGHT_OK);
 
353 login_anonymous_available();
354
355 db_prepare(&q, brlistQuery/*works-like:""*/);
356 rNow = db_double(0.0, "SELECT julianday('now')");
357 @ <div class="brlist"><table id="branchlisttable">
@@ -367,14 +370,26 @@
367 double rMtime = db_column_double(&q, 1);
368 int isClosed = db_column_int(&q, 2);
369 const char *zMergeTo = db_column_text(&q, 3);
370 int nCkin = db_column_int(&q, 4);
371 const char *zLastCkin = db_column_text(&q, 5);
 
372 char *zAge = human_readable_age(rNow - rMtime);
373 sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
374 if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
375 @ <tr>
 
 
 
 
 
 
 
 
 
 
 
376 @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
377 @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
378 @ <td>%d(nCkin)</td>
379 fossil_free(zAge);
380 @ <td>%s(isClosed?"closed":"")</td>
381
--- src/branch.c
+++ src/branch.c
@@ -154,11 +154,11 @@
154 if( brid==0 ){
155 fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
156 }
157 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
158 if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
159 fossil_fatal("%s", g.zErrMsg);
160 }
161 assert( blob_is_reset(&branch) );
162 content_deltify(rootid, brid, 0);
163 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
164 fossil_print("New branch: %s\n", zUuid);
@@ -323,11 +323,12 @@
323 @ WHERE plink.pid=event.objid
324 @ AND tagxref.rid=plink.cid
325 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
326 @ AND tagtype>0),
327 @ count(*),
328 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid),
329 @ event.bgcolor
330 @ FROM tagxref, tag, event
331 @ WHERE tagxref.tagid=tag.tagid
332 @ AND tagxref.tagtype>0
333 @ AND tag.tagname='branch'
334 @ AND event.objid=tagxref.rid
@@ -344,14 +345,16 @@
345 ** if there are no query parameters.
346 */
347 static void new_brlist_page(void){
348 Stmt q;
349 double rNow;
350 int show_colors = PB("colors");
351 login_check_credentials();
352 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
353 style_header("Branches");
354 style_adunit_config(ADUNIT_RIGHT_OK);
355 style_submenu_binary("colors", "Color", "B/W", 0);
356 login_anonymous_available();
357
358 db_prepare(&q, brlistQuery/*works-like:""*/);
359 rNow = db_double(0.0, "SELECT julianday('now')");
360 @ <div class="brlist"><table id="branchlisttable">
@@ -367,14 +370,26 @@
370 double rMtime = db_column_double(&q, 1);
371 int isClosed = db_column_int(&q, 2);
372 const char *zMergeTo = db_column_text(&q, 3);
373 int nCkin = db_column_int(&q, 4);
374 const char *zLastCkin = db_column_text(&q, 5);
375 const char *zBgClr = db_column_text(&q, 6);
376 char *zAge = human_readable_age(rNow - rMtime);
377 sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
378 if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
379 if( zBgClr == 0 ){
380 if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){
381 zBgClr = 0;
382 }else{
383 zBgClr = hash_color(zBranch);
384 }
385 }
386 if( zBgClr && zBgClr[0] && show_colors ){
387 @ <tr style="background-color:%s(zBgClr)">
388 }else{
389 @ <tr>
390 }
391 @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
392 @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
393 @ <td>%d(nCkin)</td>
394 fossil_free(zAge);
395 @ <td>%s(isClosed?"closed":"")</td>
396
+14 -4
--- src/checkin.c
+++ src/checkin.c
@@ -1869,11 +1869,11 @@
18691869
sCiInfo.zUserOvrd = find_option("user-override",0,1);
18701870
db_must_be_within_tree();
18711871
noSign = db_get_boolean("omitsign", 0)|noSign;
18721872
if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
18731873
useCksum = db_get_boolean("repo-cksum", 1);
1874
- outputManifest = db_get_boolean("manifest", 0);
1874
+ outputManifest = db_get_manifest_setting();
18751875
verify_all_options();
18761876
18771877
/* Escape special characters in tags and put all tags in sorted order */
18781878
if( nTag ){
18791879
int i;
@@ -2230,11 +2230,11 @@
22302230
** and rollback the transaction.
22312231
*/
22322232
if( dryRunFlag ){
22332233
blob_write_to_file(&manifest, "");
22342234
}
2235
- if( outputManifest ){
2235
+ if( outputManifest & MFESTFLG_RAW ){
22362236
zManifestFile = mprintf("%smanifest", g.zLocalRoot);
22372237
blob_write_to_file(&manifest, zManifestFile);
22382238
blob_reset(&manifest);
22392239
blob_read_from_file(&manifest, zManifestFile);
22402240
free(zManifestFile);
@@ -2245,11 +2245,11 @@
22452245
fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
22462246
}
22472247
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
22482248
if( manifest_crosslink(nvid, &manifest,
22492249
dryRunFlag ? MC_NONE : MC_PERMIT_HOOKS)==0 ){
2250
- fossil_fatal("%s\n", g.zErrMsg);
2250
+ fossil_fatal("%s", g.zErrMsg);
22512251
}
22522252
assert( blob_is_reset(&manifest) );
22532253
content_deltify(vid, nvid, 0);
22542254
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
22552255
@@ -2264,11 +2264,11 @@
22642264
}
22652265
}
22662266
db_finalize(&q);
22672267
22682268
fossil_print("New_Version: %s\n", zUuid);
2269
- if( outputManifest ){
2269
+ if( outputManifest & MFESTFLG_UUID ){
22702270
zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
22712271
blob_zero(&muuid);
22722272
blob_appendf(&muuid, "%s\n", zUuid);
22732273
blob_write_to_file(&muuid, zManifestFile);
22742274
free(zManifestFile);
@@ -2346,13 +2346,23 @@
23462346
if( dryRunFlag ){
23472347
db_end_transaction(1);
23482348
exit(1);
23492349
}
23502350
db_end_transaction(0);
2351
+
2352
+ if( outputManifest & MFESTFLG_TAGS ){
2353
+ Blob tagslist;
2354
+ zManifestFile = mprintf("%smanifest.tags", g.zLocalRoot);
2355
+ blob_zero(&tagslist);
2356
+ get_checkin_taglist(nvid, &tagslist);
2357
+ blob_write_to_file(&tagslist, zManifestFile);
2358
+ blob_reset(&tagslist);
2359
+ free(zManifestFile);
2360
+ }
23512361
23522362
if( !g.markPrivate ){
23532363
autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
23542364
}
23552365
if( count_nonbranch_children(vid)>1 ){
23562366
fossil_print("**** warning: a fork has occurred *****\n");
23572367
}
23582368
}
23592369
--- src/checkin.c
+++ src/checkin.c
@@ -1869,11 +1869,11 @@
1869 sCiInfo.zUserOvrd = find_option("user-override",0,1);
1870 db_must_be_within_tree();
1871 noSign = db_get_boolean("omitsign", 0)|noSign;
1872 if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
1873 useCksum = db_get_boolean("repo-cksum", 1);
1874 outputManifest = db_get_boolean("manifest", 0);
1875 verify_all_options();
1876
1877 /* Escape special characters in tags and put all tags in sorted order */
1878 if( nTag ){
1879 int i;
@@ -2230,11 +2230,11 @@
2230 ** and rollback the transaction.
2231 */
2232 if( dryRunFlag ){
2233 blob_write_to_file(&manifest, "");
2234 }
2235 if( outputManifest ){
2236 zManifestFile = mprintf("%smanifest", g.zLocalRoot);
2237 blob_write_to_file(&manifest, zManifestFile);
2238 blob_reset(&manifest);
2239 blob_read_from_file(&manifest, zManifestFile);
2240 free(zManifestFile);
@@ -2245,11 +2245,11 @@
2245 fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
2246 }
2247 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
2248 if( manifest_crosslink(nvid, &manifest,
2249 dryRunFlag ? MC_NONE : MC_PERMIT_HOOKS)==0 ){
2250 fossil_fatal("%s\n", g.zErrMsg);
2251 }
2252 assert( blob_is_reset(&manifest) );
2253 content_deltify(vid, nvid, 0);
2254 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
2255
@@ -2264,11 +2264,11 @@
2264 }
2265 }
2266 db_finalize(&q);
2267
2268 fossil_print("New_Version: %s\n", zUuid);
2269 if( outputManifest ){
2270 zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
2271 blob_zero(&muuid);
2272 blob_appendf(&muuid, "%s\n", zUuid);
2273 blob_write_to_file(&muuid, zManifestFile);
2274 free(zManifestFile);
@@ -2346,13 +2346,23 @@
2346 if( dryRunFlag ){
2347 db_end_transaction(1);
2348 exit(1);
2349 }
2350 db_end_transaction(0);
 
 
 
 
 
 
 
 
 
 
2351
2352 if( !g.markPrivate ){
2353 autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
2354 }
2355 if( count_nonbranch_children(vid)>1 ){
2356 fossil_print("**** warning: a fork has occurred *****\n");
2357 }
2358 }
2359
--- src/checkin.c
+++ src/checkin.c
@@ -1869,11 +1869,11 @@
1869 sCiInfo.zUserOvrd = find_option("user-override",0,1);
1870 db_must_be_within_tree();
1871 noSign = db_get_boolean("omitsign", 0)|noSign;
1872 if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
1873 useCksum = db_get_boolean("repo-cksum", 1);
1874 outputManifest = db_get_manifest_setting();
1875 verify_all_options();
1876
1877 /* Escape special characters in tags and put all tags in sorted order */
1878 if( nTag ){
1879 int i;
@@ -2230,11 +2230,11 @@
2230 ** and rollback the transaction.
2231 */
2232 if( dryRunFlag ){
2233 blob_write_to_file(&manifest, "");
2234 }
2235 if( outputManifest & MFESTFLG_RAW ){
2236 zManifestFile = mprintf("%smanifest", g.zLocalRoot);
2237 blob_write_to_file(&manifest, zManifestFile);
2238 blob_reset(&manifest);
2239 blob_read_from_file(&manifest, zManifestFile);
2240 free(zManifestFile);
@@ -2245,11 +2245,11 @@
2245 fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
2246 }
2247 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
2248 if( manifest_crosslink(nvid, &manifest,
2249 dryRunFlag ? MC_NONE : MC_PERMIT_HOOKS)==0 ){
2250 fossil_fatal("%s", g.zErrMsg);
2251 }
2252 assert( blob_is_reset(&manifest) );
2253 content_deltify(vid, nvid, 0);
2254 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
2255
@@ -2264,11 +2264,11 @@
2264 }
2265 }
2266 db_finalize(&q);
2267
2268 fossil_print("New_Version: %s\n", zUuid);
2269 if( outputManifest & MFESTFLG_UUID ){
2270 zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
2271 blob_zero(&muuid);
2272 blob_appendf(&muuid, "%s\n", zUuid);
2273 blob_write_to_file(&muuid, zManifestFile);
2274 free(zManifestFile);
@@ -2346,13 +2346,23 @@
2346 if( dryRunFlag ){
2347 db_end_transaction(1);
2348 exit(1);
2349 }
2350 db_end_transaction(0);
2351
2352 if( outputManifest & MFESTFLG_TAGS ){
2353 Blob tagslist;
2354 zManifestFile = mprintf("%smanifest.tags", g.zLocalRoot);
2355 blob_zero(&tagslist);
2356 get_checkin_taglist(nvid, &tagslist);
2357 blob_write_to_file(&tagslist, zManifestFile);
2358 blob_reset(&tagslist);
2359 free(zManifestFile);
2360 }
2361
2362 if( !g.markPrivate ){
2363 autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
2364 }
2365 if( count_nonbranch_children(vid)>1 ){
2366 fossil_print("**** warning: a fork has occurred *****\n");
2367 }
2368 }
2369
+65 -7
--- src/checkout.c
+++ src/checkout.c
@@ -127,44 +127,102 @@
127127
128128
/*
129129
** If the "manifest" setting is true, then automatically generate
130130
** files named "manifest" and "manifest.uuid" containing, respectively,
131131
** the text of the manifest and the artifact ID of the manifest.
132
+** If the manifest setting is set, but is not a boolean value, then treat
133
+** each character as a flag to enable writing "manifest", "manifest.uuid" or
134
+** "manifest.tags".
132135
*/
133136
void manifest_to_disk(int vid){
134137
char *zManFile;
135138
Blob manifest;
136139
Blob hash;
140
+ Blob taglist;
141
+ int flg;
142
+
143
+ flg = db_get_manifest_setting();
137144
138
- if( db_get_boolean("manifest",0) ){
145
+ if( flg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
139146
blob_zero(&manifest);
140147
content_get(vid, &manifest);
141
- zManFile = mprintf("%smanifest", g.zLocalRoot);
142148
blob_zero(&hash);
143149
sha1sum_blob(&manifest, &hash);
144150
sterilize_manifest(&manifest);
151
+ }
152
+ if( flg & MFESTFLG_RAW ){
153
+ zManFile = mprintf("%smanifest", g.zLocalRoot);
145154
blob_write_to_file(&manifest, zManFile);
146155
free(zManFile);
147
- zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
148
- blob_append(&hash, "\n", 1);
149
- blob_write_to_file(&hash, zManFile);
150
- free(zManFile);
151
- blob_reset(&hash);
152156
}else{
153157
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
154158
zManFile = mprintf("%smanifest", g.zLocalRoot);
155159
file_delete(zManFile);
156160
free(zManFile);
157161
}
162
+ }
163
+ if( flg & MFESTFLG_UUID ){
164
+ zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
165
+ blob_append(&hash, "\n", 1);
166
+ blob_write_to_file(&hash, zManFile);
167
+ free(zManFile);
168
+ blob_reset(&hash);
169
+ }else{
158170
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
159171
zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
160172
file_delete(zManFile);
161173
free(zManFile);
162174
}
163175
}
176
+ if( flg & MFESTFLG_TAGS ){
177
+ blob_zero(&taglist);
178
+ zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
179
+ get_checkin_taglist(vid, &taglist);
180
+ blob_write_to_file(&taglist, zManFile);
181
+ free(zManFile);
182
+ blob_reset(&taglist);
183
+ }else{
184
+ if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.tags'") ){
185
+ zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
186
+ file_delete(zManFile);
187
+ free(zManFile);
188
+ }
189
+ }
190
+}
164191
192
+/*
193
+** Find the branch name and all symbolic tags for a particular check-in
194
+** identified by "rid".
195
+**
196
+** The branch name is actually only extracted if this procedure is run
197
+** from within a local check-out. And the branch name is not the branch
198
+** name for "rid" but rather the branch name for the current check-out.
199
+** It is unclear if the rid parameter is always the same as the current
200
+** check-out.
201
+*/
202
+void get_checkin_taglist(int rid, Blob *pOut){
203
+ Stmt stmt;
204
+ char *zCurrent;
205
+ blob_reset(pOut);
206
+ zCurrent = db_text(0, "SELECT value FROM tagxref"
207
+ " WHERE rid=%d AND tagid=%d", rid, TAG_BRANCH);
208
+ blob_appendf(pOut, "branch %s\n", zCurrent);
209
+ db_prepare(&stmt, "SELECT substr(tagname, 5)"
210
+ " FROM tagxref, tag"
211
+ " WHERE tagxref.rid=%d"
212
+ " AND tagxref.tagtype>0"
213
+ " AND tag.tagid=tagxref.tagid"
214
+ " AND tag.tagname GLOB 'sym-*'", rid);
215
+ while( db_step(&stmt)==SQLITE_ROW ){
216
+ const char *zName;
217
+ zName = db_column_text(&stmt, 0);
218
+ blob_appendf(pOut, "tag %s\n", zName);
219
+ }
220
+ db_reset(&stmt);
221
+ db_finalize(&stmt);
165222
}
223
+
166224
167225
/*
168226
** COMMAND: checkout*
169227
** COMMAND: co*
170228
**
171229
--- src/checkout.c
+++ src/checkout.c
@@ -127,44 +127,102 @@
127
128 /*
129 ** If the "manifest" setting is true, then automatically generate
130 ** files named "manifest" and "manifest.uuid" containing, respectively,
131 ** the text of the manifest and the artifact ID of the manifest.
 
 
 
132 */
133 void manifest_to_disk(int vid){
134 char *zManFile;
135 Blob manifest;
136 Blob hash;
 
 
 
 
137
138 if( db_get_boolean("manifest",0) ){
139 blob_zero(&manifest);
140 content_get(vid, &manifest);
141 zManFile = mprintf("%smanifest", g.zLocalRoot);
142 blob_zero(&hash);
143 sha1sum_blob(&manifest, &hash);
144 sterilize_manifest(&manifest);
 
 
 
145 blob_write_to_file(&manifest, zManFile);
146 free(zManFile);
147 zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
148 blob_append(&hash, "\n", 1);
149 blob_write_to_file(&hash, zManFile);
150 free(zManFile);
151 blob_reset(&hash);
152 }else{
153 if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
154 zManFile = mprintf("%smanifest", g.zLocalRoot);
155 file_delete(zManFile);
156 free(zManFile);
157 }
 
 
 
 
 
 
 
 
158 if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
159 zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
160 file_delete(zManFile);
161 free(zManFile);
162 }
163 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165 }
 
166
167 /*
168 ** COMMAND: checkout*
169 ** COMMAND: co*
170 **
171
--- src/checkout.c
+++ src/checkout.c
@@ -127,44 +127,102 @@
127
128 /*
129 ** If the "manifest" setting is true, then automatically generate
130 ** files named "manifest" and "manifest.uuid" containing, respectively,
131 ** the text of the manifest and the artifact ID of the manifest.
132 ** If the manifest setting is set, but is not a boolean value, then treat
133 ** each character as a flag to enable writing "manifest", "manifest.uuid" or
134 ** "manifest.tags".
135 */
136 void manifest_to_disk(int vid){
137 char *zManFile;
138 Blob manifest;
139 Blob hash;
140 Blob taglist;
141 int flg;
142
143 flg = db_get_manifest_setting();
144
145 if( flg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
146 blob_zero(&manifest);
147 content_get(vid, &manifest);
 
148 blob_zero(&hash);
149 sha1sum_blob(&manifest, &hash);
150 sterilize_manifest(&manifest);
151 }
152 if( flg & MFESTFLG_RAW ){
153 zManFile = mprintf("%smanifest", g.zLocalRoot);
154 blob_write_to_file(&manifest, zManFile);
155 free(zManFile);
 
 
 
 
 
156 }else{
157 if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
158 zManFile = mprintf("%smanifest", g.zLocalRoot);
159 file_delete(zManFile);
160 free(zManFile);
161 }
162 }
163 if( flg & MFESTFLG_UUID ){
164 zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
165 blob_append(&hash, "\n", 1);
166 blob_write_to_file(&hash, zManFile);
167 free(zManFile);
168 blob_reset(&hash);
169 }else{
170 if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
171 zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
172 file_delete(zManFile);
173 free(zManFile);
174 }
175 }
176 if( flg & MFESTFLG_TAGS ){
177 blob_zero(&taglist);
178 zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
179 get_checkin_taglist(vid, &taglist);
180 blob_write_to_file(&taglist, zManFile);
181 free(zManFile);
182 blob_reset(&taglist);
183 }else{
184 if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.tags'") ){
185 zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
186 file_delete(zManFile);
187 free(zManFile);
188 }
189 }
190 }
191
192 /*
193 ** Find the branch name and all symbolic tags for a particular check-in
194 ** identified by "rid".
195 **
196 ** The branch name is actually only extracted if this procedure is run
197 ** from within a local check-out. And the branch name is not the branch
198 ** name for "rid" but rather the branch name for the current check-out.
199 ** It is unclear if the rid parameter is always the same as the current
200 ** check-out.
201 */
202 void get_checkin_taglist(int rid, Blob *pOut){
203 Stmt stmt;
204 char *zCurrent;
205 blob_reset(pOut);
206 zCurrent = db_text(0, "SELECT value FROM tagxref"
207 " WHERE rid=%d AND tagid=%d", rid, TAG_BRANCH);
208 blob_appendf(pOut, "branch %s\n", zCurrent);
209 db_prepare(&stmt, "SELECT substr(tagname, 5)"
210 " FROM tagxref, tag"
211 " WHERE tagxref.rid=%d"
212 " AND tagxref.tagtype>0"
213 " AND tag.tagid=tagxref.tagid"
214 " AND tag.tagname GLOB 'sym-*'", rid);
215 while( db_step(&stmt)==SQLITE_ROW ){
216 const char *zName;
217 zName = db_column_text(&stmt, 0);
218 blob_appendf(pOut, "tag %s\n", zName);
219 }
220 db_reset(&stmt);
221 db_finalize(&stmt);
222 }
223
224
225 /*
226 ** COMMAND: checkout*
227 ** COMMAND: co*
228 **
229
+207 -18
--- src/db.c
+++ src/db.c
@@ -27,11 +27,15 @@
2727
** (3) A local checkout database named "_FOSSIL_" or ".fslckout"
2828
** and located at the root of the local copy of the source tree.
2929
**
3030
*/
3131
#include "config.h"
32
-#if ! defined(_WIN32)
32
+#if defined(_WIN32)
33
+# if USE_SEE
34
+# include <windows.h>
35
+# endif
36
+#else
3337
# include <pwd.h>
3438
#endif
3539
#include <sqlite3.h>
3640
#include <sys/types.h>
3741
#include <sys/stat.h>
@@ -870,31 +874,170 @@
870874
db_tolocal_function, 0, 0);
871875
sqlite3_create_function(db, "fromLocal", 0, SQLITE_UTF8, 0,
872876
db_fromlocal_function, 0, 0);
873877
}
874878
879
+#if USE_SEE
880
+/*
881
+** This is a pointer to the saved database encryption key string.
882
+*/
883
+static char *zSavedKey = 0;
884
+
885
+/*
886
+** This is the size of the saved database encryption key, in bytes.
887
+*/
888
+size_t savedKeySize = 0;
889
+
890
+/*
891
+** This function returns the saved database encryption key -OR- zero if
892
+** no database encryption key is saved.
893
+*/
894
+char *db_get_saved_encryption_key(){
895
+ return zSavedKey;
896
+}
897
+
898
+/*
899
+** This function returns the size of the saved database encryption key
900
+** -OR- zero if no database encryption key is saved.
901
+*/
902
+size_t db_get_saved_encryption_key_size(){
903
+ return savedKeySize;
904
+}
905
+
906
+/*
907
+** This function arranges for the database encryption key to be securely
908
+** saved in non-pagable memory (on platforms where this is possible).
909
+*/
910
+static void db_save_encryption_key(
911
+ Blob *pKey
912
+){
913
+ void *p = NULL;
914
+ size_t n = 0;
915
+ size_t pageSize = 0;
916
+ size_t blobSize = 0;
917
+
918
+ blobSize = blob_size(pKey);
919
+ if( blobSize==0 ) return;
920
+ fossil_get_page_size(&pageSize);
921
+ assert( pageSize>0 );
922
+ if( blobSize>pageSize ){
923
+ fossil_fatal("key blob too large: %u versus %u", blobSize, pageSize);
924
+ }
925
+ p = fossil_secure_alloc_page(&n);
926
+ assert( p!=NULL );
927
+ assert( n==pageSize );
928
+ assert( n>=blobSize );
929
+ memcpy(p, blob_str(pKey), blobSize);
930
+ zSavedKey = p;
931
+ savedKeySize = n;
932
+}
933
+
934
+/*
935
+** This function arranges for the saved database encryption key to be
936
+** securely zeroed, unlocked (if necessary), and freed.
937
+*/
938
+void db_unsave_encryption_key(){
939
+ fossil_secure_free_page(zSavedKey, savedKeySize);
940
+ zSavedKey = NULL;
941
+ savedKeySize = 0;
942
+}
943
+
944
+/*
945
+** This function sets the saved database encryption key to the specified
946
+** string value, allocating or freeing the underlying memory if needed.
947
+*/
948
+void db_set_saved_encryption_key(
949
+ Blob *pKey
950
+){
951
+ if( zSavedKey!=NULL ){
952
+ size_t blobSize = blob_size(pKey);
953
+ if( blobSize==0 ){
954
+ db_unsave_encryption_key();
955
+ }else{
956
+ if( blobSize>savedKeySize ){
957
+ fossil_fatal("key blob too large: %u versus %u",
958
+ blobSize, savedKeySize);
959
+ }
960
+ fossil_secure_zero(zSavedKey, savedKeySize);
961
+ memcpy(zSavedKey, blob_str(pKey), blobSize);
962
+ }
963
+ }else{
964
+ db_save_encryption_key(pKey);
965
+ }
966
+}
967
+
968
+#if defined(_WIN32)
969
+/*
970
+** This function sets the saved database encryption key to one that gets
971
+** read from the specified Fossil parent process. This is only necessary
972
+** (or functional) on Windows.
973
+*/
974
+void db_read_saved_encryption_key_from_process(
975
+ DWORD processId, /* Identifier for Fossil parent process. */
976
+ LPVOID pAddress, /* Pointer to saved key buffer in the parent process. */
977
+ SIZE_T nSize /* Size of saved key buffer in the parent process. */
978
+){
979
+ void *p = NULL;
980
+ size_t n = 0;
981
+ size_t pageSize = 0;
982
+ HANDLE hProcess = NULL;
983
+
984
+ fossil_get_page_size(&pageSize);
985
+ assert( pageSize>0 );
986
+ if( nSize>pageSize ){
987
+ fossil_fatal("key too large: %u versus %u", nSize, pageSize);
988
+ }
989
+ p = fossil_secure_alloc_page(&n);
990
+ assert( p!=NULL );
991
+ assert( n==pageSize );
992
+ assert( n>=nSize );
993
+ hProcess = OpenProcess(PROCESS_VM_READ, FALSE, processId);
994
+ if( hProcess!=NULL ){
995
+ SIZE_T nRead = 0;
996
+ if( ReadProcessMemory(hProcess, pAddress, p, nSize, &nRead) ){
997
+ CloseHandle(hProcess);
998
+ if( nRead==nSize ){
999
+ db_unsave_encryption_key();
1000
+ zSavedKey = p;
1001
+ savedKeySize = n;
1002
+ }else{
1003
+ fossil_fatal("bad size read, %u out of %u bytes at %p from pid %lu",
1004
+ nRead, nSize, pAddress, processId);
1005
+ }
1006
+ }else{
1007
+ CloseHandle(hProcess);
1008
+ fossil_fatal("failed read, %u bytes at %p from pid %lu: %lu", nSize,
1009
+ pAddress, processId, GetLastError());
1010
+ }
1011
+ }else{
1012
+ fossil_fatal("failed to open pid %lu: %lu", processId, GetLastError());
1013
+ }
1014
+}
1015
+#endif /* defined(_WIN32) */
1016
+#endif /* USE_SEE */
1017
+
8751018
/*
8761019
** If the database file zDbFile has a name that suggests that it is
877
-** encrypted, then prompt for the encryption key and return it in the
878
-** blob *pKey. Or, if the encryption key has previously been requested,
879
-** just return a copy of the previous result.
1020
+** encrypted, then prompt for the database encryption key and return it
1021
+** in the blob *pKey. Or, if the encryption key has previously been
1022
+** requested, just return a copy of the previous result. The blob in
1023
+** *pKey must be initialized.
8801024
*/
881
-static void db_encryption_key(
1025
+static void db_maybe_obtain_encryption_key(
8821026
const char *zDbFile, /* Name of the database file */
8831027
Blob *pKey /* Put the encryption key here */
8841028
){
885
- blob_init(pKey, 0, 0);
8861029
#if USE_SEE
8871030
if( sqlite3_strglob("*.efossil", zDbFile)==0 ){
888
- static char *zSavedKey = 0;
889
- if( zSavedKey ){
890
- blob_set(pKey, zSavedKey);
1031
+ char *zKey = db_get_saved_encryption_key();
1032
+ if( zKey ){
1033
+ blob_set(pKey, zKey);
8911034
}else{
8921035
char *zPrompt = mprintf("\rencryption key for '%s': ", zDbFile);
8931036
prompt_for_password(zPrompt, pKey, 0);
8941037
fossil_free(zPrompt);
895
- zSavedKey = fossil_strdup(blob_str(pKey));
1038
+ db_set_saved_encryption_key(pKey);
8961039
}
8971040
}
8981041
#endif
8991042
}
9001043
@@ -915,14 +1058,16 @@
9151058
g.zVfsName
9161059
);
9171060
if( rc!=SQLITE_OK ){
9181061
db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
9191062
}
920
- db_encryption_key(zDbName, &key);
1063
+ blob_init(&key, 0, 0);
1064
+ db_maybe_obtain_encryption_key(zDbName, &key);
9211065
if( blob_size(&key)>0 ){
9221066
char *zCmd = sqlite3_mprintf("PRAGMA key(%Q)", blob_str(&key));
9231067
sqlite3_exec(db, zCmd, 0, 0, 0);
1068
+ fossil_secure_zero(zCmd, strlen(zCmd));
9241069
sqlite3_free(zCmd);
9251070
}
9261071
blob_reset(&key);
9271072
sqlite3_busy_timeout(db, 5000);
9281073
sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
@@ -955,14 +1100,19 @@
9551100
/*
9561101
** zDbName is the name of a database file. Attach zDbName using
9571102
** the name zLabel.
9581103
*/
9591104
void db_attach(const char *zDbName, const char *zLabel){
1105
+ char *zCmd;
9601106
Blob key;
961
- db_encryption_key(zDbName, &key);
962
- db_multi_exec("ATTACH DATABASE %Q AS %Q KEY %Q",
963
- zDbName, zLabel, blob_str(&key));
1107
+ blob_init(&key, 0, 0);
1108
+ db_maybe_obtain_encryption_key(zDbName, &key);
1109
+ zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
1110
+ zDbName, zLabel, blob_str(&key));
1111
+ db_multi_exec(zCmd /*works-like:""*/);
1112
+ fossil_secure_zero(zCmd, strlen(zCmd));
1113
+ sqlite3_free(zCmd);
9641114
blob_reset(&key);
9651115
}
9661116
9671117
/*
9681118
** Change the schema name of the "main" database to zLabel.
@@ -1192,10 +1342,11 @@
11921342
}
11931343
if( db_local_table_exists_but_lacks_column("undo_vfile", "islink") ){
11941344
db_multi_exec("ALTER TABLE undo_vfile ADD COLUMN islink BOOL DEFAULT 0");
11951345
}
11961346
}
1347
+ fossil_free(zVFileDef);
11971348
return 1;
11981349
}
11991350
12001351
/*
12011352
** Locate the root directory of the local repository tree. The root
@@ -2270,10 +2421,45 @@
22702421
return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
22712422
}
22722423
void db_lset_int(const char *zName, int value){
22732424
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
22742425
}
2426
+
2427
+#if INTERFACE
2428
+/* Manifest generation flags */
2429
+#define MFESTFLG_RAW 0x01
2430
+#define MFESTFLG_UUID 0x02
2431
+#define MFESTFLG_TAGS 0x04
2432
+#endif /* INTERFACE */
2433
+
2434
+/*
2435
+** Get the manifest setting. For backwards compatibility first check if the
2436
+** value is a boolean. If it's not a boolean, treat each character as a flag
2437
+** to enable a manifest type. This system puts certain boundary conditions on
2438
+** which letters can be used to represent flags (any permutation of flags must
2439
+** not be able to fully form one of the boolean values).
2440
+*/
2441
+int db_get_manifest_setting(void){
2442
+ int flg;
2443
+ char *zVal = db_get("manifest", 0);
2444
+ if( zVal==0 || is_false(zVal) ){
2445
+ return 0;
2446
+ }else if( is_truth(zVal) ){
2447
+ return MFESTFLG_RAW|MFESTFLG_UUID;
2448
+ }
2449
+ flg = 0;
2450
+ while( *zVal ){
2451
+ switch( *zVal ){
2452
+ case 'r': flg |= MFESTFLG_RAW; break;
2453
+ case 'u': flg |= MFESTFLG_UUID; break;
2454
+ case 't': flg |= MFESTFLG_TAGS; break;
2455
+ }
2456
+ zVal++;
2457
+ }
2458
+ return flg;
2459
+}
2460
+
22752461
22762462
/*
22772463
** Record the name of a local repository in the global_config() database.
22782464
** The repository filename %s is recorded as an entry with a "name" field
22792465
** of the following form:
@@ -2570,11 +2756,11 @@
25702756
{ "https-login", 0, 0, 0, 0, "off" },
25712757
{ "ignore-glob", 0, 40, 1, 0, "" },
25722758
{ "keep-glob", 0, 40, 1, 0, "" },
25732759
{ "localauth", 0, 0, 0, 0, "off" },
25742760
{ "main-branch", 0, 40, 0, 0, "trunk" },
2575
- { "manifest", 0, 0, 1, 0, "off" },
2761
+ { "manifest", 0, 5, 1, 0, "off" },
25762762
{ "max-loadavg", 0, 25, 0, 0, "0.0" },
25772763
{ "max-upload", 0, 25, 0, 0, "250000" },
25782764
{ "mtime-changes", 0, 0, 0, 0, "on" },
25792765
#if FOSSIL_ENABLE_LEGACY_MV_RM
25802766
{ "mv-rm-files", 0, 0, 0, 0, "off" },
@@ -2775,13 +2961,16 @@
27752961
** false, all HTTP requests from localhost have
27762962
** unrestricted access to the repository.
27772963
**
27782964
** main-branch The primary branch for the project. Default: trunk
27792965
**
2780
-** manifest If enabled, automatically create files "manifest" and
2781
-** (versionable) "manifest.uuid" in every checkout. The SQLite and
2782
-** Fossil repositories both require this. Default: off.
2966
+** manifest If set to a true boolean value, automatically create
2967
+** (versionable) files "manifest" and "manifest.uuid" in every checkout.
2968
+** Optionally use combinations of characters 'r'
2969
+** for "manifest", 'u' for "manifest.uuid" and 't' for
2970
+** "manifest.tags". The SQLite and Fossil repositories
2971
+** both require manifests. Default: off.
27832972
**
27842973
** max-loadavg Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
27852974
** are disallowed if the system load average goes above this
27862975
** value. "0.0" means no limit. This only works on unix.
27872976
** Only local settings of this value make a difference since
27882977
--- src/db.c
+++ src/db.c
@@ -27,11 +27,15 @@
27 ** (3) A local checkout database named "_FOSSIL_" or ".fslckout"
28 ** and located at the root of the local copy of the source tree.
29 **
30 */
31 #include "config.h"
32 #if ! defined(_WIN32)
 
 
 
 
33 # include <pwd.h>
34 #endif
35 #include <sqlite3.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
@@ -870,31 +874,170 @@
870 db_tolocal_function, 0, 0);
871 sqlite3_create_function(db, "fromLocal", 0, SQLITE_UTF8, 0,
872 db_fromlocal_function, 0, 0);
873 }
874
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
875 /*
876 ** If the database file zDbFile has a name that suggests that it is
877 ** encrypted, then prompt for the encryption key and return it in the
878 ** blob *pKey. Or, if the encryption key has previously been requested,
879 ** just return a copy of the previous result.
 
880 */
881 static void db_encryption_key(
882 const char *zDbFile, /* Name of the database file */
883 Blob *pKey /* Put the encryption key here */
884 ){
885 blob_init(pKey, 0, 0);
886 #if USE_SEE
887 if( sqlite3_strglob("*.efossil", zDbFile)==0 ){
888 static char *zSavedKey = 0;
889 if( zSavedKey ){
890 blob_set(pKey, zSavedKey);
891 }else{
892 char *zPrompt = mprintf("\rencryption key for '%s': ", zDbFile);
893 prompt_for_password(zPrompt, pKey, 0);
894 fossil_free(zPrompt);
895 zSavedKey = fossil_strdup(blob_str(pKey));
896 }
897 }
898 #endif
899 }
900
@@ -915,14 +1058,16 @@
915 g.zVfsName
916 );
917 if( rc!=SQLITE_OK ){
918 db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
919 }
920 db_encryption_key(zDbName, &key);
 
921 if( blob_size(&key)>0 ){
922 char *zCmd = sqlite3_mprintf("PRAGMA key(%Q)", blob_str(&key));
923 sqlite3_exec(db, zCmd, 0, 0, 0);
 
924 sqlite3_free(zCmd);
925 }
926 blob_reset(&key);
927 sqlite3_busy_timeout(db, 5000);
928 sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
@@ -955,14 +1100,19 @@
955 /*
956 ** zDbName is the name of a database file. Attach zDbName using
957 ** the name zLabel.
958 */
959 void db_attach(const char *zDbName, const char *zLabel){
 
960 Blob key;
961 db_encryption_key(zDbName, &key);
962 db_multi_exec("ATTACH DATABASE %Q AS %Q KEY %Q",
963 zDbName, zLabel, blob_str(&key));
 
 
 
 
964 blob_reset(&key);
965 }
966
967 /*
968 ** Change the schema name of the "main" database to zLabel.
@@ -1192,10 +1342,11 @@
1192 }
1193 if( db_local_table_exists_but_lacks_column("undo_vfile", "islink") ){
1194 db_multi_exec("ALTER TABLE undo_vfile ADD COLUMN islink BOOL DEFAULT 0");
1195 }
1196 }
 
1197 return 1;
1198 }
1199
1200 /*
1201 ** Locate the root directory of the local repository tree. The root
@@ -2270,10 +2421,45 @@
2270 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
2271 }
2272 void db_lset_int(const char *zName, int value){
2273 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
2274 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2275
2276 /*
2277 ** Record the name of a local repository in the global_config() database.
2278 ** The repository filename %s is recorded as an entry with a "name" field
2279 ** of the following form:
@@ -2570,11 +2756,11 @@
2570 { "https-login", 0, 0, 0, 0, "off" },
2571 { "ignore-glob", 0, 40, 1, 0, "" },
2572 { "keep-glob", 0, 40, 1, 0, "" },
2573 { "localauth", 0, 0, 0, 0, "off" },
2574 { "main-branch", 0, 40, 0, 0, "trunk" },
2575 { "manifest", 0, 0, 1, 0, "off" },
2576 { "max-loadavg", 0, 25, 0, 0, "0.0" },
2577 { "max-upload", 0, 25, 0, 0, "250000" },
2578 { "mtime-changes", 0, 0, 0, 0, "on" },
2579 #if FOSSIL_ENABLE_LEGACY_MV_RM
2580 { "mv-rm-files", 0, 0, 0, 0, "off" },
@@ -2775,13 +2961,16 @@
2775 ** false, all HTTP requests from localhost have
2776 ** unrestricted access to the repository.
2777 **
2778 ** main-branch The primary branch for the project. Default: trunk
2779 **
2780 ** manifest If enabled, automatically create files "manifest" and
2781 ** (versionable) "manifest.uuid" in every checkout. The SQLite and
2782 ** Fossil repositories both require this. Default: off.
 
 
 
2783 **
2784 ** max-loadavg Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
2785 ** are disallowed if the system load average goes above this
2786 ** value. "0.0" means no limit. This only works on unix.
2787 ** Only local settings of this value make a difference since
2788
--- src/db.c
+++ src/db.c
@@ -27,11 +27,15 @@
27 ** (3) A local checkout database named "_FOSSIL_" or ".fslckout"
28 ** and located at the root of the local copy of the source tree.
29 **
30 */
31 #include "config.h"
32 #if defined(_WIN32)
33 # if USE_SEE
34 # include <windows.h>
35 # endif
36 #else
37 # include <pwd.h>
38 #endif
39 #include <sqlite3.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
@@ -870,31 +874,170 @@
874 db_tolocal_function, 0, 0);
875 sqlite3_create_function(db, "fromLocal", 0, SQLITE_UTF8, 0,
876 db_fromlocal_function, 0, 0);
877 }
878
879 #if USE_SEE
880 /*
881 ** This is a pointer to the saved database encryption key string.
882 */
883 static char *zSavedKey = 0;
884
885 /*
886 ** This is the size of the saved database encryption key, in bytes.
887 */
888 size_t savedKeySize = 0;
889
890 /*
891 ** This function returns the saved database encryption key -OR- zero if
892 ** no database encryption key is saved.
893 */
894 char *db_get_saved_encryption_key(){
895 return zSavedKey;
896 }
897
898 /*
899 ** This function returns the size of the saved database encryption key
900 ** -OR- zero if no database encryption key is saved.
901 */
902 size_t db_get_saved_encryption_key_size(){
903 return savedKeySize;
904 }
905
906 /*
907 ** This function arranges for the database encryption key to be securely
908 ** saved in non-pagable memory (on platforms where this is possible).
909 */
910 static void db_save_encryption_key(
911 Blob *pKey
912 ){
913 void *p = NULL;
914 size_t n = 0;
915 size_t pageSize = 0;
916 size_t blobSize = 0;
917
918 blobSize = blob_size(pKey);
919 if( blobSize==0 ) return;
920 fossil_get_page_size(&pageSize);
921 assert( pageSize>0 );
922 if( blobSize>pageSize ){
923 fossil_fatal("key blob too large: %u versus %u", blobSize, pageSize);
924 }
925 p = fossil_secure_alloc_page(&n);
926 assert( p!=NULL );
927 assert( n==pageSize );
928 assert( n>=blobSize );
929 memcpy(p, blob_str(pKey), blobSize);
930 zSavedKey = p;
931 savedKeySize = n;
932 }
933
934 /*
935 ** This function arranges for the saved database encryption key to be
936 ** securely zeroed, unlocked (if necessary), and freed.
937 */
938 void db_unsave_encryption_key(){
939 fossil_secure_free_page(zSavedKey, savedKeySize);
940 zSavedKey = NULL;
941 savedKeySize = 0;
942 }
943
944 /*
945 ** This function sets the saved database encryption key to the specified
946 ** string value, allocating or freeing the underlying memory if needed.
947 */
948 void db_set_saved_encryption_key(
949 Blob *pKey
950 ){
951 if( zSavedKey!=NULL ){
952 size_t blobSize = blob_size(pKey);
953 if( blobSize==0 ){
954 db_unsave_encryption_key();
955 }else{
956 if( blobSize>savedKeySize ){
957 fossil_fatal("key blob too large: %u versus %u",
958 blobSize, savedKeySize);
959 }
960 fossil_secure_zero(zSavedKey, savedKeySize);
961 memcpy(zSavedKey, blob_str(pKey), blobSize);
962 }
963 }else{
964 db_save_encryption_key(pKey);
965 }
966 }
967
968 #if defined(_WIN32)
969 /*
970 ** This function sets the saved database encryption key to one that gets
971 ** read from the specified Fossil parent process. This is only necessary
972 ** (or functional) on Windows.
973 */
974 void db_read_saved_encryption_key_from_process(
975 DWORD processId, /* Identifier for Fossil parent process. */
976 LPVOID pAddress, /* Pointer to saved key buffer in the parent process. */
977 SIZE_T nSize /* Size of saved key buffer in the parent process. */
978 ){
979 void *p = NULL;
980 size_t n = 0;
981 size_t pageSize = 0;
982 HANDLE hProcess = NULL;
983
984 fossil_get_page_size(&pageSize);
985 assert( pageSize>0 );
986 if( nSize>pageSize ){
987 fossil_fatal("key too large: %u versus %u", nSize, pageSize);
988 }
989 p = fossil_secure_alloc_page(&n);
990 assert( p!=NULL );
991 assert( n==pageSize );
992 assert( n>=nSize );
993 hProcess = OpenProcess(PROCESS_VM_READ, FALSE, processId);
994 if( hProcess!=NULL ){
995 SIZE_T nRead = 0;
996 if( ReadProcessMemory(hProcess, pAddress, p, nSize, &nRead) ){
997 CloseHandle(hProcess);
998 if( nRead==nSize ){
999 db_unsave_encryption_key();
1000 zSavedKey = p;
1001 savedKeySize = n;
1002 }else{
1003 fossil_fatal("bad size read, %u out of %u bytes at %p from pid %lu",
1004 nRead, nSize, pAddress, processId);
1005 }
1006 }else{
1007 CloseHandle(hProcess);
1008 fossil_fatal("failed read, %u bytes at %p from pid %lu: %lu", nSize,
1009 pAddress, processId, GetLastError());
1010 }
1011 }else{
1012 fossil_fatal("failed to open pid %lu: %lu", processId, GetLastError());
1013 }
1014 }
1015 #endif /* defined(_WIN32) */
1016 #endif /* USE_SEE */
1017
1018 /*
1019 ** If the database file zDbFile has a name that suggests that it is
1020 ** encrypted, then prompt for the database encryption key and return it
1021 ** in the blob *pKey. Or, if the encryption key has previously been
1022 ** requested, just return a copy of the previous result. The blob in
1023 ** *pKey must be initialized.
1024 */
1025 static void db_maybe_obtain_encryption_key(
1026 const char *zDbFile, /* Name of the database file */
1027 Blob *pKey /* Put the encryption key here */
1028 ){
 
1029 #if USE_SEE
1030 if( sqlite3_strglob("*.efossil", zDbFile)==0 ){
1031 char *zKey = db_get_saved_encryption_key();
1032 if( zKey ){
1033 blob_set(pKey, zKey);
1034 }else{
1035 char *zPrompt = mprintf("\rencryption key for '%s': ", zDbFile);
1036 prompt_for_password(zPrompt, pKey, 0);
1037 fossil_free(zPrompt);
1038 db_set_saved_encryption_key(pKey);
1039 }
1040 }
1041 #endif
1042 }
1043
@@ -915,14 +1058,16 @@
1058 g.zVfsName
1059 );
1060 if( rc!=SQLITE_OK ){
1061 db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
1062 }
1063 blob_init(&key, 0, 0);
1064 db_maybe_obtain_encryption_key(zDbName, &key);
1065 if( blob_size(&key)>0 ){
1066 char *zCmd = sqlite3_mprintf("PRAGMA key(%Q)", blob_str(&key));
1067 sqlite3_exec(db, zCmd, 0, 0, 0);
1068 fossil_secure_zero(zCmd, strlen(zCmd));
1069 sqlite3_free(zCmd);
1070 }
1071 blob_reset(&key);
1072 sqlite3_busy_timeout(db, 5000);
1073 sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
@@ -955,14 +1100,19 @@
1100 /*
1101 ** zDbName is the name of a database file. Attach zDbName using
1102 ** the name zLabel.
1103 */
1104 void db_attach(const char *zDbName, const char *zLabel){
1105 char *zCmd;
1106 Blob key;
1107 blob_init(&key, 0, 0);
1108 db_maybe_obtain_encryption_key(zDbName, &key);
1109 zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
1110 zDbName, zLabel, blob_str(&key));
1111 db_multi_exec(zCmd /*works-like:""*/);
1112 fossil_secure_zero(zCmd, strlen(zCmd));
1113 sqlite3_free(zCmd);
1114 blob_reset(&key);
1115 }
1116
1117 /*
1118 ** Change the schema name of the "main" database to zLabel.
@@ -1192,10 +1342,11 @@
1342 }
1343 if( db_local_table_exists_but_lacks_column("undo_vfile", "islink") ){
1344 db_multi_exec("ALTER TABLE undo_vfile ADD COLUMN islink BOOL DEFAULT 0");
1345 }
1346 }
1347 fossil_free(zVFileDef);
1348 return 1;
1349 }
1350
1351 /*
1352 ** Locate the root directory of the local repository tree. The root
@@ -2270,10 +2421,45 @@
2421 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
2422 }
2423 void db_lset_int(const char *zName, int value){
2424 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
2425 }
2426
2427 #if INTERFACE
2428 /* Manifest generation flags */
2429 #define MFESTFLG_RAW 0x01
2430 #define MFESTFLG_UUID 0x02
2431 #define MFESTFLG_TAGS 0x04
2432 #endif /* INTERFACE */
2433
2434 /*
2435 ** Get the manifest setting. For backwards compatibility first check if the
2436 ** value is a boolean. If it's not a boolean, treat each character as a flag
2437 ** to enable a manifest type. This system puts certain boundary conditions on
2438 ** which letters can be used to represent flags (any permutation of flags must
2439 ** not be able to fully form one of the boolean values).
2440 */
2441 int db_get_manifest_setting(void){
2442 int flg;
2443 char *zVal = db_get("manifest", 0);
2444 if( zVal==0 || is_false(zVal) ){
2445 return 0;
2446 }else if( is_truth(zVal) ){
2447 return MFESTFLG_RAW|MFESTFLG_UUID;
2448 }
2449 flg = 0;
2450 while( *zVal ){
2451 switch( *zVal ){
2452 case 'r': flg |= MFESTFLG_RAW; break;
2453 case 'u': flg |= MFESTFLG_UUID; break;
2454 case 't': flg |= MFESTFLG_TAGS; break;
2455 }
2456 zVal++;
2457 }
2458 return flg;
2459 }
2460
2461
2462 /*
2463 ** Record the name of a local repository in the global_config() database.
2464 ** The repository filename %s is recorded as an entry with a "name" field
2465 ** of the following form:
@@ -2570,11 +2756,11 @@
2756 { "https-login", 0, 0, 0, 0, "off" },
2757 { "ignore-glob", 0, 40, 1, 0, "" },
2758 { "keep-glob", 0, 40, 1, 0, "" },
2759 { "localauth", 0, 0, 0, 0, "off" },
2760 { "main-branch", 0, 40, 0, 0, "trunk" },
2761 { "manifest", 0, 5, 1, 0, "off" },
2762 { "max-loadavg", 0, 25, 0, 0, "0.0" },
2763 { "max-upload", 0, 25, 0, 0, "250000" },
2764 { "mtime-changes", 0, 0, 0, 0, "on" },
2765 #if FOSSIL_ENABLE_LEGACY_MV_RM
2766 { "mv-rm-files", 0, 0, 0, 0, "off" },
@@ -2775,13 +2961,16 @@
2961 ** false, all HTTP requests from localhost have
2962 ** unrestricted access to the repository.
2963 **
2964 ** main-branch The primary branch for the project. Default: trunk
2965 **
2966 ** manifest If set to a true boolean value, automatically create
2967 ** (versionable) files "manifest" and "manifest.uuid" in every checkout.
2968 ** Optionally use combinations of characters 'r'
2969 ** for "manifest", 'u' for "manifest.uuid" and 't' for
2970 ** "manifest.tags". The SQLite and Fossil repositories
2971 ** both require manifests. Default: off.
2972 **
2973 ** max-loadavg Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
2974 ** are disallowed if the system load average goes above this
2975 ** value. "0.0" means no limit. This only works on unix.
2976 ** Only local settings of this value make a difference since
2977
+1 -2
--- src/delta.c
+++ src/delta.c
@@ -377,13 +377,12 @@
377377
/* Compute the hash table used to locate matching sections in the
378378
** source file.
379379
*/
380380
nHash = lenSrc/NHASH;
381381
collide = fossil_malloc( nHash*2*sizeof(int) );
382
+ memset(collide, -1, nHash*2*sizeof(int));
382383
landmark = &collide[nHash];
383
- memset(landmark, -1, nHash*sizeof(int));
384
- memset(collide, -1, nHash*sizeof(int));
385384
for(i=0; i<lenSrc-NHASH; i+=NHASH){
386385
int hv = hash_once(&zSrc[i]) % nHash;
387386
collide[i/NHASH] = landmark[hv];
388387
landmark[hv] = i/NHASH;
389388
}
390389
--- src/delta.c
+++ src/delta.c
@@ -377,13 +377,12 @@
377 /* Compute the hash table used to locate matching sections in the
378 ** source file.
379 */
380 nHash = lenSrc/NHASH;
381 collide = fossil_malloc( nHash*2*sizeof(int) );
 
382 landmark = &collide[nHash];
383 memset(landmark, -1, nHash*sizeof(int));
384 memset(collide, -1, nHash*sizeof(int));
385 for(i=0; i<lenSrc-NHASH; i+=NHASH){
386 int hv = hash_once(&zSrc[i]) % nHash;
387 collide[i/NHASH] = landmark[hv];
388 landmark[hv] = i/NHASH;
389 }
390
--- src/delta.c
+++ src/delta.c
@@ -377,13 +377,12 @@
377 /* Compute the hash table used to locate matching sections in the
378 ** source file.
379 */
380 nHash = lenSrc/NHASH;
381 collide = fossil_malloc( nHash*2*sizeof(int) );
382 memset(collide, -1, nHash*2*sizeof(int));
383 landmark = &collide[nHash];
 
 
384 for(i=0; i<lenSrc-NHASH; i+=NHASH){
385 int hv = hash_once(&zSrc[i]) % nHash;
386 collide[i/NHASH] = landmark[hv];
387 landmark[hv] = i/NHASH;
388 }
389
+11 -11
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -29,16 +29,16 @@
2929
const char *zOrig, *zTarg;
3030
int lenOrig, lenTarg;
3131
int len;
3232
char *zRes;
3333
blob_zero(pDelta);
34
- zOrig = blob_buffer(pOriginal);
34
+ zOrig = blob_materialize(pOriginal);
3535
lenOrig = blob_size(pOriginal);
36
- zTarg = blob_buffer(pTarget);
36
+ zTarg = blob_materialize(pTarget);
3737
lenTarg = blob_size(pTarget);
3838
blob_resize(pDelta, lenTarg+16);
39
- zRes = blob_buffer(pDelta);
39
+ zRes = blob_materialize(pDelta);
4040
len = delta_create(zOrig, lenOrig, zTarg, lenTarg, zRes);
4141
blob_resize(pDelta, len);
4242
return 0;
4343
}
4444
@@ -54,18 +54,18 @@
5454
Blob orig, target, delta;
5555
if( g.argc!=5 ){
5656
usage("ORIGIN TARGET DELTA");
5757
}
5858
if( blob_read_from_file(&orig, g.argv[2])<0 ){
59
- fossil_fatal("cannot read %s\n", g.argv[2]);
59
+ fossil_fatal("cannot read %s", g.argv[2]);
6060
}
6161
if( blob_read_from_file(&target, g.argv[3])<0 ){
62
- fossil_fatal("cannot read %s\n", g.argv[3]);
62
+ fossil_fatal("cannot read %s", g.argv[3]);
6363
}
6464
blob_delta_create(&orig, &target, &delta);
6565
if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){
66
- fossil_fatal("cannot write %s\n", g.argv[4]);
66
+ fossil_fatal("cannot write %s", g.argv[4]);
6767
}
6868
blob_reset(&orig);
6969
blob_reset(&target);
7070
blob_reset(&delta);
7171
}
@@ -85,14 +85,14 @@
8585
int sz1, sz2, sz3;
8686
if( g.argc!=4 ){
8787
usage("ORIGIN TARGET");
8888
}
8989
if( blob_read_from_file(&orig, g.argv[2])<0 ){
90
- fossil_fatal("cannot read %s\n", g.argv[2]);
90
+ fossil_fatal("cannot read %s", g.argv[2]);
9191
}
9292
if( blob_read_from_file(&target, g.argv[3])<0 ){
93
- fossil_fatal("cannot read %s\n", g.argv[3]);
93
+ fossil_fatal("cannot read %s", g.argv[3]);
9494
}
9595
blob_delta_create(&orig, &target, &delta);
9696
delta_analyze(blob_buffer(&delta), blob_size(&delta), &nCopy, &nInsert);
9797
sz1 = blob_size(&orig);
9898
sz2 = blob_size(&target);
@@ -153,18 +153,18 @@
153153
Blob orig, target, delta;
154154
if( g.argc!=5 ){
155155
usage("ORIGIN DELTA TARGET");
156156
}
157157
if( blob_read_from_file(&orig, g.argv[2])<0 ){
158
- fossil_fatal("cannot read %s\n", g.argv[2]);
158
+ fossil_fatal("cannot read %s", g.argv[2]);
159159
}
160160
if( blob_read_from_file(&delta, g.argv[3])<0 ){
161
- fossil_fatal("cannot read %s\n", g.argv[3]);
161
+ fossil_fatal("cannot read %s", g.argv[3]);
162162
}
163163
blob_delta_apply(&orig, &delta, &target);
164164
if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){
165
- fossil_fatal("cannot write %s\n", g.argv[4]);
165
+ fossil_fatal("cannot write %s", g.argv[4]);
166166
}
167167
blob_reset(&orig);
168168
blob_reset(&target);
169169
blob_reset(&delta);
170170
}
171171
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -29,16 +29,16 @@
29 const char *zOrig, *zTarg;
30 int lenOrig, lenTarg;
31 int len;
32 char *zRes;
33 blob_zero(pDelta);
34 zOrig = blob_buffer(pOriginal);
35 lenOrig = blob_size(pOriginal);
36 zTarg = blob_buffer(pTarget);
37 lenTarg = blob_size(pTarget);
38 blob_resize(pDelta, lenTarg+16);
39 zRes = blob_buffer(pDelta);
40 len = delta_create(zOrig, lenOrig, zTarg, lenTarg, zRes);
41 blob_resize(pDelta, len);
42 return 0;
43 }
44
@@ -54,18 +54,18 @@
54 Blob orig, target, delta;
55 if( g.argc!=5 ){
56 usage("ORIGIN TARGET DELTA");
57 }
58 if( blob_read_from_file(&orig, g.argv[2])<0 ){
59 fossil_fatal("cannot read %s\n", g.argv[2]);
60 }
61 if( blob_read_from_file(&target, g.argv[3])<0 ){
62 fossil_fatal("cannot read %s\n", g.argv[3]);
63 }
64 blob_delta_create(&orig, &target, &delta);
65 if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){
66 fossil_fatal("cannot write %s\n", g.argv[4]);
67 }
68 blob_reset(&orig);
69 blob_reset(&target);
70 blob_reset(&delta);
71 }
@@ -85,14 +85,14 @@
85 int sz1, sz2, sz3;
86 if( g.argc!=4 ){
87 usage("ORIGIN TARGET");
88 }
89 if( blob_read_from_file(&orig, g.argv[2])<0 ){
90 fossil_fatal("cannot read %s\n", g.argv[2]);
91 }
92 if( blob_read_from_file(&target, g.argv[3])<0 ){
93 fossil_fatal("cannot read %s\n", g.argv[3]);
94 }
95 blob_delta_create(&orig, &target, &delta);
96 delta_analyze(blob_buffer(&delta), blob_size(&delta), &nCopy, &nInsert);
97 sz1 = blob_size(&orig);
98 sz2 = blob_size(&target);
@@ -153,18 +153,18 @@
153 Blob orig, target, delta;
154 if( g.argc!=5 ){
155 usage("ORIGIN DELTA TARGET");
156 }
157 if( blob_read_from_file(&orig, g.argv[2])<0 ){
158 fossil_fatal("cannot read %s\n", g.argv[2]);
159 }
160 if( blob_read_from_file(&delta, g.argv[3])<0 ){
161 fossil_fatal("cannot read %s\n", g.argv[3]);
162 }
163 blob_delta_apply(&orig, &delta, &target);
164 if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){
165 fossil_fatal("cannot write %s\n", g.argv[4]);
166 }
167 blob_reset(&orig);
168 blob_reset(&target);
169 blob_reset(&delta);
170 }
171
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -29,16 +29,16 @@
29 const char *zOrig, *zTarg;
30 int lenOrig, lenTarg;
31 int len;
32 char *zRes;
33 blob_zero(pDelta);
34 zOrig = blob_materialize(pOriginal);
35 lenOrig = blob_size(pOriginal);
36 zTarg = blob_materialize(pTarget);
37 lenTarg = blob_size(pTarget);
38 blob_resize(pDelta, lenTarg+16);
39 zRes = blob_materialize(pDelta);
40 len = delta_create(zOrig, lenOrig, zTarg, lenTarg, zRes);
41 blob_resize(pDelta, len);
42 return 0;
43 }
44
@@ -54,18 +54,18 @@
54 Blob orig, target, delta;
55 if( g.argc!=5 ){
56 usage("ORIGIN TARGET DELTA");
57 }
58 if( blob_read_from_file(&orig, g.argv[2])<0 ){
59 fossil_fatal("cannot read %s", g.argv[2]);
60 }
61 if( blob_read_from_file(&target, g.argv[3])<0 ){
62 fossil_fatal("cannot read %s", g.argv[3]);
63 }
64 blob_delta_create(&orig, &target, &delta);
65 if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){
66 fossil_fatal("cannot write %s", g.argv[4]);
67 }
68 blob_reset(&orig);
69 blob_reset(&target);
70 blob_reset(&delta);
71 }
@@ -85,14 +85,14 @@
85 int sz1, sz2, sz3;
86 if( g.argc!=4 ){
87 usage("ORIGIN TARGET");
88 }
89 if( blob_read_from_file(&orig, g.argv[2])<0 ){
90 fossil_fatal("cannot read %s", g.argv[2]);
91 }
92 if( blob_read_from_file(&target, g.argv[3])<0 ){
93 fossil_fatal("cannot read %s", g.argv[3]);
94 }
95 blob_delta_create(&orig, &target, &delta);
96 delta_analyze(blob_buffer(&delta), blob_size(&delta), &nCopy, &nInsert);
97 sz1 = blob_size(&orig);
98 sz2 = blob_size(&target);
@@ -153,18 +153,18 @@
153 Blob orig, target, delta;
154 if( g.argc!=5 ){
155 usage("ORIGIN DELTA TARGET");
156 }
157 if( blob_read_from_file(&orig, g.argv[2])<0 ){
158 fossil_fatal("cannot read %s", g.argv[2]);
159 }
160 if( blob_read_from_file(&delta, g.argv[3])<0 ){
161 fossil_fatal("cannot read %s", g.argv[3]);
162 }
163 blob_delta_apply(&orig, &delta, &target);
164 if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){
165 fossil_fatal("cannot write %s", g.argv[4]);
166 }
167 blob_reset(&orig);
168 blob_reset(&target);
169 blob_reset(&delta);
170 }
171
+57 -37
--- src/diff.c
+++ src/diff.c
@@ -115,10 +115,34 @@
115115
int nFrom; /* Number of lines in aFrom[] */
116116
DLine *aTo; /* File on right side of the diff */
117117
int nTo; /* Number of lines in aTo[] */
118118
int (*same_fn)(const DLine*,const DLine*); /* comparison function */
119119
};
120
+
121
+/*
122
+** Count the number of lines in the input string. Include the last line
123
+** in the count even if it lacks the \n terminator. If an empty string
124
+** is specified, the number of lines is zero. For the purposes of this
125
+** function, a string is considered empty if it contains no characters
126
+** -OR- it contains only NUL characters.
127
+*/
128
+static int count_lines(
129
+ const char *z,
130
+ int n,
131
+ int *pnLine
132
+){
133
+ int nLine;
134
+ const char *zNL, *z2;
135
+ for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){}
136
+ if( z2[0]!='\0' ){
137
+ nLine++;
138
+ do{ z2++; }while( z2[0]!='\0' );
139
+ }
140
+ if( n!=(int)(z2-z) ) return 0;
141
+ if( pnLine ) *pnLine = nLine;
142
+ return 1;
143
+}
120144
121145
/*
122146
** Return an array of DLine objects containing a pointer to the
123147
** start of each line and a hash of that line. The lower
124148
** bits of the hash store the length of each line.
@@ -137,45 +161,36 @@
137161
const char *z,
138162
int n,
139163
int *pnLine,
140164
u64 diffFlags
141165
){
142
- int nLine, i, j, k, s, x;
166
+ int nLine, i, k, nn, s, x;
143167
unsigned int h, h2;
144168
DLine *a;
145
-
146
- /* Count the number of lines. Allocate space to hold
147
- ** the returned array.
148
- */
149
- for(i=j=0, nLine=1; i<n; i++, j++){
150
- int c = z[i];
151
- if( c==0 ){
152
- return 0;
153
- }
154
- if( c=='\n' && z[i+1]!=0 ){
155
- nLine++;
156
- if( j>LENGTH_MASK ){
157
- return 0;
158
- }
159
- j = 0;
160
- }
161
- }
162
- if( j>LENGTH_MASK ){
163
- return 0;
164
- }
165
- a = fossil_malloc( nLine*sizeof(a[0]) );
166
- memset(a, 0, nLine*sizeof(a[0]) );
167
- if( n==0 ){
169
+ const char *zNL;
170
+
171
+ if( count_lines(z, n, &nLine)==0 ){
172
+ return 0;
173
+ }
174
+ assert( nLine>0 || z[0]=='\0' );
175
+ a = fossil_malloc( sizeof(a[0])*nLine );
176
+ memset(a, 0, sizeof(a[0])*nLine);
177
+ if( nLine==0 ){
168178
*pnLine = 0;
169179
return a;
170180
}
171
-
172
- /* Fill in the array */
173
- for(i=0; i<nLine; i++){
174
- for(j=0; z[j] && z[j]!='\n'; j++){}
181
+ i = 0;
182
+ do{
183
+ zNL = strchr(z,'\n');
184
+ if( zNL==0 ) zNL = z+n;
185
+ nn = (int)(zNL - z);
186
+ if( nn>LENGTH_MASK ){
187
+ fossil_free(a);
188
+ return 0;
189
+ }
175190
a[i].z = z;
176
- k = j;
191
+ k = nn;
177192
if( diffFlags & DIFF_STRIP_EOLCR ){
178193
if( k>0 && z[k-1]=='\r' ){ k--; }
179194
}
180195
a[i].n = k;
181196
s = 0;
@@ -184,29 +199,34 @@
184199
}
185200
if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
186201
int numws = 0;
187202
while( s<k && fossil_isspace(z[s]) ){ s++; }
188203
for(h=0, x=s; x<k; x++){
189
- if( fossil_isspace(z[x]) ){
204
+ char c = z[x];
205
+ if( fossil_isspace(c) ){
190206
++numws;
191207
}else{
192
- h = h ^ (h<<2) ^ z[x];
208
+ h += c;
209
+ h *= 0x9e3779b1;
193210
}
194211
}
195212
k -= numws;
196213
}else{
197214
for(h=0, x=s; x<k; x++){
198
- h = h ^ (h<<2) ^ z[x];
215
+ h += z[x];
216
+ h *= 0x9e3779b1;
199217
}
200218
}
201219
a[i].indent = s;
202220
a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
203221
h2 = h % nLine;
204222
a[i].iNext = a[h2].iHash;
205223
a[h2].iHash = i+1;
206
- z += j+1;
207
- }
224
+ z += nn+1; n -= nn+1;
225
+ i++;
226
+ }while( zNL[0]!='\0' && zNL[1]!='\0' );
227
+ assert( i==nLine );
208228
209229
/* Return results */
210230
*pnLine = nLine;
211231
return a;
212232
}
@@ -963,23 +983,23 @@
963983
if( nA>250 ) nA = 250;
964984
if( nB>250 ) nB = 250;
965985
avg = (nA+nB)/2;
966986
if( avg==0 ) return 0;
967987
if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
968
- memset(aFirst, 0, sizeof(aFirst));
988
+ memset(aFirst, 0xff, sizeof(aFirst));
969989
zA--; zB--; /* Make both zA[] and zB[] 1-indexed */
970990
for(i=nB; i>0; i--){
971991
c = (unsigned char)zB[i];
972992
aNext[i] = aFirst[c];
973993
aFirst[c] = i;
974994
}
975995
best = 0;
976996
for(i=1; i<=nA-best; i++){
977997
c = (unsigned char)zA[i];
978
- for(j=aFirst[c]; j>0 && j<nB-best; j = aNext[j]){
998
+ for(j=aFirst[c]; j<nB-best && memcmp(&zA[i],&zB[j],best)==0; j = aNext[j]){
979999
int limit = minInt(nA-i, nB-j);
980
- for(k=1; k<=limit && zA[k+i]==zB[k+j]; k++){}
1000
+ for(k=best; k<=limit && zA[k+i]==zB[k+j]; k++){}
9811001
if( k>best ) best = k;
9821002
}
9831003
}
9841004
score = (best>avg) ? 0 : (avg - best)*100/avg;
9851005
9861006
--- src/diff.c
+++ src/diff.c
@@ -115,10 +115,34 @@
115 int nFrom; /* Number of lines in aFrom[] */
116 DLine *aTo; /* File on right side of the diff */
117 int nTo; /* Number of lines in aTo[] */
118 int (*same_fn)(const DLine*,const DLine*); /* comparison function */
119 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
121 /*
122 ** Return an array of DLine objects containing a pointer to the
123 ** start of each line and a hash of that line. The lower
124 ** bits of the hash store the length of each line.
@@ -137,45 +161,36 @@
137 const char *z,
138 int n,
139 int *pnLine,
140 u64 diffFlags
141 ){
142 int nLine, i, j, k, s, x;
143 unsigned int h, h2;
144 DLine *a;
145
146 /* Count the number of lines. Allocate space to hold
147 ** the returned array.
148 */
149 for(i=j=0, nLine=1; i<n; i++, j++){
150 int c = z[i];
151 if( c==0 ){
152 return 0;
153 }
154 if( c=='\n' && z[i+1]!=0 ){
155 nLine++;
156 if( j>LENGTH_MASK ){
157 return 0;
158 }
159 j = 0;
160 }
161 }
162 if( j>LENGTH_MASK ){
163 return 0;
164 }
165 a = fossil_malloc( nLine*sizeof(a[0]) );
166 memset(a, 0, nLine*sizeof(a[0]) );
167 if( n==0 ){
168 *pnLine = 0;
169 return a;
170 }
171
172 /* Fill in the array */
173 for(i=0; i<nLine; i++){
174 for(j=0; z[j] && z[j]!='\n'; j++){}
 
 
 
 
 
175 a[i].z = z;
176 k = j;
177 if( diffFlags & DIFF_STRIP_EOLCR ){
178 if( k>0 && z[k-1]=='\r' ){ k--; }
179 }
180 a[i].n = k;
181 s = 0;
@@ -184,29 +199,34 @@
184 }
185 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
186 int numws = 0;
187 while( s<k && fossil_isspace(z[s]) ){ s++; }
188 for(h=0, x=s; x<k; x++){
189 if( fossil_isspace(z[x]) ){
 
190 ++numws;
191 }else{
192 h = h ^ (h<<2) ^ z[x];
 
193 }
194 }
195 k -= numws;
196 }else{
197 for(h=0, x=s; x<k; x++){
198 h = h ^ (h<<2) ^ z[x];
 
199 }
200 }
201 a[i].indent = s;
202 a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
203 h2 = h % nLine;
204 a[i].iNext = a[h2].iHash;
205 a[h2].iHash = i+1;
206 z += j+1;
207 }
 
 
208
209 /* Return results */
210 *pnLine = nLine;
211 return a;
212 }
@@ -963,23 +983,23 @@
963 if( nA>250 ) nA = 250;
964 if( nB>250 ) nB = 250;
965 avg = (nA+nB)/2;
966 if( avg==0 ) return 0;
967 if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
968 memset(aFirst, 0, sizeof(aFirst));
969 zA--; zB--; /* Make both zA[] and zB[] 1-indexed */
970 for(i=nB; i>0; i--){
971 c = (unsigned char)zB[i];
972 aNext[i] = aFirst[c];
973 aFirst[c] = i;
974 }
975 best = 0;
976 for(i=1; i<=nA-best; i++){
977 c = (unsigned char)zA[i];
978 for(j=aFirst[c]; j>0 && j<nB-best; j = aNext[j]){
979 int limit = minInt(nA-i, nB-j);
980 for(k=1; k<=limit && zA[k+i]==zB[k+j]; k++){}
981 if( k>best ) best = k;
982 }
983 }
984 score = (best>avg) ? 0 : (avg - best)*100/avg;
985
986
--- src/diff.c
+++ src/diff.c
@@ -115,10 +115,34 @@
115 int nFrom; /* Number of lines in aFrom[] */
116 DLine *aTo; /* File on right side of the diff */
117 int nTo; /* Number of lines in aTo[] */
118 int (*same_fn)(const DLine*,const DLine*); /* comparison function */
119 };
120
121 /*
122 ** Count the number of lines in the input string. Include the last line
123 ** in the count even if it lacks the \n terminator. If an empty string
124 ** is specified, the number of lines is zero. For the purposes of this
125 ** function, a string is considered empty if it contains no characters
126 ** -OR- it contains only NUL characters.
127 */
128 static int count_lines(
129 const char *z,
130 int n,
131 int *pnLine
132 ){
133 int nLine;
134 const char *zNL, *z2;
135 for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){}
136 if( z2[0]!='\0' ){
137 nLine++;
138 do{ z2++; }while( z2[0]!='\0' );
139 }
140 if( n!=(int)(z2-z) ) return 0;
141 if( pnLine ) *pnLine = nLine;
142 return 1;
143 }
144
145 /*
146 ** Return an array of DLine objects containing a pointer to the
147 ** start of each line and a hash of that line. The lower
148 ** bits of the hash store the length of each line.
@@ -137,45 +161,36 @@
161 const char *z,
162 int n,
163 int *pnLine,
164 u64 diffFlags
165 ){
166 int nLine, i, k, nn, s, x;
167 unsigned int h, h2;
168 DLine *a;
169 const char *zNL;
170
171 if( count_lines(z, n, &nLine)==0 ){
172 return 0;
173 }
174 assert( nLine>0 || z[0]=='\0' );
175 a = fossil_malloc( sizeof(a[0])*nLine );
176 memset(a, 0, sizeof(a[0])*nLine);
177 if( nLine==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178 *pnLine = 0;
179 return a;
180 }
181 i = 0;
182 do{
183 zNL = strchr(z,'\n');
184 if( zNL==0 ) zNL = z+n;
185 nn = (int)(zNL - z);
186 if( nn>LENGTH_MASK ){
187 fossil_free(a);
188 return 0;
189 }
190 a[i].z = z;
191 k = nn;
192 if( diffFlags & DIFF_STRIP_EOLCR ){
193 if( k>0 && z[k-1]=='\r' ){ k--; }
194 }
195 a[i].n = k;
196 s = 0;
@@ -184,29 +199,34 @@
199 }
200 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
201 int numws = 0;
202 while( s<k && fossil_isspace(z[s]) ){ s++; }
203 for(h=0, x=s; x<k; x++){
204 char c = z[x];
205 if( fossil_isspace(c) ){
206 ++numws;
207 }else{
208 h += c;
209 h *= 0x9e3779b1;
210 }
211 }
212 k -= numws;
213 }else{
214 for(h=0, x=s; x<k; x++){
215 h += z[x];
216 h *= 0x9e3779b1;
217 }
218 }
219 a[i].indent = s;
220 a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
221 h2 = h % nLine;
222 a[i].iNext = a[h2].iHash;
223 a[h2].iHash = i+1;
224 z += nn+1; n -= nn+1;
225 i++;
226 }while( zNL[0]!='\0' && zNL[1]!='\0' );
227 assert( i==nLine );
228
229 /* Return results */
230 *pnLine = nLine;
231 return a;
232 }
@@ -963,23 +983,23 @@
983 if( nA>250 ) nA = 250;
984 if( nB>250 ) nB = 250;
985 avg = (nA+nB)/2;
986 if( avg==0 ) return 0;
987 if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
988 memset(aFirst, 0xff, sizeof(aFirst));
989 zA--; zB--; /* Make both zA[] and zB[] 1-indexed */
990 for(i=nB; i>0; i--){
991 c = (unsigned char)zB[i];
992 aNext[i] = aFirst[c];
993 aFirst[c] = i;
994 }
995 best = 0;
996 for(i=1; i<=nA-best; i++){
997 c = (unsigned char)zA[i];
998 for(j=aFirst[c]; j<nB-best && memcmp(&zA[i],&zB[j],best)==0; j = aNext[j]){
999 int limit = minInt(nA-i, nB-j);
1000 for(k=best; k<=limit && zA[k+i]==zB[k+j]; k++){}
1001 if( k>best ) best = k;
1002 }
1003 }
1004 score = (best>avg) ? 0 : (avg - best)*100/avg;
1005
1006
+30 -6
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -412,10 +412,11 @@
412412
" ORDER BY pathname /*scan*/",
413413
vid
414414
);
415415
}
416416
db_prepare(&q, "%s", blob_sql_text(&sql));
417
+ blob_reset(&sql);
417418
while( db_step(&q)==SQLITE_ROW ){
418419
const char *zPathname = db_column_text(&q,0);
419420
int isDeleted = db_column_int(&q, 1);
420421
int isChnged = db_column_int(&q,2);
421422
int isNew = db_column_int(&q,3);
@@ -773,10 +774,13 @@
773774
**
774775
** If the "--to VERSION" option appears, it specifies the check-in from
775776
** which the second version of the file or files is taken. If there is
776777
** no "--to" option then the (possibly edited) files in the current check-out
777778
** are used.
779
+**
780
+** The "--checkin VERSION" option shows the changes made by
781
+** check-in VERSION relative to its primary parent.
778782
**
779783
** The "-i" command-line option forces the use of the internal diff logic
780784
** rather than any external diff program that might be configured using
781785
** the "setting" command. If no external diff program is configured, then
782786
** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff".
@@ -793,10 +797,12 @@
793797
**
794798
** Options:
795799
** --binary PATTERN Treat files that match the glob PATTERN as binary
796800
** --branch BRANCH Show diff of all changes on BRANCH
797801
** --brief Show filenames only
802
+** --checkin VERSION Show diff of all changes in VERSION
803
+** --command PROG External diff program - overrides "diff-command"
798804
** --context|-c N Use N lines of context
799805
** --diff-binary BOOL Include binary files when using external commands
800806
** --exec-abs-paths Force absolute path names with external commands.
801807
** --exec-rel-paths Force relative path names with external commands.
802808
** --from|-r VERSION Select VERSION as source for the diff
@@ -816,10 +822,11 @@
816822
int isGDiff; /* True for gdiff. False for normal diff */
817823
int isInternDiff; /* True for internal diff */
818824
int verboseFlag; /* True if -v or --verbose flag is used */
819825
const char *zFrom; /* Source version number */
820826
const char *zTo; /* Target version number */
827
+ const char *zCheckin; /* Check-in version number */
821828
const char *zBranch; /* Branch to diff */
822829
const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
823830
const char *zBinGlob = 0; /* Treat file names matching this as binary */
824831
int fIncludeBinary = 0; /* Include binary files for external diff */
825832
int againstUndo = 0; /* Diff against files in the undo buffer */
@@ -832,37 +839,43 @@
832839
}
833840
isGDiff = g.argv[1][0]=='g';
834841
isInternDiff = find_option("internal","i",0)!=0;
835842
zFrom = find_option("from", "r", 1);
836843
zTo = find_option("to", 0, 1);
844
+ zCheckin = find_option("checkin", 0, 1);
837845
zBranch = find_option("branch", 0, 1);
838846
againstUndo = find_option("undo",0,0)!=0;
839847
diffFlags = diff_options();
840848
verboseFlag = find_option("verbose","v",0)!=0;
841849
if( !verboseFlag ){
842850
verboseFlag = find_option("new-file","N",0)!=0; /* deprecated */
843851
}
844852
if( verboseFlag ) diffFlags |= DIFF_VERBOSE;
845
- if( againstUndo && (zFrom!=0 || zTo!=0 || zBranch!=0) ){
846
- fossil_fatal("cannot use --undo together with --from or --to or --branch");
853
+ if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
854
+ fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
855
+ " or --branch");
847856
}
848857
if( zBranch ){
849
- if( zTo || zFrom ){
850
- fossil_fatal("cannot use --from or --to with --branch");
858
+ if( zTo || zFrom || zCheckin ){
859
+ fossil_fatal("cannot use --from, --to, or --checkin with --branch");
851860
}
852861
zTo = zBranch;
853862
zFrom = mprintf("root:%s", zBranch);
854863
}
864
+ if( zCheckin!=0 && ( zFrom!=0 || zTo!=0 ) ){
865
+ fossil_fatal("cannot use --checkin together with --from or --to");
866
+ }
855867
if( zTo==0 || againstUndo ){
856868
db_must_be_within_tree();
857869
}else if( zFrom==0 ){
858870
fossil_fatal("must use --from if --to is present");
859871
}else{
860872
db_find_and_open_repository(0, 0);
861873
}
862874
if( !isInternDiff ){
863
- zDiffCmd = diff_command_external(isGDiff);
875
+ zDiffCmd = find_option("command", 0, 1);
876
+ if( zDiffCmd==0 ) zDiffCmd = diff_command_external(isGDiff);
864877
}
865878
zBinGlob = diff_get_binary_glob();
866879
fIncludeBinary = diff_include_binary_files();
867880
determine_exec_relative_option(1);
868881
verify_all_options();
@@ -881,10 +894,21 @@
881894
}
882895
pFileDir[i-2].nName = blob_size(&fname);
883896
pFileDir[i-2].nUsed = 0;
884897
blob_reset(&fname);
885898
}
899
+ }
900
+ if ( zCheckin!=0 ){
901
+ int ridTo = name_to_typed_rid(zCheckin, "ci");
902
+ zTo = zCheckin;
903
+ zFrom = db_text(0,
904
+ "SELECT uuid FROM blob, plink"
905
+ " WHERE plink.cid=%d AND plink.isprim AND plink.pid=blob.rid",
906
+ ridTo);
907
+ if( zFrom==0 ){
908
+ fossil_fatal("check-in %s has no parent", zTo);
909
+ }
886910
}
887911
if( againstUndo ){
888912
if( db_lget_int("undo_available",0)==0 ){
889913
fossil_print("No undo or redo is available\n");
890914
return;
@@ -901,11 +925,11 @@
901925
if( pFileDir ){
902926
int i;
903927
for(i=0; pFileDir[i].zName; i++){
904928
if( pFileDir[i].nUsed==0
905929
&& strcmp(pFileDir[0].zName,".")!=0
906
- && !file_isdir(g.argv[i+2])
930
+ && !file_wd_isdir(g.argv[i+2])
907931
){
908932
fossil_fatal("not found: '%s'", g.argv[i+2]);
909933
}
910934
fossil_free(pFileDir[i].zName);
911935
}
912936
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -412,10 +412,11 @@
412 " ORDER BY pathname /*scan*/",
413 vid
414 );
415 }
416 db_prepare(&q, "%s", blob_sql_text(&sql));
 
417 while( db_step(&q)==SQLITE_ROW ){
418 const char *zPathname = db_column_text(&q,0);
419 int isDeleted = db_column_int(&q, 1);
420 int isChnged = db_column_int(&q,2);
421 int isNew = db_column_int(&q,3);
@@ -773,10 +774,13 @@
773 **
774 ** If the "--to VERSION" option appears, it specifies the check-in from
775 ** which the second version of the file or files is taken. If there is
776 ** no "--to" option then the (possibly edited) files in the current check-out
777 ** are used.
 
 
 
778 **
779 ** The "-i" command-line option forces the use of the internal diff logic
780 ** rather than any external diff program that might be configured using
781 ** the "setting" command. If no external diff program is configured, then
782 ** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff".
@@ -793,10 +797,12 @@
793 **
794 ** Options:
795 ** --binary PATTERN Treat files that match the glob PATTERN as binary
796 ** --branch BRANCH Show diff of all changes on BRANCH
797 ** --brief Show filenames only
 
 
798 ** --context|-c N Use N lines of context
799 ** --diff-binary BOOL Include binary files when using external commands
800 ** --exec-abs-paths Force absolute path names with external commands.
801 ** --exec-rel-paths Force relative path names with external commands.
802 ** --from|-r VERSION Select VERSION as source for the diff
@@ -816,10 +822,11 @@
816 int isGDiff; /* True for gdiff. False for normal diff */
817 int isInternDiff; /* True for internal diff */
818 int verboseFlag; /* True if -v or --verbose flag is used */
819 const char *zFrom; /* Source version number */
820 const char *zTo; /* Target version number */
 
821 const char *zBranch; /* Branch to diff */
822 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
823 const char *zBinGlob = 0; /* Treat file names matching this as binary */
824 int fIncludeBinary = 0; /* Include binary files for external diff */
825 int againstUndo = 0; /* Diff against files in the undo buffer */
@@ -832,37 +839,43 @@
832 }
833 isGDiff = g.argv[1][0]=='g';
834 isInternDiff = find_option("internal","i",0)!=0;
835 zFrom = find_option("from", "r", 1);
836 zTo = find_option("to", 0, 1);
 
837 zBranch = find_option("branch", 0, 1);
838 againstUndo = find_option("undo",0,0)!=0;
839 diffFlags = diff_options();
840 verboseFlag = find_option("verbose","v",0)!=0;
841 if( !verboseFlag ){
842 verboseFlag = find_option("new-file","N",0)!=0; /* deprecated */
843 }
844 if( verboseFlag ) diffFlags |= DIFF_VERBOSE;
845 if( againstUndo && (zFrom!=0 || zTo!=0 || zBranch!=0) ){
846 fossil_fatal("cannot use --undo together with --from or --to or --branch");
 
847 }
848 if( zBranch ){
849 if( zTo || zFrom ){
850 fossil_fatal("cannot use --from or --to with --branch");
851 }
852 zTo = zBranch;
853 zFrom = mprintf("root:%s", zBranch);
854 }
 
 
 
855 if( zTo==0 || againstUndo ){
856 db_must_be_within_tree();
857 }else if( zFrom==0 ){
858 fossil_fatal("must use --from if --to is present");
859 }else{
860 db_find_and_open_repository(0, 0);
861 }
862 if( !isInternDiff ){
863 zDiffCmd = diff_command_external(isGDiff);
 
864 }
865 zBinGlob = diff_get_binary_glob();
866 fIncludeBinary = diff_include_binary_files();
867 determine_exec_relative_option(1);
868 verify_all_options();
@@ -881,10 +894,21 @@
881 }
882 pFileDir[i-2].nName = blob_size(&fname);
883 pFileDir[i-2].nUsed = 0;
884 blob_reset(&fname);
885 }
 
 
 
 
 
 
 
 
 
 
 
886 }
887 if( againstUndo ){
888 if( db_lget_int("undo_available",0)==0 ){
889 fossil_print("No undo or redo is available\n");
890 return;
@@ -901,11 +925,11 @@
901 if( pFileDir ){
902 int i;
903 for(i=0; pFileDir[i].zName; i++){
904 if( pFileDir[i].nUsed==0
905 && strcmp(pFileDir[0].zName,".")!=0
906 && !file_isdir(g.argv[i+2])
907 ){
908 fossil_fatal("not found: '%s'", g.argv[i+2]);
909 }
910 fossil_free(pFileDir[i].zName);
911 }
912
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -412,10 +412,11 @@
412 " ORDER BY pathname /*scan*/",
413 vid
414 );
415 }
416 db_prepare(&q, "%s", blob_sql_text(&sql));
417 blob_reset(&sql);
418 while( db_step(&q)==SQLITE_ROW ){
419 const char *zPathname = db_column_text(&q,0);
420 int isDeleted = db_column_int(&q, 1);
421 int isChnged = db_column_int(&q,2);
422 int isNew = db_column_int(&q,3);
@@ -773,10 +774,13 @@
774 **
775 ** If the "--to VERSION" option appears, it specifies the check-in from
776 ** which the second version of the file or files is taken. If there is
777 ** no "--to" option then the (possibly edited) files in the current check-out
778 ** are used.
779 **
780 ** The "--checkin VERSION" option shows the changes made by
781 ** check-in VERSION relative to its primary parent.
782 **
783 ** The "-i" command-line option forces the use of the internal diff logic
784 ** rather than any external diff program that might be configured using
785 ** the "setting" command. If no external diff program is configured, then
786 ** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff".
@@ -793,10 +797,12 @@
797 **
798 ** Options:
799 ** --binary PATTERN Treat files that match the glob PATTERN as binary
800 ** --branch BRANCH Show diff of all changes on BRANCH
801 ** --brief Show filenames only
802 ** --checkin VERSION Show diff of all changes in VERSION
803 ** --command PROG External diff program - overrides "diff-command"
804 ** --context|-c N Use N lines of context
805 ** --diff-binary BOOL Include binary files when using external commands
806 ** --exec-abs-paths Force absolute path names with external commands.
807 ** --exec-rel-paths Force relative path names with external commands.
808 ** --from|-r VERSION Select VERSION as source for the diff
@@ -816,10 +822,11 @@
822 int isGDiff; /* True for gdiff. False for normal diff */
823 int isInternDiff; /* True for internal diff */
824 int verboseFlag; /* True if -v or --verbose flag is used */
825 const char *zFrom; /* Source version number */
826 const char *zTo; /* Target version number */
827 const char *zCheckin; /* Check-in version number */
828 const char *zBranch; /* Branch to diff */
829 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
830 const char *zBinGlob = 0; /* Treat file names matching this as binary */
831 int fIncludeBinary = 0; /* Include binary files for external diff */
832 int againstUndo = 0; /* Diff against files in the undo buffer */
@@ -832,37 +839,43 @@
839 }
840 isGDiff = g.argv[1][0]=='g';
841 isInternDiff = find_option("internal","i",0)!=0;
842 zFrom = find_option("from", "r", 1);
843 zTo = find_option("to", 0, 1);
844 zCheckin = find_option("checkin", 0, 1);
845 zBranch = find_option("branch", 0, 1);
846 againstUndo = find_option("undo",0,0)!=0;
847 diffFlags = diff_options();
848 verboseFlag = find_option("verbose","v",0)!=0;
849 if( !verboseFlag ){
850 verboseFlag = find_option("new-file","N",0)!=0; /* deprecated */
851 }
852 if( verboseFlag ) diffFlags |= DIFF_VERBOSE;
853 if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
854 fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
855 " or --branch");
856 }
857 if( zBranch ){
858 if( zTo || zFrom || zCheckin ){
859 fossil_fatal("cannot use --from, --to, or --checkin with --branch");
860 }
861 zTo = zBranch;
862 zFrom = mprintf("root:%s", zBranch);
863 }
864 if( zCheckin!=0 && ( zFrom!=0 || zTo!=0 ) ){
865 fossil_fatal("cannot use --checkin together with --from or --to");
866 }
867 if( zTo==0 || againstUndo ){
868 db_must_be_within_tree();
869 }else if( zFrom==0 ){
870 fossil_fatal("must use --from if --to is present");
871 }else{
872 db_find_and_open_repository(0, 0);
873 }
874 if( !isInternDiff ){
875 zDiffCmd = find_option("command", 0, 1);
876 if( zDiffCmd==0 ) zDiffCmd = diff_command_external(isGDiff);
877 }
878 zBinGlob = diff_get_binary_glob();
879 fIncludeBinary = diff_include_binary_files();
880 determine_exec_relative_option(1);
881 verify_all_options();
@@ -881,10 +894,21 @@
894 }
895 pFileDir[i-2].nName = blob_size(&fname);
896 pFileDir[i-2].nUsed = 0;
897 blob_reset(&fname);
898 }
899 }
900 if ( zCheckin!=0 ){
901 int ridTo = name_to_typed_rid(zCheckin, "ci");
902 zTo = zCheckin;
903 zFrom = db_text(0,
904 "SELECT uuid FROM blob, plink"
905 " WHERE plink.cid=%d AND plink.isprim AND plink.pid=blob.rid",
906 ridTo);
907 if( zFrom==0 ){
908 fossil_fatal("check-in %s has no parent", zTo);
909 }
910 }
911 if( againstUndo ){
912 if( db_lget_int("undo_available",0)==0 ){
913 fossil_print("No undo or redo is available\n");
914 return;
@@ -901,11 +925,11 @@
925 if( pFileDir ){
926 int i;
927 for(i=0; pFileDir[i].zName; i++){
928 if( pFileDir[i].nUsed==0
929 && strcmp(pFileDir[0].zName,".")!=0
930 && !file_wd_isdir(g.argv[i+2])
931 ){
932 fossil_fatal("not found: '%s'", g.argv[i+2]);
933 }
934 fossil_free(pFileDir[i].zName);
935 }
936
+91 -48
--- src/export.c
+++ src/export.c
@@ -132,23 +132,28 @@
132132
133133
/*
134134
** create_mark()
135135
** Create a new (mark,rid,uuid) entry for the given rid in the 'xmark' table,
136136
** and return that information as a struct mark_t in *mark.
137
+** *unused_mark is a value representing a mark that is free for use--that is,
138
+** it does not appear in the marks file, and has not been used during this
139
+** export run. Specifically, it is the supremum of the set of used marks
140
+** plus one.
137141
** This function returns -1 in the case where 'rid' does not exist, otherwise
138142
** it returns 0.
139143
** mark->name is dynamically allocated and is owned by the caller upon return.
140144
*/
141
-int create_mark(int rid, struct mark_t *mark){
145
+int create_mark(int rid, struct mark_t *mark, unsigned int *unused_mark){
142146
char sid[13];
143147
char *zUuid = rid_to_uuid(rid);
144
- if(!zUuid){
148
+ if( !zUuid ){
145149
fossil_trace("Undefined rid=%d\n", rid);
146150
return -1;
147151
}
148152
mark->rid = rid;
149
- sqlite3_snprintf(sizeof(sid), sid, ":%d", COMMITMARK(rid));
153
+ sqlite3_snprintf(sizeof(sid), sid, ":%d", *unused_mark);
154
+ *unused_mark += 1;
150155
mark->name = fossil_strdup(sid);
151156
sqlite3_snprintf(sizeof(mark->uuid), mark->uuid, "%s", zUuid);
152157
free(zUuid);
153158
insert_commit_xref(mark->rid, mark->name, mark->uuid);
154159
return 0;
@@ -156,19 +161,22 @@
156161
157162
/*
158163
** mark_name_from_rid()
159164
** Find the mark associated with the given rid. Mark names always start
160165
** with ':', and are pulled from the 'xmark' temporary table.
161
-** This function returns NULL if the rid does not exist in the 'xmark' table.
162
-** Otherwise, it returns the name of the mark, which is dynamically allocated
163
-** and is owned by the caller of this function.
166
+** If the given rid doesn't have a mark associated with it yet, one is
167
+** created with a value of *unused_mark.
168
+** *unused_mark functions exactly as in create_mark().
169
+** This function returns NULL if the rid does not have an associated UUID,
170
+** (i.e. is not valid). Otherwise, it returns the name of the mark, which is
171
+** dynamically allocated and is owned by the caller of this function.
164172
*/
165
-char * mark_name_from_rid(int rid){
173
+char * mark_name_from_rid(int rid, unsigned int *unused_mark){
166174
char *zMark = db_text(0, "SELECT tname FROM xmark WHERE trid=%d", rid);
167
- if(zMark==NULL){
175
+ if( zMark==NULL ){
168176
struct mark_t mark;
169
- if(create_mark(rid, &mark)==0){
177
+ if( create_mark(rid, &mark, unused_mark)==0 ){
170178
zMark = mark.name;
171179
}else{
172180
return NULL;
173181
}
174182
}
@@ -185,43 +193,52 @@
185193
** database. Otherwise, 0 is returned.
186194
** mark->name is dynamically allocated, and owned by the caller.
187195
*/
188196
int parse_mark(char *line, struct mark_t *mark){
189197
char *cur_tok;
198
+ char type_;
190199
cur_tok = strtok(line, " \t");
191
- if(!cur_tok||strlen(cur_tok)<2){
200
+ if( !cur_tok || strlen(cur_tok)<2 ){
192201
return -1;
193202
}
194203
mark->rid = atoi(&cur_tok[1]);
195
- if(cur_tok[0]!='c'){
204
+ type_ = cur_tok[0];
205
+ if( type_!='c' && type_!='b' ){
196206
/* This is probably a blob mark */
197207
mark->name = NULL;
198208
return 0;
199209
}
200210
201211
cur_tok = strtok(NULL, " \t");
202
- if(!cur_tok){
212
+ if( !cur_tok ){
203213
/* This mark was generated by an older version of Fossil and doesn't
204214
** include the mark name and uuid. create_mark() will name the new mark
205215
** exactly as it was when exported to git, so that we should have a
206216
** valid mapping from git sha1<->mark name<->fossil sha1. */
207
- return create_mark(mark->rid, mark);
217
+ unsigned int mid;
218
+ if( type_=='c' ){
219
+ mid = COMMITMARK(mark->rid);
220
+ }
221
+ else{
222
+ mid = BLOBMARK(mark->rid);
223
+ }
224
+ return create_mark(mark->rid, mark, &mid);
208225
}else{
209226
mark->name = fossil_strdup(cur_tok);
210227
}
211228
212229
cur_tok = strtok(NULL, "\n");
213
- if(!cur_tok||strlen(cur_tok)!=40){
230
+ if( !cur_tok || strlen(cur_tok)!=40 ){
214231
free(mark->name);
215232
fossil_trace("Invalid SHA-1 in marks file: %s\n", cur_tok);
216233
return -1;
217234
}else{
218235
sqlite3_snprintf(sizeof(mark->uuid), mark->uuid, "%s", cur_tok);
219236
}
220237
221238
/* make sure that rid corresponds to UUID */
222
- if(fast_uuid_to_rid(mark->uuid)!=mark->rid){
239
+ if( fast_uuid_to_rid(mark->uuid)!=mark->rid ){
223240
free(mark->name);
224241
fossil_trace("Non-existent SHA-1 in marks file: %s\n", mark->uuid);
225242
return -1;
226243
}
227244
@@ -233,40 +250,66 @@
233250
/*
234251
** import_marks()
235252
** Import the marks specified in file 'f' into the 'xmark' table.
236253
** If 'blobs' is non-null, insert all blob marks into it.
237254
** If 'vers' is non-null, insert all commit marks into it.
255
+** If 'unused_marks' is non-null, upon return of this function, all values
256
+** x >= *unused_marks are free to use as marks, i.e. they do not clash with
257
+** any marks appearing in the marks file.
238258
** Each line in the file must be at most 100 characters in length. This
239259
** seems like a reasonable maximum for a 40-character uuid, and 1-13
240260
** character rid.
241261
** The function returns -1 if any of the lines in file 'f' are malformed,
242262
** or the rid/uuid information doesn't match what is in the repository
243263
** database. Otherwise, 0 is returned.
244264
*/
245
-int import_marks(FILE* f, Bag *blobs, Bag *vers){
265
+int import_marks(FILE* f, Bag *blobs, Bag *vers, unsigned int *unused_mark){
246266
char line[101];
247267
while(fgets(line, sizeof(line), f)){
248268
struct mark_t mark;
249
- if(strlen(line)==100&&line[99]!='\n'){
269
+ if( strlen(line)==100 && line[99]!='\n' ){
250270
/* line too long */
251271
return -1;
252272
}
253273
if( parse_mark(line, &mark)<0 ){
254274
return -1;
255275
}else if( line[0]=='b' ){
256
- /* Don't import blob marks into 'xmark' table--git doesn't use them,
257
- ** so they need to be left free for git to reuse. */
258
- if(blobs!=NULL){
276
+ if( blobs!=NULL ){
259277
bag_insert(blobs, mark.rid);
260278
}
261
- }else if( vers!=NULL ){
262
- bag_insert(vers, mark.rid);
279
+ }else{
280
+ if( vers!=NULL ){
281
+ bag_insert(vers, mark.rid);
282
+ }
283
+ }
284
+ if( unused_mark!=NULL ){
285
+ unsigned int mid = atoi(mark.name + 1);
286
+ if( mid>=*unused_mark ){
287
+ *unused_mark = mid + 1;
288
+ }
263289
}
264290
free(mark.name);
265291
}
266292
return 0;
267293
}
294
+
295
+void export_mark(FILE* f, int rid, char obj_type)
296
+{
297
+ unsigned int z = 0;
298
+ char *zUuid = rid_to_uuid(rid);
299
+ char *zMark;
300
+ if( zUuid==NULL ){
301
+ fossil_trace("No uuid matching rid=%d when exporting marks\n", rid);
302
+ return;
303
+ }
304
+ /* Since rid is already in the 'xmark' table, the value of z won't be
305
+ ** used, but pass in a valid pointer just to be safe. */
306
+ zMark = mark_name_from_rid(rid, &z);
307
+ fprintf(f, "%c%d %s %s\n", obj_type, rid, zMark, zUuid);
308
+ free(zMark);
309
+ free(zUuid);
310
+}
268311
269312
/*
270313
** If 'blobs' is non-null, it must point to a Bag of blob rids to be
271314
** written to disk. Blob rids are written as 'b<rid>'.
272315
** If 'vers' is non-null, it must point to a Bag of commit rids to be
@@ -275,32 +318,24 @@
275318
** This function does not fail, but may produce errors if a uuid cannot
276319
** be found for an rid in 'vers'.
277320
*/
278321
void export_marks(FILE* f, Bag *blobs, Bag *vers){
279322
int rid;
323
+
280324
if( blobs!=NULL ){
281325
rid = bag_first(blobs);
282
- if(rid!=0){
326
+ if( rid!=0 ){
283327
do{
284
- fprintf(f, "b%d\n", rid);
285
- }while((rid = bag_next(blobs, rid))!=0);
328
+ export_mark(f, rid, 'b');
329
+ }while( (rid = bag_next(blobs, rid))!=0 );
286330
}
287331
}
288332
if( vers!=NULL ){
289333
rid = bag_first(vers);
290334
if( rid!=0 ){
291335
do{
292
- char *zUuid = rid_to_uuid(rid);
293
- char *zMark;
294
- if(zUuid==NULL){
295
- fossil_trace("No uuid matching rid=%d when exporting marks\n", rid);
296
- continue;
297
- }
298
- zMark = mark_name_from_rid(rid);
299
- fprintf(f, "c%d %s %s\n", rid, zMark, zUuid);
300
- free(zMark);
301
- free(zUuid);
336
+ export_mark(f, rid, 'c');
302337
}while( (rid = bag_next(vers, rid))!=0 );
303338
}
304339
}
305340
}
306341
@@ -336,10 +371,11 @@
336371
*/
337372
void export_cmd(void){
338373
Stmt q, q2, q3;
339374
int i;
340375
Bag blobs, vers;
376
+ unsigned int unused_mark = 1;
341377
const char *markfile_in;
342378
const char *markfile_out;
343379
344380
bag_init(&blobs);
345381
bag_init(&vers);
@@ -362,25 +398,25 @@
362398
363399
f = fossil_fopen(markfile_in, "r");
364400
if( f==0 ){
365401
fossil_fatal("cannot open %s for reading", markfile_in);
366402
}
367
- if(import_marks(f, &blobs, &vers)<0){
368
- fossil_fatal("error importing marks from file: %s\n", markfile_in);
403
+ if( import_marks(f, &blobs, &vers, &unused_mark)<0 ){
404
+ fossil_fatal("error importing marks from file: %s", markfile_in);
369405
}
370406
db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)");
371407
db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)");
372408
rid = bag_first(&blobs);
373
- if(rid!=0){
409
+ if( rid!=0 ){
374410
do{
375411
db_bind_int(&qb, ":rid", rid);
376412
db_step(&qb);
377413
db_reset(&qb);
378414
}while((rid = bag_next(&blobs, rid))!=0);
379415
}
380416
rid = bag_first(&vers);
381
- if(rid!=0){
417
+ if( rid!=0 ){
382418
do{
383419
db_bind_int(&qc, ":rid", rid);
384420
db_step(&qc);
385421
db_reset(&qc);
386422
}while((rid = bag_next(&vers, rid))!=0);
@@ -416,15 +452,18 @@
416452
while( db_step(&q)==SQLITE_ROW ){
417453
int rid = db_column_int(&q, 0);
418454
Blob content;
419455
420456
while( !bag_find(&blobs, rid) ){
457
+ char *zMark;
421458
content_get(rid, &content);
422459
db_bind_int(&q2, ":rid", rid);
423460
db_step(&q2);
424461
db_reset(&q2);
425
- printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content));
462
+ zMark = mark_name_from_rid(rid, &unused_mark);
463
+ printf("blob\nmark %s\ndata %d\n", zMark, blob_size(&content));
464
+ free(zMark);
426465
bag_insert(&blobs, rid);
427466
fwrite(blob_buffer(&content), 1, blob_size(&content), stdout);
428467
printf("\n");
429468
blob_reset(&content);
430469
@@ -470,11 +509,11 @@
470509
if( zBranch==0 ) zBranch = "trunk";
471510
zBr = mprintf("%s", zBranch);
472511
for(i=0; zBr[i]; i++){
473512
if( !fossil_isalnum(zBr[i]) ) zBr[i] = '_';
474513
}
475
- zMark = mark_name_from_rid(ckinId);
514
+ zMark = mark_name_from_rid(ckinId, &unused_mark);
476515
printf("commit refs/heads/%s\nmark %s\n", zBr, zMark);
477516
free(zMark);
478517
free(zBr);
479518
printf("committer");
480519
print_person(zUser);
@@ -487,21 +526,21 @@
487526
" AND pid IN (SELECT objid FROM event)",
488527
ckinId
489528
);
490529
if( db_step(&q3) == SQLITE_ROW ){
491530
int pid = db_column_int(&q3, 0);
492
- zMark = mark_name_from_rid(pid);
531
+ zMark = mark_name_from_rid(pid, &unused_mark);
493532
printf("from %s\n", zMark);
494533
free(zMark);
495534
db_prepare(&q4,
496535
"SELECT pid FROM plink"
497536
" WHERE cid=%d AND NOT isprim"
498537
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)"
499538
" ORDER BY pid",
500539
ckinId);
501540
while( db_step(&q4)==SQLITE_ROW ){
502
- zMark = mark_name_from_rid(db_column_int(&q4, 0));
541
+ zMark = mark_name_from_rid(db_column_int(&q4, 0), &unused_mark);
503542
printf("merge %s\n", zMark);
504543
free(zMark);
505544
}
506545
db_finalize(&q4);
507546
}else{
@@ -516,20 +555,22 @@
516555
);
517556
while( db_step(&q4)==SQLITE_ROW ){
518557
const char *zName = db_column_text(&q4,0);
519558
int zNew = db_column_int(&q4,1);
520559
int mPerm = db_column_int(&q4,2);
521
- if( zNew==0)
560
+ if( zNew==0 ){
522561
printf("D %s\n", zName);
523
- else if( bag_find(&blobs, zNew) ) {
562
+ }else if( bag_find(&blobs, zNew) ){
524563
const char *zPerm;
564
+ zMark = mark_name_from_rid(zNew, &unused_mark);
525565
switch( mPerm ){
526566
case PERM_LNK: zPerm = "120000"; break;
527567
case PERM_EXE: zPerm = "100755"; break;
528568
default: zPerm = "100644"; break;
529569
}
530
- printf("M %s :%d %s\n", zPerm, BLOBMARK(zNew), zName);
570
+ printf("M %s %s %s\n", zPerm, zMark, zName);
571
+ free(zMark);
531572
}
532573
}
533574
db_finalize(&q4);
534575
db_finalize(&q3);
535576
printf("\n");
@@ -547,20 +588,22 @@
547588
);
548589
while( db_step(&q)==SQLITE_ROW ){
549590
const char *zTagname = db_column_text(&q, 0);
550591
char *zEncoded = 0;
551592
int rid = db_column_int(&q, 1);
593
+ char *zMark = mark_name_from_rid(rid, &unused_mark);
552594
const char *zSecSince1970 = db_column_text(&q, 2);
553595
int i;
554596
if( rid==0 || !bag_find(&vers, rid) ) continue;
555597
zTagname += 4;
556598
zEncoded = mprintf("%s", zTagname);
557599
for(i=0; zEncoded[i]; i++){
558600
if( !fossil_isalnum(zEncoded[i]) ) zEncoded[i] = '_';
559601
}
560602
printf("tag %s\n", zEncoded);
561
- printf("from :%d\n", COMMITMARK(rid));
603
+ printf("from %s\n", zMark);
604
+ free(zMark);
562605
printf("tagger <tagger> %s +0000\n", zSecSince1970);
563606
printf("data 0\n");
564607
fossil_free(zEncoded);
565608
}
566609
db_finalize(&q);
@@ -570,12 +613,12 @@
570613
f = fossil_fopen(markfile_out, "w");
571614
if( f == 0 ){
572615
fossil_fatal("cannot open %s for writing", markfile_out);
573616
}
574617
export_marks(f, &blobs, &vers);
575
- if( ferror(f)!=0 || fclose(f)!=0 ) {
618
+ if( ferror(f)!=0 || fclose(f)!=0 ){
576619
fossil_fatal("error while writing %s", markfile_out);
577620
}
578621
}
579622
bag_clear(&blobs);
580623
bag_clear(&vers);
581624
}
582625
--- src/export.c
+++ src/export.c
@@ -132,23 +132,28 @@
132
133 /*
134 ** create_mark()
135 ** Create a new (mark,rid,uuid) entry for the given rid in the 'xmark' table,
136 ** and return that information as a struct mark_t in *mark.
 
 
 
 
137 ** This function returns -1 in the case where 'rid' does not exist, otherwise
138 ** it returns 0.
139 ** mark->name is dynamically allocated and is owned by the caller upon return.
140 */
141 int create_mark(int rid, struct mark_t *mark){
142 char sid[13];
143 char *zUuid = rid_to_uuid(rid);
144 if(!zUuid){
145 fossil_trace("Undefined rid=%d\n", rid);
146 return -1;
147 }
148 mark->rid = rid;
149 sqlite3_snprintf(sizeof(sid), sid, ":%d", COMMITMARK(rid));
 
150 mark->name = fossil_strdup(sid);
151 sqlite3_snprintf(sizeof(mark->uuid), mark->uuid, "%s", zUuid);
152 free(zUuid);
153 insert_commit_xref(mark->rid, mark->name, mark->uuid);
154 return 0;
@@ -156,19 +161,22 @@
156
157 /*
158 ** mark_name_from_rid()
159 ** Find the mark associated with the given rid. Mark names always start
160 ** with ':', and are pulled from the 'xmark' temporary table.
161 ** This function returns NULL if the rid does not exist in the 'xmark' table.
162 ** Otherwise, it returns the name of the mark, which is dynamically allocated
163 ** and is owned by the caller of this function.
 
 
 
164 */
165 char * mark_name_from_rid(int rid){
166 char *zMark = db_text(0, "SELECT tname FROM xmark WHERE trid=%d", rid);
167 if(zMark==NULL){
168 struct mark_t mark;
169 if(create_mark(rid, &mark)==0){
170 zMark = mark.name;
171 }else{
172 return NULL;
173 }
174 }
@@ -185,43 +193,52 @@
185 ** database. Otherwise, 0 is returned.
186 ** mark->name is dynamically allocated, and owned by the caller.
187 */
188 int parse_mark(char *line, struct mark_t *mark){
189 char *cur_tok;
 
190 cur_tok = strtok(line, " \t");
191 if(!cur_tok||strlen(cur_tok)<2){
192 return -1;
193 }
194 mark->rid = atoi(&cur_tok[1]);
195 if(cur_tok[0]!='c'){
 
196 /* This is probably a blob mark */
197 mark->name = NULL;
198 return 0;
199 }
200
201 cur_tok = strtok(NULL, " \t");
202 if(!cur_tok){
203 /* This mark was generated by an older version of Fossil and doesn't
204 ** include the mark name and uuid. create_mark() will name the new mark
205 ** exactly as it was when exported to git, so that we should have a
206 ** valid mapping from git sha1<->mark name<->fossil sha1. */
207 return create_mark(mark->rid, mark);
 
 
 
 
 
 
 
208 }else{
209 mark->name = fossil_strdup(cur_tok);
210 }
211
212 cur_tok = strtok(NULL, "\n");
213 if(!cur_tok||strlen(cur_tok)!=40){
214 free(mark->name);
215 fossil_trace("Invalid SHA-1 in marks file: %s\n", cur_tok);
216 return -1;
217 }else{
218 sqlite3_snprintf(sizeof(mark->uuid), mark->uuid, "%s", cur_tok);
219 }
220
221 /* make sure that rid corresponds to UUID */
222 if(fast_uuid_to_rid(mark->uuid)!=mark->rid){
223 free(mark->name);
224 fossil_trace("Non-existent SHA-1 in marks file: %s\n", mark->uuid);
225 return -1;
226 }
227
@@ -233,40 +250,66 @@
233 /*
234 ** import_marks()
235 ** Import the marks specified in file 'f' into the 'xmark' table.
236 ** If 'blobs' is non-null, insert all blob marks into it.
237 ** If 'vers' is non-null, insert all commit marks into it.
 
 
 
238 ** Each line in the file must be at most 100 characters in length. This
239 ** seems like a reasonable maximum for a 40-character uuid, and 1-13
240 ** character rid.
241 ** The function returns -1 if any of the lines in file 'f' are malformed,
242 ** or the rid/uuid information doesn't match what is in the repository
243 ** database. Otherwise, 0 is returned.
244 */
245 int import_marks(FILE* f, Bag *blobs, Bag *vers){
246 char line[101];
247 while(fgets(line, sizeof(line), f)){
248 struct mark_t mark;
249 if(strlen(line)==100&&line[99]!='\n'){
250 /* line too long */
251 return -1;
252 }
253 if( parse_mark(line, &mark)<0 ){
254 return -1;
255 }else if( line[0]=='b' ){
256 /* Don't import blob marks into 'xmark' table--git doesn't use them,
257 ** so they need to be left free for git to reuse. */
258 if(blobs!=NULL){
259 bag_insert(blobs, mark.rid);
260 }
261 }else if( vers!=NULL ){
262 bag_insert(vers, mark.rid);
 
 
 
 
 
 
 
 
263 }
264 free(mark.name);
265 }
266 return 0;
267 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
269 /*
270 ** If 'blobs' is non-null, it must point to a Bag of blob rids to be
271 ** written to disk. Blob rids are written as 'b<rid>'.
272 ** If 'vers' is non-null, it must point to a Bag of commit rids to be
@@ -275,32 +318,24 @@
275 ** This function does not fail, but may produce errors if a uuid cannot
276 ** be found for an rid in 'vers'.
277 */
278 void export_marks(FILE* f, Bag *blobs, Bag *vers){
279 int rid;
 
280 if( blobs!=NULL ){
281 rid = bag_first(blobs);
282 if(rid!=0){
283 do{
284 fprintf(f, "b%d\n", rid);
285 }while((rid = bag_next(blobs, rid))!=0);
286 }
287 }
288 if( vers!=NULL ){
289 rid = bag_first(vers);
290 if( rid!=0 ){
291 do{
292 char *zUuid = rid_to_uuid(rid);
293 char *zMark;
294 if(zUuid==NULL){
295 fossil_trace("No uuid matching rid=%d when exporting marks\n", rid);
296 continue;
297 }
298 zMark = mark_name_from_rid(rid);
299 fprintf(f, "c%d %s %s\n", rid, zMark, zUuid);
300 free(zMark);
301 free(zUuid);
302 }while( (rid = bag_next(vers, rid))!=0 );
303 }
304 }
305 }
306
@@ -336,10 +371,11 @@
336 */
337 void export_cmd(void){
338 Stmt q, q2, q3;
339 int i;
340 Bag blobs, vers;
 
341 const char *markfile_in;
342 const char *markfile_out;
343
344 bag_init(&blobs);
345 bag_init(&vers);
@@ -362,25 +398,25 @@
362
363 f = fossil_fopen(markfile_in, "r");
364 if( f==0 ){
365 fossil_fatal("cannot open %s for reading", markfile_in);
366 }
367 if(import_marks(f, &blobs, &vers)<0){
368 fossil_fatal("error importing marks from file: %s\n", markfile_in);
369 }
370 db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)");
371 db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)");
372 rid = bag_first(&blobs);
373 if(rid!=0){
374 do{
375 db_bind_int(&qb, ":rid", rid);
376 db_step(&qb);
377 db_reset(&qb);
378 }while((rid = bag_next(&blobs, rid))!=0);
379 }
380 rid = bag_first(&vers);
381 if(rid!=0){
382 do{
383 db_bind_int(&qc, ":rid", rid);
384 db_step(&qc);
385 db_reset(&qc);
386 }while((rid = bag_next(&vers, rid))!=0);
@@ -416,15 +452,18 @@
416 while( db_step(&q)==SQLITE_ROW ){
417 int rid = db_column_int(&q, 0);
418 Blob content;
419
420 while( !bag_find(&blobs, rid) ){
 
421 content_get(rid, &content);
422 db_bind_int(&q2, ":rid", rid);
423 db_step(&q2);
424 db_reset(&q2);
425 printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content));
 
 
426 bag_insert(&blobs, rid);
427 fwrite(blob_buffer(&content), 1, blob_size(&content), stdout);
428 printf("\n");
429 blob_reset(&content);
430
@@ -470,11 +509,11 @@
470 if( zBranch==0 ) zBranch = "trunk";
471 zBr = mprintf("%s", zBranch);
472 for(i=0; zBr[i]; i++){
473 if( !fossil_isalnum(zBr[i]) ) zBr[i] = '_';
474 }
475 zMark = mark_name_from_rid(ckinId);
476 printf("commit refs/heads/%s\nmark %s\n", zBr, zMark);
477 free(zMark);
478 free(zBr);
479 printf("committer");
480 print_person(zUser);
@@ -487,21 +526,21 @@
487 " AND pid IN (SELECT objid FROM event)",
488 ckinId
489 );
490 if( db_step(&q3) == SQLITE_ROW ){
491 int pid = db_column_int(&q3, 0);
492 zMark = mark_name_from_rid(pid);
493 printf("from %s\n", zMark);
494 free(zMark);
495 db_prepare(&q4,
496 "SELECT pid FROM plink"
497 " WHERE cid=%d AND NOT isprim"
498 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)"
499 " ORDER BY pid",
500 ckinId);
501 while( db_step(&q4)==SQLITE_ROW ){
502 zMark = mark_name_from_rid(db_column_int(&q4, 0));
503 printf("merge %s\n", zMark);
504 free(zMark);
505 }
506 db_finalize(&q4);
507 }else{
@@ -516,20 +555,22 @@
516 );
517 while( db_step(&q4)==SQLITE_ROW ){
518 const char *zName = db_column_text(&q4,0);
519 int zNew = db_column_int(&q4,1);
520 int mPerm = db_column_int(&q4,2);
521 if( zNew==0)
522 printf("D %s\n", zName);
523 else if( bag_find(&blobs, zNew) ) {
524 const char *zPerm;
 
525 switch( mPerm ){
526 case PERM_LNK: zPerm = "120000"; break;
527 case PERM_EXE: zPerm = "100755"; break;
528 default: zPerm = "100644"; break;
529 }
530 printf("M %s :%d %s\n", zPerm, BLOBMARK(zNew), zName);
 
531 }
532 }
533 db_finalize(&q4);
534 db_finalize(&q3);
535 printf("\n");
@@ -547,20 +588,22 @@
547 );
548 while( db_step(&q)==SQLITE_ROW ){
549 const char *zTagname = db_column_text(&q, 0);
550 char *zEncoded = 0;
551 int rid = db_column_int(&q, 1);
 
552 const char *zSecSince1970 = db_column_text(&q, 2);
553 int i;
554 if( rid==0 || !bag_find(&vers, rid) ) continue;
555 zTagname += 4;
556 zEncoded = mprintf("%s", zTagname);
557 for(i=0; zEncoded[i]; i++){
558 if( !fossil_isalnum(zEncoded[i]) ) zEncoded[i] = '_';
559 }
560 printf("tag %s\n", zEncoded);
561 printf("from :%d\n", COMMITMARK(rid));
 
562 printf("tagger <tagger> %s +0000\n", zSecSince1970);
563 printf("data 0\n");
564 fossil_free(zEncoded);
565 }
566 db_finalize(&q);
@@ -570,12 +613,12 @@
570 f = fossil_fopen(markfile_out, "w");
571 if( f == 0 ){
572 fossil_fatal("cannot open %s for writing", markfile_out);
573 }
574 export_marks(f, &blobs, &vers);
575 if( ferror(f)!=0 || fclose(f)!=0 ) {
576 fossil_fatal("error while writing %s", markfile_out);
577 }
578 }
579 bag_clear(&blobs);
580 bag_clear(&vers);
581 }
582
--- src/export.c
+++ src/export.c
@@ -132,23 +132,28 @@
132
133 /*
134 ** create_mark()
135 ** Create a new (mark,rid,uuid) entry for the given rid in the 'xmark' table,
136 ** and return that information as a struct mark_t in *mark.
137 ** *unused_mark is a value representing a mark that is free for use--that is,
138 ** it does not appear in the marks file, and has not been used during this
139 ** export run. Specifically, it is the supremum of the set of used marks
140 ** plus one.
141 ** This function returns -1 in the case where 'rid' does not exist, otherwise
142 ** it returns 0.
143 ** mark->name is dynamically allocated and is owned by the caller upon return.
144 */
145 int create_mark(int rid, struct mark_t *mark, unsigned int *unused_mark){
146 char sid[13];
147 char *zUuid = rid_to_uuid(rid);
148 if( !zUuid ){
149 fossil_trace("Undefined rid=%d\n", rid);
150 return -1;
151 }
152 mark->rid = rid;
153 sqlite3_snprintf(sizeof(sid), sid, ":%d", *unused_mark);
154 *unused_mark += 1;
155 mark->name = fossil_strdup(sid);
156 sqlite3_snprintf(sizeof(mark->uuid), mark->uuid, "%s", zUuid);
157 free(zUuid);
158 insert_commit_xref(mark->rid, mark->name, mark->uuid);
159 return 0;
@@ -156,19 +161,22 @@
161
162 /*
163 ** mark_name_from_rid()
164 ** Find the mark associated with the given rid. Mark names always start
165 ** with ':', and are pulled from the 'xmark' temporary table.
166 ** If the given rid doesn't have a mark associated with it yet, one is
167 ** created with a value of *unused_mark.
168 ** *unused_mark functions exactly as in create_mark().
169 ** This function returns NULL if the rid does not have an associated UUID,
170 ** (i.e. is not valid). Otherwise, it returns the name of the mark, which is
171 ** dynamically allocated and is owned by the caller of this function.
172 */
173 char * mark_name_from_rid(int rid, unsigned int *unused_mark){
174 char *zMark = db_text(0, "SELECT tname FROM xmark WHERE trid=%d", rid);
175 if( zMark==NULL ){
176 struct mark_t mark;
177 if( create_mark(rid, &mark, unused_mark)==0 ){
178 zMark = mark.name;
179 }else{
180 return NULL;
181 }
182 }
@@ -185,43 +193,52 @@
193 ** database. Otherwise, 0 is returned.
194 ** mark->name is dynamically allocated, and owned by the caller.
195 */
196 int parse_mark(char *line, struct mark_t *mark){
197 char *cur_tok;
198 char type_;
199 cur_tok = strtok(line, " \t");
200 if( !cur_tok || strlen(cur_tok)<2 ){
201 return -1;
202 }
203 mark->rid = atoi(&cur_tok[1]);
204 type_ = cur_tok[0];
205 if( type_!='c' && type_!='b' ){
206 /* This is probably a blob mark */
207 mark->name = NULL;
208 return 0;
209 }
210
211 cur_tok = strtok(NULL, " \t");
212 if( !cur_tok ){
213 /* This mark was generated by an older version of Fossil and doesn't
214 ** include the mark name and uuid. create_mark() will name the new mark
215 ** exactly as it was when exported to git, so that we should have a
216 ** valid mapping from git sha1<->mark name<->fossil sha1. */
217 unsigned int mid;
218 if( type_=='c' ){
219 mid = COMMITMARK(mark->rid);
220 }
221 else{
222 mid = BLOBMARK(mark->rid);
223 }
224 return create_mark(mark->rid, mark, &mid);
225 }else{
226 mark->name = fossil_strdup(cur_tok);
227 }
228
229 cur_tok = strtok(NULL, "\n");
230 if( !cur_tok || strlen(cur_tok)!=40 ){
231 free(mark->name);
232 fossil_trace("Invalid SHA-1 in marks file: %s\n", cur_tok);
233 return -1;
234 }else{
235 sqlite3_snprintf(sizeof(mark->uuid), mark->uuid, "%s", cur_tok);
236 }
237
238 /* make sure that rid corresponds to UUID */
239 if( fast_uuid_to_rid(mark->uuid)!=mark->rid ){
240 free(mark->name);
241 fossil_trace("Non-existent SHA-1 in marks file: %s\n", mark->uuid);
242 return -1;
243 }
244
@@ -233,40 +250,66 @@
250 /*
251 ** import_marks()
252 ** Import the marks specified in file 'f' into the 'xmark' table.
253 ** If 'blobs' is non-null, insert all blob marks into it.
254 ** If 'vers' is non-null, insert all commit marks into it.
255 ** If 'unused_marks' is non-null, upon return of this function, all values
256 ** x >= *unused_marks are free to use as marks, i.e. they do not clash with
257 ** any marks appearing in the marks file.
258 ** Each line in the file must be at most 100 characters in length. This
259 ** seems like a reasonable maximum for a 40-character uuid, and 1-13
260 ** character rid.
261 ** The function returns -1 if any of the lines in file 'f' are malformed,
262 ** or the rid/uuid information doesn't match what is in the repository
263 ** database. Otherwise, 0 is returned.
264 */
265 int import_marks(FILE* f, Bag *blobs, Bag *vers, unsigned int *unused_mark){
266 char line[101];
267 while(fgets(line, sizeof(line), f)){
268 struct mark_t mark;
269 if( strlen(line)==100 && line[99]!='\n' ){
270 /* line too long */
271 return -1;
272 }
273 if( parse_mark(line, &mark)<0 ){
274 return -1;
275 }else if( line[0]=='b' ){
276 if( blobs!=NULL ){
 
 
277 bag_insert(blobs, mark.rid);
278 }
279 }else{
280 if( vers!=NULL ){
281 bag_insert(vers, mark.rid);
282 }
283 }
284 if( unused_mark!=NULL ){
285 unsigned int mid = atoi(mark.name + 1);
286 if( mid>=*unused_mark ){
287 *unused_mark = mid + 1;
288 }
289 }
290 free(mark.name);
291 }
292 return 0;
293 }
294
295 void export_mark(FILE* f, int rid, char obj_type)
296 {
297 unsigned int z = 0;
298 char *zUuid = rid_to_uuid(rid);
299 char *zMark;
300 if( zUuid==NULL ){
301 fossil_trace("No uuid matching rid=%d when exporting marks\n", rid);
302 return;
303 }
304 /* Since rid is already in the 'xmark' table, the value of z won't be
305 ** used, but pass in a valid pointer just to be safe. */
306 zMark = mark_name_from_rid(rid, &z);
307 fprintf(f, "%c%d %s %s\n", obj_type, rid, zMark, zUuid);
308 free(zMark);
309 free(zUuid);
310 }
311
312 /*
313 ** If 'blobs' is non-null, it must point to a Bag of blob rids to be
314 ** written to disk. Blob rids are written as 'b<rid>'.
315 ** If 'vers' is non-null, it must point to a Bag of commit rids to be
@@ -275,32 +318,24 @@
318 ** This function does not fail, but may produce errors if a uuid cannot
319 ** be found for an rid in 'vers'.
320 */
321 void export_marks(FILE* f, Bag *blobs, Bag *vers){
322 int rid;
323
324 if( blobs!=NULL ){
325 rid = bag_first(blobs);
326 if( rid!=0 ){
327 do{
328 export_mark(f, rid, 'b');
329 }while( (rid = bag_next(blobs, rid))!=0 );
330 }
331 }
332 if( vers!=NULL ){
333 rid = bag_first(vers);
334 if( rid!=0 ){
335 do{
336 export_mark(f, rid, 'c');
 
 
 
 
 
 
 
 
 
337 }while( (rid = bag_next(vers, rid))!=0 );
338 }
339 }
340 }
341
@@ -336,10 +371,11 @@
371 */
372 void export_cmd(void){
373 Stmt q, q2, q3;
374 int i;
375 Bag blobs, vers;
376 unsigned int unused_mark = 1;
377 const char *markfile_in;
378 const char *markfile_out;
379
380 bag_init(&blobs);
381 bag_init(&vers);
@@ -362,25 +398,25 @@
398
399 f = fossil_fopen(markfile_in, "r");
400 if( f==0 ){
401 fossil_fatal("cannot open %s for reading", markfile_in);
402 }
403 if( import_marks(f, &blobs, &vers, &unused_mark)<0 ){
404 fossil_fatal("error importing marks from file: %s", markfile_in);
405 }
406 db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)");
407 db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)");
408 rid = bag_first(&blobs);
409 if( rid!=0 ){
410 do{
411 db_bind_int(&qb, ":rid", rid);
412 db_step(&qb);
413 db_reset(&qb);
414 }while((rid = bag_next(&blobs, rid))!=0);
415 }
416 rid = bag_first(&vers);
417 if( rid!=0 ){
418 do{
419 db_bind_int(&qc, ":rid", rid);
420 db_step(&qc);
421 db_reset(&qc);
422 }while((rid = bag_next(&vers, rid))!=0);
@@ -416,15 +452,18 @@
452 while( db_step(&q)==SQLITE_ROW ){
453 int rid = db_column_int(&q, 0);
454 Blob content;
455
456 while( !bag_find(&blobs, rid) ){
457 char *zMark;
458 content_get(rid, &content);
459 db_bind_int(&q2, ":rid", rid);
460 db_step(&q2);
461 db_reset(&q2);
462 zMark = mark_name_from_rid(rid, &unused_mark);
463 printf("blob\nmark %s\ndata %d\n", zMark, blob_size(&content));
464 free(zMark);
465 bag_insert(&blobs, rid);
466 fwrite(blob_buffer(&content), 1, blob_size(&content), stdout);
467 printf("\n");
468 blob_reset(&content);
469
@@ -470,11 +509,11 @@
509 if( zBranch==0 ) zBranch = "trunk";
510 zBr = mprintf("%s", zBranch);
511 for(i=0; zBr[i]; i++){
512 if( !fossil_isalnum(zBr[i]) ) zBr[i] = '_';
513 }
514 zMark = mark_name_from_rid(ckinId, &unused_mark);
515 printf("commit refs/heads/%s\nmark %s\n", zBr, zMark);
516 free(zMark);
517 free(zBr);
518 printf("committer");
519 print_person(zUser);
@@ -487,21 +526,21 @@
526 " AND pid IN (SELECT objid FROM event)",
527 ckinId
528 );
529 if( db_step(&q3) == SQLITE_ROW ){
530 int pid = db_column_int(&q3, 0);
531 zMark = mark_name_from_rid(pid, &unused_mark);
532 printf("from %s\n", zMark);
533 free(zMark);
534 db_prepare(&q4,
535 "SELECT pid FROM plink"
536 " WHERE cid=%d AND NOT isprim"
537 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)"
538 " ORDER BY pid",
539 ckinId);
540 while( db_step(&q4)==SQLITE_ROW ){
541 zMark = mark_name_from_rid(db_column_int(&q4, 0), &unused_mark);
542 printf("merge %s\n", zMark);
543 free(zMark);
544 }
545 db_finalize(&q4);
546 }else{
@@ -516,20 +555,22 @@
555 );
556 while( db_step(&q4)==SQLITE_ROW ){
557 const char *zName = db_column_text(&q4,0);
558 int zNew = db_column_int(&q4,1);
559 int mPerm = db_column_int(&q4,2);
560 if( zNew==0 ){
561 printf("D %s\n", zName);
562 }else if( bag_find(&blobs, zNew) ){
563 const char *zPerm;
564 zMark = mark_name_from_rid(zNew, &unused_mark);
565 switch( mPerm ){
566 case PERM_LNK: zPerm = "120000"; break;
567 case PERM_EXE: zPerm = "100755"; break;
568 default: zPerm = "100644"; break;
569 }
570 printf("M %s %s %s\n", zPerm, zMark, zName);
571 free(zMark);
572 }
573 }
574 db_finalize(&q4);
575 db_finalize(&q3);
576 printf("\n");
@@ -547,20 +588,22 @@
588 );
589 while( db_step(&q)==SQLITE_ROW ){
590 const char *zTagname = db_column_text(&q, 0);
591 char *zEncoded = 0;
592 int rid = db_column_int(&q, 1);
593 char *zMark = mark_name_from_rid(rid, &unused_mark);
594 const char *zSecSince1970 = db_column_text(&q, 2);
595 int i;
596 if( rid==0 || !bag_find(&vers, rid) ) continue;
597 zTagname += 4;
598 zEncoded = mprintf("%s", zTagname);
599 for(i=0; zEncoded[i]; i++){
600 if( !fossil_isalnum(zEncoded[i]) ) zEncoded[i] = '_';
601 }
602 printf("tag %s\n", zEncoded);
603 printf("from %s\n", zMark);
604 free(zMark);
605 printf("tagger <tagger> %s +0000\n", zSecSince1970);
606 printf("data 0\n");
607 fossil_free(zEncoded);
608 }
609 db_finalize(&q);
@@ -570,12 +613,12 @@
613 f = fossil_fopen(markfile_out, "w");
614 if( f == 0 ){
615 fossil_fatal("cannot open %s for writing", markfile_out);
616 }
617 export_marks(f, &blobs, &vers);
618 if( ferror(f)!=0 || fclose(f)!=0 ){
619 fossil_fatal("error while writing %s", markfile_out);
620 }
621 }
622 bag_clear(&blobs);
623 bag_clear(&vers);
624 }
625
+63 -12
--- src/file.c
+++ src/file.c
@@ -293,24 +293,36 @@
293293
}
294294
return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
295295
}
296296
297297
/*
298
-** Same as file_isdir(), but takes into account symlinks.
298
+** Same as file_isdir(), but takes into account symlinks. Return 1 if
299
+** zFilename is a directory -OR- a symlink that points to a directory.
300
+** Return 0 if zFilename does not exist. Return 2 if zFilename exists
301
+** but is something other than a directory.
299302
*/
300303
int file_wd_isdir(const char *zFilename){
301304
int rc;
305
+ char *zFN;
302306
303
- if( zFilename ){
304
- char *zFN = mprintf("%s", zFilename);
305
- file_simplify_name(zFN, -1, 0);
306
- rc = getStat(zFN, 1);
307
- free(zFN);
307
+ zFN = mprintf("%s", zFilename);
308
+ file_simplify_name(zFN, -1, 0);
309
+ rc = getStat(zFN, 1);
310
+ if( rc ){
311
+ rc = 0; /* It does not exist at all. */
312
+ }else if( S_ISDIR(fileStat.st_mode) ){
313
+ rc = 1; /* It exists and is a real directory. */
314
+ }else if( S_ISLNK(fileStat.st_mode) ){
315
+ Blob content;
316
+ blob_read_link(&content, zFN); /* It exists and is a link. */
317
+ rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
318
+ blob_reset(&content);
308319
}else{
309
- rc = getStat(0, 1);
320
+ rc = 2; /* It exists and is something else. */
310321
}
311
- return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
322
+ free(zFN);
323
+ return rc;
312324
}
313325
314326
315327
/*
316328
** Wrapper around the access() system call.
@@ -471,16 +483,16 @@
471483
#if !defined(_WIN32)
472484
struct stat buf;
473485
if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
474486
if( onoff ){
475487
int targetMode = (buf.st_mode & 0444)>>2;
476
- if( (buf.st_mode & 0100) == 0 ){
488
+ if( (buf.st_mode & 0100)==0 ){
477489
chmod(zFilename, buf.st_mode | targetMode);
478490
rc = 1;
479491
}
480492
}else{
481
- if( (buf.st_mode & 0100) != 0 ){
493
+ if( (buf.st_mode & 0100)!=0 ){
482494
chmod(zFilename, buf.st_mode & ~0111);
483495
rc = 1;
484496
}
485497
}
486498
#endif /* _WIN32 */
@@ -600,11 +612,11 @@
600612
** The if stops us from trying to create a directory of a drive letter
601613
** C: in this example.
602614
*/
603615
if( !(i==2 && zName[1]==':') ){
604616
#endif
605
- if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
617
+ if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){
606618
if (errorReturn <= 0) {
607619
fossil_fatal_recursive("unable to create directory %s", zName);
608620
}
609621
rc = errorReturn;
610622
break;
@@ -851,11 +863,11 @@
851863
#ifdef _WIN32
852864
win32_getcwd(zBuf, nBuf);
853865
#else
854866
if( getcwd(zBuf, nBuf-1)==0 ){
855867
if( errno==ERANGE ){
856
- fossil_fatal("pwd too big: max %d\n", nBuf-1);
868
+ fossil_fatal("pwd too big: max %d", nBuf-1);
857869
}else{
858870
fossil_fatal("cannot find current working directory; %s",
859871
strerror(errno));
860872
}
861873
}
@@ -1384,5 +1396,44 @@
13841396
#else
13851397
FILE *f = fopen(zName, zMode);
13861398
#endif
13871399
return f;
13881400
}
1401
+
1402
+/*
1403
+** Return non-NULL if zFilename contains pathname elements that
1404
+** are reserved on Windows. The returned string is the disallowed
1405
+** path element.
1406
+*/
1407
+const char *file_is_win_reserved(const char *zPath){
1408
+ static const char *azRes[] = { "CON", "PRN", "AUX", "NUL", "COM", "LPT" };
1409
+ static char zReturn[5];
1410
+ int i;
1411
+ while( zPath[0] ){
1412
+ for(i=0; i<ArraySize(azRes); i++){
1413
+ if( sqlite3_strnicmp(zPath, azRes[i], 3)==0
1414
+ && ((i>=4 && fossil_isdigit(zPath[3])
1415
+ && (zPath[4]=='/' || zPath[4]=='.' || zPath[4]==0))
1416
+ || (i<4 && (zPath[3]=='/' || zPath[3]=='.' || zPath[3]==0)))
1417
+ ){
1418
+ sqlite3_snprintf(5,zReturn,"%.*s", i>=4 ? 4 : 3, zPath);
1419
+ return zReturn;
1420
+ }
1421
+ }
1422
+ while( zPath[0] && zPath[0]!='/' ) zPath++;
1423
+ while( zPath[0]=='/' ) zPath++;
1424
+ }
1425
+ return 0;
1426
+}
1427
+
1428
+/*
1429
+** COMMAND: test-valid-for-windows
1430
+** Usage: fossil test-valid-for-windows FILENAME ....
1431
+**
1432
+** Show which filenames are not valid for Windows
1433
+*/
1434
+void file_test_valid_for_windows(void){
1435
+ int i;
1436
+ for(i=2; i<g.argc; i++){
1437
+ fossil_print("%s %s\n", file_is_win_reserved(g.argv[i]), g.argv[i]);
1438
+ }
1439
+}
13891440
--- src/file.c
+++ src/file.c
@@ -293,24 +293,36 @@
293 }
294 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
295 }
296
297 /*
298 ** Same as file_isdir(), but takes into account symlinks.
 
 
 
299 */
300 int file_wd_isdir(const char *zFilename){
301 int rc;
 
302
303 if( zFilename ){
304 char *zFN = mprintf("%s", zFilename);
305 file_simplify_name(zFN, -1, 0);
306 rc = getStat(zFN, 1);
307 free(zFN);
 
 
 
 
 
 
 
308 }else{
309 rc = getStat(0, 1);
310 }
311 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
 
312 }
313
314
315 /*
316 ** Wrapper around the access() system call.
@@ -471,16 +483,16 @@
471 #if !defined(_WIN32)
472 struct stat buf;
473 if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
474 if( onoff ){
475 int targetMode = (buf.st_mode & 0444)>>2;
476 if( (buf.st_mode & 0100) == 0 ){
477 chmod(zFilename, buf.st_mode | targetMode);
478 rc = 1;
479 }
480 }else{
481 if( (buf.st_mode & 0100) != 0 ){
482 chmod(zFilename, buf.st_mode & ~0111);
483 rc = 1;
484 }
485 }
486 #endif /* _WIN32 */
@@ -600,11 +612,11 @@
600 ** The if stops us from trying to create a directory of a drive letter
601 ** C: in this example.
602 */
603 if( !(i==2 && zName[1]==':') ){
604 #endif
605 if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
606 if (errorReturn <= 0) {
607 fossil_fatal_recursive("unable to create directory %s", zName);
608 }
609 rc = errorReturn;
610 break;
@@ -851,11 +863,11 @@
851 #ifdef _WIN32
852 win32_getcwd(zBuf, nBuf);
853 #else
854 if( getcwd(zBuf, nBuf-1)==0 ){
855 if( errno==ERANGE ){
856 fossil_fatal("pwd too big: max %d\n", nBuf-1);
857 }else{
858 fossil_fatal("cannot find current working directory; %s",
859 strerror(errno));
860 }
861 }
@@ -1384,5 +1396,44 @@
1384 #else
1385 FILE *f = fopen(zName, zMode);
1386 #endif
1387 return f;
1388 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1389
--- src/file.c
+++ src/file.c
@@ -293,24 +293,36 @@
293 }
294 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
295 }
296
297 /*
298 ** Same as file_isdir(), but takes into account symlinks. Return 1 if
299 ** zFilename is a directory -OR- a symlink that points to a directory.
300 ** Return 0 if zFilename does not exist. Return 2 if zFilename exists
301 ** but is something other than a directory.
302 */
303 int file_wd_isdir(const char *zFilename){
304 int rc;
305 char *zFN;
306
307 zFN = mprintf("%s", zFilename);
308 file_simplify_name(zFN, -1, 0);
309 rc = getStat(zFN, 1);
310 if( rc ){
311 rc = 0; /* It does not exist at all. */
312 }else if( S_ISDIR(fileStat.st_mode) ){
313 rc = 1; /* It exists and is a real directory. */
314 }else if( S_ISLNK(fileStat.st_mode) ){
315 Blob content;
316 blob_read_link(&content, zFN); /* It exists and is a link. */
317 rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
318 blob_reset(&content);
319 }else{
320 rc = 2; /* It exists and is something else. */
321 }
322 free(zFN);
323 return rc;
324 }
325
326
327 /*
328 ** Wrapper around the access() system call.
@@ -471,16 +483,16 @@
483 #if !defined(_WIN32)
484 struct stat buf;
485 if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
486 if( onoff ){
487 int targetMode = (buf.st_mode & 0444)>>2;
488 if( (buf.st_mode & 0100)==0 ){
489 chmod(zFilename, buf.st_mode | targetMode);
490 rc = 1;
491 }
492 }else{
493 if( (buf.st_mode & 0100)!=0 ){
494 chmod(zFilename, buf.st_mode & ~0111);
495 rc = 1;
496 }
497 }
498 #endif /* _WIN32 */
@@ -600,11 +612,11 @@
612 ** The if stops us from trying to create a directory of a drive letter
613 ** C: in this example.
614 */
615 if( !(i==2 && zName[1]==':') ){
616 #endif
617 if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){
618 if (errorReturn <= 0) {
619 fossil_fatal_recursive("unable to create directory %s", zName);
620 }
621 rc = errorReturn;
622 break;
@@ -851,11 +863,11 @@
863 #ifdef _WIN32
864 win32_getcwd(zBuf, nBuf);
865 #else
866 if( getcwd(zBuf, nBuf-1)==0 ){
867 if( errno==ERANGE ){
868 fossil_fatal("pwd too big: max %d", nBuf-1);
869 }else{
870 fossil_fatal("cannot find current working directory; %s",
871 strerror(errno));
872 }
873 }
@@ -1384,5 +1396,44 @@
1396 #else
1397 FILE *f = fopen(zName, zMode);
1398 #endif
1399 return f;
1400 }
1401
1402 /*
1403 ** Return non-NULL if zFilename contains pathname elements that
1404 ** are reserved on Windows. The returned string is the disallowed
1405 ** path element.
1406 */
1407 const char *file_is_win_reserved(const char *zPath){
1408 static const char *azRes[] = { "CON", "PRN", "AUX", "NUL", "COM", "LPT" };
1409 static char zReturn[5];
1410 int i;
1411 while( zPath[0] ){
1412 for(i=0; i<ArraySize(azRes); i++){
1413 if( sqlite3_strnicmp(zPath, azRes[i], 3)==0
1414 && ((i>=4 && fossil_isdigit(zPath[3])
1415 && (zPath[4]=='/' || zPath[4]=='.' || zPath[4]==0))
1416 || (i<4 && (zPath[3]=='/' || zPath[3]=='.' || zPath[3]==0)))
1417 ){
1418 sqlite3_snprintf(5,zReturn,"%.*s", i>=4 ? 4 : 3, zPath);
1419 return zReturn;
1420 }
1421 }
1422 while( zPath[0] && zPath[0]!='/' ) zPath++;
1423 while( zPath[0]=='/' ) zPath++;
1424 }
1425 return 0;
1426 }
1427
1428 /*
1429 ** COMMAND: test-valid-for-windows
1430 ** Usage: fossil test-valid-for-windows FILENAME ....
1431 **
1432 ** Show which filenames are not valid for Windows
1433 */
1434 void file_test_valid_for_windows(void){
1435 int i;
1436 for(i=2; i<g.argc; i++){
1437 fossil_print("%s %s\n", file_is_win_reserved(g.argv[i]), g.argv[i]);
1438 }
1439 }
1440
+1 -1
--- src/finfo.c
+++ src/finfo.c
@@ -705,11 +705,11 @@
705705
int isExec = db_column_int(&q,6);
706706
int isAux = db_column_int(&q,7);
707707
@ <tr>
708708
@ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td>
709709
if( zParent ){
710
- @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td>
710
+ @ <td><a href='%R/info/%!S(zParent)'>%S(zParent)</a></td>
711711
}else{
712712
@ <td><i>(New)</i></td>
713713
}
714714
@ <td align='center'>%s(isAux?"&#x2713;":"")</td>
715715
if( zFid ){
716716
--- src/finfo.c
+++ src/finfo.c
@@ -705,11 +705,11 @@
705 int isExec = db_column_int(&q,6);
706 int isAux = db_column_int(&q,7);
707 @ <tr>
708 @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td>
709 if( zParent ){
710 @ <td><a href='%R/info/%!S(zPid)'>%S(zParent)</a></td>
711 }else{
712 @ <td><i>(New)</i></td>
713 }
714 @ <td align='center'>%s(isAux?"&#x2713;":"")</td>
715 if( zFid ){
716
--- src/finfo.c
+++ src/finfo.c
@@ -705,11 +705,11 @@
705 int isExec = db_column_int(&q,6);
706 int isAux = db_column_int(&q,7);
707 @ <tr>
708 @ <td><a href='%R/finfo?name=%t(zName)'>%h(zName)</a></td>
709 if( zParent ){
710 @ <td><a href='%R/info/%!S(zParent)'>%S(zParent)</a></td>
711 }else{
712 @ <td><i>(New)</i></td>
713 }
714 @ <td align='center'>%s(isAux?"&#x2713;":"")</td>
715 if( zFid ){
716
+4 -7
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,20 +20,20 @@
2020
**
2121
** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
2222
** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
2323
** the Fuse Filesystem, of course.
2424
*/
25
+#ifdef FOSSIL_HAVE_FUSEFS
2526
#include "config.h"
2627
#include <stdio.h>
2728
#include <string.h>
2829
#include <errno.h>
2930
#include <fcntl.h>
3031
#include <stdlib.h>
3132
#include <unistd.h>
3233
#include <sys/types.h>
3334
#include "fusefs.h"
34
-#ifdef FOSSIL_HAVE_FUSEFS
3535
3636
#define FUSE_USE_VERSION 26
3737
#include <fuse.h>
3838
3939
/*
@@ -207,11 +207,12 @@
207207
filler(buf, ".", NULL, 0);
208208
filler(buf, "..", NULL, 0);
209209
manifest_file_rewind(fusefs.pMan);
210210
if( n==2 ){
211211
while( (pFile = manifest_file_next(fusefs.pMan, 0))!=0 ){
212
- if( nPrev>0 && strncmp(pFile->zName, zPrev, nPrev)==0 ) continue;
212
+ if( nPrev>0 && strncmp(pFile->zName, zPrev, nPrev)==0
213
+ && pFile->zName[nPrev]=='/' ) continue;
213214
zPrev = pFile->zName;
214215
for(nPrev=0; zPrev[nPrev] && zPrev[nPrev]!='/'; nPrev++){}
215216
z = mprintf("%.*s", nPrev, zPrev);
216217
filler(buf, z, NULL, 0);
217218
fossil_free(z);
@@ -282,11 +283,10 @@
282283
static struct fuse_operations fusefs_methods = {
283284
.getattr = fusefs_getattr,
284285
.readdir = fusefs_readdir,
285286
.read = fusefs_read,
286287
};
287
-#endif /* FOSSIL_HAVE_FUSEFS */
288288
289289
/*
290290
** COMMAND: fusefs
291291
**
292292
** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,13 +314,10 @@
314314
** After stopping the "fossil fusefs" command, it might also be necessary
315315
** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316316
** again.
317317
*/
318318
void fusefs_cmd(void){
319
-#ifndef FOSSIL_HAVE_FUSEFS
320
- fossil_fatal("this build of fossil does not support the fuse filesystem");
321
-#else
322319
char *zMountPoint;
323320
char *azNewArgv[5];
324321
int doDebug = find_option("debug","d",0)!=0;
325322
326323
db_find_and_open_repository(0,0);
@@ -338,7 +335,7 @@
338335
azNewArgv[4] = 0;
339336
g.localOpen = 0; /* Prevent tags like "current" and "prev" */
340337
fuse_main(4, azNewArgv, &fusefs_methods, NULL);
341338
fusefs_reset();
342339
fusefs_clear_path();
343
-#endif
344340
}
341
+#endif /* FOSSIL_HAVE_FUSEFS */
345342
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,20 +20,20 @@
20 **
21 ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
22 ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
23 ** the Fuse Filesystem, of course.
24 */
 
25 #include "config.h"
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include "fusefs.h"
34 #ifdef FOSSIL_HAVE_FUSEFS
35
36 #define FUSE_USE_VERSION 26
37 #include <fuse.h>
38
39 /*
@@ -207,11 +207,12 @@
207 filler(buf, ".", NULL, 0);
208 filler(buf, "..", NULL, 0);
209 manifest_file_rewind(fusefs.pMan);
210 if( n==2 ){
211 while( (pFile = manifest_file_next(fusefs.pMan, 0))!=0 ){
212 if( nPrev>0 && strncmp(pFile->zName, zPrev, nPrev)==0 ) continue;
 
213 zPrev = pFile->zName;
214 for(nPrev=0; zPrev[nPrev] && zPrev[nPrev]!='/'; nPrev++){}
215 z = mprintf("%.*s", nPrev, zPrev);
216 filler(buf, z, NULL, 0);
217 fossil_free(z);
@@ -282,11 +283,10 @@
282 static struct fuse_operations fusefs_methods = {
283 .getattr = fusefs_getattr,
284 .readdir = fusefs_readdir,
285 .read = fusefs_read,
286 };
287 #endif /* FOSSIL_HAVE_FUSEFS */
288
289 /*
290 ** COMMAND: fusefs
291 **
292 ** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,13 +314,10 @@
314 ** After stopping the "fossil fusefs" command, it might also be necessary
315 ** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316 ** again.
317 */
318 void fusefs_cmd(void){
319 #ifndef FOSSIL_HAVE_FUSEFS
320 fossil_fatal("this build of fossil does not support the fuse filesystem");
321 #else
322 char *zMountPoint;
323 char *azNewArgv[5];
324 int doDebug = find_option("debug","d",0)!=0;
325
326 db_find_and_open_repository(0,0);
@@ -338,7 +335,7 @@
338 azNewArgv[4] = 0;
339 g.localOpen = 0; /* Prevent tags like "current" and "prev" */
340 fuse_main(4, azNewArgv, &fusefs_methods, NULL);
341 fusefs_reset();
342 fusefs_clear_path();
343 #endif
344 }
 
345
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,20 +20,20 @@
20 **
21 ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
22 ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
23 ** the Fuse Filesystem, of course.
24 */
25 #ifdef FOSSIL_HAVE_FUSEFS
26 #include "config.h"
27 #include <stdio.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include "fusefs.h"
 
35
36 #define FUSE_USE_VERSION 26
37 #include <fuse.h>
38
39 /*
@@ -207,11 +207,12 @@
207 filler(buf, ".", NULL, 0);
208 filler(buf, "..", NULL, 0);
209 manifest_file_rewind(fusefs.pMan);
210 if( n==2 ){
211 while( (pFile = manifest_file_next(fusefs.pMan, 0))!=0 ){
212 if( nPrev>0 && strncmp(pFile->zName, zPrev, nPrev)==0
213 && pFile->zName[nPrev]=='/' ) continue;
214 zPrev = pFile->zName;
215 for(nPrev=0; zPrev[nPrev] && zPrev[nPrev]!='/'; nPrev++){}
216 z = mprintf("%.*s", nPrev, zPrev);
217 filler(buf, z, NULL, 0);
218 fossil_free(z);
@@ -282,11 +283,10 @@
283 static struct fuse_operations fusefs_methods = {
284 .getattr = fusefs_getattr,
285 .readdir = fusefs_readdir,
286 .read = fusefs_read,
287 };
 
288
289 /*
290 ** COMMAND: fusefs
291 **
292 ** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,13 +314,10 @@
314 ** After stopping the "fossil fusefs" command, it might also be necessary
315 ** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316 ** again.
317 */
318 void fusefs_cmd(void){
 
 
 
319 char *zMountPoint;
320 char *azNewArgv[5];
321 int doDebug = find_option("debug","d",0)!=0;
322
323 db_find_and_open_repository(0,0);
@@ -338,7 +335,7 @@
335 azNewArgv[4] = 0;
336 g.localOpen = 0; /* Prevent tags like "current" and "prev" */
337 fuse_main(4, azNewArgv, &fusefs_methods, NULL);
338 fusefs_reset();
339 fusefs_clear_path();
 
340 }
341 #endif /* FOSSIL_HAVE_FUSEFS */
342
+19 -4
--- src/graph.c
+++ src/graph.c
@@ -258,11 +258,10 @@
258258
int iRail = pBottom->iRail;
259259
GraphRow *pCurrent;
260260
GraphRow *pPrior;
261261
u64 mask = ((u64)1)<<iRail;
262262
263
- pBottom->iRail = iRail;
264263
pBottom->railInUse |= mask;
265264
pPrior = pBottom;
266265
for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
267266
assert( pPrior->idx > pCurrent->idx );
268267
assert( pCurrent->iRail<0 );
@@ -344,14 +343,16 @@
344343
/*
345344
** Compute the complete graph
346345
*/
347346
void graph_finish(GraphContext *p, int omitDescenders){
348347
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
349
- int i;
348
+ int i, j;
350349
u64 mask;
351350
int hasDup = 0; /* True if one or more isDup entries */
352351
const char *zTrunk;
352
+ int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines
353
+ that enter from bottom of screen */
353354
354355
if( p==0 || p->pFirst==0 || p->nErr ) return;
355356
p->nErr = 1; /* Assume an error until proven otherwise */
356357
357358
/* Initialize all rows */
@@ -366,10 +367,11 @@
366367
pDup->isDup = 1;
367368
}
368369
hashInsert(p, pRow, 1);
369370
}
370371
p->mxRail = -1;
372
+ memset(railRid, 0, sizeof(railRid));
371373
372374
/* Purge merge-parents that are out-of-graph if descenders are not
373375
** drawn.
374376
**
375377
** Each node has one primary parent and zero or more "merge" parents.
@@ -458,10 +460,13 @@
458460
}
459461
if( p->mxRail>=GR_MAX_RAIL ) return;
460462
mask = BIT(pRow->iRail);
461463
if( !omitDescenders ){
462464
pRow->bDescender = pRow->nParent>0;
465
+ if( pRow->bDescender ){
466
+ railRid[pRow->iRail] = pRow->aParent[0];
467
+ }
463468
for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
464469
pLoop->railInUse |= mask;
465470
}
466471
}
467472
assignChildrenToRail(pRow);
@@ -536,12 +541,22 @@
536541
for(i=1; i<pRow->nParent; i++){
537542
int parentRid = pRow->aParent[i];
538543
pDesc = hashFind(p, parentRid);
539544
if( pDesc==0 ){
540545
/* Merge from a node that is off-screen */
541
- int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
542
- if( p->mxRail>=GR_MAX_RAIL ) return;
546
+ int iMrail = -1;
547
+ for(j=0; j<GR_MAX_RAIL; j++){
548
+ if( railRid[j]==parentRid ){
549
+ iMrail = j;
550
+ break;
551
+ }
552
+ }
553
+ if( iMrail==-1 ){
554
+ iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
555
+ if( p->mxRail>=GR_MAX_RAIL ) return;
556
+ railRid[iMrail] = parentRid;
557
+ }
543558
mask = BIT(iMrail);
544559
pRow->mergeIn[iMrail] = 1;
545560
pRow->mergeDown |= mask;
546561
for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
547562
pLoop->railInUse |= mask;
548563
--- src/graph.c
+++ src/graph.c
@@ -258,11 +258,10 @@
258 int iRail = pBottom->iRail;
259 GraphRow *pCurrent;
260 GraphRow *pPrior;
261 u64 mask = ((u64)1)<<iRail;
262
263 pBottom->iRail = iRail;
264 pBottom->railInUse |= mask;
265 pPrior = pBottom;
266 for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
267 assert( pPrior->idx > pCurrent->idx );
268 assert( pCurrent->iRail<0 );
@@ -344,14 +343,16 @@
344 /*
345 ** Compute the complete graph
346 */
347 void graph_finish(GraphContext *p, int omitDescenders){
348 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
349 int i;
350 u64 mask;
351 int hasDup = 0; /* True if one or more isDup entries */
352 const char *zTrunk;
 
 
353
354 if( p==0 || p->pFirst==0 || p->nErr ) return;
355 p->nErr = 1; /* Assume an error until proven otherwise */
356
357 /* Initialize all rows */
@@ -366,10 +367,11 @@
366 pDup->isDup = 1;
367 }
368 hashInsert(p, pRow, 1);
369 }
370 p->mxRail = -1;
 
371
372 /* Purge merge-parents that are out-of-graph if descenders are not
373 ** drawn.
374 **
375 ** Each node has one primary parent and zero or more "merge" parents.
@@ -458,10 +460,13 @@
458 }
459 if( p->mxRail>=GR_MAX_RAIL ) return;
460 mask = BIT(pRow->iRail);
461 if( !omitDescenders ){
462 pRow->bDescender = pRow->nParent>0;
 
 
 
463 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
464 pLoop->railInUse |= mask;
465 }
466 }
467 assignChildrenToRail(pRow);
@@ -536,12 +541,22 @@
536 for(i=1; i<pRow->nParent; i++){
537 int parentRid = pRow->aParent[i];
538 pDesc = hashFind(p, parentRid);
539 if( pDesc==0 ){
540 /* Merge from a node that is off-screen */
541 int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
542 if( p->mxRail>=GR_MAX_RAIL ) return;
 
 
 
 
 
 
 
 
 
 
543 mask = BIT(iMrail);
544 pRow->mergeIn[iMrail] = 1;
545 pRow->mergeDown |= mask;
546 for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
547 pLoop->railInUse |= mask;
548
--- src/graph.c
+++ src/graph.c
@@ -258,11 +258,10 @@
258 int iRail = pBottom->iRail;
259 GraphRow *pCurrent;
260 GraphRow *pPrior;
261 u64 mask = ((u64)1)<<iRail;
262
 
263 pBottom->railInUse |= mask;
264 pPrior = pBottom;
265 for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
266 assert( pPrior->idx > pCurrent->idx );
267 assert( pCurrent->iRail<0 );
@@ -344,14 +343,16 @@
343 /*
344 ** Compute the complete graph
345 */
346 void graph_finish(GraphContext *p, int omitDescenders){
347 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
348 int i, j;
349 u64 mask;
350 int hasDup = 0; /* True if one or more isDup entries */
351 const char *zTrunk;
352 int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines
353 that enter from bottom of screen */
354
355 if( p==0 || p->pFirst==0 || p->nErr ) return;
356 p->nErr = 1; /* Assume an error until proven otherwise */
357
358 /* Initialize all rows */
@@ -366,10 +367,11 @@
367 pDup->isDup = 1;
368 }
369 hashInsert(p, pRow, 1);
370 }
371 p->mxRail = -1;
372 memset(railRid, 0, sizeof(railRid));
373
374 /* Purge merge-parents that are out-of-graph if descenders are not
375 ** drawn.
376 **
377 ** Each node has one primary parent and zero or more "merge" parents.
@@ -458,10 +460,13 @@
460 }
461 if( p->mxRail>=GR_MAX_RAIL ) return;
462 mask = BIT(pRow->iRail);
463 if( !omitDescenders ){
464 pRow->bDescender = pRow->nParent>0;
465 if( pRow->bDescender ){
466 railRid[pRow->iRail] = pRow->aParent[0];
467 }
468 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
469 pLoop->railInUse |= mask;
470 }
471 }
472 assignChildrenToRail(pRow);
@@ -536,12 +541,22 @@
541 for(i=1; i<pRow->nParent; i++){
542 int parentRid = pRow->aParent[i];
543 pDesc = hashFind(p, parentRid);
544 if( pDesc==0 ){
545 /* Merge from a node that is off-screen */
546 int iMrail = -1;
547 for(j=0; j<GR_MAX_RAIL; j++){
548 if( railRid[j]==parentRid ){
549 iMrail = j;
550 break;
551 }
552 }
553 if( iMrail==-1 ){
554 iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
555 if( p->mxRail>=GR_MAX_RAIL ) return;
556 railRid[iMrail] = parentRid;
557 }
558 mask = BIT(iMrail);
559 pRow->mergeIn[iMrail] = 1;
560 pRow->mergeDown |= mask;
561 for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
562 pLoop->railInUse |= mask;
563
+8 -7
--- src/import.c
+++ src/import.c
@@ -1761,21 +1761,22 @@
17611761
** times but only the last tag should be used. And we do not know which
17621762
** occurrence of the tag is the last until the import finishes.
17631763
*/
17641764
db_multi_exec(
17651765
"CREATE TEMP TABLE xmark(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
1766
+ "CREATE INDEX temp.i_xmark ON xmark(trid);"
17661767
"CREATE TEMP TABLE xbranch(tname TEXT UNIQUE, brnm TEXT);"
17671768
"CREATE TEMP TABLE xtag(tname TEXT UNIQUE, tcontent TEXT);"
17681769
);
17691770
17701771
if( markfile_in ){
17711772
FILE *f = fossil_fopen(markfile_in, "r");
17721773
if( !f ){
1773
- fossil_fatal("cannot open %s for reading\n", markfile_in);
1774
+ fossil_fatal("cannot open %s for reading", markfile_in);
17741775
}
1775
- if(import_marks(f, &blobs, NULL)<0){
1776
- fossil_fatal("error importing marks from file: %s\n", markfile_in);
1776
+ if( import_marks(f, &blobs, NULL, NULL)<0 ){
1777
+ fossil_fatal("error importing marks from file: %s", markfile_in);
17771778
}
17781779
fclose(f);
17791780
}
17801781
17811782
manifest_crosslink_begin();
@@ -1795,21 +1796,21 @@
17951796
db_prepare(&q_marks, "SELECT DISTINCT trid FROM xmark");
17961797
while( db_step(&q_marks)==SQLITE_ROW ){
17971798
rid = db_column_int(&q_marks, 0);
17981799
if( db_int(0, "SELECT count(objid) FROM event"
17991800
" WHERE objid=%d AND type='ci'", rid)==0 ){
1800
- if( bag_find(&blobs, rid)==0 ){
1801
- bag_insert(&blobs, rid);
1802
- }
1801
+ /* Blob marks exported by git aren't saved between runs, so they need
1802
+ ** to be left free for git to re-use in the future.
1803
+ */
18031804
}else{
18041805
bag_insert(&vers, rid);
18051806
}
18061807
}
18071808
db_finalize(&q_marks);
18081809
f = fossil_fopen(markfile_out, "w");
18091810
if( !f ){
1810
- fossil_fatal("cannot open %s for writing\n", markfile_out);
1811
+ fossil_fatal("cannot open %s for writing", markfile_out);
18111812
}
18121813
export_marks(f, &blobs, &vers);
18131814
fclose(f);
18141815
bag_clear(&blobs);
18151816
bag_clear(&vers);
18161817
--- src/import.c
+++ src/import.c
@@ -1761,21 +1761,22 @@
1761 ** times but only the last tag should be used. And we do not know which
1762 ** occurrence of the tag is the last until the import finishes.
1763 */
1764 db_multi_exec(
1765 "CREATE TEMP TABLE xmark(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
 
1766 "CREATE TEMP TABLE xbranch(tname TEXT UNIQUE, brnm TEXT);"
1767 "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, tcontent TEXT);"
1768 );
1769
1770 if( markfile_in ){
1771 FILE *f = fossil_fopen(markfile_in, "r");
1772 if( !f ){
1773 fossil_fatal("cannot open %s for reading\n", markfile_in);
1774 }
1775 if(import_marks(f, &blobs, NULL)<0){
1776 fossil_fatal("error importing marks from file: %s\n", markfile_in);
1777 }
1778 fclose(f);
1779 }
1780
1781 manifest_crosslink_begin();
@@ -1795,21 +1796,21 @@
1795 db_prepare(&q_marks, "SELECT DISTINCT trid FROM xmark");
1796 while( db_step(&q_marks)==SQLITE_ROW ){
1797 rid = db_column_int(&q_marks, 0);
1798 if( db_int(0, "SELECT count(objid) FROM event"
1799 " WHERE objid=%d AND type='ci'", rid)==0 ){
1800 if( bag_find(&blobs, rid)==0 ){
1801 bag_insert(&blobs, rid);
1802 }
1803 }else{
1804 bag_insert(&vers, rid);
1805 }
1806 }
1807 db_finalize(&q_marks);
1808 f = fossil_fopen(markfile_out, "w");
1809 if( !f ){
1810 fossil_fatal("cannot open %s for writing\n", markfile_out);
1811 }
1812 export_marks(f, &blobs, &vers);
1813 fclose(f);
1814 bag_clear(&blobs);
1815 bag_clear(&vers);
1816
--- src/import.c
+++ src/import.c
@@ -1761,21 +1761,22 @@
1761 ** times but only the last tag should be used. And we do not know which
1762 ** occurrence of the tag is the last until the import finishes.
1763 */
1764 db_multi_exec(
1765 "CREATE TEMP TABLE xmark(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
1766 "CREATE INDEX temp.i_xmark ON xmark(trid);"
1767 "CREATE TEMP TABLE xbranch(tname TEXT UNIQUE, brnm TEXT);"
1768 "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, tcontent TEXT);"
1769 );
1770
1771 if( markfile_in ){
1772 FILE *f = fossil_fopen(markfile_in, "r");
1773 if( !f ){
1774 fossil_fatal("cannot open %s for reading", markfile_in);
1775 }
1776 if( import_marks(f, &blobs, NULL, NULL)<0 ){
1777 fossil_fatal("error importing marks from file: %s", markfile_in);
1778 }
1779 fclose(f);
1780 }
1781
1782 manifest_crosslink_begin();
@@ -1795,21 +1796,21 @@
1796 db_prepare(&q_marks, "SELECT DISTINCT trid FROM xmark");
1797 while( db_step(&q_marks)==SQLITE_ROW ){
1798 rid = db_column_int(&q_marks, 0);
1799 if( db_int(0, "SELECT count(objid) FROM event"
1800 " WHERE objid=%d AND type='ci'", rid)==0 ){
1801 /* Blob marks exported by git aren't saved between runs, so they need
1802 ** to be left free for git to re-use in the future.
1803 */
1804 }else{
1805 bag_insert(&vers, rid);
1806 }
1807 }
1808 db_finalize(&q_marks);
1809 f = fossil_fopen(markfile_out, "w");
1810 if( !f ){
1811 fossil_fatal("cannot open %s for writing", markfile_out);
1812 }
1813 export_marks(f, &blobs, &vers);
1814 fclose(f);
1815 bag_clear(&blobs);
1816 bag_clear(&vers);
1817
+1 -1
--- src/info.c
+++ src/info.c
@@ -231,11 +231,11 @@
231231
db_int(-1, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"));
232232
}else{
233233
int rid;
234234
rid = name_to_rid(g.argv[2]);
235235
if( rid==0 ){
236
- fossil_fatal("no such object: %s\n", g.argv[2]);
236
+ fossil_fatal("no such object: %s", g.argv[2]);
237237
}
238238
show_common_info(rid, "uuid:", 1, 1);
239239
}
240240
}
241241
242242
--- src/info.c
+++ src/info.c
@@ -231,11 +231,11 @@
231 db_int(-1, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"));
232 }else{
233 int rid;
234 rid = name_to_rid(g.argv[2]);
235 if( rid==0 ){
236 fossil_fatal("no such object: %s\n", g.argv[2]);
237 }
238 show_common_info(rid, "uuid:", 1, 1);
239 }
240 }
241
242
--- src/info.c
+++ src/info.c
@@ -231,11 +231,11 @@
231 db_int(-1, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"));
232 }else{
233 int rid;
234 rid = name_to_rid(g.argv[2]);
235 if( rid==0 ){
236 fossil_fatal("no such object: %s", g.argv[2]);
237 }
238 show_common_info(rid, "uuid:", 1, 1);
239 }
240 }
241
242
--- src/json_branch.c
+++ src/json_branch.c
@@ -292,11 +292,11 @@
292292
if( brid==0 ){
293293
fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
294294
}
295295
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
296296
if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
297
- fossil_fatal("%s\n", g.zErrMsg);
297
+ fossil_fatal("%s", g.zErrMsg);
298298
}
299299
assert( blob_is_reset(&branch) );
300300
content_deltify(rootid, brid, 0);
301301
if( zNewRid ){
302302
*zNewRid = brid;
303303
--- src/json_branch.c
+++ src/json_branch.c
@@ -292,11 +292,11 @@
292 if( brid==0 ){
293 fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
294 }
295 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
296 if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
297 fossil_fatal("%s\n", g.zErrMsg);
298 }
299 assert( blob_is_reset(&branch) );
300 content_deltify(rootid, brid, 0);
301 if( zNewRid ){
302 *zNewRid = brid;
303
--- src/json_branch.c
+++ src/json_branch.c
@@ -292,11 +292,11 @@
292 if( brid==0 ){
293 fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
294 }
295 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
296 if( manifest_crosslink(brid, &branch, MC_PERMIT_HOOKS)==0 ){
297 fossil_fatal("%s", g.zErrMsg);
298 }
299 assert( blob_is_reset(&branch) );
300 content_deltify(rootid, brid, 0);
301 if( zNewRid ){
302 *zNewRid = brid;
303
+19 -1
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -115,12 +115,30 @@
115115
if( contentFormat>0 ){/*HTML-ize it*/
116116
Blob content = empty_blob;
117117
Blob raw = empty_blob;
118118
zFormat = "html";
119119
if(zBody && *zBody){
120
+ const char *zMimetype = pWiki->zMimetype;
121
+ if( zMimetype==0 ) zMimetype = "text/plain";
122
+ zMimetype = wiki_filter_mimetypes(zMimetype);
120123
blob_append(&raw,zBody,-1);
121
- wiki_convert(&raw,&content,0);
124
+ if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
125
+ wiki_convert(&raw,&content,0);
126
+ }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
127
+ markdown_to_html(&raw,0,&content);
128
+ }else if( fossil_strcmp(zMimetype, "text/plain")==0 ){
129
+ htmlize_to_blob(&content,blob_str(&raw),blob_size(&raw));
130
+ }else{
131
+ json_set_err( FSL_JSON_E_UNKNOWN,
132
+ "Unsupported MIME type '%s' for wiki page '%s'.",
133
+ zMimetype, pWiki->zWikiTitle );
134
+ blob_reset(&content);
135
+ blob_reset(&raw);
136
+ cson_free_object(pay);
137
+ manifest_destroy(pWiki);
138
+ return NULL;
139
+ }
122140
len = (unsigned int)blob_size(&content);
123141
}
124142
cson_object_set(pay,"size",json_new_int((cson_int_t)len));
125143
cson_object_set(pay,"content",
126144
cson_value_new_string(blob_buffer(&content),len));
127145
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -115,12 +115,30 @@
115 if( contentFormat>0 ){/*HTML-ize it*/
116 Blob content = empty_blob;
117 Blob raw = empty_blob;
118 zFormat = "html";
119 if(zBody && *zBody){
 
 
 
120 blob_append(&raw,zBody,-1);
121 wiki_convert(&raw,&content,0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122 len = (unsigned int)blob_size(&content);
123 }
124 cson_object_set(pay,"size",json_new_int((cson_int_t)len));
125 cson_object_set(pay,"content",
126 cson_value_new_string(blob_buffer(&content),len));
127
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -115,12 +115,30 @@
115 if( contentFormat>0 ){/*HTML-ize it*/
116 Blob content = empty_blob;
117 Blob raw = empty_blob;
118 zFormat = "html";
119 if(zBody && *zBody){
120 const char *zMimetype = pWiki->zMimetype;
121 if( zMimetype==0 ) zMimetype = "text/plain";
122 zMimetype = wiki_filter_mimetypes(zMimetype);
123 blob_append(&raw,zBody,-1);
124 if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
125 wiki_convert(&raw,&content,0);
126 }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
127 markdown_to_html(&raw,0,&content);
128 }else if( fossil_strcmp(zMimetype, "text/plain")==0 ){
129 htmlize_to_blob(&content,blob_str(&raw),blob_size(&raw));
130 }else{
131 json_set_err( FSL_JSON_E_UNKNOWN,
132 "Unsupported MIME type '%s' for wiki page '%s'.",
133 zMimetype, pWiki->zWikiTitle );
134 blob_reset(&content);
135 blob_reset(&raw);
136 cson_free_object(pay);
137 manifest_destroy(pWiki);
138 return NULL;
139 }
140 len = (unsigned int)blob_size(&content);
141 }
142 cson_object_set(pay,"size",json_new_int((cson_int_t)len));
143 cson_object_set(pay,"content",
144 cson_value_new_string(blob_buffer(&content),len));
145
+79 -4
--- src/main.c
+++ src/main.c
@@ -18,20 +18,21 @@
1818
** This module codes the main() procedure that runs first when the
1919
** program is invoked.
2020
*/
2121
#include "VERSION.h"
2222
#include "config.h"
23
+#if defined(_WIN32)
24
+# include <windows.h>
25
+#endif
2326
#include "main.h"
2427
#include <string.h>
2528
#include <time.h>
2629
#include <fcntl.h>
2730
#include <sys/types.h>
2831
#include <sys/stat.h>
2932
#include <stdlib.h> /* atexit() */
30
-#if defined(_WIN32)
31
-# include <windows.h>
32
-#else
33
+#if !defined(_WIN32)
3334
# include <errno.h> /* errno global */
3435
#endif
3536
#ifdef FOSSIL_ENABLE_SSL
3637
# include "openssl/crypto.h"
3738
#endif
@@ -299,10 +300,22 @@
299300
/*
300301
** atexit() handler which frees up "some" of the resources
301302
** used by fossil.
302303
*/
303304
static void fossil_atexit(void) {
305
+#if USE_SEE
306
+ /*
307
+ ** Zero, unlock, and free the saved database encryption key now.
308
+ */
309
+ db_unsave_encryption_key();
310
+#endif
311
+#if defined(_WIN32) || defined(__BIONIC__)
312
+ /*
313
+ ** Free the secure getpass() buffer now.
314
+ */
315
+ freepass();
316
+#endif
304317
#if defined(_WIN32) && !defined(_WIN64) && defined(FOSSIL_ENABLE_TCL) && \
305318
defined(USE_TCL_STUBS)
306319
/*
307320
** If Tcl is compiled on Windows using the latest MinGW, Fossil can crash
308321
** when exiting while a stubs-enabled Tcl is still loaded. This is due to
@@ -1917,10 +1930,41 @@
19171930
}
19181931
}
19191932
}
19201933
}
19211934
1935
+#if defined(_WIN32) && USE_SEE
1936
+/*
1937
+** This function attempts to parse a string value in the following
1938
+** format:
1939
+**
1940
+** "%lu:%p:%u"
1941
+**
1942
+** There are three parts, which must be delimited by colons. The
1943
+** first part is an unsigned long integer in base-10 (decimal) format.
1944
+** The second part is a numerical representation of a native pointer,
1945
+** in the appropriate implementation defined format. The third part
1946
+** is an unsigned integer in base-10 (decimal) format.
1947
+**
1948
+** If the specified value cannot be parsed, for any reason, a fatal
1949
+** error will be raised and the process will be terminated.
1950
+*/
1951
+void parse_pid_key_value(
1952
+ const char *zPidKey, /* The value to be parsed. */
1953
+ DWORD *pProcessId, /* The extracted process identifier. */
1954
+ LPVOID *ppAddress, /* The extracted pointer value. */
1955
+ SIZE_T *pnSize /* The extracted size value. */
1956
+){
1957
+ unsigned int nSize = 0;
1958
+ if( sscanf(zPidKey, "%lu:%p:%u", pProcessId, ppAddress, &nSize)==3 ){
1959
+ *pnSize = (SIZE_T)nSize;
1960
+ }else{
1961
+ fossil_fatal("failed to parse pid key");
1962
+ }
1963
+}
1964
+#endif
1965
+
19221966
/*
19231967
** undocumented format:
19241968
**
19251969
** fossil http INFILE OUTFILE IPADDR ?REPOSITORY?
19261970
**
@@ -1968,10 +2012,12 @@
19682012
** --notfound URL use URL as "HTTP 404, object not found" page.
19692013
** --repolist If REPOSITORY is directory, URL "/" lists all repos
19702014
** --scgi Interpret input as SCGI rather than HTTP
19712015
** --skin LABEL Use override skin LABEL
19722016
** --th-trace trace TH1 execution (for debugging purposes)
2017
+** --usepidkey Use saved encryption key from parent process. This is
2018
+** only necessary when using SEE on Windows.
19732019
**
19742020
** See also: cgi, server, winsrv
19752021
*/
19762022
void cmd_http(void){
19772023
const char *zIpAddr = 0;
@@ -1980,10 +2026,13 @@
19802026
const char *zAltBase;
19812027
const char *zFileGlob;
19822028
int useSCGI;
19832029
int noJail;
19842030
int allowRepoList;
2031
+#if defined(_WIN32) && USE_SEE
2032
+ const char *zPidKey;
2033
+#endif
19852034
19862035
Th_InitTraceLog();
19872036
19882037
/* The winhttp module passes the --files option as --files-urlenc with
19892038
** the argument being URL encoded, to avoid wildcard expansion in the
@@ -2010,10 +2059,21 @@
20102059
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
20112060
cgi_replace_parameter("HTTPS","on");
20122061
}
20132062
zHost = find_option("host", 0, 1);
20142063
if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
2064
+
2065
+#if defined(_WIN32) && USE_SEE
2066
+ zPidKey = find_option("usepidkey", 0, 1);
2067
+ if( zPidKey ){
2068
+ DWORD processId = 0;
2069
+ LPVOID pAddress = NULL;
2070
+ SIZE_T nSize = 0;
2071
+ parse_pid_key_value(zPidKey, &processId, &pAddress, &nSize);
2072
+ db_read_saved_encryption_key_from_process(processId, pAddress, nSize);
2073
+ }
2074
+#endif
20152075
20162076
/* We should be done with options.. */
20172077
verify_all_options();
20182078
20192079
if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
@@ -2171,11 +2231,12 @@
21712231
** -P|--port TCPPORT listen to request on port TCPPORT
21722232
** --th-trace trace TH1 execution (for debugging purposes)
21732233
** --repolist If REPOSITORY is dir, URL "/" lists repos.
21742234
** --scgi Accept SCGI rather than HTTP
21752235
** --skin LABEL Use override skin LABEL
2176
-
2236
+** --usepidkey Use saved encryption key from parent process. This is
2237
+** only necessary when using SEE on Windows.
21772238
**
21782239
** See also: cgi, http, winsrv
21792240
*/
21802241
void cmd_webserver(void){
21812242
int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2192,10 +2253,13 @@
21922253
const char *zAltBase; /* Argument to the --baseurl option */
21932254
const char *zFileGlob; /* Static content must match this */
21942255
char *zIpAddr = 0; /* Bind to this IP address */
21952256
int fCreate = 0; /* The --create flag */
21962257
const char *zInitPage = 0; /* Start on this page. --page option */
2258
+#if defined(_WIN32) && USE_SEE
2259
+ const char *zPidKey;
2260
+#endif
21972261
21982262
#if defined(_WIN32)
21992263
const char *zStopperFile; /* Name of file used to terminate server */
22002264
zStopperFile = find_option("stopper", 0, 1);
22012265
#endif
@@ -2235,10 +2299,21 @@
22352299
g.sslNotAvailable = 1;
22362300
}
22372301
if( find_option("localhost", 0, 0)!=0 ){
22382302
flags |= HTTP_SERVER_LOCALHOST;
22392303
}
2304
+
2305
+#if defined(_WIN32) && USE_SEE
2306
+ zPidKey = find_option("usepidkey", 0, 1);
2307
+ if( zPidKey ){
2308
+ DWORD processId = 0;
2309
+ LPVOID pAddress = NULL;
2310
+ SIZE_T nSize = 0;
2311
+ parse_pid_key_value(zPidKey, &processId, &pAddress, &nSize);
2312
+ db_read_saved_encryption_key_from_process(processId, pAddress, nSize);
2313
+ }
2314
+#endif
22402315
22412316
/* We should be done with options.. */
22422317
verify_all_options();
22432318
22442319
if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
22452320
--- src/main.c
+++ src/main.c
@@ -18,20 +18,21 @@
18 ** This module codes the main() procedure that runs first when the
19 ** program is invoked.
20 */
21 #include "VERSION.h"
22 #include "config.h"
 
 
 
23 #include "main.h"
24 #include <string.h>
25 #include <time.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <stdlib.h> /* atexit() */
30 #if defined(_WIN32)
31 # include <windows.h>
32 #else
33 # include <errno.h> /* errno global */
34 #endif
35 #ifdef FOSSIL_ENABLE_SSL
36 # include "openssl/crypto.h"
37 #endif
@@ -299,10 +300,22 @@
299 /*
300 ** atexit() handler which frees up "some" of the resources
301 ** used by fossil.
302 */
303 static void fossil_atexit(void) {
 
 
 
 
 
 
 
 
 
 
 
 
304 #if defined(_WIN32) && !defined(_WIN64) && defined(FOSSIL_ENABLE_TCL) && \
305 defined(USE_TCL_STUBS)
306 /*
307 ** If Tcl is compiled on Windows using the latest MinGW, Fossil can crash
308 ** when exiting while a stubs-enabled Tcl is still loaded. This is due to
@@ -1917,10 +1930,41 @@
1917 }
1918 }
1919 }
1920 }
1921
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1922 /*
1923 ** undocumented format:
1924 **
1925 ** fossil http INFILE OUTFILE IPADDR ?REPOSITORY?
1926 **
@@ -1968,10 +2012,12 @@
1968 ** --notfound URL use URL as "HTTP 404, object not found" page.
1969 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
1970 ** --scgi Interpret input as SCGI rather than HTTP
1971 ** --skin LABEL Use override skin LABEL
1972 ** --th-trace trace TH1 execution (for debugging purposes)
 
 
1973 **
1974 ** See also: cgi, server, winsrv
1975 */
1976 void cmd_http(void){
1977 const char *zIpAddr = 0;
@@ -1980,10 +2026,13 @@
1980 const char *zAltBase;
1981 const char *zFileGlob;
1982 int useSCGI;
1983 int noJail;
1984 int allowRepoList;
 
 
 
1985
1986 Th_InitTraceLog();
1987
1988 /* The winhttp module passes the --files option as --files-urlenc with
1989 ** the argument being URL encoded, to avoid wildcard expansion in the
@@ -2010,10 +2059,21 @@
2010 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
2011 cgi_replace_parameter("HTTPS","on");
2012 }
2013 zHost = find_option("host", 0, 1);
2014 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
 
 
 
 
 
 
 
 
 
 
 
2015
2016 /* We should be done with options.. */
2017 verify_all_options();
2018
2019 if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
@@ -2171,11 +2231,12 @@
2171 ** -P|--port TCPPORT listen to request on port TCPPORT
2172 ** --th-trace trace TH1 execution (for debugging purposes)
2173 ** --repolist If REPOSITORY is dir, URL "/" lists repos.
2174 ** --scgi Accept SCGI rather than HTTP
2175 ** --skin LABEL Use override skin LABEL
2176
 
2177 **
2178 ** See also: cgi, http, winsrv
2179 */
2180 void cmd_webserver(void){
2181 int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2192,10 +2253,13 @@
2192 const char *zAltBase; /* Argument to the --baseurl option */
2193 const char *zFileGlob; /* Static content must match this */
2194 char *zIpAddr = 0; /* Bind to this IP address */
2195 int fCreate = 0; /* The --create flag */
2196 const char *zInitPage = 0; /* Start on this page. --page option */
 
 
 
2197
2198 #if defined(_WIN32)
2199 const char *zStopperFile; /* Name of file used to terminate server */
2200 zStopperFile = find_option("stopper", 0, 1);
2201 #endif
@@ -2235,10 +2299,21 @@
2235 g.sslNotAvailable = 1;
2236 }
2237 if( find_option("localhost", 0, 0)!=0 ){
2238 flags |= HTTP_SERVER_LOCALHOST;
2239 }
 
 
 
 
 
 
 
 
 
 
 
2240
2241 /* We should be done with options.. */
2242 verify_all_options();
2243
2244 if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
2245
--- src/main.c
+++ src/main.c
@@ -18,20 +18,21 @@
18 ** This module codes the main() procedure that runs first when the
19 ** program is invoked.
20 */
21 #include "VERSION.h"
22 #include "config.h"
23 #if defined(_WIN32)
24 # include <windows.h>
25 #endif
26 #include "main.h"
27 #include <string.h>
28 #include <time.h>
29 #include <fcntl.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <stdlib.h> /* atexit() */
33 #if !defined(_WIN32)
 
 
34 # include <errno.h> /* errno global */
35 #endif
36 #ifdef FOSSIL_ENABLE_SSL
37 # include "openssl/crypto.h"
38 #endif
@@ -299,10 +300,22 @@
300 /*
301 ** atexit() handler which frees up "some" of the resources
302 ** used by fossil.
303 */
304 static void fossil_atexit(void) {
305 #if USE_SEE
306 /*
307 ** Zero, unlock, and free the saved database encryption key now.
308 */
309 db_unsave_encryption_key();
310 #endif
311 #if defined(_WIN32) || defined(__BIONIC__)
312 /*
313 ** Free the secure getpass() buffer now.
314 */
315 freepass();
316 #endif
317 #if defined(_WIN32) && !defined(_WIN64) && defined(FOSSIL_ENABLE_TCL) && \
318 defined(USE_TCL_STUBS)
319 /*
320 ** If Tcl is compiled on Windows using the latest MinGW, Fossil can crash
321 ** when exiting while a stubs-enabled Tcl is still loaded. This is due to
@@ -1917,10 +1930,41 @@
1930 }
1931 }
1932 }
1933 }
1934
1935 #if defined(_WIN32) && USE_SEE
1936 /*
1937 ** This function attempts to parse a string value in the following
1938 ** format:
1939 **
1940 ** "%lu:%p:%u"
1941 **
1942 ** There are three parts, which must be delimited by colons. The
1943 ** first part is an unsigned long integer in base-10 (decimal) format.
1944 ** The second part is a numerical representation of a native pointer,
1945 ** in the appropriate implementation defined format. The third part
1946 ** is an unsigned integer in base-10 (decimal) format.
1947 **
1948 ** If the specified value cannot be parsed, for any reason, a fatal
1949 ** error will be raised and the process will be terminated.
1950 */
1951 void parse_pid_key_value(
1952 const char *zPidKey, /* The value to be parsed. */
1953 DWORD *pProcessId, /* The extracted process identifier. */
1954 LPVOID *ppAddress, /* The extracted pointer value. */
1955 SIZE_T *pnSize /* The extracted size value. */
1956 ){
1957 unsigned int nSize = 0;
1958 if( sscanf(zPidKey, "%lu:%p:%u", pProcessId, ppAddress, &nSize)==3 ){
1959 *pnSize = (SIZE_T)nSize;
1960 }else{
1961 fossil_fatal("failed to parse pid key");
1962 }
1963 }
1964 #endif
1965
1966 /*
1967 ** undocumented format:
1968 **
1969 ** fossil http INFILE OUTFILE IPADDR ?REPOSITORY?
1970 **
@@ -1968,10 +2012,12 @@
2012 ** --notfound URL use URL as "HTTP 404, object not found" page.
2013 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2014 ** --scgi Interpret input as SCGI rather than HTTP
2015 ** --skin LABEL Use override skin LABEL
2016 ** --th-trace trace TH1 execution (for debugging purposes)
2017 ** --usepidkey Use saved encryption key from parent process. This is
2018 ** only necessary when using SEE on Windows.
2019 **
2020 ** See also: cgi, server, winsrv
2021 */
2022 void cmd_http(void){
2023 const char *zIpAddr = 0;
@@ -1980,10 +2026,13 @@
2026 const char *zAltBase;
2027 const char *zFileGlob;
2028 int useSCGI;
2029 int noJail;
2030 int allowRepoList;
2031 #if defined(_WIN32) && USE_SEE
2032 const char *zPidKey;
2033 #endif
2034
2035 Th_InitTraceLog();
2036
2037 /* The winhttp module passes the --files option as --files-urlenc with
2038 ** the argument being URL encoded, to avoid wildcard expansion in the
@@ -2010,10 +2059,21 @@
2059 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
2060 cgi_replace_parameter("HTTPS","on");
2061 }
2062 zHost = find_option("host", 0, 1);
2063 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
2064
2065 #if defined(_WIN32) && USE_SEE
2066 zPidKey = find_option("usepidkey", 0, 1);
2067 if( zPidKey ){
2068 DWORD processId = 0;
2069 LPVOID pAddress = NULL;
2070 SIZE_T nSize = 0;
2071 parse_pid_key_value(zPidKey, &processId, &pAddress, &nSize);
2072 db_read_saved_encryption_key_from_process(processId, pAddress, nSize);
2073 }
2074 #endif
2075
2076 /* We should be done with options.. */
2077 verify_all_options();
2078
2079 if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
@@ -2171,11 +2231,12 @@
2231 ** -P|--port TCPPORT listen to request on port TCPPORT
2232 ** --th-trace trace TH1 execution (for debugging purposes)
2233 ** --repolist If REPOSITORY is dir, URL "/" lists repos.
2234 ** --scgi Accept SCGI rather than HTTP
2235 ** --skin LABEL Use override skin LABEL
2236 ** --usepidkey Use saved encryption key from parent process. This is
2237 ** only necessary when using SEE on Windows.
2238 **
2239 ** See also: cgi, http, winsrv
2240 */
2241 void cmd_webserver(void){
2242 int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2192,10 +2253,13 @@
2253 const char *zAltBase; /* Argument to the --baseurl option */
2254 const char *zFileGlob; /* Static content must match this */
2255 char *zIpAddr = 0; /* Bind to this IP address */
2256 int fCreate = 0; /* The --create flag */
2257 const char *zInitPage = 0; /* Start on this page. --page option */
2258 #if defined(_WIN32) && USE_SEE
2259 const char *zPidKey;
2260 #endif
2261
2262 #if defined(_WIN32)
2263 const char *zStopperFile; /* Name of file used to terminate server */
2264 zStopperFile = find_option("stopper", 0, 1);
2265 #endif
@@ -2235,10 +2299,21 @@
2299 g.sslNotAvailable = 1;
2300 }
2301 if( find_option("localhost", 0, 0)!=0 ){
2302 flags |= HTTP_SERVER_LOCALHOST;
2303 }
2304
2305 #if defined(_WIN32) && USE_SEE
2306 zPidKey = find_option("usepidkey", 0, 1);
2307 if( zPidKey ){
2308 DWORD processId = 0;
2309 LPVOID pAddress = NULL;
2310 SIZE_T nSize = 0;
2311 parse_pid_key_value(zPidKey, &processId, &pAddress, &nSize);
2312 db_read_saved_encryption_key_from_process(processId, pAddress, nSize);
2313 }
2314 #endif
2315
2316 /* We should be done with options.. */
2317 verify_all_options();
2318
2319 if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
2320
--- src/main.mk
+++ src/main.mk
@@ -498,10 +498,12 @@
498498
-DSQLITE_OMIT_DECLTYPE \
499499
-DSQLITE_OMIT_DEPRECATED \
500500
-DSQLITE_OMIT_PROGRESS_CALLBACK \
501501
-DSQLITE_OMIT_SHARED_CACHE \
502502
-DSQLITE_OMIT_LOAD_EXTENSION \
503
+ -DSQLITE_MAX_EXPR_DEPTH=0 \
504
+ -DSQLITE_USE_ALLOCA \
503505
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
504506
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
505507
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
506508
-DSQLITE_ENABLE_FTS4 \
507509
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
508510
--- src/main.mk
+++ src/main.mk
@@ -498,10 +498,12 @@
498 -DSQLITE_OMIT_DECLTYPE \
499 -DSQLITE_OMIT_DEPRECATED \
500 -DSQLITE_OMIT_PROGRESS_CALLBACK \
501 -DSQLITE_OMIT_SHARED_CACHE \
502 -DSQLITE_OMIT_LOAD_EXTENSION \
 
 
503 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
504 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
505 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
506 -DSQLITE_ENABLE_FTS4 \
507 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
508
--- src/main.mk
+++ src/main.mk
@@ -498,10 +498,12 @@
498 -DSQLITE_OMIT_DECLTYPE \
499 -DSQLITE_OMIT_DEPRECATED \
500 -DSQLITE_OMIT_PROGRESS_CALLBACK \
501 -DSQLITE_OMIT_SHARED_CACHE \
502 -DSQLITE_OMIT_LOAD_EXTENSION \
503 -DSQLITE_MAX_EXPR_DEPTH=0 \
504 -DSQLITE_USE_ALLOCA \
505 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
506 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
507 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
508 -DSQLITE_ENABLE_FTS4 \
509 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
510
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,10 +164,12 @@
164164
-DSQLITE_OMIT_DECLTYPE
165165
-DSQLITE_OMIT_DEPRECATED
166166
-DSQLITE_OMIT_PROGRESS_CALLBACK
167167
-DSQLITE_OMIT_SHARED_CACHE
168168
-DSQLITE_OMIT_LOAD_EXTENSION
169
+ -DSQLITE_MAX_EXPR_DEPTH=0
170
+ -DSQLITE_USE_ALLOCA
169171
-DSQLITE_ENABLE_LOCKING_STYLE=0
170172
-DSQLITE_DEFAULT_FILE_FORMAT=4
171173
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
172174
-DSQLITE_ENABLE_FTS4
173175
-DSQLITE_ENABLE_FTS3_PARENTHESIS
174176
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,10 +164,12 @@
164 -DSQLITE_OMIT_DECLTYPE
165 -DSQLITE_OMIT_DEPRECATED
166 -DSQLITE_OMIT_PROGRESS_CALLBACK
167 -DSQLITE_OMIT_SHARED_CACHE
168 -DSQLITE_OMIT_LOAD_EXTENSION
 
 
169 -DSQLITE_ENABLE_LOCKING_STYLE=0
170 -DSQLITE_DEFAULT_FILE_FORMAT=4
171 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
172 -DSQLITE_ENABLE_FTS4
173 -DSQLITE_ENABLE_FTS3_PARENTHESIS
174
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,10 +164,12 @@
164 -DSQLITE_OMIT_DECLTYPE
165 -DSQLITE_OMIT_DEPRECATED
166 -DSQLITE_OMIT_PROGRESS_CALLBACK
167 -DSQLITE_OMIT_SHARED_CACHE
168 -DSQLITE_OMIT_LOAD_EXTENSION
169 -DSQLITE_MAX_EXPR_DEPTH=0
170 -DSQLITE_USE_ALLOCA
171 -DSQLITE_ENABLE_LOCKING_STYLE=0
172 -DSQLITE_DEFAULT_FILE_FORMAT=4
173 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
174 -DSQLITE_ENABLE_FTS4
175 -DSQLITE_ENABLE_FTS3_PARENTHESIS
176
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,10 +164,12 @@
164164
-DSQLITE_OMIT_DECLTYPE
165165
-DSQLITE_OMIT_DEPRECATED
166166
-DSQLITE_OMIT_PROGRESS_CALLBACK
167167
-DSQLITE_OMIT_SHARED_CACHE
168168
-DSQLITE_OMIT_LOAD_EXTENSION
169
+ -DSQLITE_MAX_EXPR_DEPTH=0
170
+ -DSQLITE_USE_ALLOCA
169171
-DSQLITE_ENABLE_LOCKING_STYLE=0
170172
-DSQLITE_DEFAULT_FILE_FORMAT=4
171173
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
172174
-DSQLITE_ENABLE_FTS4
173175
-DSQLITE_ENABLE_FTS3_PARENTHESIS
174176
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,10 +164,12 @@
164 -DSQLITE_OMIT_DECLTYPE
165 -DSQLITE_OMIT_DEPRECATED
166 -DSQLITE_OMIT_PROGRESS_CALLBACK
167 -DSQLITE_OMIT_SHARED_CACHE
168 -DSQLITE_OMIT_LOAD_EXTENSION
 
 
169 -DSQLITE_ENABLE_LOCKING_STYLE=0
170 -DSQLITE_DEFAULT_FILE_FORMAT=4
171 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
172 -DSQLITE_ENABLE_FTS4
173 -DSQLITE_ENABLE_FTS3_PARENTHESIS
174
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,10 +164,12 @@
164 -DSQLITE_OMIT_DECLTYPE
165 -DSQLITE_OMIT_DEPRECATED
166 -DSQLITE_OMIT_PROGRESS_CALLBACK
167 -DSQLITE_OMIT_SHARED_CACHE
168 -DSQLITE_OMIT_LOAD_EXTENSION
169 -DSQLITE_MAX_EXPR_DEPTH=0
170 -DSQLITE_USE_ALLOCA
171 -DSQLITE_ENABLE_LOCKING_STYLE=0
172 -DSQLITE_DEFAULT_FILE_FORMAT=4
173 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
174 -DSQLITE_ENABLE_FTS4
175 -DSQLITE_ENABLE_FTS3_PARENTHESIS
176
+4 -4
--- src/merge3.c
+++ src/merge3.c
@@ -376,21 +376,21 @@
376376
377377
if( g.argc!=6 ){
378378
usage("PIVOT V1 V2 MERGED");
379379
}
380380
if( blob_read_from_file(&pivot, g.argv[2])<0 ){
381
- fossil_fatal("cannot read %s\n", g.argv[2]);
381
+ fossil_fatal("cannot read %s", g.argv[2]);
382382
}
383383
if( blob_read_from_file(&v1, g.argv[3])<0 ){
384
- fossil_fatal("cannot read %s\n", g.argv[3]);
384
+ fossil_fatal("cannot read %s", g.argv[3]);
385385
}
386386
if( blob_read_from_file(&v2, g.argv[4])<0 ){
387
- fossil_fatal("cannot read %s\n", g.argv[4]);
387
+ fossil_fatal("cannot read %s", g.argv[4]);
388388
}
389389
blob_merge(&pivot, &v1, &v2, &merged);
390390
if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
391
- fossil_fatal("cannot write %s\n", g.argv[4]);
391
+ fossil_fatal("cannot write %s", g.argv[4]);
392392
}
393393
blob_reset(&pivot);
394394
blob_reset(&v1);
395395
blob_reset(&v2);
396396
blob_reset(&merged);
397397
--- src/merge3.c
+++ src/merge3.c
@@ -376,21 +376,21 @@
376
377 if( g.argc!=6 ){
378 usage("PIVOT V1 V2 MERGED");
379 }
380 if( blob_read_from_file(&pivot, g.argv[2])<0 ){
381 fossil_fatal("cannot read %s\n", g.argv[2]);
382 }
383 if( blob_read_from_file(&v1, g.argv[3])<0 ){
384 fossil_fatal("cannot read %s\n", g.argv[3]);
385 }
386 if( blob_read_from_file(&v2, g.argv[4])<0 ){
387 fossil_fatal("cannot read %s\n", g.argv[4]);
388 }
389 blob_merge(&pivot, &v1, &v2, &merged);
390 if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
391 fossil_fatal("cannot write %s\n", g.argv[4]);
392 }
393 blob_reset(&pivot);
394 blob_reset(&v1);
395 blob_reset(&v2);
396 blob_reset(&merged);
397
--- src/merge3.c
+++ src/merge3.c
@@ -376,21 +376,21 @@
376
377 if( g.argc!=6 ){
378 usage("PIVOT V1 V2 MERGED");
379 }
380 if( blob_read_from_file(&pivot, g.argv[2])<0 ){
381 fossil_fatal("cannot read %s", g.argv[2]);
382 }
383 if( blob_read_from_file(&v1, g.argv[3])<0 ){
384 fossil_fatal("cannot read %s", g.argv[3]);
385 }
386 if( blob_read_from_file(&v2, g.argv[4])<0 ){
387 fossil_fatal("cannot read %s", g.argv[4]);
388 }
389 blob_merge(&pivot, &v1, &v2, &merged);
390 if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
391 fossil_fatal("cannot write %s", g.argv[4]);
392 }
393 blob_reset(&pivot);
394 blob_reset(&v1);
395 blob_reset(&v2);
396 blob_reset(&merged);
397
+1 -1
--- src/mkindex.c
+++ src/mkindex.c
@@ -223,11 +223,11 @@
223223
fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
224224
zFile, nLine, j, &zLine[i]);
225225
nErr++;
226226
}
227227
}
228
-
228
+
229229
nUsed++;
230230
}
231231
232232
/*
233233
** Check to see if the current line is an #if and if it is, add it to
234234
--- src/mkindex.c
+++ src/mkindex.c
@@ -223,11 +223,11 @@
223 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
224 zFile, nLine, j, &zLine[i]);
225 nErr++;
226 }
227 }
228
229 nUsed++;
230 }
231
232 /*
233 ** Check to see if the current line is an #if and if it is, add it to
234
--- src/mkindex.c
+++ src/mkindex.c
@@ -223,11 +223,11 @@
223 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
224 zFile, nLine, j, &zLine[i]);
225 nErr++;
226 }
227 }
228
229 nUsed++;
230 }
231
232 /*
233 ** Check to see if the current line is an #if and if it is, add it to
234
--- src/mkversion.c
+++ src/mkversion.c
@@ -64,10 +64,14 @@
6464
printf("#define RELEASE_VERSION_NUMBER %s\n", z);
6565
memset(vx,0,sizeof(vx));
6666
strcpy(vx,b);
6767
d = 0;
6868
for(z=vx; z[0]; z++){
69
+ if( z[0]=='-' ){
70
+ z[0] = 0;
71
+ break;
72
+ }
6973
if( z[0]!='.' ) continue;
7074
if ( d<3 ){
7175
z[0] = ',';
7276
d++;
7377
}else{
7478
--- src/mkversion.c
+++ src/mkversion.c
@@ -64,10 +64,14 @@
64 printf("#define RELEASE_VERSION_NUMBER %s\n", z);
65 memset(vx,0,sizeof(vx));
66 strcpy(vx,b);
67 d = 0;
68 for(z=vx; z[0]; z++){
 
 
 
 
69 if( z[0]!='.' ) continue;
70 if ( d<3 ){
71 z[0] = ',';
72 d++;
73 }else{
74
--- src/mkversion.c
+++ src/mkversion.c
@@ -64,10 +64,14 @@
64 printf("#define RELEASE_VERSION_NUMBER %s\n", z);
65 memset(vx,0,sizeof(vx));
66 strcpy(vx,b);
67 d = 0;
68 for(z=vx; z[0]; z++){
69 if( z[0]=='-' ){
70 z[0] = 0;
71 break;
72 }
73 if( z[0]!='.' ) continue;
74 if ( d<3 ){
75 z[0] = ',';
76 d++;
77 }else{
78
+1 -1
--- src/search.c
+++ src/search.c
@@ -407,11 +407,11 @@
407407
408408
/* search_match(TEXT, TEXT, ....)
409409
**
410410
** Using the full-scan search engine created by the most recent call
411411
** to search_init(), match the input the TEXT arguments.
412
-** Remember the results global full-scan search object.
412
+** Remember the results global full-scan search object.
413413
** Return non-zero on a match and zero on a miss.
414414
*/
415415
static void search_match_sqlfunc(
416416
sqlite3_context *context,
417417
int argc,
418418
--- src/search.c
+++ src/search.c
@@ -407,11 +407,11 @@
407
408 /* search_match(TEXT, TEXT, ....)
409 **
410 ** Using the full-scan search engine created by the most recent call
411 ** to search_init(), match the input the TEXT arguments.
412 ** Remember the results global full-scan search object.
413 ** Return non-zero on a match and zero on a miss.
414 */
415 static void search_match_sqlfunc(
416 sqlite3_context *context,
417 int argc,
418
--- src/search.c
+++ src/search.c
@@ -407,11 +407,11 @@
407
408 /* search_match(TEXT, TEXT, ....)
409 **
410 ** Using the full-scan search engine created by the most recent call
411 ** to search_init(), match the input the TEXT arguments.
412 ** Remember the results global full-scan search object.
413 ** Return non-zero on a match and zero on a miss.
414 */
415 static void search_match_sqlfunc(
416 sqlite3_context *context,
417 int argc,
418
+1 -1
--- src/setup.c
+++ src/setup.c
@@ -1537,11 +1537,11 @@
15371537
@ <p>Settings marked with (v) are 'versionable' and will be overridden
15381538
@ by the contents of files named <tt>.fossil-settings/PROPERTY</tt>
15391539
@ in the check-out root.
15401540
@ If such a file is present, the corresponding field above is not
15411541
@ editable.</p><hr /><p>
1542
- @ These settings work the same as the
1542
+ @ These settings work the same as the
15431543
@ <a href='%R/help?cmd=settings'>fossil set</a> command.
15441544
db_end_transaction(0);
15451545
style_footer();
15461546
}
15471547
15481548
--- src/setup.c
+++ src/setup.c
@@ -1537,11 +1537,11 @@
1537 @ <p>Settings marked with (v) are 'versionable' and will be overridden
1538 @ by the contents of files named <tt>.fossil-settings/PROPERTY</tt>
1539 @ in the check-out root.
1540 @ If such a file is present, the corresponding field above is not
1541 @ editable.</p><hr /><p>
1542 @ These settings work the same as the
1543 @ <a href='%R/help?cmd=settings'>fossil set</a> command.
1544 db_end_transaction(0);
1545 style_footer();
1546 }
1547
1548
--- src/setup.c
+++ src/setup.c
@@ -1537,11 +1537,11 @@
1537 @ <p>Settings marked with (v) are 'versionable' and will be overridden
1538 @ by the contents of files named <tt>.fossil-settings/PROPERTY</tt>
1539 @ in the check-out root.
1540 @ If such a file is present, the corresponding field above is not
1541 @ editable.</p><hr /><p>
1542 @ These settings work the same as the
1543 @ <a href='%R/help?cmd=settings'>fossil set</a> command.
1544 db_end_transaction(0);
1545 style_footer();
1546 }
1547
1548
+24 -16
--- src/shell.c
+++ src/shell.c
@@ -666,23 +666,25 @@
666666
#define MODE_Column 1 /* One record per line in neat columns */
667667
#define MODE_List 2 /* One record per line with a separator */
668668
#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
669669
#define MODE_Html 4 /* Generate an XHTML table */
670670
#define MODE_Insert 5 /* Generate SQL "insert" statements */
671
-#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
672
-#define MODE_Csv 7 /* Quote strings, numbers are plain */
673
-#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
674
-#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
675
-#define MODE_Pretty 10 /* Pretty-print schemas */
671
+#define MODE_Quote 6 /* Quote values as for SQL */
672
+#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
673
+#define MODE_Csv 8 /* Quote strings, numbers are plain */
674
+#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
675
+#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
676
+#define MODE_Pretty 11 /* Pretty-print schemas */
676677
677678
static const char *modeDescr[] = {
678679
"line",
679680
"column",
680681
"list",
681682
"semi",
682683
"html",
683684
"insert",
685
+ "quote",
684686
"tcl",
685687
"csv",
686688
"explain",
687689
"ascii",
688690
"prettyprint",
@@ -1196,23 +1198,26 @@
11961198
utf8_printf(p->out, "%s", p->rowSeparator);
11971199
}
11981200
setTextMode(p->out, 1);
11991201
break;
12001202
}
1203
+ case MODE_Quote:
12011204
case MODE_Insert: {
12021205
p->cnt++;
12031206
if( azArg==0 ) break;
1204
- utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1205
- if( p->showHeader ){
1206
- raw_printf(p->out,"(");
1207
- for(i=0; i<nArg; i++){
1208
- char *zSep = i>0 ? ",": "";
1209
- utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1210
- }
1211
- raw_printf(p->out,")");
1212
- }
1213
- raw_printf(p->out," VALUES(");
1207
+ if( p->cMode==MODE_Insert ){
1208
+ utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1209
+ if( p->showHeader ){
1210
+ raw_printf(p->out,"(");
1211
+ for(i=0; i<nArg; i++){
1212
+ char *zSep = i>0 ? ",": "";
1213
+ utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1214
+ }
1215
+ raw_printf(p->out,")");
1216
+ }
1217
+ raw_printf(p->out," VALUES(");
1218
+ }
12141219
for(i=0; i<nArg; i++){
12151220
char *zSep = i>0 ? ",": "";
12161221
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
12171222
utf8_printf(p->out,"%sNULL",zSep);
12181223
}else if( aiType && aiType[i]==SQLITE_TEXT ){
@@ -1231,11 +1236,11 @@
12311236
}else{
12321237
if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
12331238
output_quoted_string(p->out, azArg[i]);
12341239
}
12351240
}
1236
- raw_printf(p->out,");\n");
1241
+ raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
12371242
break;
12381243
}
12391244
case MODE_Ascii: {
12401245
if( p->cnt++==0 && p->showHeader ){
12411246
for(i=0; i<nArg; i++){
@@ -2175,10 +2180,11 @@
21752180
" column Left-aligned columns. (See .width)\n"
21762181
" html HTML <table> code\n"
21772182
" insert SQL insert statements for TABLE\n"
21782183
" line One value per line\n"
21792184
" list Values delimited by .separator strings\n"
2185
+ " quote Escape answers as for SQL\n"
21802186
" tabs Tab-separated values\n"
21812187
" tcl TCL list elements\n"
21822188
".nullvalue STRING Use STRING in place of NULL values\n"
21832189
".once FILENAME Output for the next SQL command only to FILENAME\n"
21842190
".open ?--new? ?FILE? Close existing database and reopen FILE\n"
@@ -3975,10 +3981,12 @@
39753981
p->mode = MODE_List;
39763982
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
39773983
}else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
39783984
p->mode = MODE_Insert;
39793985
set_table_name(p, nArg>=3 ? azArg[2] : "table");
3986
+ }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
3987
+ p->mode = MODE_Quote;
39803988
}else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
39813989
p->mode = MODE_Ascii;
39823990
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
39833991
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
39843992
}else {
39853993
--- src/shell.c
+++ src/shell.c
@@ -666,23 +666,25 @@
666 #define MODE_Column 1 /* One record per line in neat columns */
667 #define MODE_List 2 /* One record per line with a separator */
668 #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
669 #define MODE_Html 4 /* Generate an XHTML table */
670 #define MODE_Insert 5 /* Generate SQL "insert" statements */
671 #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
672 #define MODE_Csv 7 /* Quote strings, numbers are plain */
673 #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
674 #define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
675 #define MODE_Pretty 10 /* Pretty-print schemas */
 
676
677 static const char *modeDescr[] = {
678 "line",
679 "column",
680 "list",
681 "semi",
682 "html",
683 "insert",
 
684 "tcl",
685 "csv",
686 "explain",
687 "ascii",
688 "prettyprint",
@@ -1196,23 +1198,26 @@
1196 utf8_printf(p->out, "%s", p->rowSeparator);
1197 }
1198 setTextMode(p->out, 1);
1199 break;
1200 }
 
1201 case MODE_Insert: {
1202 p->cnt++;
1203 if( azArg==0 ) break;
1204 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1205 if( p->showHeader ){
1206 raw_printf(p->out,"(");
1207 for(i=0; i<nArg; i++){
1208 char *zSep = i>0 ? ",": "";
1209 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1210 }
1211 raw_printf(p->out,")");
1212 }
1213 raw_printf(p->out," VALUES(");
 
 
1214 for(i=0; i<nArg; i++){
1215 char *zSep = i>0 ? ",": "";
1216 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
1217 utf8_printf(p->out,"%sNULL",zSep);
1218 }else if( aiType && aiType[i]==SQLITE_TEXT ){
@@ -1231,11 +1236,11 @@
1231 }else{
1232 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
1233 output_quoted_string(p->out, azArg[i]);
1234 }
1235 }
1236 raw_printf(p->out,");\n");
1237 break;
1238 }
1239 case MODE_Ascii: {
1240 if( p->cnt++==0 && p->showHeader ){
1241 for(i=0; i<nArg; i++){
@@ -2175,10 +2180,11 @@
2175 " column Left-aligned columns. (See .width)\n"
2176 " html HTML <table> code\n"
2177 " insert SQL insert statements for TABLE\n"
2178 " line One value per line\n"
2179 " list Values delimited by .separator strings\n"
 
2180 " tabs Tab-separated values\n"
2181 " tcl TCL list elements\n"
2182 ".nullvalue STRING Use STRING in place of NULL values\n"
2183 ".once FILENAME Output for the next SQL command only to FILENAME\n"
2184 ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
@@ -3975,10 +3981,12 @@
3975 p->mode = MODE_List;
3976 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
3977 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
3978 p->mode = MODE_Insert;
3979 set_table_name(p, nArg>=3 ? azArg[2] : "table");
 
 
3980 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3981 p->mode = MODE_Ascii;
3982 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3983 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
3984 }else {
3985
--- src/shell.c
+++ src/shell.c
@@ -666,23 +666,25 @@
666 #define MODE_Column 1 /* One record per line in neat columns */
667 #define MODE_List 2 /* One record per line with a separator */
668 #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
669 #define MODE_Html 4 /* Generate an XHTML table */
670 #define MODE_Insert 5 /* Generate SQL "insert" statements */
671 #define MODE_Quote 6 /* Quote values as for SQL */
672 #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
673 #define MODE_Csv 8 /* Quote strings, numbers are plain */
674 #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
675 #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
676 #define MODE_Pretty 11 /* Pretty-print schemas */
677
678 static const char *modeDescr[] = {
679 "line",
680 "column",
681 "list",
682 "semi",
683 "html",
684 "insert",
685 "quote",
686 "tcl",
687 "csv",
688 "explain",
689 "ascii",
690 "prettyprint",
@@ -1196,23 +1198,26 @@
1198 utf8_printf(p->out, "%s", p->rowSeparator);
1199 }
1200 setTextMode(p->out, 1);
1201 break;
1202 }
1203 case MODE_Quote:
1204 case MODE_Insert: {
1205 p->cnt++;
1206 if( azArg==0 ) break;
1207 if( p->cMode==MODE_Insert ){
1208 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1209 if( p->showHeader ){
1210 raw_printf(p->out,"(");
1211 for(i=0; i<nArg; i++){
1212 char *zSep = i>0 ? ",": "";
1213 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1214 }
1215 raw_printf(p->out,")");
1216 }
1217 raw_printf(p->out," VALUES(");
1218 }
1219 for(i=0; i<nArg; i++){
1220 char *zSep = i>0 ? ",": "";
1221 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
1222 utf8_printf(p->out,"%sNULL",zSep);
1223 }else if( aiType && aiType[i]==SQLITE_TEXT ){
@@ -1231,11 +1236,11 @@
1236 }else{
1237 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
1238 output_quoted_string(p->out, azArg[i]);
1239 }
1240 }
1241 raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
1242 break;
1243 }
1244 case MODE_Ascii: {
1245 if( p->cnt++==0 && p->showHeader ){
1246 for(i=0; i<nArg; i++){
@@ -2175,10 +2180,11 @@
2180 " column Left-aligned columns. (See .width)\n"
2181 " html HTML <table> code\n"
2182 " insert SQL insert statements for TABLE\n"
2183 " line One value per line\n"
2184 " list Values delimited by .separator strings\n"
2185 " quote Escape answers as for SQL\n"
2186 " tabs Tab-separated values\n"
2187 " tcl TCL list elements\n"
2188 ".nullvalue STRING Use STRING in place of NULL values\n"
2189 ".once FILENAME Output for the next SQL command only to FILENAME\n"
2190 ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
@@ -3975,10 +3981,12 @@
3981 p->mode = MODE_List;
3982 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
3983 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
3984 p->mode = MODE_Insert;
3985 set_table_name(p, nArg>=3 ? azArg[2] : "table");
3986 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
3987 p->mode = MODE_Quote;
3988 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3989 p->mode = MODE_Ascii;
3990 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3991 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
3992 }else {
3993
+1277 -1181
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.15.0. By combining all the individual C code files into this
3
+** version 3.16.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -379,13 +379,13 @@
379379
**
380380
** See also: [sqlite3_libversion()],
381381
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
382382
** [sqlite_version()] and [sqlite_source_id()].
383383
*/
384
-#define SQLITE_VERSION "3.15.0"
385
-#define SQLITE_VERSION_NUMBER 3015000
386
-#define SQLITE_SOURCE_ID "2016-09-22 18:53:13 c3774c6a5fe48af91fda28e9e18c6ed9053ea992"
384
+#define SQLITE_VERSION "3.16.0"
385
+#define SQLITE_VERSION_NUMBER 3016000
386
+#define SQLITE_SOURCE_ID "2016-11-02 14:50:19 3028845329c9b7acdec2ec8b01d00d782347454c"
387387
388388
/*
389389
** CAPI3REF: Run-Time Library Version Numbers
390390
** KEYWORDS: sqlite3_version, sqlite3_sourceid
391391
**
@@ -1235,10 +1235,16 @@
12351235
** <li>[[SQLITE_FCNTL_HAS_MOVED]]
12361236
** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
12371237
** pointer to an integer and it writes a boolean into that integer depending
12381238
** on whether or not the file has been renamed, moved, or deleted since it
12391239
** was first opened.
1240
+**
1241
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
1242
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
1243
+** underlying native file handle associated with a file handle. This file
1244
+** control interprets its argument as a pointer to a native file handle and
1245
+** writes the resulting value there.
12401246
**
12411247
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
12421248
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
12431249
** opcode causes the xFileControl method to swap the file handle with the one
12441250
** pointed to by the pArg argument. This capability is used during testing
@@ -1286,10 +1292,12 @@
12861292
#define SQLITE_FCNTL_WAL_BLOCK 24
12871293
#define SQLITE_FCNTL_ZIPVFS 25
12881294
#define SQLITE_FCNTL_RBU 26
12891295
#define SQLITE_FCNTL_VFS_POINTER 27
12901296
#define SQLITE_FCNTL_JOURNAL_POINTER 28
1297
+#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
1298
+#define SQLITE_FCNTL_PDB 30
12911299
12921300
/* deprecated names */
12931301
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
12941302
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
12951303
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2238,18 +2246,31 @@
22382246
** does not make a copy of the new main schema name string, so the application
22392247
** must ensure that the argument passed into this DBCONFIG option is unchanged
22402248
** until after the database connection closes.
22412249
** </dd>
22422250
**
2251
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
2252
+** <dd> Usually, when a database in wal mode is closed or detached from a
2253
+** database handle, SQLite checks if this will mean that there are now no
2254
+** connections at all to the database. If so, it performs a checkpoint
2255
+** operation before closing the connection. This option may be used to
2256
+** override this behaviour. The first parameter passed to this operation
2257
+** is an integer - non-zero to disable checkpoints-on-close, or zero (the
2258
+** default) to enable them. The second parameter is a pointer to an integer
2259
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
2260
+** have been disabled - 0 if they are not disabled, 1 if they are.
2261
+** </dd>
2262
+**
22432263
** </dl>
22442264
*/
22452265
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
22462266
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
22472267
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
22482268
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
22492269
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
22502270
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
2271
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
22512272
22522273
22532274
/*
22542275
** CAPI3REF: Enable Or Disable Extended Result Codes
22552276
** METHOD: sqlite3
@@ -8915,11 +8936,11 @@
89158936
89168937
/*
89178938
** CAPI3REF: Set a table filter on a Session Object.
89188939
**
89198940
** The second argument (xFilter) is the "filter callback". For changes to rows
8920
-** in tables that are not attached to the Session oject, the filter is called
8941
+** in tables that are not attached to the Session object, the filter is called
89218942
** to determine whether changes to the table's rows should be tracked or not.
89228943
** If xFilter returns 0, changes is not tracked. Note that once a table is
89238944
** attached, xFilter will not be called again.
89248945
*/
89258946
void sqlite3session_table_filter(
@@ -9181,11 +9202,11 @@
91819202
** Assuming the changeset blob was created by one of the
91829203
** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
91839204
** [sqlite3changeset_invert()] functions, all changes within the changeset
91849205
** that apply to a single table are grouped together. This means that when
91859206
** an application iterates through a changeset using an iterator created by
9186
-** this function, all changes that relate to a single table are visted
9207
+** this function, all changes that relate to a single table are visited
91879208
** consecutively. There is no chance that the iterator will visit a change
91889209
** the applies to table X, then one for table Y, and then later on visit
91899210
** another change for table X.
91909211
*/
91919212
int sqlite3changeset_start(
@@ -9268,11 +9289,11 @@
92689289
** If successful, *pabPK is set to point to an array of nCol entries, where
92699290
** nCol is the number of columns in the table. Elements of *pabPK are set to
92709291
** 0x01 if the corresponding column is part of the tables primary key, or
92719292
** 0x00 if it is not.
92729293
**
9273
-** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
9294
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
92749295
** in the table.
92759296
**
92769297
** If this function is called when the iterator does not point to a valid
92779298
** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
92789299
** SQLITE_OK is returned and the output variables populated as described
@@ -9543,11 +9564,11 @@
95439564
** Rows within the changeset and changegroup are identified by the values in
95449565
** their PRIMARY KEY columns. A change in the changeset is considered to
95459566
** apply to the same row as a change already present in the changegroup if
95469567
** the two rows have the same primary key.
95479568
**
9548
-** Changes to rows that that do not already appear in the changegroup are
9569
+** Changes to rows that do not already appear in the changegroup are
95499570
** simply copied into it. Or, if both the new changeset and the changegroup
95509571
** contain changes that apply to a single row, the final contents of the
95519572
** changegroup depends on the type of each change, as follows:
95529573
**
95539574
** <table border=1 style="margin-left:8ex;margin-right:8ex">
@@ -11411,13 +11432,13 @@
1141111432
#define TK_GROUP 127
1141211433
#define TK_HAVING 128
1141311434
#define TK_LIMIT 129
1141411435
#define TK_WHERE 130
1141511436
#define TK_INTO 131
11416
-#define TK_INTEGER 132
11417
-#define TK_FLOAT 133
11418
-#define TK_BLOB 134
11437
+#define TK_FLOAT 132
11438
+#define TK_BLOB 133
11439
+#define TK_INTEGER 134
1141911440
#define TK_VARIABLE 135
1142011441
#define TK_CASE 136
1142111442
#define TK_WHEN 137
1142211443
#define TK_THEN 138
1142311444
#define TK_ELSE 139
@@ -12675,19 +12696,19 @@
1267512696
#define OP_SorterData 120 /* synopsis: r[P2]=data */
1267612697
#define OP_RowKey 121 /* synopsis: r[P2]=key */
1267712698
#define OP_RowData 122 /* synopsis: r[P2]=data */
1267812699
#define OP_Rowid 123 /* synopsis: r[P2]=rowid */
1267912700
#define OP_NullRow 124
12680
-#define OP_SorterInsert 125
12701
+#define OP_SorterInsert 125 /* synopsis: key=r[P2] */
1268112702
#define OP_IdxInsert 126 /* synopsis: key=r[P2] */
1268212703
#define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */
1268312704
#define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */
1268412705
#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */
1268512706
#define OP_Destroy 130
1268612707
#define OP_Clear 131
12687
-#define OP_ResetSorter 132
12688
-#define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
12708
+#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
12709
+#define OP_ResetSorter 133
1268912710
#define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */
1269012711
#define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */
1269112712
#define OP_ParseSchema 136
1269212713
#define OP_LoadAnalysis 137
1269312714
#define OP_DropTable 138
@@ -12741,11 +12762,11 @@
1274112762
/* 88 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
1274212763
/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
1274312764
/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
1274412765
/* 112 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
1274512766
/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
12746
-/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10,\
12767
+/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
1274712768
/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\
1274812769
/* 144 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\
1274912770
/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
1275012771
/* 160 */ 0x00, 0x00, 0x00,}
1275112772
@@ -13030,11 +13051,11 @@
1303013051
int,
1303113052
int,
1303213053
int,
1303313054
void(*)(DbPage*)
1303413055
);
13035
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
13056
+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*);
1303613057
SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
1303713058
1303813059
/* Functions used to configure a Pager object. */
1303913060
SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
1304013061
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
@@ -13081,19 +13102,22 @@
1308113102
SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
1308213103
SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
1308313104
SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
1308413105
1308513106
#ifndef SQLITE_OMIT_WAL
13086
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
13107
+SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
1308713108
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
1308813109
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
1308913110
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
13090
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
13111
+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
13112
+SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager);
1309113113
# ifdef SQLITE_ENABLE_SNAPSHOT
1309213114
SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
1309313115
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
1309413116
# endif
13117
+#else
13118
+# define sqlite3PagerUseWal(x) 0
1309513119
#endif
1309613120
1309713121
#ifdef SQLITE_ENABLE_ZIPVFS
1309813122
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
1309913123
#endif
@@ -14060,10 +14084,11 @@
1406014084
#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
1406114085
#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
1406214086
#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
1406314087
#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
1406414088
#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
14089
+#define SQLITE_NoCkptOnClose 0x80000000 /* No checkpoint on close()/DETACH */
1406514090
1406614091
1406714092
/*
1406814093
** Bits of the sqlite3.dbOptFlags field that are used by the
1406914094
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -14963,10 +14988,11 @@
1496314988
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
1496414989
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
1496514990
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
1496614991
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
1496714992
#define EP_Alias 0x400000 /* Is an alias for a result set column */
14993
+#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
1496814994
1496914995
/*
1497014996
** Combinations of two or more EP_* flags
1497114997
*/
1497214998
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
@@ -15514,39 +15540,27 @@
1551415540
u8 mayAbort; /* True if statement may throw an ABORT exception */
1551515541
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
1551615542
u8 okConstFactor; /* OK to factor out constants */
1551715543
u8 disableLookaside; /* Number of times lookaside has been disabled */
1551815544
u8 nColCache; /* Number of entries in aColCache[] */
15519
- int aTempReg[8]; /* Holding area for temporary registers */
1552015545
int nRangeReg; /* Size of the temporary register block */
1552115546
int iRangeReg; /* First register in temporary register block */
1552215547
int nErr; /* Number of errors seen */
1552315548
int nTab; /* Number of previously allocated VDBE cursors */
1552415549
int nMem; /* Number of memory cells used so far */
15525
- int nSet; /* Number of sets used so far */
1552615550
int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
1552715551
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
15528
- int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
1552915552
int ckBase; /* Base register of data during check constraints */
1553015553
int iSelfTab; /* Table of an index whose exprs are being coded */
1553115554
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
1553215555
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
1553315556
int nLabel; /* Number of labels used */
1553415557
int *aLabel; /* Space to hold the labels */
15535
- struct yColCache {
15536
- int iTable; /* Table cursor number */
15537
- i16 iColumn; /* Table column number */
15538
- u8 tempReg; /* iReg is a temp register that needs to be freed */
15539
- int iLevel; /* Nesting level */
15540
- int iReg; /* Reg with value of this column. 0 means none. */
15541
- int lru; /* Least recently used entry has the smallest value */
15542
- } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
1554315558
ExprList *pConstExpr;/* Constant expressions */
1554415559
Token constraintName;/* Name of the constraint currently being parsed */
1554515560
yDbMask writeMask; /* Start a write transaction on these databases */
1554615561
yDbMask cookieMask; /* Bitmask of schema verified databases */
15547
- int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
1554815562
int regRowid; /* Register holding rowid of CREATE TABLE entry */
1554915563
int regRoot; /* Register holding root page number for new objects */
1555015564
int nMaxArg; /* Max args passed to user function by sub-program */
1555115565
#if SELECTTRACE_ENABLED
1555215566
int nSelect; /* Number of SELECT statements seen */
@@ -15555,21 +15569,38 @@
1555515569
#ifndef SQLITE_OMIT_SHARED_CACHE
1555615570
int nTableLock; /* Number of locks in aTableLock */
1555715571
TableLock *aTableLock; /* Required table locks for shared-cache mode */
1555815572
#endif
1555915573
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
15560
-
15561
- /* Information used while coding trigger programs. */
1556215574
Parse *pToplevel; /* Parse structure for main program (or NULL) */
1556315575
Table *pTriggerTab; /* Table triggers are being coded for */
1556415576
int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
1556515577
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
1556615578
u32 oldmask; /* Mask of old.* columns referenced */
1556715579
u32 newmask; /* Mask of new.* columns referenced */
1556815580
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
1556915581
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
1557015582
u8 disableTriggers; /* True to disable triggers */
15583
+
15584
+ /**************************************************************************
15585
+ ** Fields above must be initialized to zero. The fields that follow,
15586
+ ** down to the beginning of the recursive section, do not need to be
15587
+ ** initialized as they will be set before being used. The boundary is
15588
+ ** determined by offsetof(Parse,aColCache).
15589
+ **************************************************************************/
15590
+
15591
+ struct yColCache {
15592
+ int iTable; /* Table cursor number */
15593
+ i16 iColumn; /* Table column number */
15594
+ u8 tempReg; /* iReg is a temp register that needs to be freed */
15595
+ int iLevel; /* Nesting level */
15596
+ int iReg; /* Reg with value of this column. 0 means none. */
15597
+ int lru; /* Least recently used entry has the smallest value */
15598
+ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
15599
+ int aTempReg[8]; /* Holding area for temporary registers */
15600
+ Token sNameToken; /* Token with unqualified schema object name */
15601
+ Token sLastToken; /* The last token parsed */
1557115602
1557215603
/************************************************************************
1557315604
** Above is constant between recursions. Below is reset before and after
1557415605
** each recursion. The boundary between these two regions is determined
1557515606
** using offsetof(Parse,nVar) so the nVar field must be the first field
@@ -15582,11 +15613,10 @@
1558215613
u8 explain; /* True if the EXPLAIN flag is found on the query */
1558315614
#ifndef SQLITE_OMIT_VIRTUALTABLE
1558415615
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
1558515616
int nVtabLock; /* Number of virtual tables to lock */
1558615617
#endif
15587
- int nAlias; /* Number of aliased result set columns */
1558815618
int nHeight; /* Expression tree height of current sub-select */
1558915619
#ifndef SQLITE_OMIT_EXPLAIN
1559015620
int iSelectId; /* ID of current select for EXPLAIN output */
1559115621
int iNextSelectId; /* Next available select ID for EXPLAIN output */
1559215622
#endif
@@ -15594,12 +15624,10 @@
1559415624
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
1559515625
const char *zTail; /* All SQL text past the last semicolon parsed */
1559615626
Table *pNewTable; /* A table being constructed by CREATE TABLE */
1559715627
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
1559815628
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
15599
- Token sNameToken; /* Token with unqualified schema object name */
15600
- Token sLastToken; /* The last token parsed */
1560115629
#ifndef SQLITE_OMIT_VIRTUALTABLE
1560215630
Token sArg; /* Complete text of a module argument */
1560315631
Table **apVtabLock; /* Pointer to virtual tables needing locking */
1560415632
#endif
1560515633
Table *pZombieTab; /* List of Table objects to delete after code gen */
@@ -15606,10 +15634,18 @@
1560615634
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
1560715635
With *pWith; /* Current WITH clause, or NULL */
1560815636
With *pWithToFree; /* Free this WITH object at the end of the parse */
1560915637
};
1561015638
15639
+/*
15640
+** Sizes and pointers of various parts of the Parse object.
15641
+*/
15642
+#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
15643
+#define PARSE_RECURSE_SZ offsetof(Parse,nVar) /* Recursive part */
15644
+#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
15645
+#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
15646
+
1561115647
/*
1561215648
** Return true if currently inside an sqlite3_declare_vtab() call.
1561315649
*/
1561415650
#ifdef SQLITE_OMIT_VIRTUALTABLE
1561515651
#define IN_DECLARE_VTAB 0
@@ -16169,11 +16205,11 @@
1616916205
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
1617016206
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
1617116207
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
1617216208
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
1617316209
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
16174
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
16210
+SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
1617516211
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
1617616212
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
1617716213
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
1617816214
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
1617916215
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
@@ -16989,20 +17025,17 @@
1698917025
** If x is a lower-case ASCII character, then its upper-case equivalent
1699017026
** is (x - 0x20). Therefore toupper() can be implemented as:
1699117027
**
1699217028
** (x & ~(map[x]&0x20))
1699317029
**
16994
-** Standard function tolower() is implemented using the sqlite3UpperToLower[]
17030
+** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
1699517031
** array. tolower() is used more often than toupper() by SQLite.
1699617032
**
16997
-** Bit 0x40 is set if the character non-alphanumeric and can be used in an
17033
+** Bit 0x40 is set if the character is non-alphanumeric and can be used in an
1699817034
** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
1699917035
** non-ASCII UTF character. Hence the test for whether or not a character is
1700017036
** part of an identifier is 0x46.
17001
-**
17002
-** SQLite's versions are identical to the standard versions assuming a
17003
-** locale of "C". They are implemented as macros in sqliteInt.h.
1700417037
*/
1700517038
#ifdef SQLITE_ASCII
1700617039
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
1700717040
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
1700817041
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
@@ -17071,11 +17104,11 @@
1707117104
#ifndef SQLITE_SORTER_PMASZ
1707217105
# define SQLITE_SORTER_PMASZ 250
1707317106
#endif
1707417107
1707517108
/* Statement journals spill to disk when their size exceeds the following
17076
-** threashold (in bytes). 0 means that statement journals are created and
17109
+** threshold (in bytes). 0 means that statement journals are created and
1707717110
** written to disk immediately (the default behavior for SQLite versions
1707817111
** before 3.12.0). -1 means always keep the entire statement journal in
1707917112
** memory. (The statement journal is also always held entirely in memory
1708017113
** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
1708117114
** setting.)
@@ -17159,11 +17192,11 @@
1715917192
1716017193
/*
1716117194
** The value of the "pending" byte must be 0x40000000 (1 byte past the
1716217195
** 1-gibabyte boundary) in a compatible database. SQLite never uses
1716317196
** the database page that contains the pending byte. It never attempts
17164
-** to read or write that page. The pending byte page is set assign
17197
+** to read or write that page. The pending byte page is set aside
1716517198
** for use by the VFS layers as space for managing file locks.
1716617199
**
1716717200
** During testing, it is often desirable to move the pending byte to
1716817201
** a different position in the file. This allows code that has to
1716917202
** deal with the pending byte to run on files that are much smaller
@@ -17260,10 +17293,13 @@
1726017293
#if SQLITE_DEFAULT_LOCKING_MODE
1726117294
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
1726217295
#endif
1726317296
#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
1726417297
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
17298
+#endif
17299
+#if SQLITE_DIRECT_OVERFLOW_READ
17300
+ "DIRECT_OVERFLOW_READ",
1726517301
#endif
1726617302
#if SQLITE_DISABLE_DIRSYNC
1726717303
"DISABLE_DIRSYNC",
1726817304
#endif
1726917305
#if SQLITE_DISABLE_LFS
@@ -17346,10 +17382,13 @@
1734617382
#if SQLITE_ENABLE_UNLOCK_NOTIFY
1734717383
"ENABLE_UNLOCK_NOTIFY",
1734817384
#endif
1734917385
#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
1735017386
"ENABLE_UPDATE_DELETE_LIMIT",
17387
+#endif
17388
+#if defined(SQLITE_ENABLE_URI_00_ERROR)
17389
+ "ENABLE_URI_00_ERROR",
1735117390
#endif
1735217391
#if SQLITE_HAS_CODEC
1735317392
"HAS_CODEC",
1735417393
#endif
1735517394
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
@@ -17719,13 +17758,10 @@
1771917758
typedef unsigned Bool;
1772017759
1772117760
/* Opaque type used by code in vdbesort.c */
1772217761
typedef struct VdbeSorter VdbeSorter;
1772317762
17724
-/* Opaque type used by the explainer */
17725
-typedef struct Explain Explain;
17726
-
1772717763
/* Elements of the linked list at Vdbe.pAuxData */
1772817764
typedef struct AuxData AuxData;
1772917765
1773017766
/* Types of VDBE cursors */
1773117767
#define CURTYPE_BTREE 0
@@ -17796,10 +17832,16 @@
1779617832
/* 2*nField extra array elements allocated for aType[], beyond the one
1779717833
** static element declared in the structure. nField total array slots for
1779817834
** aType[] and nField+1 array slots for aOffset[] */
1779917835
};
1780017836
17837
+
17838
+/*
17839
+** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
17840
+*/
17841
+#define CACHE_STALE 0
17842
+
1780117843
/*
1780217844
** When a sub-program is executed (OP_Program), a structure of this type
1780317845
** is allocated to store the current value of the program counter, as
1780417846
** well as the current memory cell array and various other frame specific
1780517847
** values stored in the Vdbe struct. When the sub-program is finished,
@@ -17840,15 +17882,10 @@
1784017882
int nDbChange; /* Value of db->nChange */
1784117883
};
1784217884
1784317885
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
1784417886
17845
-/*
17846
-** A value for VdbeCursor.cacheValid that means the cache is always invalid.
17847
-*/
17848
-#define CACHE_STALE 0
17849
-
1785017887
/*
1785117888
** Internally, the vdbe manipulates nearly all SQL values as Mem
1785217889
** structures. Each Mem struct may cache multiple representations (string,
1785317890
** integer etc.) of the same value.
1785417891
*/
@@ -17985,22 +18022,10 @@
1798518022
u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
1798618023
u8 argc; /* Number of arguments */
1798718024
sqlite3_value *argv[1]; /* Argument set */
1798818025
};
1798918026
17990
-/*
17991
-** An Explain object accumulates indented output which is helpful
17992
-** in describing recursive data structures.
17993
-*/
17994
-struct Explain {
17995
- Vdbe *pVdbe; /* Attach the explanation to this Vdbe */
17996
- StrAccum str; /* The string being accumulated */
17997
- int nIndent; /* Number of elements in aIndent */
17998
- u16 aIndent[100]; /* Levels of indentation */
17999
- char zBase[100]; /* Initial space */
18000
-};
18001
-
1800218027
/* A bitfield type for use inside of structures. Always follow with :N where
1800318028
** N is the number of bits.
1800418029
*/
1800518030
typedef unsigned bft; /* Bit Field Type */
1800618031
@@ -18021,57 +18046,61 @@
1802118046
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
1802218047
** is really a pointer to an instance of this structure.
1802318048
*/
1802418049
struct Vdbe {
1802518050
sqlite3 *db; /* The database connection that owns this statement */
18051
+ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
18052
+ Parse *pParse; /* Parsing context used to create this Vdbe */
18053
+ ynVar nVar; /* Number of entries in aVar[] */
18054
+ ynVar nzVar; /* Number of entries in azVar[] */
18055
+ u32 magic; /* Magic number for sanity checking */
18056
+ int nMem; /* Number of memory locations currently allocated */
18057
+ int nCursor; /* Number of slots in apCsr[] */
18058
+ u32 cacheCtr; /* VdbeCursor row cache generation counter */
18059
+ int pc; /* The program counter */
18060
+ int rc; /* Value to return */
18061
+ int nChange; /* Number of db changes made since last reset */
18062
+ int iStatement; /* Statement number (or 0 if has not opened stmt) */
18063
+ i64 iCurrentTime; /* Value of julianday('now') for this statement */
18064
+ i64 nFkConstraint; /* Number of imm. FK constraints this VM */
18065
+ i64 nStmtDefCons; /* Number of def. constraints when stmt started */
18066
+ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
18067
+
18068
+ /* When allocating a new Vdbe object, all of the fields below should be
18069
+ ** initialized to zero or NULL */
18070
+
1802618071
Op *aOp; /* Space to hold the virtual machine's program */
1802718072
Mem *aMem; /* The memory locations */
1802818073
Mem **apArg; /* Arguments to currently executing user function */
1802918074
Mem *aColName; /* Column names to return */
1803018075
Mem *pResultSet; /* Pointer to an array of results */
18031
- Parse *pParse; /* Parsing context used to create this Vdbe */
18032
- int nMem; /* Number of memory locations currently allocated */
18033
- int nOp; /* Number of instructions in the program */
18034
- int nCursor; /* Number of slots in apCsr[] */
18035
- u32 magic; /* Magic number for sanity checking */
1803618076
char *zErrMsg; /* Error message written here */
18037
- Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
1803818077
VdbeCursor **apCsr; /* One element of this array for each open cursor */
1803918078
Mem *aVar; /* Values for the OP_Variable opcode. */
1804018079
char **azVar; /* Name of variables */
18041
- ynVar nVar; /* Number of entries in aVar[] */
18042
- ynVar nzVar; /* Number of entries in azVar[] */
18043
- u32 cacheCtr; /* VdbeCursor row cache generation counter */
18044
- int pc; /* The program counter */
18045
- int rc; /* Value to return */
18080
+#ifndef SQLITE_OMIT_TRACE
18081
+ i64 startTime; /* Time when query started - used for profiling */
18082
+#endif
18083
+ int nOp; /* Number of instructions in the program */
1804618084
#ifdef SQLITE_DEBUG
1804718085
int rcApp; /* errcode set by sqlite3_result_error_code() */
1804818086
#endif
1804918087
u16 nResColumn; /* Number of columns in one row of the result set */
1805018088
u8 errorAction; /* Recovery action to do in case of an error */
18089
+ u8 minWriteFileFormat; /* Minimum file format for writable database files */
1805118090
bft expired:1; /* True if the VM needs to be recompiled */
1805218091
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
18053
- u8 minWriteFileFormat; /* Minimum file format for writable database files */
1805418092
bft explain:2; /* True if EXPLAIN present on SQL command */
1805518093
bft changeCntOn:1; /* True to update the change-counter */
1805618094
bft runOnlyOnce:1; /* Automatically expire on reset */
1805718095
bft usesStmtJournal:1; /* True if uses a statement journal */
1805818096
bft readOnly:1; /* True for statements that do not write */
1805918097
bft bIsReader:1; /* True for statements that read */
1806018098
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
18061
- int nChange; /* Number of db changes made since last reset */
1806218099
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
1806318100
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
18064
- int iStatement; /* Statement number (or 0 if has not opened stmt) */
1806518101
u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
18066
-#ifndef SQLITE_OMIT_TRACE
18067
- i64 startTime; /* Time when query started - used for profiling */
18068
-#endif
18069
- i64 iCurrentTime; /* Value of julianday('now') for this statement */
18070
- i64 nFkConstraint; /* Number of imm. FK constraints this VM */
18071
- i64 nStmtDefCons; /* Number of def. constraints when stmt started */
18072
- i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
1807318102
char *zSql; /* Text of the SQL statement that generated this */
1807418103
void *pFree; /* Free this when deleting the vdbe */
1807518104
VdbeFrame *pFrame; /* Parent frame */
1807618105
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
1807718106
int nFrame; /* Number of frames in pFrame list */
@@ -18086,14 +18115,15 @@
1808618115
};
1808718116
1808818117
/*
1808918118
** The following are allowed values for Vdbe.magic
1809018119
*/
18091
-#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
18092
-#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
18093
-#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
18094
-#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
18120
+#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
18121
+#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
18122
+#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
18123
+#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
18124
+#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
1809518125
1809618126
/*
1809718127
** Structure used to store the context required by the
1809818128
** sqlite3_preupdate_*() API functions.
1809918129
*/
@@ -18106,12 +18136,12 @@
1810618136
UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
1810718137
UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
1810818138
int iNewReg; /* Register for new.* values */
1810918139
i64 iKey1; /* First key value passed to hook */
1811018140
i64 iKey2; /* Second key value passed to hook */
18111
- int iPKey; /* If not negative index of IPK column */
1811218141
Mem *aNew; /* Array of new.* values */
18142
+ Table *pTab; /* Schema object being upated */
1811318143
};
1811418144
1811518145
/*
1811618146
** Function prototypes
1811718147
*/
@@ -24599,13 +24629,12 @@
2459924629
char *zNew;
2460024630
size_t n;
2460124631
if( z==0 ){
2460224632
return 0;
2460324633
}
24604
- n = sqlite3Strlen30(z) + 1;
24605
- assert( (n&0x7fffffff)==n );
24606
- zNew = sqlite3DbMallocRaw(db, (int)n);
24634
+ n = strlen(z) + 1;
24635
+ zNew = sqlite3DbMallocRaw(db, n);
2460724636
if( zNew ){
2460824637
memcpy(zNew, z, n);
2460924638
}
2461024639
return zNew;
2461124640
}
@@ -28775,11 +28804,15 @@
2877528804
*/
2877628805
static unsigned int strHash(const char *z){
2877728806
unsigned int h = 0;
2877828807
unsigned char c;
2877928808
while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
28780
- h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
28809
+ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
28810
+ ** 0x9e3779b1 is 2654435761 which is the closest prime number to
28811
+ ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
28812
+ h += sqlite3UpperToLower[c];
28813
+ h *= 0x9e3779b1;
2878128814
}
2878228815
return h;
2878328816
}
2878428817
2878528818
@@ -29124,19 +29157,19 @@
2912429157
/* 120 */ "SorterData" OpHelp("r[P2]=data"),
2912529158
/* 121 */ "RowKey" OpHelp("r[P2]=key"),
2912629159
/* 122 */ "RowData" OpHelp("r[P2]=data"),
2912729160
/* 123 */ "Rowid" OpHelp("r[P2]=rowid"),
2912829161
/* 124 */ "NullRow" OpHelp(""),
29129
- /* 125 */ "SorterInsert" OpHelp(""),
29162
+ /* 125 */ "SorterInsert" OpHelp("key=r[P2]"),
2913029163
/* 126 */ "IdxInsert" OpHelp("key=r[P2]"),
2913129164
/* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
2913229165
/* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"),
2913329166
/* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"),
2913429167
/* 130 */ "Destroy" OpHelp(""),
2913529168
/* 131 */ "Clear" OpHelp(""),
29136
- /* 132 */ "ResetSorter" OpHelp(""),
29137
- /* 133 */ "Real" OpHelp("r[P2]=P4"),
29169
+ /* 132 */ "Real" OpHelp("r[P2]=P4"),
29170
+ /* 133 */ "ResetSorter" OpHelp(""),
2913829171
/* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
2913929172
/* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
2914029173
/* 136 */ "ParseSchema" OpHelp(""),
2914129174
/* 137 */ "LoadAnalysis" OpHelp(""),
2914229175
/* 138 */ "DropTable" OpHelp(""),
@@ -40671,10 +40704,16 @@
4067140704
a[1] = winIoerrRetryDelay;
4067240705
}
4067340706
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
4067440707
return SQLITE_OK;
4067540708
}
40709
+ case SQLITE_FCNTL_WIN32_GET_HANDLE: {
40710
+ LPHANDLE phFile = (LPHANDLE)pArg;
40711
+ *phFile = pFile->h;
40712
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
40713
+ return SQLITE_OK;
40714
+ }
4067640715
#ifdef SQLITE_TEST
4067740716
case SQLITE_FCNTL_WIN32_SET_HANDLE: {
4067840717
LPHANDLE phFile = (LPHANDLE)pArg;
4067940718
HANDLE hOldFile = pFile->h;
4068040719
pFile->h = *phFile;
@@ -44018,11 +44057,11 @@
4401844057
){
4401944058
PgHdr *pPgHdr;
4402044059
assert( pPage!=0 );
4402144060
pPgHdr = (PgHdr*)pPage->pExtra;
4402244061
assert( pPgHdr->pPage==0 );
44023
- memset(pPgHdr, 0, sizeof(PgHdr));
44062
+ memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
4402444063
pPgHdr->pPage = pPage;
4402544064
pPgHdr->pData = pPage->pBuf;
4402644065
pPgHdr->pExtra = (void *)&pPgHdr[1];
4402744066
memset(pPgHdr->pExtra, 0, pCache->szExtra);
4402844067
pPgHdr->pCache = pCache;
@@ -44712,11 +44751,11 @@
4471244751
szBulk = pCache->szAlloc * (i64)pcache1.nInitPage;
4471344752
}else{
4471444753
szBulk = -1024 * (i64)pcache1.nInitPage;
4471544754
}
4471644755
if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
44717
- szBulk = pCache->szAlloc*pCache->nMax;
44756
+ szBulk = pCache->szAlloc*(i64)pCache->nMax;
4471844757
}
4471944758
zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
4472044759
sqlite3EndBenignMalloc();
4472144760
if( zBulk ){
4472244761
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
@@ -46246,21 +46285,21 @@
4624646285
#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */
4624746286
4624846287
#ifdef SQLITE_OMIT_WAL
4624946288
# define sqlite3WalOpen(x,y,z) 0
4625046289
# define sqlite3WalLimit(x,y)
46251
-# define sqlite3WalClose(w,x,y,z) 0
46290
+# define sqlite3WalClose(v,w,x,y,z) 0
4625246291
# define sqlite3WalBeginReadTransaction(y,z) 0
4625346292
# define sqlite3WalEndReadTransaction(z)
4625446293
# define sqlite3WalDbsize(y) 0
4625546294
# define sqlite3WalBeginWriteTransaction(y) 0
4625646295
# define sqlite3WalEndWriteTransaction(x) 0
4625746296
# define sqlite3WalUndo(x,y,z) 0
4625846297
# define sqlite3WalSavepoint(y,z)
4625946298
# define sqlite3WalSavepointUndo(y,z) 0
4626046299
# define sqlite3WalFrames(u,v,w,x,y,z) 0
46261
-# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
46300
+# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
4626246301
# define sqlite3WalCallback(z) 0
4626346302
# define sqlite3WalExclusiveMode(y,z) 0
4626446303
# define sqlite3WalHeapMemory(z) 0
4626546304
# define sqlite3WalFramesize(z) 0
4626646305
# define sqlite3WalFindFrame(x,y,z) 0
@@ -46274,11 +46313,11 @@
4627446313
*/
4627546314
typedef struct Wal Wal;
4627646315
4627746316
/* Open and close a connection to a write-ahead log. */
4627846317
SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
46279
-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
46318
+SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
4628046319
4628146320
/* Set the limiting size of a WAL file. */
4628246321
SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
4628346322
4628446323
/* Used by readers to open (lock) and close (unlock) a snapshot. A
@@ -46317,10 +46356,11 @@
4631746356
SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
4631846357
4631946358
/* Copy pages from the log to the database file */
4632046359
SQLITE_PRIVATE int sqlite3WalCheckpoint(
4632146360
Wal *pWal, /* Write-ahead log connection */
46361
+ sqlite3 *db, /* Check this handle's interrupt flag */
4632246362
int eMode, /* One of PASSIVE, FULL and RESTART */
4632346363
int (*xBusy)(void*), /* Function to call when busy */
4632446364
void *pBusyArg, /* Context argument for xBusyHandler */
4632546365
int sync_flags, /* Flags to sync db file with (or 0) */
4632646366
int nBuf, /* Size of buffer nBuf */
@@ -47161,13 +47201,14 @@
4716147201
/*
4716247202
** Return true if this pager uses a write-ahead log instead of the usual
4716347203
** rollback journal. Otherwise false.
4716447204
*/
4716547205
#ifndef SQLITE_OMIT_WAL
47166
-static int pagerUseWal(Pager *pPager){
47206
+SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager){
4716747207
return (pPager->pWal!=0);
4716847208
}
47209
+# define pagerUseWal(x) sqlite3PagerUseWal(x)
4716947210
#else
4717047211
# define pagerUseWal(x) 0
4717147212
# define pagerRollbackWal(x) 0
4717247213
# define pagerWalFrames(v,w,x,y) 0
4717347214
# define pagerOpenWalIfPresent(z) SQLITE_OK
@@ -50365,21 +50406,22 @@
5036550406
** This function always succeeds. If a transaction is active an attempt
5036650407
** is made to roll it back. If an error occurs during the rollback
5036750408
** a hot journal may be left in the filesystem but no error is returned
5036850409
** to the caller.
5036950410
*/
50370
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
50411
+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
5037150412
u8 *pTmp = (u8 *)pPager->pTmpSpace;
5037250413
50414
+ assert( db || pagerUseWal(pPager)==0 );
5037350415
assert( assert_pager_state(pPager) );
5037450416
disable_simulated_io_errors();
5037550417
sqlite3BeginBenignMalloc();
5037650418
pagerFreeMapHdrs(pPager);
5037750419
/* pPager->errCode = 0; */
5037850420
pPager->exclusiveMode = 0;
5037950421
#ifndef SQLITE_OMIT_WAL
50380
- sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
50422
+ sqlite3WalClose(pPager->pWal,db,pPager->ckptSyncFlags,pPager->pageSize,pTmp);
5038150423
pPager->pWal = 0;
5038250424
#endif
5038350425
pager_reset(pPager);
5038450426
if( MEMDB ){
5038550427
pager_unlock(pPager);
@@ -53538,14 +53580,20 @@
5353853580
** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
5353953581
** or wal_blocking_checkpoint() API functions.
5354053582
**
5354153583
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
5354253584
*/
53543
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
53585
+SQLITE_PRIVATE int sqlite3PagerCheckpoint(
53586
+ Pager *pPager, /* Checkpoint on this pager */
53587
+ sqlite3 *db, /* Db handle used to check for interrupts */
53588
+ int eMode, /* Type of checkpoint */
53589
+ int *pnLog, /* OUT: Final number of frames in log */
53590
+ int *pnCkpt /* OUT: Final number of checkpointed frames */
53591
+){
5354453592
int rc = SQLITE_OK;
5354553593
if( pPager->pWal ){
53546
- rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
53594
+ rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
5354753595
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
5354853596
pPager->pBusyHandlerArg,
5354953597
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
5355053598
pnLog, pnCkpt
5355153599
);
@@ -53673,11 +53721,11 @@
5367353721
** Before closing the log file, this function attempts to take an
5367453722
** EXCLUSIVE lock on the database file. If this cannot be obtained, an
5367553723
** error (SQLITE_BUSY) is returned and the log connection is not closed.
5367653724
** If successful, the EXCLUSIVE lock is not released before returning.
5367753725
*/
53678
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
53726
+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
5367953727
int rc = SQLITE_OK;
5368053728
5368153729
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
5368253730
5368353731
/* If the log file is not already open, but does exist in the file-system,
@@ -53701,11 +53749,11 @@
5370153749
** the database file, the log and log-summary files will be deleted.
5370253750
*/
5370353751
if( rc==SQLITE_OK && pPager->pWal ){
5370453752
rc = pagerExclusiveLock(pPager);
5370553753
if( rc==SQLITE_OK ){
53706
- rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
53754
+ rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
5370753755
pPager->pageSize, (u8*)pPager->pTmpSpace);
5370853756
pPager->pWal = 0;
5370953757
pagerFixMaplimit(pPager);
5371053758
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
5371153759
}
@@ -55484,10 +55532,11 @@
5548455532
** checkpoint is running (in any other thread or process) at the same
5548555533
** time.
5548655534
*/
5548755535
static int walCheckpoint(
5548855536
Wal *pWal, /* Wal connection */
55537
+ sqlite3 *db, /* Check for interrupts on this handle */
5548955538
int eMode, /* One of PASSIVE, FULL or RESTART */
5549055539
int (*xBusy)(void*), /* Function to call when busy */
5549155540
void *pBusyArg, /* Context argument for xBusyHandler */
5549255541
int sync_flags, /* Flags for OsSync() (or 0) */
5549355542
u8 *zBuf /* Temporary buffer to use */
@@ -55578,10 +55627,14 @@
5557855627
5557955628
/* Iterate through the contents of the WAL, copying data to the db file */
5558055629
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
5558155630
i64 iOffset;
5558255631
assert( walFramePgno(pWal, iFrame)==iDbpage );
55632
+ if( db->u1.isInterrupted ){
55633
+ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
55634
+ break;
55635
+ }
5558355636
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
5558455637
continue;
5558555638
}
5558655639
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
5558755640
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
@@ -55682,10 +55735,11 @@
5568255735
/*
5568355736
** Close a connection to a log file.
5568455737
*/
5568555738
SQLITE_PRIVATE int sqlite3WalClose(
5568655739
Wal *pWal, /* Wal to close */
55740
+ sqlite3 *db, /* For interrupt flag */
5568755741
int sync_flags, /* Flags to pass to OsSync() (or 0) */
5568855742
int nBuf,
5568955743
u8 *zBuf /* Buffer of at least nBuf bytes */
5569055744
){
5569155745
int rc = SQLITE_OK;
@@ -55698,17 +55752,18 @@
5569855752
** the database. In this case checkpoint the database and unlink both
5569955753
** the wal and wal-index files.
5570055754
**
5570155755
** The EXCLUSIVE lock is not released before returning.
5570255756
*/
55703
- rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
55704
- if( rc==SQLITE_OK ){
55757
+ if( (db->flags & SQLITE_NoCkptOnClose)==0
55758
+ && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
55759
+ ){
5570555760
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
5570655761
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
5570755762
}
55708
- rc = sqlite3WalCheckpoint(
55709
- pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
55763
+ rc = sqlite3WalCheckpoint(pWal, db,
55764
+ SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
5571055765
);
5571155766
if( rc==SQLITE_OK ){
5571255767
int bPersist = -1;
5571355768
sqlite3OsFileControlHint(
5571455769
pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist
@@ -56952,10 +57007,11 @@
5695257007
** If parameter xBusy is not NULL, it is a pointer to a busy-handler
5695357008
** callback. In this case this function runs a blocking checkpoint.
5695457009
*/
5695557010
SQLITE_PRIVATE int sqlite3WalCheckpoint(
5695657011
Wal *pWal, /* Wal connection */
57012
+ sqlite3 *db, /* Check this handle's interrupt flag */
5695757013
int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
5695857014
int (*xBusy)(void*), /* Function to call when busy */
5695957015
void *pBusyArg, /* Context argument for xBusyHandler */
5696057016
int sync_flags, /* Flags to sync db file with (or 0) */
5696157017
int nBuf, /* Size of temporary buffer */
@@ -57026,11 +57082,11 @@
5702657082
if( rc==SQLITE_OK ){
5702757083
5702857084
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
5702957085
rc = SQLITE_CORRUPT_BKPT;
5703057086
}else{
57031
- rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
57087
+ rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
5703257088
}
5703357089
5703457090
/* If no error occurred, set the output variables. */
5703557091
if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
5703657092
if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
@@ -58984,11 +59040,11 @@
5898459040
int bias, /* Bias search to the high end */
5898559041
int *pRes /* Write search results here */
5898659042
){
5898759043
int rc; /* Status code */
5898859044
UnpackedRecord *pIdxKey; /* Unpacked index key */
58989
- char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */
59045
+ char aSpace[384]; /* Temp space for pIdxKey - to avoid a malloc */
5899059046
char *pFree = 0;
5899159047
5899259048
if( pKey ){
5899359049
assert( nKey==(i64)(int)nKey );
5899459050
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
@@ -60616,23 +60672,30 @@
6061660672
*ppBtree = p;
6061760673
6061860674
btree_open_out:
6061960675
if( rc!=SQLITE_OK ){
6062060676
if( pBt && pBt->pPager ){
60621
- sqlite3PagerClose(pBt->pPager);
60677
+ sqlite3PagerClose(pBt->pPager, 0);
6062260678
}
6062360679
sqlite3_free(pBt);
6062460680
sqlite3_free(p);
6062560681
*ppBtree = 0;
6062660682
}else{
60683
+ sqlite3_file *pFile;
60684
+
6062760685
/* If the B-Tree was successfully opened, set the pager-cache size to the
6062860686
** default value. Except, when opening on an existing shared pager-cache,
6062960687
** do not change the pager-cache size.
6063060688
*/
6063160689
if( sqlite3BtreeSchema(p, 0, 0)==0 ){
6063260690
sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
6063360691
}
60692
+
60693
+ pFile = sqlite3PagerFile(pBt->pPager);
60694
+ if( pFile->pMethods ){
60695
+ sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
60696
+ }
6063460697
}
6063560698
if( mutexOpen ){
6063660699
assert( sqlite3_mutex_held(mutexOpen) );
6063760700
sqlite3_mutex_leave(mutexOpen);
6063860701
}
@@ -60758,11 +60821,11 @@
6075860821
** it without having to hold the mutex.
6075960822
**
6076060823
** Clean out and delete the BtShared object.
6076160824
*/
6076260825
assert( !pBt->pCursor );
60763
- sqlite3PagerClose(pBt->pPager);
60826
+ sqlite3PagerClose(pBt->pPager, p->db);
6076460827
if( pBt->xFreeSchema && pBt->pSchema ){
6076560828
pBt->xFreeSchema(pBt->pSchema);
6076660829
}
6076760830
sqlite3DbFree(0, pBt->pSchema);
6076860831
freeTempSpace(pBt);
@@ -62822,11 +62885,11 @@
6282262885
if( (eOp&0x01)==0 /* (1) */
6282362886
&& offset==0 /* (2) */
6282462887
&& (bEnd || a==ovflSize) /* (6) */
6282562888
&& pBt->inTransaction==TRANS_READ /* (4) */
6282662889
&& (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
62827
- && pBt->pPage1->aData[19]==0x01 /* (5) */
62890
+ && 0==sqlite3PagerUseWal(pBt->pPager) /* (5) */
6282862891
&& &pBuf[-4]>=pBufStart /* (7) */
6282962892
){
6283062893
u8 aSave[4];
6283162894
u8 *aWrite = &pBuf[-4];
6283262895
assert( aWrite>=pBufStart ); /* hence (7) */
@@ -63078,13 +63141,16 @@
6307863141
}
6307963142
sqlite3BtreeClearCursor(pCur);
6308063143
}
6308163144
6308263145
if( pCur->iPage>=0 ){
63083
- while( pCur->iPage ){
63084
- assert( pCur->apPage[pCur->iPage]!=0 );
63085
- releasePageNotNull(pCur->apPage[pCur->iPage--]);
63146
+ if( pCur->iPage ){
63147
+ do{
63148
+ assert( pCur->apPage[pCur->iPage]!=0 );
63149
+ releasePageNotNull(pCur->apPage[pCur->iPage--]);
63150
+ }while( pCur->iPage);
63151
+ goto skip_init;
6308663152
}
6308763153
}else if( pCur->pgnoRoot==0 ){
6308863154
pCur->eState = CURSOR_INVALID;
6308963155
return SQLITE_OK;
6309063156
}else{
@@ -63091,11 +63157,11 @@
6309163157
assert( pCur->iPage==(-1) );
6309263158
rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
6309363159
0, pCur->curPagerFlags);
6309463160
if( rc!=SQLITE_OK ){
6309563161
pCur->eState = CURSOR_INVALID;
63096
- return rc;
63162
+ return rc;
6309763163
}
6309863164
pCur->iPage = 0;
6309963165
pCur->curIntKey = pCur->apPage[0]->intKey;
6310063166
}
6310163167
pRoot = pCur->apPage[0];
@@ -63114,14 +63180,16 @@
6311463180
assert( pRoot->intKey==1 || pRoot->intKey==0 );
6311563181
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
6311663182
return SQLITE_CORRUPT_BKPT;
6311763183
}
6311863184
63185
+skip_init:
6311963186
pCur->aiIdx[0] = 0;
6312063187
pCur->info.nSize = 0;
6312163188
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
6312263189
63190
+ pRoot = pCur->apPage[0];
6312363191
if( pRoot->nCell>0 ){
6312463192
pCur->eState = CURSOR_VALID;
6312563193
}else if( !pRoot->leaf ){
6312663194
Pgno subpage;
6312763195
if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
@@ -64321,12 +64389,10 @@
6432164389
nSrc = pX->nData;
6432264390
assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
6432364391
nHeader += putVarint32(&pCell[nHeader], nPayload);
6432464392
nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
6432564393
}else{
64326
- assert( pX->nData==0 );
64327
- assert( pX->nZero==0 );
6432864394
assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
6432964395
nSrc = nPayload = (int)pX->nKey;
6433064396
pSrc = pX->pKey;
6433164397
nHeader += putVarint32(&pCell[nHeader], nPayload);
6433264398
}
@@ -67700,11 +67766,11 @@
6770067766
BtShared *pBt = p->pBt;
6770167767
sqlite3BtreeEnter(p);
6770267768
if( pBt->inTransaction!=TRANS_NONE ){
6770367769
rc = SQLITE_LOCKED;
6770467770
}else{
67705
- rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
67771
+ rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
6770667772
}
6770767773
sqlite3BtreeLeave(p);
6770867774
}
6770967775
return rc;
6771067776
}
@@ -68022,26 +68088,20 @@
6802268088
*/
6802368089
static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
6802468090
int i = sqlite3FindDbName(pDb, zDb);
6802568091
6802668092
if( i==1 ){
68027
- Parse *pParse;
68093
+ Parse sParse;
6802868094
int rc = 0;
68029
- pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
68030
- if( pParse==0 ){
68031
- sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
68032
- rc = SQLITE_NOMEM_BKPT;
68033
- }else{
68034
- pParse->db = pDb;
68035
- if( sqlite3OpenTempDatabase(pParse) ){
68036
- sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
68037
- rc = SQLITE_ERROR;
68038
- }
68039
- sqlite3DbFree(pErrorDb, pParse->zErrMsg);
68040
- sqlite3ParserReset(pParse);
68041
- sqlite3StackFree(pErrorDb, pParse);
68042
- }
68095
+ memset(&sParse, 0, sizeof(sParse));
68096
+ sParse.db = pDb;
68097
+ if( sqlite3OpenTempDatabase(&sParse) ){
68098
+ sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
68099
+ rc = SQLITE_ERROR;
68100
+ }
68101
+ sqlite3DbFree(pErrorDb, sParse.zErrMsg);
68102
+ sqlite3ParserReset(&sParse);
6804368103
if( rc ){
6804468104
return 0;
6804568105
}
6804668106
}
6804768107
@@ -69041,10 +69101,11 @@
6904169101
assert( (pMem->flags&MEM_RowSet)==0 );
6904269102
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
6904369103
6904469104
6904569105
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
69106
+ pMem->enc = 0;
6904669107
return SQLITE_NOMEM_BKPT;
6904769108
}
6904869109
6904969110
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
6905069111
** string representation of the value. Then, if the required encoding
@@ -69340,11 +69401,11 @@
6934069401
switch( aff ){
6934169402
case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */
6934269403
if( (pMem->flags & MEM_Blob)==0 ){
6934369404
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
6934469405
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
69345
- MemSetTypeFlag(pMem, MEM_Blob);
69406
+ if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
6934669407
}else{
6934769408
pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
6934869409
}
6934969410
break;
6935069411
}
@@ -70017,14 +70078,11 @@
7001770078
sqlite3_value *pVal = 0;
7001870079
int negInt = 1;
7001970080
const char *zNeg = "";
7002070081
int rc = SQLITE_OK;
7002170082
70022
- if( !pExpr ){
70023
- *ppVal = 0;
70024
- return SQLITE_OK;
70025
- }
70083
+ assert( pExpr!=0 );
7002670084
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
7002770085
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
7002870086
7002970087
/* Compressed expressions only appear when parsing the DEFAULT clause
7003070088
** on a table column definition, and hence only when pCtx==0. This
@@ -70144,11 +70202,11 @@
7014470202
Expr *pExpr, /* The expression to evaluate */
7014570203
u8 enc, /* Encoding to use */
7014670204
u8 affinity, /* Affinity to use */
7014770205
sqlite3_value **ppVal /* Write the new value here */
7014870206
){
70149
- return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
70207
+ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
7015070208
}
7015170209
7015270210
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
7015370211
/*
7015470212
** The implementation of the sqlite_record() function. This function accepts
@@ -70487,12 +70545,13 @@
7048770545
** Create a new virtual database engine.
7048870546
*/
7048970547
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
7049070548
sqlite3 *db = pParse->db;
7049170549
Vdbe *p;
70492
- p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
70550
+ p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
7049370551
if( p==0 ) return 0;
70552
+ memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
7049470553
p->db = db;
7049570554
if( db->pVdbe ){
7049670555
db->pVdbe->pPrev = p;
7049770556
}
7049870557
p->pNext = db->pVdbe;
@@ -70650,13 +70709,12 @@
7065070709
#endif
7065170710
#ifdef SQLITE_DEBUG
7065270711
if( p->db->flags & SQLITE_VdbeAddopTrace ){
7065370712
int jj, kk;
7065470713
Parse *pParse = p->pParse;
70655
- for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
70714
+ for(jj=kk=0; jj<pParse->nColCache; jj++){
7065670715
struct yColCache *x = pParse->aColCache + jj;
70657
- if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
7065870716
printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
7065970717
kk++;
7066070718
}
7066170719
if( kk ) printf("\n");
7066270720
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
@@ -70840,11 +70898,10 @@
7084070898
assert( j<p->nLabel );
7084170899
assert( j>=0 );
7084270900
if( p->aLabel ){
7084370901
p->aLabel[j] = v->nOp;
7084470902
}
70845
- p->iFixedOp = v->nOp - 1;
7084670903
}
7084770904
7084870905
/*
7084970906
** Mark the VDBE as one that can only be run one time.
7085070907
*/
@@ -71231,19 +71288,19 @@
7123171288
}
7123271289
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
7123371290
sqlite3VdbeGetOp(p,addr)->p3 = val;
7123471291
}
7123571292
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
71236
- if( !p->db->mallocFailed ) p->aOp[p->nOp-1].p5 = p5;
71293
+ assert( p->nOp>0 || p->db->mallocFailed );
71294
+ if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
7123771295
}
7123871296
7123971297
/*
7124071298
** Change the P2 operand of instruction addr so that it points to
7124171299
** the address of the next instruction to be coded.
7124271300
*/
7124371301
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
71244
- p->pParse->iFixedOp = p->nOp - 1;
7124571302
sqlite3VdbeChangeP2(p, addr, p->nOp);
7124671303
}
7124771304
7124871305
7124971306
/*
@@ -71362,11 +71419,11 @@
7136271419
/*
7136371420
** If the last opcode is "op" and it is not a jump destination,
7136471421
** then remove it. Return true if and only if an opcode was removed.
7136571422
*/
7136671423
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
71367
- if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
71424
+ if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
7136871425
return sqlite3VdbeChangeToNoop(p, p->nOp-1);
7136971426
}else{
7137071427
return 0;
7137171428
}
7137271429
}
@@ -71924,10 +71981,25 @@
7192471981
zCom
7192571982
);
7192671983
fflush(pOut);
7192771984
}
7192871985
#endif
71986
+
71987
+/*
71988
+** Initialize an array of N Mem element.
71989
+*/
71990
+static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
71991
+ while( (N--)>0 ){
71992
+ p->db = db;
71993
+ p->flags = flags;
71994
+ p->szMalloc = 0;
71995
+#ifdef SQLITE_DEBUG
71996
+ p->pScopyFrom = 0;
71997
+#endif
71998
+ p++;
71999
+ }
72000
+}
7192972001
7193072002
/*
7193172003
** Release an array of N Mem elements
7193272004
*/
7193372005
static void releaseMemArray(Mem *p, int N){
@@ -72136,10 +72208,11 @@
7213672208
return SQLITE_ERROR;
7213772209
}
7213872210
pMem->flags = MEM_Str|MEM_Term;
7213972211
zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
7214072212
if( zP4!=pMem->z ){
72213
+ pMem->n = 0;
7214172214
sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
7214272215
}else{
7214372216
assert( pMem->z!=0 );
7214472217
pMem->n = sqlite3Strlen30(pMem->z);
7214572218
pMem->enc = SQLITE_UTF8;
@@ -72278,11 +72351,11 @@
7227872351
SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
7227972352
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
7228072353
int i;
7228172354
#endif
7228272355
assert( p!=0 );
72283
- assert( p->magic==VDBE_MAGIC_INIT );
72356
+ assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );
7228472357
7228572358
/* There should be at least one opcode.
7228672359
*/
7228772360
assert( p->nOp>0 );
7228872361
@@ -72367,14 +72440,11 @@
7236772440
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
7236872441
x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
7236972442
assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
7237072443
x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
7237172444
assert( x.nFree>=0 );
72372
- if( x.nFree>0 ){
72373
- memset(x.pSpace, 0, x.nFree);
72374
- assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
72375
- }
72445
+ assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
7237672446
7237772447
resolveP2Values(p, &nArg);
7237872448
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
7237972449
if( pParse->explain && nMem<10 ){
7238072450
nMem = 10;
@@ -72399,34 +72469,34 @@
7239972469
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
7240072470
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
7240172471
p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
7240272472
#endif
7240372473
if( x.nNeeded==0 ) break;
72404
- x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
72474
+ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
7240572475
x.nFree = x.nNeeded;
7240672476
}while( !db->mallocFailed );
7240772477
72408
- p->nCursor = nCursor;
72409
- if( p->aVar ){
72410
- p->nVar = (ynVar)nVar;
72411
- for(n=0; n<nVar; n++){
72412
- p->aVar[n].flags = MEM_Null;
72413
- p->aVar[n].db = db;
72414
- }
72415
- }
7241672478
p->nzVar = pParse->nzVar;
7241772479
p->azVar = pParse->azVar;
7241872480
pParse->nzVar = 0;
7241972481
pParse->azVar = 0;
72420
- if( p->aMem ){
72421
- p->nMem = nMem;
72422
- for(n=0; n<nMem; n++){
72423
- p->aMem[n].flags = MEM_Undefined;
72424
- p->aMem[n].db = db;
72425
- }
72426
- }
7242772482
p->explain = pParse->explain;
72483
+ if( db->mallocFailed ){
72484
+ p->nVar = 0;
72485
+ p->nCursor = 0;
72486
+ p->nMem = 0;
72487
+ }else{
72488
+ p->nCursor = nCursor;
72489
+ p->nVar = (ynVar)nVar;
72490
+ initMemArray(p->aVar, nVar, db, MEM_Null);
72491
+ p->nMem = nMem;
72492
+ initMemArray(p->aMem, nMem, db, MEM_Undefined);
72493
+ memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
72494
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
72495
+ memset(p->anExec, 0, p->nOp*sizeof(i64));
72496
+#endif
72497
+ }
7242872498
sqlite3VdbeRewind(p);
7242972499
}
7243072500
7243172501
/*
7243272502
** Close a VDBE cursor and release all the resources that cursor
@@ -72574,17 +72644,13 @@
7257472644
7257572645
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
7257672646
sqlite3DbFree(db, p->aColName);
7257772647
n = nResColumn*COLNAME_N;
7257872648
p->nResColumn = (u16)nResColumn;
72579
- p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
72649
+ p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
7258072650
if( p->aColName==0 ) return;
72581
- while( n-- > 0 ){
72582
- pColName->flags = MEM_Null;
72583
- pColName->db = p->db;
72584
- pColName++;
72585
- }
72651
+ initMemArray(p->aColName, n, p->db, MEM_Null);
7258672652
}
7258772653
7258872654
/*
7258972655
** Set the name of the idx'th column to be returned by the SQL statement.
7259072656
** zName must be a pointer to a nul terminated string.
@@ -73342,11 +73408,11 @@
7334273408
fclose(out);
7334373409
}
7334473410
}
7334573411
#endif
7334673412
p->iCurrentTime = 0;
73347
- p->magic = VDBE_MAGIC_INIT;
73413
+ p->magic = VDBE_MAGIC_RESET;
7334873414
return p->rc & db->errMask;
7334973415
}
7335073416
7335173417
/*
7335273418
** Clean up and delete a VDBE after execution. Return an integer which is
@@ -73406,23 +73472,25 @@
7340673472
*/
7340773473
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
7340873474
SubProgram *pSub, *pNext;
7340973475
int i;
7341073476
assert( p->db==0 || p->db==db );
73411
- releaseMemArray(p->aVar, p->nVar);
7341273477
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
7341373478
for(pSub=p->pProgram; pSub; pSub=pNext){
7341473479
pNext = pSub->pNext;
7341573480
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
7341673481
sqlite3DbFree(db, pSub);
7341773482
}
73418
- for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
73419
- sqlite3DbFree(db, p->azVar);
73483
+ if( p->magic!=VDBE_MAGIC_INIT ){
73484
+ releaseMemArray(p->aVar, p->nVar);
73485
+ for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
73486
+ sqlite3DbFree(db, p->azVar);
73487
+ sqlite3DbFree(db, p->pFree);
73488
+ }
7342073489
vdbeFreeOpArray(db, p->aOp, p->nOp);
7342173490
sqlite3DbFree(db, p->aColName);
7342273491
sqlite3DbFree(db, p->zSql);
73423
- sqlite3DbFree(db, p->pFree);
7342473492
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
7342573493
for(i=0; i<p->nScan; i++){
7342673494
sqlite3DbFree(db, p->aScan[i].zName);
7342773495
}
7342873496
sqlite3DbFree(db, p->aScan);
@@ -75073,11 +75141,11 @@
7507375141
preupdate.keyinfo.enc = ENC(db);
7507475142
preupdate.keyinfo.nField = pTab->nCol;
7507575143
preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
7507675144
preupdate.iKey1 = iKey1;
7507775145
preupdate.iKey2 = iKey2;
75078
- preupdate.iPKey = pTab->iPKey;
75146
+ preupdate.pTab = pTab;
7507975147
7508075148
db->pPreUpdate = &preupdate;
7508175149
db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
7508275150
db->pPreUpdate = 0;
7508375151
sqlite3DbFree(db, preupdate.aRecord);
@@ -76047,18 +76115,17 @@
7604776115
static Mem *columnMem(sqlite3_stmt *pStmt, int i){
7604876116
Vdbe *pVm;
7604976117
Mem *pOut;
7605076118
7605176119
pVm = (Vdbe *)pStmt;
76052
- if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
76053
- sqlite3_mutex_enter(pVm->db->mutex);
76120
+ if( pVm==0 ) return (Mem*)columnNullValue();
76121
+ assert( pVm->db );
76122
+ sqlite3_mutex_enter(pVm->db->mutex);
76123
+ if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
7605476124
pOut = &pVm->pResultSet[i];
7605576125
}else{
76056
- if( pVm && ALWAYS(pVm->db) ){
76057
- sqlite3_mutex_enter(pVm->db->mutex);
76058
- sqlite3Error(pVm->db, SQLITE_RANGE);
76059
- }
76126
+ sqlite3Error(pVm->db, SQLITE_RANGE);
7606076127
pOut = (Mem*)columnNullValue();
7606176128
}
7606276129
return pOut;
7606376130
}
7606476131
@@ -76087,10 +76154,12 @@
7608776154
** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
7608876155
** and _finalize() will return NOMEM.
7608976156
*/
7609076157
Vdbe *p = (Vdbe *)pStmt;
7609176158
if( p ){
76159
+ assert( p->db!=0 );
76160
+ assert( sqlite3_mutex_held(p->db->mutex) );
7609276161
p->rc = sqlite3ApiExit(p->db, p->rc);
7609376162
sqlite3_mutex_leave(p->db->mutex);
7609476163
}
7609576164
}
7609676165
@@ -76663,11 +76732,11 @@
7666376732
/*
7666476733
** Return true if the prepared statement is in need of being reset.
7666576734
*/
7666676735
SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
7666776736
Vdbe *v = (Vdbe*)pStmt;
76668
- return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
76737
+ return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
7666976738
}
7667076739
7667176740
/*
7667276741
** Return a pointer to the next prepared statement after pStmt associated
7667376742
** with database connection pDb. If pStmt is NULL, return the first
@@ -76804,13 +76873,18 @@
7680476873
}
7680576874
7680676875
if( iIdx>=p->pUnpacked->nField ){
7680776876
*ppValue = (sqlite3_value *)columnNullValue();
7680876877
}else{
76878
+ Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
7680976879
*ppValue = &p->pUnpacked->aMem[iIdx];
76810
- if( iIdx==p->iPKey ){
76811
- sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);
76880
+ if( iIdx==p->pTab->iPKey ){
76881
+ sqlite3VdbeMemSetInt64(pMem, p->iKey1);
76882
+ }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
76883
+ if( pMem->flags & MEM_Int ){
76884
+ sqlite3VdbeMemRealify(pMem);
76885
+ }
7681276886
}
7681376887
}
7681476888
7681576889
preupdate_old_out:
7681676890
sqlite3Error(db, rc);
@@ -76883,11 +76957,11 @@
7688376957
}
7688476958
if( iIdx>=pUnpack->nField ){
7688576959
pMem = (sqlite3_value *)columnNullValue();
7688676960
}else{
7688776961
pMem = &pUnpack->aMem[iIdx];
76888
- if( iIdx==p->iPKey ){
76962
+ if( iIdx==p->pTab->iPKey ){
7688976963
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
7689076964
}
7689176965
}
7689276966
}else{
7689376967
/* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
@@ -76904,11 +76978,11 @@
7690476978
}
7690576979
}
7690676980
assert( iIdx>=0 && iIdx<p->pCsr->nField );
7690776981
pMem = &p->aNew[iIdx];
7690876982
if( pMem->flags==0 ){
76909
- if( iIdx==p->iPKey ){
76983
+ if( iIdx==p->pTab->iPKey ){
7691076984
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
7691176985
}else{
7691276986
rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
7691376987
if( rc!=SQLITE_OK ) goto preupdate_new_out;
7691476988
}
@@ -78415,15 +78489,17 @@
7841578489
u16 nullFlag;
7841678490
pOut = out2Prerelease(p, pOp);
7841778491
cnt = pOp->p3-pOp->p2;
7841878492
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
7841978493
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
78494
+ pOut->n = 0;
7842078495
while( cnt>0 ){
7842178496
pOut++;
7842278497
memAboutToChange(p, pOut);
7842378498
sqlite3VdbeMemSetNull(pOut);
7842478499
pOut->flags = nullFlag;
78500
+ pOut->n = 0;
7842578501
cnt--;
7842678502
}
7842778503
break;
7842878504
}
7842978505
@@ -79280,12 +79356,11 @@
7928079356
** or not both operands are null.
7928179357
*/
7928279358
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
7928379359
assert( (flags1 & MEM_Cleared)==0 );
7928479360
assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
79285
- if( (flags1&MEM_Null)!=0
79286
- && (flags3&MEM_Null)!=0
79361
+ if( (flags1&flags3&MEM_Null)!=0
7928779362
&& (flags3&MEM_Cleared)==0
7928879363
){
7928979364
res = 0; /* Operands are equal */
7929079365
}else{
7929179366
res = 1; /* Operands are not equal */
@@ -80487,14 +80562,13 @@
8048780562
p->nStmtDefCons = db->nDeferredCons;
8048880563
p->nStmtDefImmCons = db->nDeferredImmCons;
8048980564
}
8049080565
8049180566
/* Gather the schema version number for checking:
80492
- ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
80493
- ** each time a query is executed to ensure that the internal cache of the
80494
- ** schema used when compiling the SQL query matches the schema of the
80495
- ** database against which the compiled query is actually executed.
80567
+ ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
80568
+ ** version is checked to ensure that the schema has not changed since the
80569
+ ** SQL statement was prepared.
8049680570
*/
8049780571
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
8049880572
iGen = db->aDb[pOp->p1].pSchema->iGeneration;
8049980573
}else{
8050080574
iGen = iMeta = 0;
@@ -81549,11 +81623,11 @@
8154981623
8155081624
REGISTER_TRACE(pOp->p3, pMem);
8155181625
sqlite3VdbeMemIntegerify(pMem);
8155281626
assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
8155381627
if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
81554
- rc = SQLITE_FULL; /* IMP: R-12275-61338 */
81628
+ rc = SQLITE_FULL; /* IMP: R-17817-00630 */
8155581629
goto abort_due_to_error;
8155681630
}
8155781631
if( v<pMem->u.i+1 ){
8155881632
v = pMem->u.i + 1;
8155981633
}
@@ -81746,11 +81820,11 @@
8174681820
** change count is incremented (otherwise not).
8174781821
**
8174881822
** P1 must not be pseudo-table. It has to be a real table with
8174981823
** multiple rows.
8175081824
**
81751
-** If P4 is not NULL then it points to a Table struture. In this case either
81825
+** If P4 is not NULL then it points to a Table object. In this case either
8175281826
** the update or pre-update hook, or both, may be invoked. The P1 cursor must
8175381827
** have been positioned using OP_NotFound prior to invoking this opcode in
8175481828
** this case. Specifically, if one is configured, the pre-update hook is
8175581829
** invoked if P4 is not NULL. The update-hook is invoked if one is configured,
8175681830
** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
@@ -82316,10 +82390,17 @@
8231682390
** This flag avoids doing an extra seek.
8231782391
**
8231882392
** This instruction only works for indices. The equivalent instruction
8231982393
** for tables is OP_Insert.
8232082394
*/
82395
+/* Opcode: SorterInsert P1 P2 * * *
82396
+** Synopsis: key=r[P2]
82397
+**
82398
+** Register P2 holds an SQL index key made using the
82399
+** MakeRecord instructions. This opcode writes that key
82400
+** into the sorter P1. Data for the entry is nil.
82401
+*/
8232182402
case OP_SorterInsert: /* in2 */
8232282403
case OP_IdxInsert: { /* in2 */
8232382404
VdbeCursor *pC;
8232482405
BtreePayload x;
8232582406
@@ -82337,13 +82418,10 @@
8233782418
if( pOp->opcode==OP_SorterInsert ){
8233882419
rc = sqlite3VdbeSorterWrite(pC, pIn2);
8233982420
}else{
8234082421
x.nKey = pIn2->n;
8234182422
x.pKey = pIn2->z;
82342
- x.nData = 0;
82343
- x.nZero = 0;
82344
- x.pData = 0;
8234582423
rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3,
8234682424
((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
8234782425
);
8234882426
assert( pC->deferredMoveto==0 );
8234982427
pC->cacheStatus = CACHE_STALE;
@@ -83547,11 +83625,11 @@
8354783625
/* If leaving WAL mode, close the log file. If successful, the call
8354883626
** to PagerCloseWal() checkpoints and deletes the write-ahead-log
8354983627
** file. An EXCLUSIVE lock may still be held on the database file
8355083628
** after a successful return.
8355183629
*/
83552
- rc = sqlite3PagerCloseWal(pPager);
83630
+ rc = sqlite3PagerCloseWal(pPager, db);
8355383631
if( rc==SQLITE_OK ){
8355483632
sqlite3PagerSetJournalMode(pPager, eNew);
8355583633
}
8355683634
}else if( eOld==PAGER_JOURNALMODE_MEMORY ){
8355783635
/* Cannot transition directly from MEMORY to WAL. Use mode OFF
@@ -88036,11 +88114,13 @@
8803688114
static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
8803788115
int rc;
8803888116
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
8803988117
testcase( ExprHasProperty(pExpr, EP_Reduced) );
8804088118
rc = pWalker->xExprCallback(pWalker, pExpr);
88041
- if( rc || ExprHasProperty(pExpr,EP_TokenOnly) ) return rc & WRC_Abort;
88119
+ if( rc || ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
88120
+ return rc & WRC_Abort;
88121
+ }
8804288122
if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
8804388123
if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
8804488124
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
8804588125
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
8804688126
}else if( pExpr->x.pList ){
@@ -88780,11 +88860,10 @@
8878088860
const char *zDb;
8878188861
Expr *pRight;
8878288862
8878388863
/* if( pSrcList==0 ) break; */
8878488864
notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
88785
- /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/
8878688865
pRight = pExpr->pRight;
8878788866
if( pRight->op==TK_ID ){
8878888867
zDb = 0;
8878988868
zTable = pExpr->pLeft->u.zToken;
8879088869
zColumn = pRight->u.zToken;
@@ -88809,11 +88888,10 @@
8880988888
const char *zId; /* The function name. */
8881088889
FuncDef *pDef; /* Information about the function */
8881188890
u8 enc = ENC(pParse->db); /* The database encoding */
8881288891
8881388892
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
88814
- notValid(pParse, pNC, "functions", NC_PartIdx);
8881588893
zId = pExpr->u.zToken;
8881688894
nId = sqlite3Strlen30(zId);
8881788895
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
8881888896
if( pDef==0 ){
8881988897
pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
@@ -88869,11 +88947,12 @@
8886988947
}
8887088948
if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
8887188949
/* Date/time functions that use 'now', and other functions like
8887288950
** sqlite_version() that might change over time cannot be used
8887388951
** in an index. */
88874
- notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr);
88952
+ notValid(pParse, pNC, "non-deterministic functions",
88953
+ NC_IdxExpr|NC_PartIdx);
8887588954
}
8887688955
}
8887788956
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
8887888957
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
8887988958
pNC->nErr++;
@@ -90409,11 +90488,11 @@
9040990488
** stored in u.zToken. Instead, the integer values is written
9041090489
** into u.iValue and the EP_IntValue flag is set. No extra storage
9041190490
** is allocated to hold the integer text and the dequote flag is ignored.
9041290491
*/
9041390492
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
90414
- sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
90493
+ sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */
9041590494
int op, /* Expression opcode */
9041690495
const Token *pToken, /* Token argument. Might be NULL */
9041790496
int dequote /* True to dequote */
9041890497
){
9041990498
Expr *pNew;
@@ -90627,40 +90706,40 @@
9062790706
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
9062890707
** as the previous instance of the same wildcard. Or if this is the first
9062990708
** instance of the wildcard, the next sequential variable number is
9063090709
** assigned.
9063190710
*/
90632
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
90711
+SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
9063390712
sqlite3 *db = pParse->db;
9063490713
const char *z;
9063590714
9063690715
if( pExpr==0 ) return;
9063790716
assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
9063890717
z = pExpr->u.zToken;
9063990718
assert( z!=0 );
9064090719
assert( z[0]!=0 );
90720
+ assert( n==sqlite3Strlen30(z) );
9064190721
if( z[1]==0 ){
9064290722
/* Wildcard of the form "?". Assign the next variable number */
9064390723
assert( z[0]=='?' );
9064490724
pExpr->iColumn = (ynVar)(++pParse->nVar);
9064590725
}else{
90646
- ynVar x = 0;
90647
- u32 n = sqlite3Strlen30(z);
90726
+ ynVar x;
9064890727
if( z[0]=='?' ){
9064990728
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
9065090729
** use it as the variable number */
9065190730
i64 i;
9065290731
int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
90653
- pExpr->iColumn = x = (ynVar)i;
90732
+ x = (ynVar)i;
9065490733
testcase( i==0 );
9065590734
testcase( i==1 );
9065690735
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
9065790736
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
9065890737
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
9065990738
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
9066090739
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
90661
- x = 0;
90740
+ return;
9066290741
}
9066390742
if( i>pParse->nVar ){
9066490743
pParse->nVar = (int)i;
9066590744
}
9066690745
}else{
@@ -90667,37 +90746,35 @@
9066790746
/* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
9066890747
** number as the prior appearance of the same name, or if the name
9066990748
** has never appeared before, reuse the same variable number
9067090749
*/
9067190750
ynVar i;
90672
- for(i=0; i<pParse->nzVar; i++){
90751
+ for(i=x=0; i<pParse->nzVar; i++){
9067390752
if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
90674
- pExpr->iColumn = x = (ynVar)i+1;
90675
- break;
90676
- }
90677
- }
90678
- if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
90679
- }
90680
- if( x>0 ){
90681
- if( x>pParse->nzVar ){
90682
- char **a;
90683
- a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
90684
- if( a==0 ){
90685
- assert( db->mallocFailed ); /* Error reported through mallocFailed */
90686
- return;
90687
- }
90688
- pParse->azVar = a;
90689
- memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
90690
- pParse->nzVar = x;
90691
- }
90692
- if( z[0]!='?' || pParse->azVar[x-1]==0 ){
90693
- sqlite3DbFree(db, pParse->azVar[x-1]);
90694
- pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
90695
- }
90696
- }
90697
- }
90698
- if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
90753
+ x = (ynVar)i+1;
90754
+ break;
90755
+ }
90756
+ }
90757
+ if( x==0 ) x = (ynVar)(++pParse->nVar);
90758
+ }
90759
+ pExpr->iColumn = x;
90760
+ if( x>pParse->nzVar ){
90761
+ char **a;
90762
+ a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
90763
+ if( a==0 ){
90764
+ assert( db->mallocFailed ); /* Error reported through mallocFailed */
90765
+ return;
90766
+ }
90767
+ pParse->azVar = a;
90768
+ memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
90769
+ pParse->nzVar = x;
90770
+ }
90771
+ if( pParse->azVar[x-1]==0 ){
90772
+ pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
90773
+ }
90774
+ }
90775
+ if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
9069990776
sqlite3ErrorMsg(pParse, "too many SQL variables");
9070090777
}
9070190778
}
9070290779
9070390780
/*
@@ -90705,22 +90782,29 @@
9070590782
*/
9070690783
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
9070790784
assert( p!=0 );
9070890785
/* Sanity check: Assert that the IntValue is non-negative if it exists */
9070990786
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
90710
- if( !ExprHasProperty(p, EP_TokenOnly) ){
90787
+#ifdef SQLITE_DEBUG
90788
+ if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
90789
+ assert( p->pLeft==0 );
90790
+ assert( p->pRight==0 );
90791
+ assert( p->x.pSelect==0 );
90792
+ }
90793
+#endif
90794
+ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
9071190795
/* The Expr.x union is never used at the same time as Expr.pRight */
9071290796
assert( p->x.pList==0 || p->pRight==0 );
9071390797
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
9071490798
sqlite3ExprDelete(db, p->pRight);
90715
- if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
9071690799
if( ExprHasProperty(p, EP_xIsSelect) ){
9071790800
sqlite3SelectDelete(db, p->x.pSelect);
9071890801
}else{
9071990802
sqlite3ExprListDelete(db, p->x.pList);
9072090803
}
9072190804
}
90805
+ if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
9072290806
if( !ExprHasProperty(p, EP_Static) ){
9072390807
sqlite3DbFree(db, p);
9072490808
}
9072590809
}
9072690810
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -90893,11 +90977,11 @@
9089390977
if( nToken ){
9089490978
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
9089590979
memcpy(zToken, p->u.zToken, nToken);
9089690980
}
9089790981
90898
- if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
90982
+ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
9089990983
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
9090090984
if( ExprHasProperty(p, EP_xIsSelect) ){
9090190985
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
9090290986
}else{
9090390987
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
@@ -90905,21 +90989,21 @@
9090590989
}
9090690990
9090790991
/* Fill in pNew->pLeft and pNew->pRight. */
9090890992
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
9090990993
zAlloc += dupedExprNodeSize(p, dupFlags);
90910
- if( ExprHasProperty(pNew, EP_Reduced) ){
90994
+ if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
9091190995
pNew->pLeft = p->pLeft ?
9091290996
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
9091390997
pNew->pRight = p->pRight ?
9091490998
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
9091590999
}
9091691000
if( pzBuffer ){
9091791001
*pzBuffer = zAlloc;
9091891002
}
9091991003
}else{
90920
- if( !ExprHasProperty(p, EP_TokenOnly) ){
91004
+ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
9092191005
if( pNew->op==TK_SELECT_COLUMN ){
9092291006
pNew->pLeft = p->pLeft;
9092391007
}else{
9092491008
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
9092591009
}
@@ -92276,12 +92360,12 @@
9227692360
dest.eDest = SRT_Exists;
9227792361
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
9227892362
VdbeComment((v, "Init EXISTS result"));
9227992363
}
9228092364
sqlite3ExprDelete(pParse->db, pSel->pLimit);
92281
- pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
92282
- &sqlite3IntTokens[1]);
92365
+ pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
92366
+ &sqlite3IntTokens[1], 0);
9228392367
pSel->iLimit = 0;
9228492368
pSel->selFlags &= ~SF_MultiValue;
9228592369
if( sqlite3Select(pParse, pSel, &dest) ){
9228692370
return 0;
9228792371
}
@@ -92646,36 +92730,23 @@
9264692730
#endif
9264792731
}
9264892732
}
9264992733
}
9265092734
92651
-#if defined(SQLITE_DEBUG)
92652
-/*
92653
-** Verify the consistency of the column cache
92654
-*/
92655
-static int cacheIsValid(Parse *pParse){
92656
- int i, n;
92657
- for(i=n=0; i<SQLITE_N_COLCACHE; i++){
92658
- if( pParse->aColCache[i].iReg>0 ) n++;
92659
- }
92660
- return n==pParse->nColCache;
92661
-}
92662
-#endif
92663
-
92664
-/*
92665
-** Clear a cache entry.
92666
-*/
92667
-static void cacheEntryClear(Parse *pParse, struct yColCache *p){
92668
- if( p->tempReg ){
92735
+/*
92736
+** Erase column-cache entry number i
92737
+*/
92738
+static void cacheEntryClear(Parse *pParse, int i){
92739
+ if( pParse->aColCache[i].tempReg ){
9266992740
if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
92670
- pParse->aTempReg[pParse->nTempReg++] = p->iReg;
92741
+ pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
9267192742
}
92672
- p->tempReg = 0;
9267392743
}
92674
- p->iReg = 0;
9267592744
pParse->nColCache--;
92676
- assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
92745
+ if( i<pParse->nColCache ){
92746
+ pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
92747
+ }
9267792748
}
9267892749
9267992750
9268092751
/*
9268192752
** Record in the column cache that a particular column from a
@@ -92701,64 +92772,52 @@
9270192772
**
9270292773
** Actually, the way the column cache is currently used, we are guaranteed
9270392774
** that the object will never already be in cache. Verify this guarantee.
9270492775
*/
9270592776
#ifndef NDEBUG
92706
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92707
- assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
92777
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
92778
+ assert( p->iTable!=iTab || p->iColumn!=iCol );
9270892779
}
9270992780
#endif
9271092781
92711
- /* Find an empty slot and replace it */
92712
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92713
- if( p->iReg==0 ){
92714
- p->iLevel = pParse->iCacheLevel;
92715
- p->iTable = iTab;
92716
- p->iColumn = iCol;
92717
- p->iReg = iReg;
92718
- p->tempReg = 0;
92719
- p->lru = pParse->iCacheCnt++;
92720
- pParse->nColCache++;
92721
- assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
92722
- return;
92723
- }
92724
- }
92725
-
92726
- /* Replace the last recently used */
92727
- minLru = 0x7fffffff;
92728
- idxLru = -1;
92729
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92730
- if( p->lru<minLru ){
92731
- idxLru = i;
92732
- minLru = p->lru;
92733
- }
92734
- }
92735
- if( ALWAYS(idxLru>=0) ){
92782
+ /* If the cache is already full, delete the least recently used entry */
92783
+ if( pParse->nColCache>=SQLITE_N_COLCACHE ){
92784
+ minLru = 0x7fffffff;
92785
+ idxLru = -1;
92786
+ for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92787
+ if( p->lru<minLru ){
92788
+ idxLru = i;
92789
+ minLru = p->lru;
92790
+ }
92791
+ }
9273692792
p = &pParse->aColCache[idxLru];
92737
- p->iLevel = pParse->iCacheLevel;
92738
- p->iTable = iTab;
92739
- p->iColumn = iCol;
92740
- p->iReg = iReg;
92741
- p->tempReg = 0;
92742
- p->lru = pParse->iCacheCnt++;
92743
- assert( cacheIsValid(pParse) );
92744
- return;
92745
- }
92793
+ }else{
92794
+ p = &pParse->aColCache[pParse->nColCache++];
92795
+ }
92796
+
92797
+ /* Add the new entry to the end of the cache */
92798
+ p->iLevel = pParse->iCacheLevel;
92799
+ p->iTable = iTab;
92800
+ p->iColumn = iCol;
92801
+ p->iReg = iReg;
92802
+ p->tempReg = 0;
92803
+ p->lru = pParse->iCacheCnt++;
9274692804
}
9274792805
9274892806
/*
9274992807
** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
9275092808
** Purge the range of registers from the column cache.
9275192809
*/
9275292810
SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
92753
- struct yColCache *p;
92754
- if( iReg<=0 || pParse->nColCache==0 ) return;
92755
- p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
92756
- while(1){
92757
- if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
92758
- if( p==pParse->aColCache ) break;
92759
- p--;
92811
+ int i = 0;
92812
+ while( i<pParse->nColCache ){
92813
+ struct yColCache *p = &pParse->aColCache[i];
92814
+ if( p->iReg >= iReg && p->iReg < iReg+nReg ){
92815
+ cacheEntryClear(pParse, i);
92816
+ }else{
92817
+ i++;
92818
+ }
9276092819
}
9276192820
}
9276292821
9276392822
/*
9276492823
** Remember the current column cache context. Any new entries added
@@ -92778,22 +92837,23 @@
9277892837
** Remove from the column cache any entries that were added since the
9277992838
** the previous sqlite3ExprCachePush operation. In other words, restore
9278092839
** the cache to the state it was in prior the most recent Push.
9278192840
*/
9278292841
SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
92783
- int i;
92784
- struct yColCache *p;
92842
+ int i = 0;
9278592843
assert( pParse->iCacheLevel>=1 );
9278692844
pParse->iCacheLevel--;
9278792845
#ifdef SQLITE_DEBUG
9278892846
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
9278992847
printf("POP to %d\n", pParse->iCacheLevel);
9279092848
}
9279192849
#endif
92792
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92793
- if( p->iReg && p->iLevel>pParse->iCacheLevel ){
92794
- cacheEntryClear(pParse, p);
92850
+ while( i<pParse->nColCache ){
92851
+ if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
92852
+ cacheEntryClear(pParse, i);
92853
+ }else{
92854
+ i++;
9279592855
}
9279692856
}
9279792857
}
9279892858
9279992859
/*
@@ -92803,11 +92863,11 @@
9280392863
** get them all.
9280492864
*/
9280592865
static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
9280692866
int i;
9280792867
struct yColCache *p;
92808
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92868
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
9280992869
if( p->iReg==iReg ){
9281092870
p->tempReg = 0;
9281192871
}
9281292872
}
9281392873
}
@@ -92881,12 +92941,12 @@
9288192941
){
9288292942
Vdbe *v = pParse->pVdbe;
9288392943
int i;
9288492944
struct yColCache *p;
9288592945
92886
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92887
- if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
92946
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
92947
+ if( p->iTable==iTable && p->iColumn==iColumn ){
9288892948
p->lru = pParse->iCacheCnt++;
9288992949
sqlite3ExprCachePinRegister(pParse, p->iReg);
9289092950
return p->iReg;
9289192951
}
9289292952
}
@@ -92914,22 +92974,24 @@
9291492974
/*
9291592975
** Clear all column cache entries.
9291692976
*/
9291792977
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
9291892978
int i;
92919
- struct yColCache *p;
9292092979
9292192980
#if SQLITE_DEBUG
9292292981
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
9292392982
printf("CLEAR\n");
9292492983
}
9292592984
#endif
92926
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92927
- if( p->iReg ){
92928
- cacheEntryClear(pParse, p);
92985
+ for(i=0; i<pParse->nColCache; i++){
92986
+ if( pParse->aColCache[i].tempReg
92987
+ && pParse->nTempReg<ArraySize(pParse->aTempReg)
92988
+ ){
92989
+ pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
9292992990
}
9293092991
}
92992
+ pParse->nColCache = 0;
9293192993
}
9293292994
9293392995
/*
9293492996
** Record the fact that an affinity change has occurred on iCount
9293592997
** registers starting with iStart.
@@ -92957,11 +93019,11 @@
9295793019
** and does not appear in a normal build.
9295893020
*/
9295993021
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
9296093022
int i;
9296193023
struct yColCache *p;
92962
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
93024
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
9296393025
int r = p->iReg;
9296493026
if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
9296593027
}
9296693028
return 0;
9296793029
}
@@ -94306,15 +94368,14 @@
9430694368
&& (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
9430794369
|| sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
9430894370
){
9430994371
return 1;
9431094372
}
94311
- if( pE2->op==TK_NOTNULL
94312
- && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
94313
- && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
94314
- ){
94315
- return 1;
94373
+ if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
94374
+ Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
94375
+ testcase( pX!=pE1->pLeft );
94376
+ if( sqlite3ExprCompare(pX, pE2->pLeft, iTab)==0 ) return 1;
9431694377
}
9431794378
return 0;
9431894379
}
9431994380
9432094381
/*
@@ -94653,11 +94714,11 @@
9465394714
*/
9465494715
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
9465594716
if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
9465694717
int i;
9465794718
struct yColCache *p;
94658
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
94719
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
9465994720
if( p->iReg==iReg ){
9466094721
p->tempReg = 1;
9466194722
return;
9466294723
}
9466394724
}
@@ -97959,11 +98020,11 @@
9795998020
}else{
9796098021
sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
9796198022
return 1;
9796298023
}
9796398024
}
97964
- if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
98025
+ if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break;
9796598026
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
9796698027
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
9796798028
}else{
9796898029
if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
9796998030
}
@@ -98423,11 +98484,10 @@
9842398484
*/
9842498485
v = sqlite3GetVdbe(pParse);
9842598486
assert( !pParse->isMultiWrite
9842698487
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
9842798488
if( v ){
98428
- while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
9842998489
sqlite3VdbeAddOp0(v, OP_Halt);
9843098490
9843198491
#if SQLITE_USER_AUTHENTICATION
9843298492
if( pParse->nTableLock>0 && db->init.busy==0 ){
9843398493
sqlite3UserAuthInit(db);
@@ -98450,18 +98510,20 @@
9845098510
){
9845198511
int iDb, i;
9845298512
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
9845398513
sqlite3VdbeJumpHere(v, 0);
9845498514
for(iDb=0; iDb<db->nDb; iDb++){
98515
+ Schema *pSchema;
9845598516
if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
9845698517
sqlite3VdbeUsesBtree(v, iDb);
98518
+ pSchema = db->aDb[iDb].pSchema;
9845798519
sqlite3VdbeAddOp4Int(v,
9845898520
OP_Transaction, /* Opcode */
9845998521
iDb, /* P1 */
9846098522
DbMaskTest(pParse->writeMask,iDb), /* P2 */
98461
- pParse->cookieValue[iDb], /* P3 */
98462
- db->aDb[iDb].pSchema->iGeneration /* P4 */
98523
+ pSchema->schema_cookie, /* P3 */
98524
+ pSchema->iGeneration /* P4 */
9846398525
);
9846498526
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
9846598527
VdbeComment((v,
9846698528
"usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
9846798529
}
@@ -98508,20 +98570,10 @@
9850898570
sqlite3VdbeMakeReady(v, pParse);
9850998571
pParse->rc = SQLITE_DONE;
9851098572
}else{
9851198573
pParse->rc = SQLITE_ERROR;
9851298574
}
98513
-
98514
- /* We are done with this Parse object. There is no need to de-initialize it */
98515
-#if 0
98516
- pParse->colNamesSet = 0;
98517
- pParse->nTab = 0;
98518
- pParse->nMem = 0;
98519
- pParse->nSet = 0;
98520
- pParse->nVar = 0;
98521
- DbMaskZero(pParse->cookieMask);
98522
-#endif
9852398575
}
9852498576
9852598577
/*
9852698578
** Run the parser and code generator recursively in order to generate
9852798579
** code for the SQL statement given onto the end of the pParse context
@@ -98537,12 +98589,11 @@
9853798589
SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
9853898590
va_list ap;
9853998591
char *zSql;
9854098592
char *zErrMsg = 0;
9854198593
sqlite3 *db = pParse->db;
98542
-# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
98543
- char saveBuf[SAVE_SZ];
98594
+ char saveBuf[PARSE_TAIL_SZ];
9854498595
9854598596
if( pParse->nErr ) return;
9854698597
assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
9854798598
va_start(ap, zFormat);
9854898599
zSql = sqlite3VMPrintf(db, zFormat, ap);
@@ -98549,16 +98600,16 @@
9854998600
va_end(ap);
9855098601
if( zSql==0 ){
9855198602
return; /* A malloc must have failed */
9855298603
}
9855398604
pParse->nested++;
98554
- memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
98555
- memset(&pParse->nVar, 0, SAVE_SZ);
98605
+ memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
98606
+ memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
9855698607
sqlite3RunParser(pParse, zSql, &zErrMsg);
9855798608
sqlite3DbFree(db, zErrMsg);
9855898609
sqlite3DbFree(db, zSql);
98559
- memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
98610
+ memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
9856098611
pParse->nested--;
9856198612
}
9856298613
9856398614
#if SQLITE_USER_AUTHENTICATION
9856498615
/*
@@ -99735,10 +99786,13 @@
9973599786
** This plan is not completely bullet-proof. It is possible for
9973699787
** the schema to change multiple times and for the cookie to be
9973799788
** set back to prior value. But schema changes are infrequent
9973899789
** and the probability of hitting the same cookie value is only
9973999790
** 1 chance in 2^32. So we're safe enough.
99791
+**
99792
+** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
99793
+** the schema-version whenever the schema changes.
9974099794
*/
9974199795
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
9974299796
sqlite3 *db = pParse->db;
9974399797
Vdbe *v = pParse->pVdbe;
9974499798
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
@@ -102318,19 +102372,17 @@
102318102372
** will occur at the end of the top-level VDBE and will be generated
102319102373
** later, by sqlite3FinishCoding().
102320102374
*/
102321102375
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
102322102376
Parse *pToplevel = sqlite3ParseToplevel(pParse);
102323
- sqlite3 *db = pToplevel->db;
102324102377
102325
- assert( iDb>=0 && iDb<db->nDb );
102326
- assert( db->aDb[iDb].pBt!=0 || iDb==1 );
102378
+ assert( iDb>=0 && iDb<pParse->db->nDb );
102379
+ assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
102327102380
assert( iDb<SQLITE_MAX_ATTACHED+2 );
102328
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
102381
+ assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
102329102382
if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
102330102383
DbMaskSet(pToplevel->cookieMask, iDb);
102331
- pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
102332102384
if( !OMIT_TEMPDB && iDb==1 ){
102333102385
sqlite3OpenTempDatabase(pToplevel);
102334102386
}
102335102387
}
102336102388
}
@@ -107192,14 +107244,14 @@
107192107244
}else if( action==OE_SetDflt ){
107193107245
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
107194107246
if( pDflt ){
107195107247
pNew = sqlite3ExprDup(db, pDflt, 0);
107196107248
}else{
107197
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
107249
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
107198107250
}
107199107251
}else{
107200
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
107252
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
107201107253
}
107202107254
pList = sqlite3ExprListAppend(pParse, pList, pNew);
107203107255
sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
107204107256
}
107205107257
}
@@ -109538,10 +109590,11 @@
109538109590
}
109539109591
if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
109540109592
sqlite3ReleaseTempReg(pParse, regRowid);
109541109593
sqlite3ReleaseTempReg(pParse, regData);
109542109594
if( emptyDestTest ){
109595
+ sqlite3AutoincrementEnd(pParse);
109543109596
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
109544109597
sqlite3VdbeJumpHere(v, emptyDestTest);
109545109598
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
109546109599
return 0;
109547109600
}else{
@@ -114034,22 +114087,18 @@
114034114087
int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
114035114088
Vdbe *pReprepare, /* VM being reprepared */
114036114089
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
114037114090
const char **pzTail /* OUT: End of parsed string */
114038114091
){
114039
- Parse *pParse; /* Parsing context */
114040114092
char *zErrMsg = 0; /* Error message */
114041114093
int rc = SQLITE_OK; /* Result code */
114042114094
int i; /* Loop counter */
114043
-
114044
- /* Allocate the parsing context */
114045
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
114046
- if( pParse==0 ){
114047
- rc = SQLITE_NOMEM_BKPT;
114048
- goto end_prepare;
114049
- }
114050
- pParse->pReprepare = pReprepare;
114095
+ Parse sParse; /* Parsing context */
114096
+
114097
+ memset(&sParse, 0, PARSE_HDR_SZ);
114098
+ memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
114099
+ sParse.pReprepare = pReprepare;
114051114100
assert( ppStmt && *ppStmt==0 );
114052114101
/* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
114053114102
assert( sqlite3_mutex_held(db->mutex) );
114054114103
114055114104
/* Check to verify that it is possible to get a read lock on all
@@ -114089,12 +114138,11 @@
114089114138
}
114090114139
}
114091114140
114092114141
sqlite3VtabUnlockList(db);
114093114142
114094
- pParse->db = db;
114095
- pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */
114143
+ sParse.db = db;
114096114144
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
114097114145
char *zSqlCopy;
114098114146
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
114099114147
testcase( nBytes==mxLen );
114100114148
testcase( nBytes==mxLen+1 );
@@ -114103,65 +114151,65 @@
114103114151
rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
114104114152
goto end_prepare;
114105114153
}
114106114154
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
114107114155
if( zSqlCopy ){
114108
- sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
114109
- pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
114156
+ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
114157
+ sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
114110114158
sqlite3DbFree(db, zSqlCopy);
114111114159
}else{
114112
- pParse->zTail = &zSql[nBytes];
114160
+ sParse.zTail = &zSql[nBytes];
114113114161
}
114114114162
}else{
114115
- sqlite3RunParser(pParse, zSql, &zErrMsg);
114163
+ sqlite3RunParser(&sParse, zSql, &zErrMsg);
114116114164
}
114117
- assert( 0==pParse->nQueryLoop );
114165
+ assert( 0==sParse.nQueryLoop );
114118114166
114119
- if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
114120
- if( pParse->checkSchema ){
114121
- schemaIsValid(pParse);
114167
+ if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
114168
+ if( sParse.checkSchema ){
114169
+ schemaIsValid(&sParse);
114122114170
}
114123114171
if( db->mallocFailed ){
114124
- pParse->rc = SQLITE_NOMEM_BKPT;
114172
+ sParse.rc = SQLITE_NOMEM_BKPT;
114125114173
}
114126114174
if( pzTail ){
114127
- *pzTail = pParse->zTail;
114175
+ *pzTail = sParse.zTail;
114128114176
}
114129
- rc = pParse->rc;
114177
+ rc = sParse.rc;
114130114178
114131114179
#ifndef SQLITE_OMIT_EXPLAIN
114132
- if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
114180
+ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
114133114181
static const char * const azColName[] = {
114134114182
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
114135114183
"selectid", "order", "from", "detail"
114136114184
};
114137114185
int iFirst, mx;
114138
- if( pParse->explain==2 ){
114139
- sqlite3VdbeSetNumCols(pParse->pVdbe, 4);
114186
+ if( sParse.explain==2 ){
114187
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
114140114188
iFirst = 8;
114141114189
mx = 12;
114142114190
}else{
114143
- sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
114191
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
114144114192
iFirst = 0;
114145114193
mx = 8;
114146114194
}
114147114195
for(i=iFirst; i<mx; i++){
114148
- sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
114196
+ sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
114149114197
azColName[i], SQLITE_STATIC);
114150114198
}
114151114199
}
114152114200
#endif
114153114201
114154114202
if( db->init.busy==0 ){
114155
- Vdbe *pVdbe = pParse->pVdbe;
114156
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
114203
+ Vdbe *pVdbe = sParse.pVdbe;
114204
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
114157114205
}
114158
- if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
114159
- sqlite3VdbeFinalize(pParse->pVdbe);
114206
+ if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
114207
+ sqlite3VdbeFinalize(sParse.pVdbe);
114160114208
assert(!(*ppStmt));
114161114209
}else{
114162
- *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
114210
+ *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
114163114211
}
114164114212
114165114213
if( zErrMsg ){
114166114214
sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
114167114215
sqlite3DbFree(db, zErrMsg);
@@ -114168,20 +114216,19 @@
114168114216
}else{
114169114217
sqlite3Error(db, rc);
114170114218
}
114171114219
114172114220
/* Delete any TriggerPrg structures allocated while parsing this statement. */
114173
- while( pParse->pTriggerPrg ){
114174
- TriggerPrg *pT = pParse->pTriggerPrg;
114175
- pParse->pTriggerPrg = pT->pNext;
114221
+ while( sParse.pTriggerPrg ){
114222
+ TriggerPrg *pT = sParse.pTriggerPrg;
114223
+ sParse.pTriggerPrg = pT->pNext;
114176114224
sqlite3DbFree(db, pT);
114177114225
}
114178114226
114179114227
end_prepare:
114180114228
114181
- sqlite3ParserReset(pParse);
114182
- sqlite3StackFree(db, pParse);
114229
+ sqlite3ParserReset(&sParse);
114183114230
rc = sqlite3ApiExit(db, rc);
114184114231
assert( (rc&db->errMask)==rc );
114185114232
return rc;
114186114233
}
114187114234
static int sqlite3LockAndPrepare(
@@ -115382,11 +115429,11 @@
115382115429
** Allocate a KeyInfo object sufficient for an index of N key columns and
115383115430
** X extra columns.
115384115431
*/
115385115432
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
115386115433
int nExtra = (N+X)*(sizeof(CollSeq*)+1);
115387
- KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra);
115434
+ KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
115388115435
if( p ){
115389115436
p->aSortOrder = (u8*)&p->aColl[N+X];
115390115437
p->nField = (u16)N;
115391115438
p->nXField = (u16)X;
115392115439
p->enc = ENC(db);
@@ -118072,16 +118119,17 @@
118072118119
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
118073118120
if( subqueryIsAgg ){
118074118121
assert( pParent->pHaving==0 );
118075118122
pParent->pHaving = pParent->pWhere;
118076118123
pParent->pWhere = pWhere;
118077
- pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
118078
- sqlite3ExprDup(db, pSub->pHaving, 0));
118124
+ pParent->pHaving = sqlite3ExprAnd(db,
118125
+ sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving
118126
+ );
118079118127
assert( pParent->pGroupBy==0 );
118080118128
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
118081118129
}else{
118082
- pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
118130
+ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
118083118131
}
118084118132
substSelect(db, pParent, iParent, pSub->pEList, 0);
118085118133
118086118134
/* The flattened query is distinct if either the inner or the
118087118135
** outer query is distinct.
@@ -122381,11 +122429,11 @@
122381122429
}
122382122430
#endif
122383122431
122384122432
sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
122385122433
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
122386
- sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF);
122434
+ sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
122387122435
122388122436
/* Begin a transaction and take an exclusive lock on the main database
122389122437
** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
122390122438
** to ensure that we do not try to change the page-size on a WAL database.
122391122439
*/
@@ -124041,24 +124089,24 @@
124041124089
** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
124042124090
** is only able to process joins with 64 or fewer tables.
124043124091
*/
124044124092
struct WhereTerm {
124045124093
Expr *pExpr; /* Pointer to the subexpression that is this term */
124094
+ WhereClause *pWC; /* The clause this term is part of */
124095
+ LogEst truthProb; /* Probability of truth for this expression */
124096
+ u16 wtFlags; /* TERM_xxx bit flags. See below */
124097
+ u16 eOperator; /* A WO_xx value describing <op> */
124098
+ u8 nChild; /* Number of children that must disable us */
124099
+ u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
124046124100
int iParent; /* Disable pWC->a[iParent] when this term disabled */
124047124101
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
124048124102
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
124049124103
union {
124050124104
int leftColumn; /* Column number of X in "X <op> <expr>" */
124051124105
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
124052124106
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
124053124107
} u;
124054
- LogEst truthProb; /* Probability of truth for this expression */
124055
- u16 eOperator; /* A WO_xx value describing <op> */
124056
- u16 wtFlags; /* TERM_xxx bit flags. See below */
124057
- u8 nChild; /* Number of children that must disable us */
124058
- u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
124059
- WhereClause *pWC; /* The clause this term is part of */
124060124108
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
124061124109
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
124062124110
};
124063124111
124064124112
/*
@@ -124207,29 +124255,29 @@
124207124255
struct WhereInfo {
124208124256
Parse *pParse; /* Parsing and code generating context */
124209124257
SrcList *pTabList; /* List of tables in the join */
124210124258
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
124211124259
ExprList *pDistinctSet; /* DISTINCT over all these values */
124212
- WhereLoop *pLoops; /* List of all WhereLoop objects */
124213
- Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
124214
- LogEst nRowOut; /* Estimated number of output rows */
124215124260
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
124261
+ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
124262
+ int iContinue; /* Jump here to continue with next record */
124263
+ int iBreak; /* Jump here to break out of the loop */
124264
+ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
124216124265
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
124266
+ u8 nLevel; /* Number of nested loop */
124217124267
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
124218124268
u8 sorted; /* True if really sorted (not just grouped) */
124219124269
u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
124220124270
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
124221124271
u8 eDistinct; /* One of the WHERE_DISTINCT_* values */
124222
- u8 nLevel; /* Number of nested loop */
124223124272
u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */
124224124273
int iTop; /* The very beginning of the WHERE loop */
124225
- int iContinue; /* Jump here to continue with next record */
124226
- int iBreak; /* Jump here to break out of the loop */
124227
- int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
124228
- int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
124229
- WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
124274
+ WhereLoop *pLoops; /* List of all WhereLoop objects */
124275
+ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
124276
+ LogEst nRowOut; /* Estimated number of output rows */
124230124277
WhereClause sWC; /* Decomposition of the WHERE clause */
124278
+ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
124231124279
WhereLevel a[1]; /* Information about each nest loop in WHERE */
124232124280
};
124233124281
124234124282
/*
124235124283
** Private interfaces - callable only by other where.c routines.
@@ -124689,11 +124737,10 @@
124689124737
**
124690124738
** * the comparison will be performed with no affinity, or
124691124739
** * the affinity change in zAff is guaranteed not to change the value.
124692124740
*/
124693124741
static void updateRangeAffinityStr(
124694
- Parse *pParse, /* Parse context */
124695124742
Expr *pRight, /* RHS of comparison */
124696124743
int n, /* Number of vector elements in comparison */
124697124744
char *zAff /* Affinity string to modify */
124698124745
){
124699124746
int i;
@@ -125775,15 +125822,15 @@
125775125822
assert( (bRev & ~1)==0 );
125776125823
pLevel->iLikeRepCntr <<=1;
125777125824
pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
125778125825
}
125779125826
#endif
125780
- if( pRangeStart==0
125781
- && (j = pIdx->aiColumn[nEq])>=0
125782
- && pIdx->pTable->aCol[j].notNull==0
125783
- ){
125784
- bSeekPastNull = 1;
125827
+ if( pRangeStart==0 ){
125828
+ j = pIdx->aiColumn[nEq];
125829
+ if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
125830
+ bSeekPastNull = 1;
125831
+ }
125785125832
}
125786125833
}
125787125834
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
125788125835
125789125836
/* If we are doing a reverse order scan on an ascending index, or
@@ -125829,11 +125876,11 @@
125829125876
){
125830125877
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
125831125878
VdbeCoverage(v);
125832125879
}
125833125880
if( zStartAff ){
125834
- updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]);
125881
+ updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
125835125882
}
125836125883
nConstraint += nBtm;
125837125884
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
125838125885
if( sqlite3ExprIsVector(pRight)==0 ){
125839125886
disableTerm(pLevel, pRangeStart);
@@ -125879,11 +125926,11 @@
125879125926
){
125880125927
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
125881125928
VdbeCoverage(v);
125882125929
}
125883125930
if( zEndAff ){
125884
- updateRangeAffinityStr(pParse, pRight, nTop, zEndAff);
125931
+ updateRangeAffinityStr(pRight, nTop, zEndAff);
125885125932
codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
125886125933
}else{
125887125934
assert( pParse->db->mallocFailed );
125888125935
}
125889125936
nConstraint += nTop;
@@ -126315,11 +126362,11 @@
126315126362
** and we are coding the t1 loop and the t2 loop has not yet coded,
126316126363
** then we cannot use the "t1.a=t2.b" constraint, but we can code
126317126364
** the implied "t1.a=123" constraint.
126318126365
*/
126319126366
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
126320
- Expr *pE, *pEAlt;
126367
+ Expr *pE, sEAlt;
126321126368
WhereTerm *pAlt;
126322126369
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
126323126370
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
126324126371
if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
126325126372
if( pTerm->leftCursor!=iCur ) continue;
@@ -126333,17 +126380,13 @@
126333126380
if( pAlt->wtFlags & (TERM_CODED) ) continue;
126334126381
testcase( pAlt->eOperator & WO_EQ );
126335126382
testcase( pAlt->eOperator & WO_IS );
126336126383
testcase( pAlt->eOperator & WO_IN );
126337126384
VdbeModuleComment((v, "begin transitive constraint"));
126338
- pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
126339
- if( pEAlt ){
126340
- *pEAlt = *pAlt->pExpr;
126341
- pEAlt->pLeft = pE->pLeft;
126342
- sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
126343
- sqlite3StackFree(db, pEAlt);
126344
- }
126385
+ sEAlt = *pAlt->pExpr;
126386
+ sEAlt.pLeft = pE->pLeft;
126387
+ sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
126345126388
}
126346126389
126347126390
/* For a LEFT OUTER JOIN, generate code that will record the fact that
126348126391
** at least one row of the right table has matched the left table.
126349126392
*/
@@ -126448,11 +126491,10 @@
126448126491
memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
126449126492
if( pOld!=pWC->aStatic ){
126450126493
sqlite3DbFree(db, pOld);
126451126494
}
126452126495
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
126453
- memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
126454126496
}
126455126497
pTerm = &pWC->a[idx = pWC->nTerm++];
126456126498
if( p && ExprHasProperty(p, EP_Unlikely) ){
126457126499
pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
126458126500
}else{
@@ -126460,10 +126502,12 @@
126460126502
}
126461126503
pTerm->pExpr = sqlite3ExprSkipCollate(p);
126462126504
pTerm->wtFlags = wtFlags;
126463126505
pTerm->pWC = pWC;
126464126506
pTerm->iParent = -1;
126507
+ memset(&pTerm->eOperator, 0,
126508
+ sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
126465126509
return idx;
126466126510
}
126467126511
126468126512
/*
126469126513
** Return TRUE if the given operator is one of the operators that is
@@ -127568,10 +127612,11 @@
127568127612
Expr *pNew;
127569127613
Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
127570127614
Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
127571127615
127572127616
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
127617
+ transferJoinMarkings(pNew, pExpr);
127573127618
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
127574127619
exprAnalyze(pSrc, pWC, idxNew);
127575127620
}
127576127621
pTerm = &pWC->a[idxTerm];
127577127622
pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
@@ -127618,11 +127663,11 @@
127618127663
int idxNew;
127619127664
WhereTerm *pNewTerm;
127620127665
127621127666
pNewExpr = sqlite3PExpr(pParse, TK_GT,
127622127667
sqlite3ExprDup(db, pLeft, 0),
127623
- sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);
127668
+ sqlite3ExprAlloc(db, TK_NULL, 0, 0), 0);
127624127669
127625127670
idxNew = whereClauseInsert(pWC, pNewExpr,
127626127671
TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
127627127672
if( idxNew ){
127628127673
pNewTerm = &pWC->a[idxNew];
@@ -127796,11 +127841,11 @@
127796127841
if( k>=pTab->nCol ){
127797127842
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
127798127843
pTab->zName, j);
127799127844
return;
127800127845
}
127801
- pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
127846
+ pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
127802127847
if( pColRef==0 ) return;
127803127848
pColRef->iTable = pItem->iCursor;
127804127849
pColRef->iColumn = k++;
127805127850
pColRef->pTab = pTab;
127806127851
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
@@ -128009,15 +128054,17 @@
128009128054
Expr *pX; /* An expression being tested */
128010128055
WhereClause *pWC; /* Shorthand for pScan->pWC */
128011128056
WhereTerm *pTerm; /* The term being tested */
128012128057
int k = pScan->k; /* Where to start scanning */
128013128058
128014
- while( pScan->iEquiv<=pScan->nEquiv ){
128015
- iCur = pScan->aiCur[pScan->iEquiv-1];
128059
+ assert( pScan->iEquiv<=pScan->nEquiv );
128060
+ pWC = pScan->pWC;
128061
+ while(1){
128016128062
iColumn = pScan->aiColumn[pScan->iEquiv-1];
128017
- if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0;
128018
- while( (pWC = pScan->pWC)!=0 ){
128063
+ iCur = pScan->aiCur[pScan->iEquiv-1];
128064
+ assert( pWC!=0 );
128065
+ do{
128019128066
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
128020128067
if( pTerm->leftCursor==iCur
128021128068
&& pTerm->u.leftColumn==iColumn
128022128069
&& (iColumn!=XN_EXPR
128023128070
|| sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
@@ -128063,19 +128110,21 @@
128063128110
&& pX->iColumn==pScan->aiColumn[0]
128064128111
){
128065128112
testcase( pTerm->eOperator & WO_IS );
128066128113
continue;
128067128114
}
128115
+ pScan->pWC = pWC;
128068128116
pScan->k = k+1;
128069128117
return pTerm;
128070128118
}
128071128119
}
128072128120
}
128073
- pScan->pWC = pScan->pWC->pOuter;
128121
+ pWC = pWC->pOuter;
128074128122
k = 0;
128075
- }
128076
- pScan->pWC = pScan->pOrigWC;
128123
+ }while( pWC!=0 );
128124
+ if( pScan->iEquiv>=pScan->nEquiv ) break;
128125
+ pWC = pScan->pOrigWC;
128077128126
k = 0;
128078128127
pScan->iEquiv++;
128079128128
}
128080128129
return 0;
128081128130
}
@@ -128105,28 +128154,28 @@
128105128154
int iCur, /* Cursor to scan for */
128106128155
int iColumn, /* Column to scan for */
128107128156
u32 opMask, /* Operator(s) to scan for */
128108128157
Index *pIdx /* Must be compatible with this index */
128109128158
){
128110
- int j = 0;
128111
-
128112
- /* memset(pScan, 0, sizeof(*pScan)); */
128113128159
pScan->pOrigWC = pWC;
128114128160
pScan->pWC = pWC;
128115128161
pScan->pIdxExpr = 0;
128162
+ pScan->idxaff = 0;
128163
+ pScan->zCollName = 0;
128116128164
if( pIdx ){
128117
- j = iColumn;
128165
+ int j = iColumn;
128118128166
iColumn = pIdx->aiColumn[j];
128119
- if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
128120
- if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID;
128121
- }
128122
- if( pIdx && iColumn>=0 ){
128123
- pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
128124
- pScan->zCollName = pIdx->azColl[j];
128125
- }else{
128126
- pScan->idxaff = 0;
128127
- pScan->zCollName = 0;
128167
+ if( iColumn==XN_EXPR ){
128168
+ pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
128169
+ }else if( iColumn==pIdx->pTable->iPKey ){
128170
+ iColumn = XN_ROWID;
128171
+ }else if( iColumn>=0 ){
128172
+ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
128173
+ pScan->zCollName = pIdx->azColl[j];
128174
+ }
128175
+ }else if( iColumn==XN_EXPR ){
128176
+ return 0;
128128128177
}
128129128178
pScan->opMask = opMask;
128130128179
pScan->k = 0;
128131128180
pScan->aiCur[0] = iCur;
128132128181
pScan->aiColumn[0] = iColumn;
@@ -130034,11 +130083,11 @@
130034130083
** CREATE INDEX ... ON (a, b, c, d, e)
130035130084
**
130036130085
** then this function would be invoked with nEq=1. The value returned in
130037130086
** this case is 3.
130038130087
*/
130039
-int whereRangeVectorLen(
130088
+static int whereRangeVectorLen(
130040130089
Parse *pParse, /* Parsing context */
130041130090
int iCur, /* Cursor open on pIdx */
130042130091
Index *pIdx, /* The index to be used for a inequality constraint */
130043130092
int nEq, /* Number of prior equality constraints on same index */
130044130093
WhereTerm *pTerm /* The vector inequality constraint */
@@ -131480,11 +131529,11 @@
131480131529
if( rev ) *pRevMask |= MASKBIT(iLoop);
131481131530
revSet = 1;
131482131531
}
131483131532
}
131484131533
if( isMatch ){
131485
- if( iColumn<0 ){
131534
+ if( iColumn==XN_ROWID ){
131486131535
testcase( distinctColumns==0 );
131487131536
distinctColumns = 1;
131488131537
}
131489131538
obSat |= MASKBIT(i);
131490131539
}else{
@@ -131935,17 +131984,24 @@
131935131984
}else{
131936131985
pWInfo->nOBSat = pFrom->isOrdered;
131937131986
pWInfo->revMask = pFrom->revLoop;
131938131987
if( pWInfo->nOBSat<=0 ){
131939131988
pWInfo->nOBSat = 0;
131940
- if( nLoop>0 && (pFrom->aLoop[nLoop-1]->wsFlags & WHERE_ONEROW)==0 ){
131941
- Bitmask m = 0;
131942
- int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
131989
+ if( nLoop>0 ){
131990
+ u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
131991
+ if( (wsFlags & WHERE_ONEROW)==0
131992
+ && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
131993
+ ){
131994
+ Bitmask m = 0;
131995
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
131943131996
WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
131944
- if( rc==pWInfo->pOrderBy->nExpr ){
131945
- pWInfo->bOrderedInnerLoop = 1;
131946
- pWInfo->revMask = m;
131997
+ testcase( wsFlags & WHERE_IPK );
131998
+ testcase( wsFlags & WHERE_COLUMN_IN );
131999
+ if( rc==pWInfo->pOrderBy->nExpr ){
132000
+ pWInfo->bOrderedInnerLoop = 1;
132001
+ pWInfo->revMask = m;
132002
+ }
131947132003
}
131948132004
}
131949132005
}
131950132006
}
131951132007
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
@@ -132218,26 +132274,29 @@
132218132274
** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
132219132275
** field (type Bitmask) it must be aligned on an 8-byte boundary on
132220132276
** some architectures. Hence the ROUND8() below.
132221132277
*/
132222132278
nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
132223
- pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
132279
+ pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
132224132280
if( db->mallocFailed ){
132225132281
sqlite3DbFree(db, pWInfo);
132226132282
pWInfo = 0;
132227132283
goto whereBeginError;
132228132284
}
132229
- pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
132230
- pWInfo->nLevel = nTabList;
132231132285
pWInfo->pParse = pParse;
132232132286
pWInfo->pTabList = pTabList;
132233132287
pWInfo->pOrderBy = pOrderBy;
132234132288
pWInfo->pDistinctSet = pDistinctSet;
132289
+ pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
132290
+ pWInfo->nLevel = nTabList;
132235132291
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
132236132292
pWInfo->wctrlFlags = wctrlFlags;
132237132293
pWInfo->iLimit = iAuxArg;
132238132294
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
132295
+ memset(&pWInfo->nOBSat, 0,
132296
+ offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
132297
+ memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
132239132298
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
132240132299
pMaskSet = &pWInfo->sMaskSet;
132241132300
sWLB.pWInfo = pWInfo;
132242132301
sWLB.pWC = &pWInfo->sWC;
132243132302
sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
@@ -132661,17 +132720,19 @@
132661132720
pLevel->addrLikeRep);
132662132721
VdbeCoverage(v);
132663132722
}
132664132723
#endif
132665132724
if( pLevel->iLeftJoin ){
132725
+ int ws = pLoop->wsFlags;
132666132726
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
132667
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
132668
- || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
132669
- if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
132727
+ assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
132728
+ if( (ws & WHERE_IDX_ONLY)==0 ){
132670132729
sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
132671132730
}
132672
- if( pLoop->wsFlags & WHERE_INDEXED ){
132731
+ if( (ws & WHERE_INDEXED)
132732
+ || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
132733
+ ){
132673132734
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
132674132735
}
132675132736
if( pLevel->op==OP_Return ){
132676132737
sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
132677132738
}else{
@@ -132844,19 +132905,10 @@
132844132905
struct LimitVal {
132845132906
Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
132846132907
Expr *pOffset; /* The OFFSET expression. NULL if there is none */
132847132908
};
132848132909
132849
-/*
132850
-** An instance of this structure is used to store the LIKE,
132851
-** GLOB, NOT LIKE, and NOT GLOB operators.
132852
-*/
132853
-struct LikeOp {
132854
- Token eOperator; /* "like" or "glob" or "regexp" */
132855
- int bNot; /* True if the NOT keyword is present */
132856
-};
132857
-
132858132910
/*
132859132911
** An instance of the following structure describes the event of a
132860132912
** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
132861132913
** TK_DELETE, or TK_INSTEAD. If the event is of the form
132862132914
**
@@ -132864,15 +132916,10 @@
132864132916
**
132865132917
** Then the "b" IdList records the list "a,b,c".
132866132918
*/
132867132919
struct TrigEvent { int a; IdList * b; };
132868132920
132869
-/*
132870
-** An instance of this structure holds the ATTACH key and the key type.
132871
-*/
132872
-struct AttachKey { int type; Token key; };
132873
-
132874132921
/*
132875132922
** Disable lookaside memory allocation for objects that might be
132876132923
** shared across database connections.
132877132924
*/
132878132925
static void disableLookaside(Parse *pParse){
@@ -132915,11 +132962,28 @@
132915132962
/* Construct a new Expr object from a single identifier. Use the
132916132963
** new Expr to populate pOut. Set the span of pOut to be the identifier
132917132964
** that created the expression.
132918132965
*/
132919132966
static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
132920
- pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t);
132967
+ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
132968
+ if( p ){
132969
+ memset(p, 0, sizeof(Expr));
132970
+ p->op = (u8)op;
132971
+ p->flags = EP_Leaf;
132972
+ p->iAgg = -1;
132973
+ p->u.zToken = (char*)&p[1];
132974
+ memcpy(p->u.zToken, t.z, t.n);
132975
+ p->u.zToken[t.n] = 0;
132976
+ if( sqlite3Isquote(p->u.zToken[0]) ){
132977
+ if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
132978
+ sqlite3Dequote(p->u.zToken);
132979
+ }
132980
+#if SQLITE_MAX_EXPR_DEPTH>0
132981
+ p->nHeight = 1;
132982
+#endif
132983
+ }
132984
+ pOut->pExpr = p;
132921132985
pOut->zStart = t.z;
132922132986
pOut->zEnd = &t.z[t.n];
132923132987
}
132924132988
132925132989
/* This routine constructs a binary expression node out of two ExprSpan
@@ -133078,11 +133142,10 @@
133078133142
Select* yy243;
133079133143
IdList* yy254;
133080133144
With* yy285;
133081133145
struct TrigEvent yy332;
133082133146
struct LimitVal yy354;
133083
- struct LikeOp yy392;
133084133147
struct {int value; int mask;} yy497;
133085133148
} YYMINORTYPE;
133086133149
#ifndef YYSTACKDEPTH
133087133150
#define YYSTACKDEPTH 100
133088133151
#endif
@@ -133090,19 +133153,19 @@
133090133153
#define sqlite3ParserARG_PDECL ,Parse *pParse
133091133154
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
133092133155
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
133093133156
#define YYFALLBACK 1
133094133157
#define YYNSTATE 456
133095
-#define YYNRULE 331
133158
+#define YYNRULE 332
133096133159
#define YY_MAX_SHIFT 455
133097
-#define YY_MIN_SHIFTREDUCE 667
133098
-#define YY_MAX_SHIFTREDUCE 997
133099
-#define YY_MIN_REDUCE 998
133100
-#define YY_MAX_REDUCE 1328
133101
-#define YY_ERROR_ACTION 1329
133102
-#define YY_ACCEPT_ACTION 1330
133103
-#define YY_NO_ACTION 1331
133160
+#define YY_MIN_SHIFTREDUCE 668
133161
+#define YY_MAX_SHIFTREDUCE 999
133162
+#define YY_MIN_REDUCE 1000
133163
+#define YY_MAX_REDUCE 1331
133164
+#define YY_ERROR_ACTION 1332
133165
+#define YY_ACCEPT_ACTION 1333
133166
+#define YY_NO_ACTION 1334
133104133167
/************* End control #defines *******************************************/
133105133168
133106133169
/* Define the yytestcase() macro to be a no-op if is not already defined
133107133170
** otherwise.
133108133171
**
@@ -133170,170 +133233,169 @@
133170133233
** yy_reduce_ofst[] For each state, the offset into yy_action for
133171133234
** shifting non-terminals after a reduce.
133172133235
** yy_default[] Default action for each state.
133173133236
**
133174133237
*********** Begin parsing tables **********************************************/
133175
-#define YY_ACTTAB_COUNT (1571)
133238
+#define YY_ACTTAB_COUNT (1567)
133176133239
static const YYACTIONTYPE yy_action[] = {
133177
- /* 0 */ 325, 830, 351, 824, 5, 203, 203, 818, 99, 100,
133178
- /* 10 */ 90, 840, 840, 852, 855, 844, 844, 97, 97, 98,
133240
+ /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100,
133241
+ /* 10 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98,
133179133242
/* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95,
133180
- /* 30 */ 94, 94, 94, 93, 351, 325, 975, 975, 823, 823,
133181
- /* 40 */ 823, 945, 354, 99, 100, 90, 840, 840, 852, 855,
133182
- /* 50 */ 844, 844, 97, 97, 98, 98, 98, 98, 338, 96,
133243
+ /* 30 */ 94, 94, 94, 93, 351, 325, 977, 977, 824, 824,
133244
+ /* 40 */ 826, 947, 354, 99, 100, 90, 842, 842, 854, 857,
133245
+ /* 50 */ 846, 846, 97, 97, 98, 98, 98, 98, 338, 96,
133183133246
/* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
133184
- /* 70 */ 95, 95, 94, 94, 94, 93, 351, 790, 975, 975,
133185
- /* 80 */ 325, 94, 94, 94, 93, 351, 791, 75, 99, 100,
133186
- /* 90 */ 90, 840, 840, 852, 855, 844, 844, 97, 97, 98,
133247
+ /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 977, 977,
133248
+ /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100,
133249
+ /* 90 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98,
133187133250
/* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95,
133188
- /* 110 */ 94, 94, 94, 93, 351, 1330, 155, 155, 2, 325,
133251
+ /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325,
133189133252
/* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90,
133190
- /* 130 */ 840, 840, 852, 855, 844, 844, 97, 97, 98, 98,
133253
+ /* 130 */ 842, 842, 854, 857, 846, 846, 97, 97, 98, 98,
133191133254
/* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94,
133192
- /* 150 */ 94, 94, 93, 351, 956, 956, 325, 268, 428, 413,
133193
- /* 160 */ 411, 61, 751, 751, 99, 100, 90, 840, 840, 852,
133194
- /* 170 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 60,
133255
+ /* 150 */ 94, 94, 93, 351, 958, 958, 325, 268, 428, 413,
133256
+ /* 160 */ 411, 61, 752, 752, 99, 100, 90, 842, 842, 854,
133257
+ /* 170 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 60,
133195133258
/* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133196
- /* 190 */ 351, 325, 270, 329, 273, 277, 957, 958, 250, 99,
133197
- /* 200 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133259
+ /* 190 */ 351, 325, 270, 329, 273, 277, 959, 960, 250, 99,
133260
+ /* 200 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133198133261
/* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95,
133199
- /* 220 */ 95, 94, 94, 94, 93, 351, 325, 936, 1323, 697,
133200
- /* 230 */ 705, 1323, 242, 412, 99, 100, 90, 840, 840, 852,
133201
- /* 240 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 347,
133262
+ /* 220 */ 95, 94, 94, 94, 93, 351, 325, 938, 1326, 698,
133263
+ /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 842, 842, 854,
133264
+ /* 240 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 347,
133202133265
/* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133203
- /* 260 */ 351, 325, 936, 1324, 384, 698, 1324, 381, 379, 99,
133204
- /* 270 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133205
- /* 280 */ 98, 98, 98, 98, 700, 96, 96, 96, 96, 95,
133266
+ /* 260 */ 351, 325, 938, 1327, 384, 699, 1327, 381, 379, 99,
133267
+ /* 270 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133268
+ /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95,
133206133269
/* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178,
133207
- /* 300 */ 831, 934, 373, 699, 99, 100, 90, 840, 840, 852,
133208
- /* 310 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 375,
133270
+ /* 300 */ 833, 936, 373, 700, 99, 100, 90, 842, 842, 854,
133271
+ /* 310 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 375,
133209133272
/* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133210
- /* 330 */ 351, 325, 1273, 945, 354, 817, 934, 738, 738, 99,
133211
- /* 340 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133273
+ /* 330 */ 351, 325, 1276, 947, 354, 818, 936, 739, 739, 99,
133274
+ /* 340 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133212133275
/* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95,
133213
- /* 360 */ 95, 94, 94, 94, 93, 351, 325, 967, 227, 92,
133214
- /* 370 */ 89, 178, 373, 300, 99, 100, 90, 840, 840, 852,
133215
- /* 380 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 919,
133276
+ /* 360 */ 95, 94, 94, 94, 93, 351, 325, 969, 227, 92,
133277
+ /* 370 */ 89, 178, 373, 300, 99, 100, 90, 842, 842, 854,
133278
+ /* 380 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 921,
133216133279
/* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133217
- /* 400 */ 351, 325, 449, 447, 447, 447, 147, 736, 736, 99,
133218
- /* 410 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133280
+ /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99,
133281
+ /* 410 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133219133282
/* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95,
133220
- /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 956,
133221
- /* 440 */ 956, 158, 25, 422, 99, 100, 90, 840, 840, 852,
133222
- /* 450 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 450,
133283
+ /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 958,
133284
+ /* 440 */ 958, 158, 25, 422, 99, 100, 90, 842, 842, 854,
133285
+ /* 450 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 450,
133223133286
/* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133224
- /* 470 */ 351, 443, 224, 224, 420, 956, 956, 960, 325, 52,
133225
- /* 480 */ 52, 957, 958, 176, 415, 78, 99, 100, 90, 840,
133226
- /* 490 */ 840, 852, 855, 844, 844, 97, 97, 98, 98, 98,
133287
+ /* 470 */ 351, 443, 224, 224, 420, 958, 958, 962, 325, 52,
133288
+ /* 480 */ 52, 959, 960, 176, 415, 78, 99, 100, 90, 842,
133289
+ /* 490 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98,
133227133290
/* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94,
133228
- /* 510 */ 94, 93, 351, 325, 428, 418, 298, 957, 958, 960,
133229
- /* 520 */ 81, 99, 88, 90, 840, 840, 852, 855, 844, 844,
133230
- /* 530 */ 97, 97, 98, 98, 98, 98, 716, 96, 96, 96,
133231
- /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 841,
133232
- /* 550 */ 841, 853, 856, 994, 318, 343, 379, 100, 90, 840,
133233
- /* 560 */ 840, 852, 855, 844, 844, 97, 97, 98, 98, 98,
133291
+ /* 510 */ 94, 93, 351, 325, 428, 418, 298, 959, 960, 962,
133292
+ /* 520 */ 81, 99, 88, 90, 842, 842, 854, 857, 846, 846,
133293
+ /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96,
133294
+ /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 843,
133295
+ /* 550 */ 843, 855, 858, 996, 318, 343, 379, 100, 90, 842,
133296
+ /* 560 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98,
133234133297
/* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94,
133235133298
/* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340,
133236
- /* 590 */ 927, 52, 52, 90, 840, 840, 852, 855, 844, 844,
133299
+ /* 590 */ 929, 52, 52, 90, 842, 842, 854, 857, 846, 846,
133237133300
/* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96,
133238133301
/* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445,
133239
- /* 620 */ 845, 3, 1200, 361, 360, 378, 344, 812, 956, 956,
133240
- /* 630 */ 1297, 86, 445, 728, 3, 212, 169, 287, 405, 282,
133241
- /* 640 */ 404, 199, 232, 450, 300, 759, 83, 84, 280, 245,
133302
+ /* 620 */ 847, 3, 1203, 361, 360, 378, 344, 813, 958, 958,
133303
+ /* 630 */ 1300, 86, 445, 729, 3, 212, 169, 287, 405, 282,
133304
+ /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245,
133242133305
/* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83,
133243133306
/* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246,
133244
- /* 670 */ 957, 958, 194, 455, 669, 402, 399, 398, 448, 243,
133245
- /* 680 */ 221, 114, 434, 775, 361, 450, 397, 268, 746, 224,
133246
- /* 690 */ 224, 132, 132, 198, 830, 434, 452, 451, 428, 427,
133247
- /* 700 */ 818, 415, 733, 712, 132, 52, 52, 830, 268, 452,
133248
- /* 710 */ 451, 733, 194, 818, 363, 402, 399, 398, 450, 1268,
133249
- /* 720 */ 1268, 23, 956, 956, 86, 445, 397, 3, 228, 429,
133250
- /* 730 */ 893, 823, 823, 823, 825, 19, 203, 719, 52, 52,
133251
- /* 740 */ 428, 408, 439, 249, 823, 823, 823, 825, 19, 229,
133252
- /* 750 */ 403, 153, 83, 84, 760, 177, 241, 450, 720, 85,
133253
- /* 760 */ 352, 352, 120, 157, 957, 958, 58, 975, 409, 355,
133254
- /* 770 */ 330, 448, 268, 428, 430, 320, 789, 32, 32, 86,
133255
- /* 780 */ 445, 775, 3, 341, 98, 98, 98, 98, 434, 96,
133307
+ /* 670 */ 959, 960, 194, 455, 670, 402, 399, 398, 448, 243,
133308
+ /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224,
133309
+ /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427,
133310
+ /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452,
133311
+ /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1271,
133312
+ /* 720 */ 1271, 23, 958, 958, 86, 445, 397, 3, 228, 429,
133313
+ /* 730 */ 895, 824, 824, 826, 827, 19, 203, 720, 52, 52,
133314
+ /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229,
133315
+ /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85,
133316
+ /* 760 */ 352, 352, 120, 157, 959, 960, 58, 977, 409, 355,
133317
+ /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86,
133318
+ /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96,
133256133319
/* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
133257
- /* 800 */ 830, 120, 452, 451, 812, 885, 818, 83, 84, 975,
133258
- /* 810 */ 812, 132, 410, 918, 85, 352, 352, 132, 407, 788,
133259
- /* 820 */ 956, 956, 92, 89, 178, 915, 448, 262, 370, 261,
133260
- /* 830 */ 82, 912, 80, 262, 370, 261, 932, 823, 823, 823,
133261
- /* 840 */ 825, 19, 257, 434, 96, 96, 96, 96, 95, 95,
133262
- /* 850 */ 94, 94, 94, 93, 351, 830, 268, 452, 451, 956,
133263
- /* 860 */ 956, 818, 957, 958, 120, 92, 89, 178, 943, 2,
133264
- /* 870 */ 916, 963, 268, 1, 766, 76, 445, 761, 3, 707,
133265
- /* 880 */ 899, 899, 387, 956, 956, 756, 917, 371, 739, 777,
133266
- /* 890 */ 755, 907, 823, 823, 823, 825, 19, 883, 740, 450,
133267
- /* 900 */ 24, 957, 958, 83, 84, 369, 956, 956, 708, 226,
133268
- /* 910 */ 85, 352, 352, 745, 315, 314, 313, 215, 311, 10,
133269
- /* 920 */ 10, 682, 448, 349, 348, 957, 958, 887, 776, 691,
133270
- /* 930 */ 331, 956, 956, 337, 157, 450, 268, 103, 450, 434,
133271
- /* 940 */ 450, 816, 310, 906, 887, 889, 321, 450, 957, 958,
133272
- /* 950 */ 708, 830, 775, 452, 451, 10, 10, 818, 10, 10,
133273
- /* 960 */ 52, 52, 171, 170, 180, 225, 248, 10, 10, 339,
133274
- /* 970 */ 701, 701, 233, 957, 958, 247, 982, 741, 450, 956,
133275
- /* 980 */ 956, 425, 157, 980, 685, 981, 182, 912, 823, 823,
133276
- /* 990 */ 823, 825, 19, 183, 324, 423, 132, 181, 51, 51,
133277
- /* 1000 */ 715, 349, 348, 394, 256, 887, 334, 915, 983, 983,
133278
- /* 1010 */ 830, 417, 824, 234, 198, 234, 818, 268, 326, 382,
133279
- /* 1020 */ 120, 957, 958, 264, 177, 98, 98, 98, 98, 91,
133320
+ /* 800 */ 832, 120, 452, 451, 813, 887, 819, 83, 84, 977,
133321
+ /* 810 */ 813, 132, 410, 920, 85, 352, 352, 132, 407, 789,
133322
+ /* 820 */ 958, 958, 92, 89, 178, 917, 448, 262, 370, 261,
133323
+ /* 830 */ 82, 914, 80, 262, 370, 261, 776, 824, 824, 826,
133324
+ /* 840 */ 827, 19, 934, 434, 96, 96, 96, 96, 95, 95,
133325
+ /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 958,
133326
+ /* 860 */ 958, 819, 959, 960, 120, 92, 89, 178, 945, 2,
133327
+ /* 870 */ 918, 965, 268, 1, 976, 76, 445, 762, 3, 708,
133328
+ /* 880 */ 901, 901, 387, 958, 958, 757, 919, 371, 740, 778,
133329
+ /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450,
133330
+ /* 900 */ 24, 959, 960, 83, 84, 369, 958, 958, 177, 226,
133331
+ /* 910 */ 85, 352, 352, 885, 315, 314, 313, 215, 311, 10,
133332
+ /* 920 */ 10, 683, 448, 349, 348, 959, 960, 909, 777, 157,
133333
+ /* 930 */ 120, 958, 958, 337, 776, 416, 711, 310, 450, 434,
133334
+ /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 959, 960,
133335
+ /* 950 */ 908, 832, 792, 452, 451, 9, 9, 819, 10, 10,
133336
+ /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171,
133337
+ /* 970 */ 170, 167, 339, 959, 960, 247, 984, 702, 702, 450,
133338
+ /* 980 */ 715, 233, 686, 982, 889, 983, 182, 914, 824, 824,
133339
+ /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10,
133340
+ /* 1000 */ 10, 889, 891, 749, 958, 958, 917, 268, 985, 198,
133341
+ /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825,
133342
+ /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91,
133280133343
/* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133281
- /* 1040 */ 351, 816, 416, 371, 120, 359, 816, 823, 823, 823,
133282
- /* 1050 */ 775, 299, 916, 450, 368, 197, 196, 195, 358, 200,
133283
- /* 1060 */ 175, 380, 9, 9, 450, 1287, 875, 714, 917, 450,
133284
- /* 1070 */ 433, 237, 450, 36, 36, 132, 253, 450, 255, 450,
133285
- /* 1080 */ 117, 450, 809, 362, 37, 37, 983, 983, 450, 12,
133286
- /* 1090 */ 12, 330, 27, 27, 446, 331, 280, 38, 38, 39,
133287
- /* 1100 */ 39, 40, 40, 1207, 450, 816, 335, 356, 41, 41,
133288
- /* 1110 */ 450, 336, 450, 695, 450, 120, 450, 332, 133, 450,
133289
- /* 1120 */ 268, 450, 269, 450, 42, 42, 450, 816, 254, 450,
133290
- /* 1130 */ 28, 28, 29, 29, 31, 31, 43, 43, 450, 44,
133291
- /* 1140 */ 44, 45, 45, 11, 11, 450, 46, 46, 450, 105,
133292
- /* 1150 */ 105, 450, 748, 713, 450, 695, 450, 910, 47, 47,
133293
- /* 1160 */ 450, 267, 450, 415, 450, 48, 48, 450, 33, 33,
133294
- /* 1170 */ 386, 49, 49, 450, 50, 50, 34, 34, 450, 172,
133295
- /* 1180 */ 122, 122, 123, 123, 124, 124, 450, 56, 56, 450,
133296
- /* 1190 */ 120, 450, 345, 35, 35, 450, 790, 450, 106, 106,
133297
- /* 1200 */ 450, 74, 450, 974, 450, 791, 53, 53, 432, 107,
133298
- /* 1210 */ 107, 108, 108, 450, 272, 104, 104, 121, 121, 450,
133299
- /* 1220 */ 119, 119, 112, 112, 111, 111, 450, 317, 996, 450,
133300
- /* 1230 */ 118, 450, 162, 109, 109, 317, 935, 450, 896, 110,
133301
- /* 1240 */ 110, 450, 895, 744, 688, 436, 55, 55, 20, 57,
133302
- /* 1250 */ 57, 54, 54, 440, 444, 756, 385, 26, 26, 274,
133303
- /* 1260 */ 755, 30, 30, 21, 672, 673, 674, 223, 175, 931,
133304
- /* 1270 */ 814, 372, 319, 202, 202, 882, 120, 120, 120, 374,
133305
- /* 1280 */ 826, 710, 202, 72, 276, 263, 120, 120, 74, 395,
133306
- /* 1290 */ 278, 286, 208, 74, 718, 717, 725, 726, 892, 892,
133307
- /* 1300 */ 167, 997, 285, 753, 729, 784, 77, 878, 202, 997,
133308
- /* 1310 */ 208, 693, 891, 891, 116, 281, 782, 882, 390, 815,
133309
- /* 1320 */ 762, 773, 826, 431, 302, 303, 822, 218, 696, 289,
133310
- /* 1330 */ 690, 291, 293, 679, 678, 680, 950, 159, 316, 7,
133311
- /* 1340 */ 364, 252, 259, 804, 909, 376, 400, 295, 308, 173,
133312
- /* 1350 */ 435, 953, 168, 991, 135, 205, 926, 924, 59, 988,
133313
- /* 1360 */ 62, 284, 880, 333, 879, 712, 144, 156, 130, 72,
133314
- /* 1370 */ 366, 367, 393, 185, 189, 160, 383, 67, 389, 266,
133315
- /* 1380 */ 137, 894, 774, 219, 154, 139, 190, 140, 391, 271,
133316
- /* 1390 */ 191, 141, 142, 801, 681, 148, 811, 342, 322, 192,
133317
- /* 1400 */ 406, 732, 911, 874, 723, 731, 323, 710, 730, 71,
133318
- /* 1410 */ 704, 204, 283, 703, 6, 79, 421, 702, 965, 770,
133319
- /* 1420 */ 297, 346, 426, 102, 722, 288, 73, 424, 213, 951,
133320
- /* 1430 */ 771, 438, 22, 290, 687, 769, 442, 453, 239, 217,
133321
- /* 1440 */ 214, 668, 125, 353, 126, 216, 454, 166, 676, 115,
133322
- /* 1450 */ 675, 235, 244, 179, 670, 357, 810, 113, 890, 888,
133323
- /* 1460 */ 292, 136, 128, 752, 304, 768, 294, 305, 138, 742,
133324
- /* 1470 */ 306, 307, 127, 184, 860, 258, 905, 145, 143, 238,
133325
- /* 1480 */ 63, 64, 65, 66, 240, 129, 908, 186, 187, 904,
133326
- /* 1490 */ 8, 13, 188, 265, 897, 149, 202, 985, 388, 684,
133327
- /* 1500 */ 150, 161, 392, 285, 193, 279, 151, 396, 68, 14,
133328
- /* 1510 */ 401, 15, 327, 721, 328, 134, 69, 70, 236, 131,
133329
- /* 1520 */ 829, 828, 858, 750, 16, 201, 754, 4, 783, 220,
133330
- /* 1530 */ 414, 174, 222, 152, 77, 778, 74, 17, 18, 873,
133331
- /* 1540 */ 859, 857, 914, 862, 913, 207, 206, 940, 163, 437,
133332
- /* 1550 */ 946, 941, 164, 209, 210, 441, 861, 165, 312, 827,
133333
- /* 1560 */ 694, 87, 1000, 309, 211, 1000, 1000, 1000, 1000, 1289,
133334
- /* 1570 */ 1288,
133344
+ /* 1040 */ 351, 157, 810, 371, 382, 359, 959, 960, 358, 268,
133345
+ /* 1050 */ 450, 918, 368, 324, 824, 824, 826, 450, 709, 450,
133346
+ /* 1060 */ 264, 380, 889, 450, 877, 746, 253, 919, 255, 433,
133347
+ /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12,
133348
+ /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162,
133349
+ /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450,
133350
+ /* 1100 */ 709, 1210, 450, 132, 450, 39, 39, 450, 40, 40,
133351
+ /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28,
133352
+ /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450,
133353
+ /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767,
133354
+ /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47,
133355
+ /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172,
133356
+ /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122,
133357
+ /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 898, 56, 56,
133358
+ /* 1180 */ 450, 897, 35, 35, 450, 267, 450, 817, 450, 817,
133359
+ /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817,
133360
+ /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119,
133361
+ /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111,
133362
+ /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 912,
133363
+ /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331,
133364
+ /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 937, 197,
133365
+ /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436,
133366
+ /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 933,
133367
+ /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202,
133368
+ /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 884,
133369
+ /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74,
133370
+ /* 1300 */ 726, 727, 785, 783, 880, 202, 999, 208, 894, 893,
133371
+ /* 1310 */ 894, 893, 694, 816, 763, 116, 774, 1290, 431, 432,
133372
+ /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289,
133373
+ /* 1330 */ 679, 884, 681, 952, 291, 218, 293, 7, 316, 828,
133374
+ /* 1340 */ 173, 805, 259, 364, 252, 911, 376, 713, 295, 435,
133375
+ /* 1350 */ 308, 168, 955, 993, 135, 400, 990, 284, 882, 881,
133376
+ /* 1360 */ 205, 928, 926, 59, 333, 62, 144, 156, 130, 72,
133377
+ /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383,
133378
+ /* 1380 */ 67, 896, 140, 141, 142, 148, 389, 812, 775, 266,
133379
+ /* 1390 */ 219, 190, 154, 391, 913, 876, 271, 406, 191, 322,
133380
+ /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421,
133381
+ /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346,
133382
+ /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 967, 239,
133383
+ /* 1430 */ 769, 102, 862, 438, 426, 240, 424, 442, 73, 213,
133384
+ /* 1440 */ 688, 238, 22, 453, 953, 214, 217, 216, 454, 677,
133385
+ /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166,
133386
+ /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 892,
133387
+ /* 1470 */ 327, 890, 811, 328, 134, 128, 136, 138, 743, 258,
133388
+ /* 1480 */ 907, 184, 143, 129, 910, 186, 63, 64, 145, 187,
133389
+ /* 1490 */ 906, 65, 8, 66, 13, 188, 202, 899, 265, 149,
133390
+ /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396,
133391
+ /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131,
133392
+ /* 1520 */ 830, 860, 70, 751, 16, 414, 755, 4, 174, 220,
133393
+ /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 875,
133394
+ /* 1540 */ 861, 859, 916, 864, 915, 207, 206, 942, 163, 437,
133395
+ /* 1550 */ 948, 943, 164, 209, 1002, 441, 863, 165, 210, 829,
133396
+ /* 1560 */ 695, 87, 312, 211, 1292, 1291, 309,
133335133397
};
133336133398
static const YYCODETYPE yy_lookahead[] = {
133337133399
/* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28,
133338133400
/* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
133339133401
/* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
@@ -133415,87 +133477,86 @@
133415133477
/* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43,
133416133478
/* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
133417133479
/* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97,
133418133480
/* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175,
133419133481
/* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110,
133420
- /* 830 */ 137, 163, 139, 108, 109, 110, 152, 132, 133, 134,
133482
+ /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134,
133421133483
/* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48,
133422
- /* 850 */ 49, 50, 51, 52, 53, 95, 152, 97, 98, 55,
133484
+ /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55,
133423133485
/* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147,
133424
- /* 870 */ 57, 171, 152, 22, 213, 19, 20, 49, 22, 179,
133486
+ /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179,
133425133487
/* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124,
133426
- /* 890 */ 121, 152, 132, 133, 134, 135, 136, 193, 85, 152,
133427
- /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 55, 5,
133488
+ /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152,
133489
+ /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5,
133428133490
/* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172,
133429
- /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 166,
133430
- /* 930 */ 167, 55, 56, 186, 152, 152, 152, 22, 152, 83,
133431
- /* 940 */ 152, 152, 160, 152, 169, 170, 164, 152, 97, 98,
133432
- /* 950 */ 97, 95, 26, 97, 98, 172, 173, 101, 172, 173,
133433
- /* 960 */ 172, 173, 47, 48, 60, 22, 62, 172, 173, 186,
133434
- /* 970 */ 55, 56, 186, 97, 98, 71, 100, 193, 152, 55,
133435
- /* 980 */ 56, 186, 152, 107, 21, 109, 82, 163, 132, 133,
133436
- /* 990 */ 134, 135, 136, 89, 164, 207, 92, 93, 172, 173,
133437
- /* 1000 */ 181, 47, 48, 19, 16, 230, 217, 12, 132, 133,
133438
- /* 1010 */ 95, 163, 97, 183, 30, 185, 101, 152, 114, 152,
133439
- /* 1020 */ 196, 97, 98, 152, 98, 38, 39, 40, 41, 42,
133491
+ /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152,
133492
+ /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83,
133493
+ /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98,
133494
+ /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173,
133495
+ /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47,
133496
+ /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152,
133497
+ /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133,
133498
+ /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172,
133499
+ /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30,
133500
+ /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97,
133501
+ /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42,
133440133502
/* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
133441
- /* 1040 */ 53, 152, 152, 219, 196, 141, 152, 132, 133, 134,
133442
- /* 1050 */ 124, 225, 57, 152, 91, 108, 109, 110, 193, 211,
133443
- /* 1060 */ 212, 237, 172, 173, 152, 122, 103, 181, 73, 152,
133444
- /* 1070 */ 75, 210, 152, 172, 173, 92, 88, 152, 90, 152,
133445
- /* 1080 */ 22, 152, 163, 100, 172, 173, 132, 133, 152, 172,
133446
- /* 1090 */ 173, 107, 172, 173, 166, 167, 112, 172, 173, 172,
133447
- /* 1100 */ 173, 172, 173, 140, 152, 152, 217, 242, 172, 173,
133448
- /* 1110 */ 152, 217, 152, 55, 152, 196, 152, 245, 246, 152,
133449
- /* 1120 */ 152, 152, 152, 152, 172, 173, 152, 152, 140, 152,
133450
- /* 1130 */ 172, 173, 172, 173, 172, 173, 172, 173, 152, 172,
133451
- /* 1140 */ 173, 172, 173, 172, 173, 152, 172, 173, 152, 172,
133452
- /* 1150 */ 173, 152, 195, 152, 152, 97, 152, 163, 172, 173,
133453
- /* 1160 */ 152, 193, 152, 206, 152, 172, 173, 152, 172, 173,
133454
- /* 1170 */ 217, 172, 173, 152, 172, 173, 172, 173, 152, 26,
133455
- /* 1180 */ 172, 173, 172, 173, 172, 173, 152, 172, 173, 152,
133456
- /* 1190 */ 196, 152, 217, 172, 173, 152, 61, 152, 172, 173,
133457
- /* 1200 */ 152, 26, 152, 26, 152, 70, 172, 173, 191, 172,
133458
- /* 1210 */ 173, 172, 173, 152, 152, 172, 173, 172, 173, 152,
133459
- /* 1220 */ 172, 173, 172, 173, 172, 173, 152, 22, 23, 152,
133460
- /* 1230 */ 22, 152, 24, 172, 173, 22, 23, 152, 59, 172,
133461
- /* 1240 */ 173, 152, 63, 163, 163, 163, 172, 173, 22, 172,
133462
- /* 1250 */ 173, 172, 173, 163, 163, 116, 77, 172, 173, 152,
133463
- /* 1260 */ 121, 172, 173, 37, 7, 8, 9, 211, 212, 23,
133464
- /* 1270 */ 23, 23, 26, 26, 26, 55, 196, 196, 196, 23,
133465
- /* 1280 */ 55, 106, 26, 130, 152, 23, 196, 196, 26, 23,
133466
- /* 1290 */ 23, 101, 26, 26, 100, 101, 7, 8, 132, 133,
133467
- /* 1300 */ 123, 96, 112, 23, 152, 23, 26, 23, 26, 96,
133468
- /* 1310 */ 26, 23, 132, 133, 26, 152, 152, 97, 234, 152,
133469
- /* 1320 */ 152, 152, 97, 152, 152, 152, 152, 233, 152, 210,
133470
- /* 1330 */ 152, 210, 210, 152, 152, 152, 152, 197, 150, 198,
133471
- /* 1340 */ 214, 214, 239, 201, 201, 239, 176, 214, 200, 184,
133472
- /* 1350 */ 227, 155, 198, 67, 243, 122, 159, 159, 240, 69,
133473
- /* 1360 */ 240, 175, 175, 159, 175, 180, 22, 220, 27, 130,
133474
- /* 1370 */ 18, 159, 18, 158, 158, 220, 159, 137, 74, 235,
133475
- /* 1380 */ 189, 236, 159, 159, 22, 192, 158, 192, 177, 159,
133476
- /* 1390 */ 158, 192, 192, 201, 159, 189, 189, 76, 177, 158,
133477
- /* 1400 */ 107, 174, 201, 201, 182, 174, 177, 106, 174, 107,
133478
- /* 1410 */ 174, 159, 174, 176, 22, 137, 125, 174, 174, 216,
133479
- /* 1420 */ 159, 53, 126, 129, 182, 215, 128, 127, 25, 13,
133480
- /* 1430 */ 216, 177, 26, 215, 162, 216, 177, 161, 229, 6,
133481
- /* 1440 */ 153, 4, 165, 3, 165, 153, 151, 22, 151, 178,
133482
- /* 1450 */ 151, 178, 142, 15, 151, 94, 120, 16, 23, 23,
133483
- /* 1460 */ 215, 131, 111, 205, 204, 216, 215, 203, 123, 20,
133484
- /* 1470 */ 202, 201, 165, 125, 224, 16, 1, 131, 123, 226,
133485
- /* 1480 */ 37, 37, 37, 37, 229, 111, 56, 64, 122, 1,
133486
- /* 1490 */ 5, 22, 107, 140, 80, 80, 26, 87, 72, 20,
133487
- /* 1500 */ 107, 24, 19, 112, 105, 23, 22, 79, 22, 22,
133488
- /* 1510 */ 79, 22, 249, 58, 249, 246, 22, 26, 79, 68,
133489
- /* 1520 */ 23, 23, 23, 116, 22, 64, 23, 22, 56, 23,
133490
- /* 1530 */ 26, 122, 23, 22, 26, 124, 26, 64, 64, 23,
133503
+ /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152,
133504
+ /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152,
133505
+ /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75,
133506
+ /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172,
133507
+ /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24,
133508
+ /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152,
133509
+ /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173,
133510
+ /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172,
133511
+ /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152,
133512
+ /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213,
133513
+ /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172,
133514
+ /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26,
133515
+ /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173,
133516
+ /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173,
133517
+ /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152,
133518
+ /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152,
133519
+ /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173,
133520
+ /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173,
133521
+ /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163,
133522
+ /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167,
133523
+ /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108,
133524
+ /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163,
133525
+ /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23,
133526
+ /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26,
133527
+ /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55,
133528
+ /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26,
133529
+ /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132,
133530
+ /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191,
133531
+ /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210,
133532
+ /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97,
133533
+ /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227,
133534
+ /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175,
133535
+ /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130,
133536
+ /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159,
133537
+ /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235,
133538
+ /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177,
133539
+ /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125,
133540
+ /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53,
133541
+ /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229,
133542
+ /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25,
133543
+ /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151,
133544
+ /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22,
133545
+ /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23,
133546
+ /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16,
133547
+ /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122,
133548
+ /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80,
133549
+ /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79,
133550
+ /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68,
133551
+ /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23,
133552
+ /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23,
133491133553
/* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24,
133492
- /* 1550 */ 1, 23, 22, 26, 122, 24, 23, 22, 15, 23,
133493
- /* 1560 */ 23, 22, 251, 23, 122, 251, 251, 251, 251, 122,
133494
- /* 1570 */ 122,
133554
+ /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23,
133555
+ /* 1560 */ 23, 22, 15, 122, 122, 122, 23,
133495133556
};
133496
-#define YY_SHIFT_USE_DFLT (1571)
133557
+#define YY_SHIFT_USE_DFLT (1567)
133497133558
#define YY_SHIFT_COUNT (455)
133498133559
#define YY_SHIFT_MIN (-94)
133499133560
#define YY_SHIFT_MAX (1549)
133500133561
static const short yy_shift_ofst[] = {
133501133562
/* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19,
@@ -133507,132 +133568,132 @@
133507133568
/* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133508133569
/* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133509133570
/* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133510133571
/* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133511133572
/* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746,
133512
- /* 110 */ 801, 23, 32, 924, 963, 984, 954, 954, 924, 73,
133513
- /* 120 */ 113, -51, 1571, 1571, 1571, 536, 536, 536, 99, 99,
133514
- /* 130 */ 813, 813, 667, 205, 240, 924, 924, 924, 924, 924,
133515
- /* 140 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
133516
- /* 150 */ 924, 924, 924, 924, 924, 332, 983, 422, 422, 113,
133517
- /* 160 */ 30, 30, 30, 30, 30, 30, 1571, 1571, 1571, 915,
133518
- /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 924,
133519
- /* 180 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
133520
- /* 190 */ 924, 924, 924, 924, 924, 672, 672, 672, 924, 924,
133521
- /* 200 */ 657, 924, 924, 924, -18, 924, 924, 995, 924, 924,
133522
- /* 210 */ 924, 924, 924, 924, 924, 924, 924, 924, 772, 1179,
133523
- /* 220 */ 712, 712, 712, 926, 45, 769, 1257, 1153, 418, 418,
133524
- /* 230 */ 569, 1153, 569, 1175, 607, 663, 1135, 418, 693, 1135,
133525
- /* 240 */ 1135, 1177, 1139, 1208, 1286, 1233, 1233, 1290, 1290, 1233,
133526
- /* 250 */ 1344, 1341, 1239, 1352, 1352, 1352, 1352, 1233, 1354, 1239,
133527
- /* 260 */ 1344, 1341, 1341, 1239, 1233, 1354, 1240, 1304, 1233, 1233,
133528
- /* 270 */ 1354, 1362, 1233, 1354, 1233, 1354, 1362, 1293, 1293, 1293,
133529
- /* 280 */ 1321, 1362, 1293, 1301, 1293, 1321, 1293, 1293, 1291, 1302,
133530
- /* 290 */ 1291, 1302, 1291, 1302, 1291, 1302, 1233, 1392, 1233, 1278,
133531
- /* 300 */ 1362, 1368, 1368, 1362, 1294, 1296, 1298, 1300, 1239, 1403,
133532
- /* 310 */ 1406, 1416, 1416, 1433, 1433, 1433, 1433, 1571, 1571, 1571,
133533
- /* 320 */ 1571, 1571, 1571, 1571, 1571, 519, 988, 1205, 1213, 104,
133534
- /* 330 */ 947, 1058, 1246, 1226, 1247, 1248, 1256, 1262, 1266, 1267,
133535
- /* 340 */ 853, 1194, 1289, 1190, 1280, 1282, 1220, 1284, 1166, 1180,
133536
- /* 350 */ 1288, 1225, 943, 1437, 1440, 1425, 1310, 1438, 1361, 1441,
133537
- /* 360 */ 1435, 1436, 1336, 1330, 1351, 1345, 1449, 1348, 1459, 1475,
133538
- /* 370 */ 1355, 1346, 1443, 1444, 1445, 1446, 1374, 1430, 1423, 1366,
133539
- /* 380 */ 1488, 1485, 1469, 1385, 1353, 1414, 1470, 1415, 1410, 1426,
133540
- /* 390 */ 1393, 1477, 1479, 1483, 1391, 1399, 1484, 1428, 1486, 1487,
133541
- /* 400 */ 1482, 1489, 1431, 1455, 1494, 1439, 1451, 1497, 1498, 1499,
133542
- /* 410 */ 1491, 1407, 1502, 1503, 1505, 1504, 1409, 1506, 1509, 1472,
133543
- /* 420 */ 1461, 1511, 1411, 1508, 1473, 1510, 1474, 1516, 1508, 1517,
133573
+ /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73,
133574
+ /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99,
133575
+ /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949,
133576
+ /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
133577
+ /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113,
133578
+ /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922,
133579
+ /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949,
133580
+ /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
133581
+ /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949,
133582
+ /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949,
133583
+ /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118,
133584
+ /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418,
133585
+ /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882,
133586
+ /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238,
133587
+ /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239,
133588
+ /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238,
133589
+ /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290,
133590
+ /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304,
133591
+ /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280,
133592
+ /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414,
133593
+ /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567,
133594
+ /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104,
133595
+ /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273,
133596
+ /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177,
133597
+ /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452,
133598
+ /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479,
133599
+ /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367,
133600
+ /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429,
133601
+ /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491,
133602
+ /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498,
133603
+ /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475,
133604
+ /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517,
133544133605
/* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527,
133545
- /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1432,
133546
- /* 450 */ 1442, 1447, 1448, 1540, 1543, 1549,
133606
+ /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436,
133607
+ /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549,
133547133608
};
133548133609
#define YY_REDUCE_USE_DFLT (-130)
133549133610
#define YY_REDUCE_COUNT (324)
133550133611
#define YY_REDUCE_MIN (-129)
133551
-#define YY_REDUCE_MAX (1307)
133612
+#define YY_REDUCE_MAX (1300)
133552133613
static const short yy_reduce_ofst[] = {
133553133614
/* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435,
133554
- /* 10 */ 601, 644, 148, 747, 783, 786, 419, 788, 795, 826,
133555
- /* 20 */ 454, 775, 830, 495, 824, 848, 76, 76, 76, 76,
133615
+ /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790,
133616
+ /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76,
133556133617
/* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
133557133618
/* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
133558
- /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 890, 901,
133559
- /* 60 */ 912, 917, 920, 925, 927, 929, 936, 952, 958, 960,
133560
- /* 70 */ 962, 964, 967, 969, 971, 974, 977, 986, 993, 996,
133561
- /* 80 */ 999, 1002, 1004, 1008, 1010, 1012, 1015, 1021, 1026, 1034,
133562
- /* 90 */ 1037, 1039, 1043, 1045, 1048, 1050, 1052, 1061, 1067, 1074,
133563
- /* 100 */ 1077, 1079, 1085, 1089, 76, 76, 76, 76, 76, 76,
133564
- /* 110 */ 76, 76, 76, 865, 36, 523, 235, 416, 782, 76,
133619
+ /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898,
133620
+ /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950,
133621
+ /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984,
133622
+ /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021,
133623
+ /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062,
133624
+ /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76,
133625
+ /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76,
133565133626
/* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220,
133566133627
/* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620,
133567
- /* 140 */ 704, 720, 784, 116, 789, 349, 889, 894, 404, 953,
133568
- /* 150 */ 968, -129, 975, 492, 62, 722, 919, 763, 928, 957,
133569
- /* 160 */ 994, 1080, 1081, 1082, 1090, 1091, 872, 1056, 557, 57,
133628
+ /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047,
133629
+ /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808,
133630
+ /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57,
133570133631
/* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438,
133571
- /* 180 */ 497, 517, 591, 653, 684, 690, 739, 791, 867, 871,
133572
- /* 190 */ 970, 1062, 1107, 1132, 1152, 355, 819, 886, 1001, 1163,
133573
- /* 200 */ 661, 1164, 1167, 1168, 861, 1169, 1171, 1017, 1172, 1173,
133574
- /* 210 */ 1174, 250, 1176, 1178, 1181, 1182, 1183, 1184, 1084, 1094,
133575
- /* 220 */ 1119, 1121, 1122, 661, 1140, 1141, 1188, 1142, 1126, 1127,
133576
- /* 230 */ 1103, 1143, 1106, 1170, 1165, 1185, 1186, 1133, 1123, 1187,
133577
- /* 240 */ 1189, 1148, 1154, 1196, 1111, 1197, 1198, 1118, 1120, 1204,
133578
- /* 250 */ 1147, 1191, 1192, 1193, 1195, 1199, 1200, 1212, 1215, 1201,
133579
- /* 260 */ 1155, 1206, 1207, 1202, 1217, 1216, 1145, 1144, 1223, 1224,
133580
- /* 270 */ 1228, 1211, 1230, 1232, 1235, 1241, 1221, 1227, 1231, 1234,
133581
- /* 280 */ 1222, 1229, 1236, 1237, 1238, 1242, 1243, 1244, 1203, 1210,
133582
- /* 290 */ 1214, 1218, 1219, 1245, 1249, 1251, 1252, 1250, 1261, 1253,
133583
- /* 300 */ 1254, 1209, 1255, 1259, 1258, 1260, 1264, 1268, 1270, 1272,
133584
- /* 310 */ 1276, 1287, 1292, 1295, 1297, 1299, 1303, 1263, 1265, 1269,
133585
- /* 320 */ 1277, 1279, 1271, 1273, 1307,
133632
+ /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908,
133633
+ /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101,
133634
+ /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171,
133635
+ /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102,
133636
+ /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130,
133637
+ /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183,
133638
+ /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205,
133639
+ /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193,
133640
+ /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231,
133641
+ /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232,
133642
+ /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201,
133643
+ /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215,
133644
+ /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278,
133645
+ /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228,
133646
+ /* 320 */ 1288, 1291, 1276, 1277, 1295,
133586133647
};
133587133648
static const YYACTIONTYPE yy_default[] = {
133588
- /* 0 */ 1278, 1268, 1268, 1268, 1200, 1200, 1200, 1200, 1268, 1094,
133589
- /* 10 */ 1123, 1123, 1252, 1329, 1329, 1329, 1329, 1329, 1329, 1199,
133590
- /* 20 */ 1329, 1329, 1329, 1329, 1268, 1098, 1129, 1329, 1329, 1329,
133591
- /* 30 */ 1329, 1201, 1202, 1329, 1329, 1329, 1251, 1253, 1139, 1138,
133592
- /* 40 */ 1137, 1136, 1234, 1110, 1134, 1127, 1131, 1201, 1195, 1196,
133593
- /* 50 */ 1194, 1198, 1202, 1329, 1130, 1164, 1179, 1163, 1329, 1329,
133594
- /* 60 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133595
- /* 70 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133596
- /* 80 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133597
- /* 90 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133598
- /* 100 */ 1329, 1329, 1329, 1329, 1173, 1178, 1185, 1177, 1174, 1166,
133599
- /* 110 */ 1165, 1167, 1168, 1329, 1017, 1065, 1329, 1329, 1329, 1169,
133600
- /* 120 */ 1329, 1170, 1182, 1181, 1180, 1259, 1286, 1285, 1329, 1329,
133601
- /* 130 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133602
- /* 140 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133603
- /* 150 */ 1329, 1329, 1329, 1329, 1329, 1278, 1268, 1023, 1023, 1329,
133604
- /* 160 */ 1268, 1268, 1268, 1268, 1268, 1268, 1264, 1098, 1089, 1329,
133605
- /* 170 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133606
- /* 180 */ 1256, 1254, 1329, 1215, 1329, 1329, 1329, 1329, 1329, 1329,
133607
- /* 190 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133608
- /* 200 */ 1329, 1329, 1329, 1329, 1094, 1329, 1329, 1329, 1329, 1329,
133609
- /* 210 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1280, 1329, 1229,
133610
- /* 220 */ 1094, 1094, 1094, 1096, 1078, 1088, 1002, 1133, 1112, 1112,
133611
- /* 230 */ 1318, 1133, 1318, 1040, 1300, 1037, 1123, 1112, 1197, 1123,
133612
- /* 240 */ 1123, 1095, 1088, 1329, 1321, 1103, 1103, 1320, 1320, 1103,
133613
- /* 250 */ 1144, 1068, 1133, 1074, 1074, 1074, 1074, 1103, 1014, 1133,
133614
- /* 260 */ 1144, 1068, 1068, 1133, 1103, 1014, 1233, 1315, 1103, 1103,
133615
- /* 270 */ 1014, 1208, 1103, 1014, 1103, 1014, 1208, 1066, 1066, 1066,
133616
- /* 280 */ 1055, 1208, 1066, 1040, 1066, 1055, 1066, 1066, 1116, 1111,
133617
- /* 290 */ 1116, 1111, 1116, 1111, 1116, 1111, 1103, 1203, 1103, 1329,
133618
- /* 300 */ 1208, 1212, 1212, 1208, 1128, 1117, 1126, 1124, 1133, 1020,
133619
- /* 310 */ 1058, 1283, 1283, 1279, 1279, 1279, 1279, 1326, 1326, 1264,
133620
- /* 320 */ 1295, 1295, 1042, 1042, 1295, 1329, 1329, 1329, 1329, 1329,
133621
- /* 330 */ 1329, 1290, 1329, 1217, 1329, 1329, 1329, 1329, 1329, 1329,
133622
- /* 340 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133623
- /* 350 */ 1329, 1329, 1150, 1329, 998, 1261, 1329, 1329, 1260, 1329,
133624
- /* 360 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133625
- /* 370 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1317,
133626
- /* 380 */ 1329, 1329, 1329, 1329, 1329, 1329, 1232, 1231, 1329, 1329,
133627
- /* 390 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133628
- /* 400 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133629
- /* 410 */ 1329, 1080, 1329, 1329, 1329, 1304, 1329, 1329, 1329, 1329,
133630
- /* 420 */ 1329, 1329, 1329, 1125, 1329, 1118, 1329, 1329, 1308, 1329,
133631
- /* 430 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1270,
133632
- /* 440 */ 1329, 1329, 1329, 1269, 1329, 1329, 1329, 1329, 1329, 1152,
133633
- /* 450 */ 1329, 1151, 1155, 1329, 1008, 1329,
133649
+ /* 0 */ 1281, 1271, 1271, 1271, 1203, 1203, 1203, 1203, 1271, 1096,
133650
+ /* 10 */ 1125, 1125, 1255, 1332, 1332, 1332, 1332, 1332, 1332, 1202,
133651
+ /* 20 */ 1332, 1332, 1332, 1332, 1271, 1100, 1131, 1332, 1332, 1332,
133652
+ /* 30 */ 1332, 1204, 1205, 1332, 1332, 1332, 1254, 1256, 1141, 1140,
133653
+ /* 40 */ 1139, 1138, 1237, 1112, 1136, 1129, 1133, 1204, 1198, 1199,
133654
+ /* 50 */ 1197, 1201, 1205, 1332, 1132, 1167, 1182, 1166, 1332, 1332,
133655
+ /* 60 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133656
+ /* 70 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133657
+ /* 80 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133658
+ /* 90 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133659
+ /* 100 */ 1332, 1332, 1332, 1332, 1176, 1181, 1188, 1180, 1177, 1169,
133660
+ /* 110 */ 1168, 1170, 1171, 1332, 1019, 1067, 1332, 1332, 1332, 1172,
133661
+ /* 120 */ 1332, 1173, 1185, 1184, 1183, 1262, 1289, 1288, 1332, 1332,
133662
+ /* 130 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133663
+ /* 140 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133664
+ /* 150 */ 1332, 1332, 1332, 1332, 1332, 1281, 1271, 1025, 1025, 1332,
133665
+ /* 160 */ 1271, 1271, 1271, 1271, 1271, 1271, 1267, 1100, 1091, 1332,
133666
+ /* 170 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133667
+ /* 180 */ 1259, 1257, 1332, 1218, 1332, 1332, 1332, 1332, 1332, 1332,
133668
+ /* 190 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133669
+ /* 200 */ 1332, 1332, 1332, 1332, 1096, 1332, 1332, 1332, 1332, 1332,
133670
+ /* 210 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1283, 1332, 1232,
133671
+ /* 220 */ 1096, 1096, 1096, 1098, 1080, 1090, 1004, 1135, 1114, 1114,
133672
+ /* 230 */ 1321, 1135, 1321, 1042, 1303, 1039, 1125, 1114, 1200, 1125,
133673
+ /* 240 */ 1125, 1097, 1090, 1332, 1324, 1105, 1105, 1323, 1323, 1105,
133674
+ /* 250 */ 1146, 1070, 1135, 1076, 1076, 1076, 1076, 1105, 1016, 1135,
133675
+ /* 260 */ 1146, 1070, 1070, 1135, 1105, 1016, 1236, 1318, 1105, 1105,
133676
+ /* 270 */ 1016, 1211, 1105, 1016, 1105, 1016, 1211, 1068, 1068, 1068,
133677
+ /* 280 */ 1057, 1211, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
133678
+ /* 290 */ 1118, 1113, 1118, 1113, 1118, 1113, 1105, 1206, 1105, 1332,
133679
+ /* 300 */ 1211, 1215, 1215, 1211, 1130, 1119, 1128, 1126, 1135, 1022,
133680
+ /* 310 */ 1060, 1286, 1286, 1282, 1282, 1282, 1282, 1329, 1329, 1267,
133681
+ /* 320 */ 1298, 1298, 1044, 1044, 1298, 1332, 1332, 1332, 1332, 1332,
133682
+ /* 330 */ 1332, 1293, 1332, 1220, 1332, 1332, 1332, 1332, 1332, 1332,
133683
+ /* 340 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133684
+ /* 350 */ 1332, 1332, 1152, 1332, 1000, 1264, 1332, 1332, 1263, 1332,
133685
+ /* 360 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133686
+ /* 370 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1320,
133687
+ /* 380 */ 1332, 1332, 1332, 1332, 1332, 1332, 1235, 1234, 1332, 1332,
133688
+ /* 390 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133689
+ /* 400 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133690
+ /* 410 */ 1332, 1082, 1332, 1332, 1332, 1307, 1332, 1332, 1332, 1332,
133691
+ /* 420 */ 1332, 1332, 1332, 1127, 1332, 1120, 1332, 1332, 1311, 1332,
133692
+ /* 430 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1273,
133693
+ /* 440 */ 1332, 1332, 1332, 1272, 1332, 1332, 1332, 1332, 1332, 1154,
133694
+ /* 450 */ 1332, 1153, 1157, 1332, 1010, 1332,
133634133695
};
133635133696
/********** End of lemon-generated parsing tables *****************************/
133636133697
133637133698
/* The next table maps tokens (terminal symbols) into fallback tokens.
133638133699
** If a construct like the following:
@@ -133862,11 +133923,11 @@
133862133923
"DEFERRABLE", "FOREIGN", "DROP", "UNION",
133863133924
"ALL", "EXCEPT", "INTERSECT", "SELECT",
133864133925
"VALUES", "DISTINCT", "DOT", "FROM",
133865133926
"JOIN", "USING", "ORDER", "GROUP",
133866133927
"HAVING", "LIMIT", "WHERE", "INTO",
133867
- "INTEGER", "FLOAT", "BLOB", "VARIABLE",
133928
+ "FLOAT", "BLOB", "INTEGER", "VARIABLE",
133868133929
"CASE", "WHEN", "THEN", "ELSE",
133869133930
"INDEX", "ALTER", "ADD", "error",
133870133931
"input", "cmdlist", "ecmd", "explain",
133871133932
"cmdx", "cmd", "transtype", "trans_opt",
133872133933
"nm", "savepoint_opt", "create_table", "create_table_args",
@@ -134055,185 +134116,186 @@
134055134116
/* 151 */ "term ::= NULL",
134056134117
/* 152 */ "expr ::= ID|INDEXED",
134057134118
/* 153 */ "expr ::= JOIN_KW",
134058134119
/* 154 */ "expr ::= nm DOT nm",
134059134120
/* 155 */ "expr ::= nm DOT nm DOT nm",
134060
- /* 156 */ "term ::= INTEGER|FLOAT|BLOB",
134121
+ /* 156 */ "term ::= FLOAT|BLOB",
134061134122
/* 157 */ "term ::= STRING",
134062
- /* 158 */ "expr ::= VARIABLE",
134063
- /* 159 */ "expr ::= expr COLLATE ID|STRING",
134064
- /* 160 */ "expr ::= CAST LP expr AS typetoken RP",
134065
- /* 161 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
134066
- /* 162 */ "expr ::= ID|INDEXED LP STAR RP",
134067
- /* 163 */ "term ::= CTIME_KW",
134068
- /* 164 */ "expr ::= LP nexprlist COMMA expr RP",
134069
- /* 165 */ "expr ::= expr AND expr",
134070
- /* 166 */ "expr ::= expr OR expr",
134071
- /* 167 */ "expr ::= expr LT|GT|GE|LE expr",
134072
- /* 168 */ "expr ::= expr EQ|NE expr",
134073
- /* 169 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
134074
- /* 170 */ "expr ::= expr PLUS|MINUS expr",
134075
- /* 171 */ "expr ::= expr STAR|SLASH|REM expr",
134076
- /* 172 */ "expr ::= expr CONCAT expr",
134077
- /* 173 */ "likeop ::= LIKE_KW|MATCH",
134078
- /* 174 */ "likeop ::= NOT LIKE_KW|MATCH",
134079
- /* 175 */ "expr ::= expr likeop expr",
134080
- /* 176 */ "expr ::= expr likeop expr ESCAPE expr",
134081
- /* 177 */ "expr ::= expr ISNULL|NOTNULL",
134082
- /* 178 */ "expr ::= expr NOT NULL",
134083
- /* 179 */ "expr ::= expr IS expr",
134084
- /* 180 */ "expr ::= expr IS NOT expr",
134085
- /* 181 */ "expr ::= NOT expr",
134086
- /* 182 */ "expr ::= BITNOT expr",
134087
- /* 183 */ "expr ::= MINUS expr",
134088
- /* 184 */ "expr ::= PLUS expr",
134089
- /* 185 */ "between_op ::= BETWEEN",
134090
- /* 186 */ "between_op ::= NOT BETWEEN",
134091
- /* 187 */ "expr ::= expr between_op expr AND expr",
134092
- /* 188 */ "in_op ::= IN",
134093
- /* 189 */ "in_op ::= NOT IN",
134094
- /* 190 */ "expr ::= expr in_op LP exprlist RP",
134095
- /* 191 */ "expr ::= LP select RP",
134096
- /* 192 */ "expr ::= expr in_op LP select RP",
134097
- /* 193 */ "expr ::= expr in_op nm dbnm paren_exprlist",
134098
- /* 194 */ "expr ::= EXISTS LP select RP",
134099
- /* 195 */ "expr ::= CASE case_operand case_exprlist case_else END",
134100
- /* 196 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
134101
- /* 197 */ "case_exprlist ::= WHEN expr THEN expr",
134102
- /* 198 */ "case_else ::= ELSE expr",
134103
- /* 199 */ "case_else ::=",
134104
- /* 200 */ "case_operand ::= expr",
134105
- /* 201 */ "case_operand ::=",
134106
- /* 202 */ "exprlist ::=",
134107
- /* 203 */ "nexprlist ::= nexprlist COMMA expr",
134108
- /* 204 */ "nexprlist ::= expr",
134109
- /* 205 */ "paren_exprlist ::=",
134110
- /* 206 */ "paren_exprlist ::= LP exprlist RP",
134111
- /* 207 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
134112
- /* 208 */ "uniqueflag ::= UNIQUE",
134113
- /* 209 */ "uniqueflag ::=",
134114
- /* 210 */ "eidlist_opt ::=",
134115
- /* 211 */ "eidlist_opt ::= LP eidlist RP",
134116
- /* 212 */ "eidlist ::= eidlist COMMA nm collate sortorder",
134117
- /* 213 */ "eidlist ::= nm collate sortorder",
134118
- /* 214 */ "collate ::=",
134119
- /* 215 */ "collate ::= COLLATE ID|STRING",
134120
- /* 216 */ "cmd ::= DROP INDEX ifexists fullname",
134121
- /* 217 */ "cmd ::= VACUUM",
134122
- /* 218 */ "cmd ::= VACUUM nm",
134123
- /* 219 */ "cmd ::= PRAGMA nm dbnm",
134124
- /* 220 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
134125
- /* 221 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
134126
- /* 222 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
134127
- /* 223 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
134128
- /* 224 */ "plus_num ::= PLUS INTEGER|FLOAT",
134129
- /* 225 */ "minus_num ::= MINUS INTEGER|FLOAT",
134130
- /* 226 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
134131
- /* 227 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
134132
- /* 228 */ "trigger_time ::= BEFORE",
134133
- /* 229 */ "trigger_time ::= AFTER",
134134
- /* 230 */ "trigger_time ::= INSTEAD OF",
134135
- /* 231 */ "trigger_time ::=",
134136
- /* 232 */ "trigger_event ::= DELETE|INSERT",
134137
- /* 233 */ "trigger_event ::= UPDATE",
134138
- /* 234 */ "trigger_event ::= UPDATE OF idlist",
134139
- /* 235 */ "when_clause ::=",
134140
- /* 236 */ "when_clause ::= WHEN expr",
134141
- /* 237 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
134142
- /* 238 */ "trigger_cmd_list ::= trigger_cmd SEMI",
134143
- /* 239 */ "trnm ::= nm DOT nm",
134144
- /* 240 */ "tridxby ::= INDEXED BY nm",
134145
- /* 241 */ "tridxby ::= NOT INDEXED",
134146
- /* 242 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
134147
- /* 243 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
134148
- /* 244 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
134149
- /* 245 */ "trigger_cmd ::= select",
134150
- /* 246 */ "expr ::= RAISE LP IGNORE RP",
134151
- /* 247 */ "expr ::= RAISE LP raisetype COMMA nm RP",
134152
- /* 248 */ "raisetype ::= ROLLBACK",
134153
- /* 249 */ "raisetype ::= ABORT",
134154
- /* 250 */ "raisetype ::= FAIL",
134155
- /* 251 */ "cmd ::= DROP TRIGGER ifexists fullname",
134156
- /* 252 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
134157
- /* 253 */ "cmd ::= DETACH database_kw_opt expr",
134158
- /* 254 */ "key_opt ::=",
134159
- /* 255 */ "key_opt ::= KEY expr",
134160
- /* 256 */ "cmd ::= REINDEX",
134161
- /* 257 */ "cmd ::= REINDEX nm dbnm",
134162
- /* 258 */ "cmd ::= ANALYZE",
134163
- /* 259 */ "cmd ::= ANALYZE nm dbnm",
134164
- /* 260 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
134165
- /* 261 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
134166
- /* 262 */ "add_column_fullname ::= fullname",
134167
- /* 263 */ "cmd ::= create_vtab",
134168
- /* 264 */ "cmd ::= create_vtab LP vtabarglist RP",
134169
- /* 265 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
134170
- /* 266 */ "vtabarg ::=",
134171
- /* 267 */ "vtabargtoken ::= ANY",
134172
- /* 268 */ "vtabargtoken ::= lp anylist RP",
134173
- /* 269 */ "lp ::= LP",
134174
- /* 270 */ "with ::=",
134175
- /* 271 */ "with ::= WITH wqlist",
134176
- /* 272 */ "with ::= WITH RECURSIVE wqlist",
134177
- /* 273 */ "wqlist ::= nm eidlist_opt AS LP select RP",
134178
- /* 274 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
134179
- /* 275 */ "input ::= cmdlist",
134180
- /* 276 */ "cmdlist ::= cmdlist ecmd",
134181
- /* 277 */ "cmdlist ::= ecmd",
134182
- /* 278 */ "ecmd ::= SEMI",
134183
- /* 279 */ "ecmd ::= explain cmdx SEMI",
134184
- /* 280 */ "explain ::=",
134185
- /* 281 */ "trans_opt ::=",
134186
- /* 282 */ "trans_opt ::= TRANSACTION",
134187
- /* 283 */ "trans_opt ::= TRANSACTION nm",
134188
- /* 284 */ "savepoint_opt ::= SAVEPOINT",
134189
- /* 285 */ "savepoint_opt ::=",
134190
- /* 286 */ "cmd ::= create_table create_table_args",
134191
- /* 287 */ "columnlist ::= columnlist COMMA columnname carglist",
134192
- /* 288 */ "columnlist ::= columnname carglist",
134193
- /* 289 */ "nm ::= ID|INDEXED",
134194
- /* 290 */ "nm ::= STRING",
134195
- /* 291 */ "nm ::= JOIN_KW",
134196
- /* 292 */ "typetoken ::= typename",
134197
- /* 293 */ "typename ::= ID|STRING",
134198
- /* 294 */ "signed ::= plus_num",
134199
- /* 295 */ "signed ::= minus_num",
134200
- /* 296 */ "carglist ::= carglist ccons",
134201
- /* 297 */ "carglist ::=",
134202
- /* 298 */ "ccons ::= NULL onconf",
134203
- /* 299 */ "conslist_opt ::= COMMA conslist",
134204
- /* 300 */ "conslist ::= conslist tconscomma tcons",
134205
- /* 301 */ "conslist ::= tcons",
134206
- /* 302 */ "tconscomma ::=",
134207
- /* 303 */ "defer_subclause_opt ::= defer_subclause",
134208
- /* 304 */ "resolvetype ::= raisetype",
134209
- /* 305 */ "selectnowith ::= oneselect",
134210
- /* 306 */ "oneselect ::= values",
134211
- /* 307 */ "sclp ::= selcollist COMMA",
134212
- /* 308 */ "as ::= ID|STRING",
134213
- /* 309 */ "expr ::= term",
134214
- /* 310 */ "exprlist ::= nexprlist",
134215
- /* 311 */ "nmnum ::= plus_num",
134216
- /* 312 */ "nmnum ::= nm",
134217
- /* 313 */ "nmnum ::= ON",
134218
- /* 314 */ "nmnum ::= DELETE",
134219
- /* 315 */ "nmnum ::= DEFAULT",
134220
- /* 316 */ "plus_num ::= INTEGER|FLOAT",
134221
- /* 317 */ "foreach_clause ::=",
134222
- /* 318 */ "foreach_clause ::= FOR EACH ROW",
134223
- /* 319 */ "trnm ::= nm",
134224
- /* 320 */ "tridxby ::=",
134225
- /* 321 */ "database_kw_opt ::= DATABASE",
134226
- /* 322 */ "database_kw_opt ::=",
134227
- /* 323 */ "kwcolumn_opt ::=",
134228
- /* 324 */ "kwcolumn_opt ::= COLUMNKW",
134229
- /* 325 */ "vtabarglist ::= vtabarg",
134230
- /* 326 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
134231
- /* 327 */ "vtabarg ::= vtabarg vtabargtoken",
134232
- /* 328 */ "anylist ::=",
134233
- /* 329 */ "anylist ::= anylist LP anylist RP",
134234
- /* 330 */ "anylist ::= anylist ANY",
134123
+ /* 158 */ "term ::= INTEGER",
134124
+ /* 159 */ "expr ::= VARIABLE",
134125
+ /* 160 */ "expr ::= expr COLLATE ID|STRING",
134126
+ /* 161 */ "expr ::= CAST LP expr AS typetoken RP",
134127
+ /* 162 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
134128
+ /* 163 */ "expr ::= ID|INDEXED LP STAR RP",
134129
+ /* 164 */ "term ::= CTIME_KW",
134130
+ /* 165 */ "expr ::= LP nexprlist COMMA expr RP",
134131
+ /* 166 */ "expr ::= expr AND expr",
134132
+ /* 167 */ "expr ::= expr OR expr",
134133
+ /* 168 */ "expr ::= expr LT|GT|GE|LE expr",
134134
+ /* 169 */ "expr ::= expr EQ|NE expr",
134135
+ /* 170 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
134136
+ /* 171 */ "expr ::= expr PLUS|MINUS expr",
134137
+ /* 172 */ "expr ::= expr STAR|SLASH|REM expr",
134138
+ /* 173 */ "expr ::= expr CONCAT expr",
134139
+ /* 174 */ "likeop ::= LIKE_KW|MATCH",
134140
+ /* 175 */ "likeop ::= NOT LIKE_KW|MATCH",
134141
+ /* 176 */ "expr ::= expr likeop expr",
134142
+ /* 177 */ "expr ::= expr likeop expr ESCAPE expr",
134143
+ /* 178 */ "expr ::= expr ISNULL|NOTNULL",
134144
+ /* 179 */ "expr ::= expr NOT NULL",
134145
+ /* 180 */ "expr ::= expr IS expr",
134146
+ /* 181 */ "expr ::= expr IS NOT expr",
134147
+ /* 182 */ "expr ::= NOT expr",
134148
+ /* 183 */ "expr ::= BITNOT expr",
134149
+ /* 184 */ "expr ::= MINUS expr",
134150
+ /* 185 */ "expr ::= PLUS expr",
134151
+ /* 186 */ "between_op ::= BETWEEN",
134152
+ /* 187 */ "between_op ::= NOT BETWEEN",
134153
+ /* 188 */ "expr ::= expr between_op expr AND expr",
134154
+ /* 189 */ "in_op ::= IN",
134155
+ /* 190 */ "in_op ::= NOT IN",
134156
+ /* 191 */ "expr ::= expr in_op LP exprlist RP",
134157
+ /* 192 */ "expr ::= LP select RP",
134158
+ /* 193 */ "expr ::= expr in_op LP select RP",
134159
+ /* 194 */ "expr ::= expr in_op nm dbnm paren_exprlist",
134160
+ /* 195 */ "expr ::= EXISTS LP select RP",
134161
+ /* 196 */ "expr ::= CASE case_operand case_exprlist case_else END",
134162
+ /* 197 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
134163
+ /* 198 */ "case_exprlist ::= WHEN expr THEN expr",
134164
+ /* 199 */ "case_else ::= ELSE expr",
134165
+ /* 200 */ "case_else ::=",
134166
+ /* 201 */ "case_operand ::= expr",
134167
+ /* 202 */ "case_operand ::=",
134168
+ /* 203 */ "exprlist ::=",
134169
+ /* 204 */ "nexprlist ::= nexprlist COMMA expr",
134170
+ /* 205 */ "nexprlist ::= expr",
134171
+ /* 206 */ "paren_exprlist ::=",
134172
+ /* 207 */ "paren_exprlist ::= LP exprlist RP",
134173
+ /* 208 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
134174
+ /* 209 */ "uniqueflag ::= UNIQUE",
134175
+ /* 210 */ "uniqueflag ::=",
134176
+ /* 211 */ "eidlist_opt ::=",
134177
+ /* 212 */ "eidlist_opt ::= LP eidlist RP",
134178
+ /* 213 */ "eidlist ::= eidlist COMMA nm collate sortorder",
134179
+ /* 214 */ "eidlist ::= nm collate sortorder",
134180
+ /* 215 */ "collate ::=",
134181
+ /* 216 */ "collate ::= COLLATE ID|STRING",
134182
+ /* 217 */ "cmd ::= DROP INDEX ifexists fullname",
134183
+ /* 218 */ "cmd ::= VACUUM",
134184
+ /* 219 */ "cmd ::= VACUUM nm",
134185
+ /* 220 */ "cmd ::= PRAGMA nm dbnm",
134186
+ /* 221 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
134187
+ /* 222 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
134188
+ /* 223 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
134189
+ /* 224 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
134190
+ /* 225 */ "plus_num ::= PLUS INTEGER|FLOAT",
134191
+ /* 226 */ "minus_num ::= MINUS INTEGER|FLOAT",
134192
+ /* 227 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
134193
+ /* 228 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
134194
+ /* 229 */ "trigger_time ::= BEFORE",
134195
+ /* 230 */ "trigger_time ::= AFTER",
134196
+ /* 231 */ "trigger_time ::= INSTEAD OF",
134197
+ /* 232 */ "trigger_time ::=",
134198
+ /* 233 */ "trigger_event ::= DELETE|INSERT",
134199
+ /* 234 */ "trigger_event ::= UPDATE",
134200
+ /* 235 */ "trigger_event ::= UPDATE OF idlist",
134201
+ /* 236 */ "when_clause ::=",
134202
+ /* 237 */ "when_clause ::= WHEN expr",
134203
+ /* 238 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
134204
+ /* 239 */ "trigger_cmd_list ::= trigger_cmd SEMI",
134205
+ /* 240 */ "trnm ::= nm DOT nm",
134206
+ /* 241 */ "tridxby ::= INDEXED BY nm",
134207
+ /* 242 */ "tridxby ::= NOT INDEXED",
134208
+ /* 243 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
134209
+ /* 244 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
134210
+ /* 245 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
134211
+ /* 246 */ "trigger_cmd ::= select",
134212
+ /* 247 */ "expr ::= RAISE LP IGNORE RP",
134213
+ /* 248 */ "expr ::= RAISE LP raisetype COMMA nm RP",
134214
+ /* 249 */ "raisetype ::= ROLLBACK",
134215
+ /* 250 */ "raisetype ::= ABORT",
134216
+ /* 251 */ "raisetype ::= FAIL",
134217
+ /* 252 */ "cmd ::= DROP TRIGGER ifexists fullname",
134218
+ /* 253 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
134219
+ /* 254 */ "cmd ::= DETACH database_kw_opt expr",
134220
+ /* 255 */ "key_opt ::=",
134221
+ /* 256 */ "key_opt ::= KEY expr",
134222
+ /* 257 */ "cmd ::= REINDEX",
134223
+ /* 258 */ "cmd ::= REINDEX nm dbnm",
134224
+ /* 259 */ "cmd ::= ANALYZE",
134225
+ /* 260 */ "cmd ::= ANALYZE nm dbnm",
134226
+ /* 261 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
134227
+ /* 262 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
134228
+ /* 263 */ "add_column_fullname ::= fullname",
134229
+ /* 264 */ "cmd ::= create_vtab",
134230
+ /* 265 */ "cmd ::= create_vtab LP vtabarglist RP",
134231
+ /* 266 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
134232
+ /* 267 */ "vtabarg ::=",
134233
+ /* 268 */ "vtabargtoken ::= ANY",
134234
+ /* 269 */ "vtabargtoken ::= lp anylist RP",
134235
+ /* 270 */ "lp ::= LP",
134236
+ /* 271 */ "with ::=",
134237
+ /* 272 */ "with ::= WITH wqlist",
134238
+ /* 273 */ "with ::= WITH RECURSIVE wqlist",
134239
+ /* 274 */ "wqlist ::= nm eidlist_opt AS LP select RP",
134240
+ /* 275 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
134241
+ /* 276 */ "input ::= cmdlist",
134242
+ /* 277 */ "cmdlist ::= cmdlist ecmd",
134243
+ /* 278 */ "cmdlist ::= ecmd",
134244
+ /* 279 */ "ecmd ::= SEMI",
134245
+ /* 280 */ "ecmd ::= explain cmdx SEMI",
134246
+ /* 281 */ "explain ::=",
134247
+ /* 282 */ "trans_opt ::=",
134248
+ /* 283 */ "trans_opt ::= TRANSACTION",
134249
+ /* 284 */ "trans_opt ::= TRANSACTION nm",
134250
+ /* 285 */ "savepoint_opt ::= SAVEPOINT",
134251
+ /* 286 */ "savepoint_opt ::=",
134252
+ /* 287 */ "cmd ::= create_table create_table_args",
134253
+ /* 288 */ "columnlist ::= columnlist COMMA columnname carglist",
134254
+ /* 289 */ "columnlist ::= columnname carglist",
134255
+ /* 290 */ "nm ::= ID|INDEXED",
134256
+ /* 291 */ "nm ::= STRING",
134257
+ /* 292 */ "nm ::= JOIN_KW",
134258
+ /* 293 */ "typetoken ::= typename",
134259
+ /* 294 */ "typename ::= ID|STRING",
134260
+ /* 295 */ "signed ::= plus_num",
134261
+ /* 296 */ "signed ::= minus_num",
134262
+ /* 297 */ "carglist ::= carglist ccons",
134263
+ /* 298 */ "carglist ::=",
134264
+ /* 299 */ "ccons ::= NULL onconf",
134265
+ /* 300 */ "conslist_opt ::= COMMA conslist",
134266
+ /* 301 */ "conslist ::= conslist tconscomma tcons",
134267
+ /* 302 */ "conslist ::= tcons",
134268
+ /* 303 */ "tconscomma ::=",
134269
+ /* 304 */ "defer_subclause_opt ::= defer_subclause",
134270
+ /* 305 */ "resolvetype ::= raisetype",
134271
+ /* 306 */ "selectnowith ::= oneselect",
134272
+ /* 307 */ "oneselect ::= values",
134273
+ /* 308 */ "sclp ::= selcollist COMMA",
134274
+ /* 309 */ "as ::= ID|STRING",
134275
+ /* 310 */ "expr ::= term",
134276
+ /* 311 */ "exprlist ::= nexprlist",
134277
+ /* 312 */ "nmnum ::= plus_num",
134278
+ /* 313 */ "nmnum ::= nm",
134279
+ /* 314 */ "nmnum ::= ON",
134280
+ /* 315 */ "nmnum ::= DELETE",
134281
+ /* 316 */ "nmnum ::= DEFAULT",
134282
+ /* 317 */ "plus_num ::= INTEGER|FLOAT",
134283
+ /* 318 */ "foreach_clause ::=",
134284
+ /* 319 */ "foreach_clause ::= FOR EACH ROW",
134285
+ /* 320 */ "trnm ::= nm",
134286
+ /* 321 */ "tridxby ::=",
134287
+ /* 322 */ "database_kw_opt ::= DATABASE",
134288
+ /* 323 */ "database_kw_opt ::=",
134289
+ /* 324 */ "kwcolumn_opt ::=",
134290
+ /* 325 */ "kwcolumn_opt ::= COLUMNKW",
134291
+ /* 326 */ "vtabarglist ::= vtabarg",
134292
+ /* 327 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
134293
+ /* 328 */ "vtabarg ::= vtabarg vtabargtoken",
134294
+ /* 329 */ "anylist ::=",
134295
+ /* 330 */ "anylist ::= anylist LP anylist RP",
134296
+ /* 331 */ "anylist ::= anylist ANY",
134235134297
};
134236134298
#endif /* NDEBUG */
134237134299
134238134300
134239134301
#if YYSTACKDEPTH<=0
@@ -134811,10 +134873,11 @@
134811134873
{ 173, 1 },
134812134874
{ 173, 3 },
134813134875
{ 173, 5 },
134814134876
{ 172, 1 },
134815134877
{ 172, 1 },
134878
+ { 172, 1 },
134816134879
{ 173, 1 },
134817134880
{ 173, 3 },
134818134881
{ 173, 6 },
134819134882
{ 173, 5 },
134820134883
{ 173, 4 },
@@ -135105,11 +135168,11 @@
135105135168
case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
135106135169
case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
135107135170
case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
135108135171
case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
135109135172
case 90: /* distinct ::= */ yytestcase(yyruleno==90);
135110
- case 214: /* collate ::= */ yytestcase(yyruleno==214);
135173
+ case 215: /* collate ::= */ yytestcase(yyruleno==215);
135111135174
{yymsp[1].minor.yy194 = 0;}
135112135175
break;
135113135176
case 17: /* ifnotexists ::= IF NOT EXISTS */
135114135177
{yymsp[-2].minor.yy194 = 1;}
135115135178
break;
@@ -135249,13 +135312,13 @@
135249135312
case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144);
135250135313
{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
135251135314
break;
135252135315
case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
135253135316
case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
135254
- case 186: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==186);
135255
- case 189: /* in_op ::= NOT IN */ yytestcase(yyruleno==189);
135256
- case 215: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==215);
135317
+ case 187: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==187);
135318
+ case 190: /* in_op ::= NOT IN */ yytestcase(yyruleno==190);
135319
+ case 216: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==216);
135257135320
{yymsp[-1].minor.yy194 = 1;}
135258135321
break;
135259135322
case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
135260135323
{yymsp[-1].minor.yy194 = 0;}
135261135324
break;
@@ -135415,13 +135478,13 @@
135415135478
{yymsp[0].minor.yy194 = SF_All;}
135416135479
break;
135417135480
case 91: /* sclp ::= */
135418135481
case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
135419135482
case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
135420
- case 202: /* exprlist ::= */ yytestcase(yyruleno==202);
135421
- case 205: /* paren_exprlist ::= */ yytestcase(yyruleno==205);
135422
- case 210: /* eidlist_opt ::= */ yytestcase(yyruleno==210);
135483
+ case 203: /* exprlist ::= */ yytestcase(yyruleno==203);
135484
+ case 206: /* paren_exprlist ::= */ yytestcase(yyruleno==206);
135485
+ case 211: /* eidlist_opt ::= */ yytestcase(yyruleno==211);
135423135486
{yymsp[1].minor.yy148 = 0;}
135424135487
break;
135425135488
case 92: /* selcollist ::= sclp expr as */
135426135489
{
135427135490
yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
@@ -135435,20 +135498,20 @@
135435135498
yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
135436135499
}
135437135500
break;
135438135501
case 94: /* selcollist ::= sclp nm DOT STAR */
135439135502
{
135440
- Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &yymsp[0].minor.yy0);
135503
+ Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, 0);
135441135504
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135442135505
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
135443135506
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
135444135507
}
135445135508
break;
135446135509
case 95: /* as ::= AS nm */
135447135510
case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
135448
- case 224: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==224);
135449
- case 225: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
135511
+ case 225: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
135512
+ case 226: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==226);
135450135513
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
135451135514
break;
135452135515
case 97: /* from ::= */
135453135516
{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
135454135517
break;
@@ -135527,18 +135590,18 @@
135527135590
{yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
135528135591
break;
135529135592
case 112: /* on_opt ::= ON expr */
135530135593
case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
135531135594
case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
135532
- case 198: /* case_else ::= ELSE expr */ yytestcase(yyruleno==198);
135595
+ case 199: /* case_else ::= ELSE expr */ yytestcase(yyruleno==199);
135533135596
{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
135534135597
break;
135535135598
case 113: /* on_opt ::= */
135536135599
case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
135537135600
case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
135538
- case 199: /* case_else ::= */ yytestcase(yyruleno==199);
135539
- case 201: /* case_operand ::= */ yytestcase(yyruleno==201);
135601
+ case 200: /* case_else ::= */ yytestcase(yyruleno==200);
135602
+ case 202: /* case_operand ::= */ yytestcase(yyruleno==202);
135540135603
{yymsp[1].minor.yy72 = 0;}
135541135604
break;
135542135605
case 115: /* indexed_opt ::= INDEXED BY nm */
135543135606
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
135544135607
break;
@@ -135650,41 +135713,51 @@
135650135713
break;
135651135714
case 150: /* expr ::= LP expr RP */
135652135715
{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
135653135716
break;
135654135717
case 151: /* term ::= NULL */
135655
- case 156: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==156);
135718
+ case 156: /* term ::= FLOAT|BLOB */ yytestcase(yyruleno==156);
135656135719
case 157: /* term ::= STRING */ yytestcase(yyruleno==157);
135657135720
{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/}
135658135721
break;
135659135722
case 152: /* expr ::= ID|INDEXED */
135660135723
case 153: /* expr ::= JOIN_KW */ yytestcase(yyruleno==153);
135661135724
{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
135662135725
break;
135663135726
case 154: /* expr ::= nm DOT nm */
135664135727
{
135665
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135666
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
135728
+ Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
135729
+ Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
135667135730
spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135668135731
yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
135669135732
}
135670135733
break;
135671135734
case 155: /* expr ::= nm DOT nm DOT nm */
135672135735
{
135673
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
135674
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135675
- Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
135736
+ Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
135737
+ Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
135738
+ Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
135676135739
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
135677135740
spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135678135741
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
135679135742
}
135680135743
break;
135681
- case 158: /* expr ::= VARIABLE */
135744
+ case 158: /* term ::= INTEGER */
135745
+{
135746
+ yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
135747
+ yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z;
135748
+ yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n;
135749
+ if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf;
135750
+}
135751
+ yymsp[0].minor.yy190 = yylhsminor.yy190;
135752
+ break;
135753
+ case 159: /* expr ::= VARIABLE */
135682135754
{
135683135755
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
135756
+ u32 n = yymsp[0].minor.yy0.n;
135684135757
spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
135685
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr);
135758
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
135686135759
}else{
135687135760
/* When doing a nested parse, one can include terms in an expression
135688135761
** that look like this: #1 #2 ... These terms refer to registers
135689135762
** in the virtual machine. #N is the N-th register. */
135690135763
Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
@@ -135692,29 +135765,29 @@
135692135765
spanSet(&yymsp[0].minor.yy190, &t, &t);
135693135766
if( pParse->nested==0 ){
135694135767
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
135695135768
yymsp[0].minor.yy190.pExpr = 0;
135696135769
}else{
135697
- yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
135770
+ yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, 0);
135698135771
if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
135699135772
}
135700135773
}
135701135774
}
135702135775
break;
135703
- case 159: /* expr ::= expr COLLATE ID|STRING */
135776
+ case 160: /* expr ::= expr COLLATE ID|STRING */
135704135777
{
135705135778
yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1);
135706135779
yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135707135780
}
135708135781
break;
135709
- case 160: /* expr ::= CAST LP expr AS typetoken RP */
135782
+ case 161: /* expr ::= CAST LP expr AS typetoken RP */
135710135783
{
135711135784
spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135712135785
yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0);
135713135786
}
135714135787
break;
135715
- case 161: /* expr ::= ID|INDEXED LP distinct exprlist RP */
135788
+ case 162: /* expr ::= ID|INDEXED LP distinct exprlist RP */
135716135789
{
135717135790
if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
135718135791
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
135719135792
}
135720135793
yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
@@ -135723,25 +135796,25 @@
135723135796
yylhsminor.yy190.pExpr->flags |= EP_Distinct;
135724135797
}
135725135798
}
135726135799
yymsp[-4].minor.yy190 = yylhsminor.yy190;
135727135800
break;
135728
- case 162: /* expr ::= ID|INDEXED LP STAR RP */
135801
+ case 163: /* expr ::= ID|INDEXED LP STAR RP */
135729135802
{
135730135803
yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
135731135804
spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
135732135805
}
135733135806
yymsp[-3].minor.yy190 = yylhsminor.yy190;
135734135807
break;
135735
- case 163: /* term ::= CTIME_KW */
135808
+ case 164: /* term ::= CTIME_KW */
135736135809
{
135737135810
yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
135738135811
spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
135739135812
}
135740135813
yymsp[0].minor.yy190 = yylhsminor.yy190;
135741135814
break;
135742
- case 164: /* expr ::= LP nexprlist COMMA expr RP */
135815
+ case 165: /* expr ::= LP nexprlist COMMA expr RP */
135743135816
{
135744135817
ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
135745135818
yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0);
135746135819
if( yylhsminor.yy190.pExpr ){
135747135820
yylhsminor.yy190.pExpr->x.pList = pList;
@@ -135750,82 +135823,86 @@
135750135823
sqlite3ExprListDelete(pParse->db, pList);
135751135824
}
135752135825
}
135753135826
yymsp[-4].minor.yy190 = yylhsminor.yy190;
135754135827
break;
135755
- case 165: /* expr ::= expr AND expr */
135756
- case 166: /* expr ::= expr OR expr */ yytestcase(yyruleno==166);
135757
- case 167: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==167);
135758
- case 168: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==168);
135759
- case 169: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==169);
135760
- case 170: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==170);
135761
- case 171: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==171);
135762
- case 172: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==172);
135828
+ case 166: /* expr ::= expr AND expr */
135829
+ case 167: /* expr ::= expr OR expr */ yytestcase(yyruleno==167);
135830
+ case 168: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==168);
135831
+ case 169: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==169);
135832
+ case 170: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==170);
135833
+ case 171: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==171);
135834
+ case 172: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==172);
135835
+ case 173: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==173);
135763135836
{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
135764135837
break;
135765
- case 173: /* likeop ::= LIKE_KW|MATCH */
135766
-{yymsp[0].minor.yy392.eOperator = yymsp[0].minor.yy0; yymsp[0].minor.yy392.bNot = 0;/*A-overwrites-X*/}
135838
+ case 174: /* likeop ::= LIKE_KW|MATCH */
135839
+{yymsp[0].minor.yy0=yymsp[0].minor.yy0;/*A-overwrites-X*/}
135767135840
break;
135768
- case 174: /* likeop ::= NOT LIKE_KW|MATCH */
135769
-{yymsp[-1].minor.yy392.eOperator = yymsp[0].minor.yy0; yymsp[-1].minor.yy392.bNot = 1;}
135841
+ case 175: /* likeop ::= NOT LIKE_KW|MATCH */
135842
+{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
135770135843
break;
135771
- case 175: /* expr ::= expr likeop expr */
135844
+ case 176: /* expr ::= expr likeop expr */
135772135845
{
135773135846
ExprList *pList;
135847
+ int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
135848
+ yymsp[-1].minor.yy0.n &= 0x7fffffff;
135774135849
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr);
135775135850
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr);
135776
- yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy392.eOperator);
135777
- exprNot(pParse, yymsp[-1].minor.yy392.bNot, &yymsp[-2].minor.yy190);
135851
+ yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
135852
+ exprNot(pParse, bNot, &yymsp[-2].minor.yy190);
135778135853
yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135779135854
if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
135780135855
}
135781135856
break;
135782
- case 176: /* expr ::= expr likeop expr ESCAPE expr */
135857
+ case 177: /* expr ::= expr likeop expr ESCAPE expr */
135783135858
{
135784135859
ExprList *pList;
135860
+ int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
135861
+ yymsp[-3].minor.yy0.n &= 0x7fffffff;
135785135862
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135786135863
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr);
135787135864
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
135788
- yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy392.eOperator);
135789
- exprNot(pParse, yymsp[-3].minor.yy392.bNot, &yymsp[-4].minor.yy190);
135865
+ yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
135866
+ exprNot(pParse, bNot, &yymsp[-4].minor.yy190);
135790135867
yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135791135868
if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
135792135869
}
135793135870
break;
135794
- case 177: /* expr ::= expr ISNULL|NOTNULL */
135871
+ case 178: /* expr ::= expr ISNULL|NOTNULL */
135795135872
{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
135796135873
break;
135797
- case 178: /* expr ::= expr NOT NULL */
135874
+ case 179: /* expr ::= expr NOT NULL */
135798135875
{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
135799135876
break;
135800
- case 179: /* expr ::= expr IS expr */
135877
+ case 180: /* expr ::= expr IS expr */
135801135878
{
135802135879
spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
135803135880
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
135804135881
}
135805135882
break;
135806
- case 180: /* expr ::= expr IS NOT expr */
135883
+ case 181: /* expr ::= expr IS NOT expr */
135807135884
{
135808135885
spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
135809135886
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
135810135887
}
135811135888
break;
135812
- case 181: /* expr ::= NOT expr */
135813
- case 182: /* expr ::= BITNOT expr */ yytestcase(yyruleno==182);
135889
+ case 182: /* expr ::= NOT expr */
135890
+ case 183: /* expr ::= BITNOT expr */ yytestcase(yyruleno==183);
135814135891
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135815135892
break;
135816
- case 183: /* expr ::= MINUS expr */
135893
+ case 184: /* expr ::= MINUS expr */
135817135894
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135818135895
break;
135819
- case 184: /* expr ::= PLUS expr */
135896
+ case 185: /* expr ::= PLUS expr */
135820135897
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135821135898
break;
135822
- case 185: /* between_op ::= BETWEEN */
135823
- case 188: /* in_op ::= IN */ yytestcase(yyruleno==188);
135899
+ case 186: /* between_op ::= BETWEEN */
135900
+ case 189: /* in_op ::= IN */ yytestcase(yyruleno==189);
135824135901
{yymsp[0].minor.yy194 = 0;}
135825135902
break;
135826
- case 187: /* expr ::= expr between_op expr AND expr */
135903
+ case 188: /* expr ::= expr between_op expr AND expr */
135827135904
{
135828135905
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135829135906
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
135830135907
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0);
135831135908
if( yymsp[-4].minor.yy190.pExpr ){
@@ -135835,11 +135912,11 @@
135835135912
}
135836135913
exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135837135914
yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135838135915
}
135839135916
break;
135840
- case 190: /* expr ::= expr in_op LP exprlist RP */
135917
+ case 191: /* expr ::= expr in_op LP exprlist RP */
135841135918
{
135842135919
if( yymsp[-1].minor.yy148==0 ){
135843135920
/* Expressions of the form
135844135921
**
135845135922
** expr1 IN ()
@@ -135888,26 +135965,26 @@
135888135965
exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135889135966
}
135890135967
yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135891135968
}
135892135969
break;
135893
- case 191: /* expr ::= LP select RP */
135970
+ case 192: /* expr ::= LP select RP */
135894135971
{
135895135972
spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
135896135973
yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
135897135974
sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
135898135975
}
135899135976
break;
135900
- case 192: /* expr ::= expr in_op LP select RP */
135977
+ case 193: /* expr ::= expr in_op LP select RP */
135901135978
{
135902135979
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
135903135980
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
135904135981
exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135905135982
yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135906135983
}
135907135984
break;
135908
- case 193: /* expr ::= expr in_op nm dbnm paren_exprlist */
135985
+ case 194: /* expr ::= expr in_op nm dbnm paren_exprlist */
135909135986
{
135910135987
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
135911135988
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
135912135989
if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148);
135913135990
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
@@ -135914,19 +135991,19 @@
135914135991
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect);
135915135992
exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135916135993
yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
135917135994
}
135918135995
break;
135919
- case 194: /* expr ::= EXISTS LP select RP */
135996
+ case 195: /* expr ::= EXISTS LP select RP */
135920135997
{
135921135998
Expr *p;
135922135999
spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
135923136000
p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
135924136001
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
135925136002
}
135926136003
break;
135927
- case 195: /* expr ::= CASE case_operand case_exprlist case_else END */
136004
+ case 196: /* expr ::= CASE case_operand case_exprlist case_else END */
135928136005
{
135929136006
spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/
135930136007
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0, 0);
135931136008
if( yymsp[-4].minor.yy190.pExpr ){
135932136009
yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148;
@@ -135935,334 +136012,334 @@
135935136012
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
135936136013
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
135937136014
}
135938136015
}
135939136016
break;
135940
- case 196: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
136017
+ case 197: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
135941136018
{
135942136019
yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
135943136020
yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
135944136021
}
135945136022
break;
135946
- case 197: /* case_exprlist ::= WHEN expr THEN expr */
136023
+ case 198: /* case_exprlist ::= WHEN expr THEN expr */
135947136024
{
135948136025
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135949136026
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
135950136027
}
135951136028
break;
135952
- case 200: /* case_operand ::= expr */
136029
+ case 201: /* case_operand ::= expr */
135953136030
{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
135954136031
break;
135955
- case 203: /* nexprlist ::= nexprlist COMMA expr */
136032
+ case 204: /* nexprlist ::= nexprlist COMMA expr */
135956136033
{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
135957136034
break;
135958
- case 204: /* nexprlist ::= expr */
136035
+ case 205: /* nexprlist ::= expr */
135959136036
{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
135960136037
break;
135961
- case 206: /* paren_exprlist ::= LP exprlist RP */
135962
- case 211: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==211);
136038
+ case 207: /* paren_exprlist ::= LP exprlist RP */
136039
+ case 212: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==212);
135963136040
{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
135964136041
break;
135965
- case 207: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
136042
+ case 208: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
135966136043
{
135967136044
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
135968136045
sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194,
135969136046
&yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF);
135970136047
}
135971136048
break;
135972
- case 208: /* uniqueflag ::= UNIQUE */
135973
- case 249: /* raisetype ::= ABORT */ yytestcase(yyruleno==249);
136049
+ case 209: /* uniqueflag ::= UNIQUE */
136050
+ case 250: /* raisetype ::= ABORT */ yytestcase(yyruleno==250);
135974136051
{yymsp[0].minor.yy194 = OE_Abort;}
135975136052
break;
135976
- case 209: /* uniqueflag ::= */
136053
+ case 210: /* uniqueflag ::= */
135977136054
{yymsp[1].minor.yy194 = OE_None;}
135978136055
break;
135979
- case 212: /* eidlist ::= eidlist COMMA nm collate sortorder */
136056
+ case 213: /* eidlist ::= eidlist COMMA nm collate sortorder */
135980136057
{
135981136058
yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
135982136059
}
135983136060
break;
135984
- case 213: /* eidlist ::= nm collate sortorder */
136061
+ case 214: /* eidlist ::= nm collate sortorder */
135985136062
{
135986136063
yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
135987136064
}
135988136065
break;
135989
- case 216: /* cmd ::= DROP INDEX ifexists fullname */
136066
+ case 217: /* cmd ::= DROP INDEX ifexists fullname */
135990136067
{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
135991136068
break;
135992
- case 217: /* cmd ::= VACUUM */
136069
+ case 218: /* cmd ::= VACUUM */
135993136070
{sqlite3Vacuum(pParse,0);}
135994136071
break;
135995
- case 218: /* cmd ::= VACUUM nm */
136072
+ case 219: /* cmd ::= VACUUM nm */
135996136073
{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
135997136074
break;
135998
- case 219: /* cmd ::= PRAGMA nm dbnm */
136075
+ case 220: /* cmd ::= PRAGMA nm dbnm */
135999136076
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
136000136077
break;
136001
- case 220: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
136078
+ case 221: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
136002136079
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
136003136080
break;
136004
- case 221: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
136081
+ case 222: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
136005136082
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
136006136083
break;
136007
- case 222: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
136084
+ case 223: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
136008136085
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
136009136086
break;
136010
- case 223: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
136087
+ case 224: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
136011136088
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
136012136089
break;
136013
- case 226: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
136090
+ case 227: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
136014136091
{
136015136092
Token all;
136016136093
all.z = yymsp[-3].minor.yy0.z;
136017136094
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
136018136095
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
136019136096
}
136020136097
break;
136021
- case 227: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
136098
+ case 228: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
136022136099
{
136023136100
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
136024136101
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
136025136102
}
136026136103
break;
136027
- case 228: /* trigger_time ::= BEFORE */
136104
+ case 229: /* trigger_time ::= BEFORE */
136028136105
{ yymsp[0].minor.yy194 = TK_BEFORE; }
136029136106
break;
136030
- case 229: /* trigger_time ::= AFTER */
136107
+ case 230: /* trigger_time ::= AFTER */
136031136108
{ yymsp[0].minor.yy194 = TK_AFTER; }
136032136109
break;
136033
- case 230: /* trigger_time ::= INSTEAD OF */
136110
+ case 231: /* trigger_time ::= INSTEAD OF */
136034136111
{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
136035136112
break;
136036
- case 231: /* trigger_time ::= */
136113
+ case 232: /* trigger_time ::= */
136037136114
{ yymsp[1].minor.yy194 = TK_BEFORE; }
136038136115
break;
136039
- case 232: /* trigger_event ::= DELETE|INSERT */
136040
- case 233: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==233);
136116
+ case 233: /* trigger_event ::= DELETE|INSERT */
136117
+ case 234: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==234);
136041136118
{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
136042136119
break;
136043
- case 234: /* trigger_event ::= UPDATE OF idlist */
136120
+ case 235: /* trigger_event ::= UPDATE OF idlist */
136044136121
{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
136045136122
break;
136046
- case 235: /* when_clause ::= */
136047
- case 254: /* key_opt ::= */ yytestcase(yyruleno==254);
136123
+ case 236: /* when_clause ::= */
136124
+ case 255: /* key_opt ::= */ yytestcase(yyruleno==255);
136048136125
{ yymsp[1].minor.yy72 = 0; }
136049136126
break;
136050
- case 236: /* when_clause ::= WHEN expr */
136051
- case 255: /* key_opt ::= KEY expr */ yytestcase(yyruleno==255);
136127
+ case 237: /* when_clause ::= WHEN expr */
136128
+ case 256: /* key_opt ::= KEY expr */ yytestcase(yyruleno==256);
136052136129
{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
136053136130
break;
136054
- case 237: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
136131
+ case 238: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
136055136132
{
136056136133
assert( yymsp[-2].minor.yy145!=0 );
136057136134
yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
136058136135
yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
136059136136
}
136060136137
break;
136061
- case 238: /* trigger_cmd_list ::= trigger_cmd SEMI */
136138
+ case 239: /* trigger_cmd_list ::= trigger_cmd SEMI */
136062136139
{
136063136140
assert( yymsp[-1].minor.yy145!=0 );
136064136141
yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
136065136142
}
136066136143
break;
136067
- case 239: /* trnm ::= nm DOT nm */
136144
+ case 240: /* trnm ::= nm DOT nm */
136068136145
{
136069136146
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
136070136147
sqlite3ErrorMsg(pParse,
136071136148
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
136072136149
"statements within triggers");
136073136150
}
136074136151
break;
136075
- case 240: /* tridxby ::= INDEXED BY nm */
136152
+ case 241: /* tridxby ::= INDEXED BY nm */
136076136153
{
136077136154
sqlite3ErrorMsg(pParse,
136078136155
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
136079136156
"within triggers");
136080136157
}
136081136158
break;
136082
- case 241: /* tridxby ::= NOT INDEXED */
136159
+ case 242: /* tridxby ::= NOT INDEXED */
136083136160
{
136084136161
sqlite3ErrorMsg(pParse,
136085136162
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
136086136163
"within triggers");
136087136164
}
136088136165
break;
136089
- case 242: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
136166
+ case 243: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
136090136167
{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
136091136168
break;
136092
- case 243: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
136169
+ case 244: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
136093136170
{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
136094136171
break;
136095
- case 244: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
136172
+ case 245: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
136096136173
{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
136097136174
break;
136098
- case 245: /* trigger_cmd ::= select */
136175
+ case 246: /* trigger_cmd ::= select */
136099136176
{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
136100136177
break;
136101
- case 246: /* expr ::= RAISE LP IGNORE RP */
136178
+ case 247: /* expr ::= RAISE LP IGNORE RP */
136102136179
{
136103136180
spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
136104136181
yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
136105136182
if( yymsp[-3].minor.yy190.pExpr ){
136106136183
yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
136107136184
}
136108136185
}
136109136186
break;
136110
- case 247: /* expr ::= RAISE LP raisetype COMMA nm RP */
136187
+ case 248: /* expr ::= RAISE LP raisetype COMMA nm RP */
136111136188
{
136112136189
spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
136113136190
yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
136114136191
if( yymsp[-5].minor.yy190.pExpr ) {
136115136192
yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
136116136193
}
136117136194
}
136118136195
break;
136119
- case 248: /* raisetype ::= ROLLBACK */
136196
+ case 249: /* raisetype ::= ROLLBACK */
136120136197
{yymsp[0].minor.yy194 = OE_Rollback;}
136121136198
break;
136122
- case 250: /* raisetype ::= FAIL */
136199
+ case 251: /* raisetype ::= FAIL */
136123136200
{yymsp[0].minor.yy194 = OE_Fail;}
136124136201
break;
136125
- case 251: /* cmd ::= DROP TRIGGER ifexists fullname */
136202
+ case 252: /* cmd ::= DROP TRIGGER ifexists fullname */
136126136203
{
136127136204
sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
136128136205
}
136129136206
break;
136130
- case 252: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
136207
+ case 253: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
136131136208
{
136132136209
sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
136133136210
}
136134136211
break;
136135
- case 253: /* cmd ::= DETACH database_kw_opt expr */
136212
+ case 254: /* cmd ::= DETACH database_kw_opt expr */
136136136213
{
136137136214
sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
136138136215
}
136139136216
break;
136140
- case 256: /* cmd ::= REINDEX */
136217
+ case 257: /* cmd ::= REINDEX */
136141136218
{sqlite3Reindex(pParse, 0, 0);}
136142136219
break;
136143
- case 257: /* cmd ::= REINDEX nm dbnm */
136220
+ case 258: /* cmd ::= REINDEX nm dbnm */
136144136221
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
136145136222
break;
136146
- case 258: /* cmd ::= ANALYZE */
136223
+ case 259: /* cmd ::= ANALYZE */
136147136224
{sqlite3Analyze(pParse, 0, 0);}
136148136225
break;
136149
- case 259: /* cmd ::= ANALYZE nm dbnm */
136226
+ case 260: /* cmd ::= ANALYZE nm dbnm */
136150136227
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
136151136228
break;
136152
- case 260: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
136229
+ case 261: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
136153136230
{
136154136231
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
136155136232
}
136156136233
break;
136157
- case 261: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
136234
+ case 262: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
136158136235
{
136159136236
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
136160136237
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
136161136238
}
136162136239
break;
136163
- case 262: /* add_column_fullname ::= fullname */
136240
+ case 263: /* add_column_fullname ::= fullname */
136164136241
{
136165136242
disableLookaside(pParse);
136166136243
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
136167136244
}
136168136245
break;
136169
- case 263: /* cmd ::= create_vtab */
136246
+ case 264: /* cmd ::= create_vtab */
136170136247
{sqlite3VtabFinishParse(pParse,0);}
136171136248
break;
136172
- case 264: /* cmd ::= create_vtab LP vtabarglist RP */
136249
+ case 265: /* cmd ::= create_vtab LP vtabarglist RP */
136173136250
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
136174136251
break;
136175
- case 265: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
136252
+ case 266: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
136176136253
{
136177136254
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194);
136178136255
}
136179136256
break;
136180
- case 266: /* vtabarg ::= */
136257
+ case 267: /* vtabarg ::= */
136181136258
{sqlite3VtabArgInit(pParse);}
136182136259
break;
136183
- case 267: /* vtabargtoken ::= ANY */
136184
- case 268: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==268);
136185
- case 269: /* lp ::= LP */ yytestcase(yyruleno==269);
136260
+ case 268: /* vtabargtoken ::= ANY */
136261
+ case 269: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==269);
136262
+ case 270: /* lp ::= LP */ yytestcase(yyruleno==270);
136186136263
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
136187136264
break;
136188
- case 270: /* with ::= */
136265
+ case 271: /* with ::= */
136189136266
{yymsp[1].minor.yy285 = 0;}
136190136267
break;
136191
- case 271: /* with ::= WITH wqlist */
136268
+ case 272: /* with ::= WITH wqlist */
136192136269
{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
136193136270
break;
136194
- case 272: /* with ::= WITH RECURSIVE wqlist */
136271
+ case 273: /* with ::= WITH RECURSIVE wqlist */
136195136272
{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
136196136273
break;
136197
- case 273: /* wqlist ::= nm eidlist_opt AS LP select RP */
136274
+ case 274: /* wqlist ::= nm eidlist_opt AS LP select RP */
136198136275
{
136199136276
yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
136200136277
}
136201136278
break;
136202
- case 274: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
136279
+ case 275: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
136203136280
{
136204136281
yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
136205136282
}
136206136283
break;
136207136284
default:
136208
- /* (275) input ::= cmdlist */ yytestcase(yyruleno==275);
136209
- /* (276) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==276);
136210
- /* (277) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=277);
136211
- /* (278) ecmd ::= SEMI */ yytestcase(yyruleno==278);
136212
- /* (279) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==279);
136213
- /* (280) explain ::= */ yytestcase(yyruleno==280);
136214
- /* (281) trans_opt ::= */ yytestcase(yyruleno==281);
136215
- /* (282) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==282);
136216
- /* (283) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==283);
136217
- /* (284) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==284);
136218
- /* (285) savepoint_opt ::= */ yytestcase(yyruleno==285);
136219
- /* (286) cmd ::= create_table create_table_args */ yytestcase(yyruleno==286);
136220
- /* (287) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==287);
136221
- /* (288) columnlist ::= columnname carglist */ yytestcase(yyruleno==288);
136222
- /* (289) nm ::= ID|INDEXED */ yytestcase(yyruleno==289);
136223
- /* (290) nm ::= STRING */ yytestcase(yyruleno==290);
136224
- /* (291) nm ::= JOIN_KW */ yytestcase(yyruleno==291);
136225
- /* (292) typetoken ::= typename */ yytestcase(yyruleno==292);
136226
- /* (293) typename ::= ID|STRING */ yytestcase(yyruleno==293);
136227
- /* (294) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=294);
136228
- /* (295) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
136229
- /* (296) carglist ::= carglist ccons */ yytestcase(yyruleno==296);
136230
- /* (297) carglist ::= */ yytestcase(yyruleno==297);
136231
- /* (298) ccons ::= NULL onconf */ yytestcase(yyruleno==298);
136232
- /* (299) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==299);
136233
- /* (300) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==300);
136234
- /* (301) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=301);
136235
- /* (302) tconscomma ::= */ yytestcase(yyruleno==302);
136236
- /* (303) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=303);
136237
- /* (304) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=304);
136238
- /* (305) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=305);
136239
- /* (306) oneselect ::= values */ yytestcase(yyruleno==306);
136240
- /* (307) sclp ::= selcollist COMMA */ yytestcase(yyruleno==307);
136241
- /* (308) as ::= ID|STRING */ yytestcase(yyruleno==308);
136242
- /* (309) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=309);
136243
- /* (310) exprlist ::= nexprlist */ yytestcase(yyruleno==310);
136244
- /* (311) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=311);
136245
- /* (312) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=312);
136246
- /* (313) nmnum ::= ON */ yytestcase(yyruleno==313);
136247
- /* (314) nmnum ::= DELETE */ yytestcase(yyruleno==314);
136248
- /* (315) nmnum ::= DEFAULT */ yytestcase(yyruleno==315);
136249
- /* (316) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==316);
136250
- /* (317) foreach_clause ::= */ yytestcase(yyruleno==317);
136251
- /* (318) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==318);
136252
- /* (319) trnm ::= nm */ yytestcase(yyruleno==319);
136253
- /* (320) tridxby ::= */ yytestcase(yyruleno==320);
136254
- /* (321) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==321);
136255
- /* (322) database_kw_opt ::= */ yytestcase(yyruleno==322);
136256
- /* (323) kwcolumn_opt ::= */ yytestcase(yyruleno==323);
136257
- /* (324) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==324);
136258
- /* (325) vtabarglist ::= vtabarg */ yytestcase(yyruleno==325);
136259
- /* (326) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==326);
136260
- /* (327) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==327);
136261
- /* (328) anylist ::= */ yytestcase(yyruleno==328);
136262
- /* (329) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==329);
136263
- /* (330) anylist ::= anylist ANY */ yytestcase(yyruleno==330);
136285
+ /* (276) input ::= cmdlist */ yytestcase(yyruleno==276);
136286
+ /* (277) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==277);
136287
+ /* (278) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=278);
136288
+ /* (279) ecmd ::= SEMI */ yytestcase(yyruleno==279);
136289
+ /* (280) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==280);
136290
+ /* (281) explain ::= */ yytestcase(yyruleno==281);
136291
+ /* (282) trans_opt ::= */ yytestcase(yyruleno==282);
136292
+ /* (283) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==283);
136293
+ /* (284) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==284);
136294
+ /* (285) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==285);
136295
+ /* (286) savepoint_opt ::= */ yytestcase(yyruleno==286);
136296
+ /* (287) cmd ::= create_table create_table_args */ yytestcase(yyruleno==287);
136297
+ /* (288) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==288);
136298
+ /* (289) columnlist ::= columnname carglist */ yytestcase(yyruleno==289);
136299
+ /* (290) nm ::= ID|INDEXED */ yytestcase(yyruleno==290);
136300
+ /* (291) nm ::= STRING */ yytestcase(yyruleno==291);
136301
+ /* (292) nm ::= JOIN_KW */ yytestcase(yyruleno==292);
136302
+ /* (293) typetoken ::= typename */ yytestcase(yyruleno==293);
136303
+ /* (294) typename ::= ID|STRING */ yytestcase(yyruleno==294);
136304
+ /* (295) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
136305
+ /* (296) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=296);
136306
+ /* (297) carglist ::= carglist ccons */ yytestcase(yyruleno==297);
136307
+ /* (298) carglist ::= */ yytestcase(yyruleno==298);
136308
+ /* (299) ccons ::= NULL onconf */ yytestcase(yyruleno==299);
136309
+ /* (300) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==300);
136310
+ /* (301) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==301);
136311
+ /* (302) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=302);
136312
+ /* (303) tconscomma ::= */ yytestcase(yyruleno==303);
136313
+ /* (304) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=304);
136314
+ /* (305) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=305);
136315
+ /* (306) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=306);
136316
+ /* (307) oneselect ::= values */ yytestcase(yyruleno==307);
136317
+ /* (308) sclp ::= selcollist COMMA */ yytestcase(yyruleno==308);
136318
+ /* (309) as ::= ID|STRING */ yytestcase(yyruleno==309);
136319
+ /* (310) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=310);
136320
+ /* (311) exprlist ::= nexprlist */ yytestcase(yyruleno==311);
136321
+ /* (312) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=312);
136322
+ /* (313) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=313);
136323
+ /* (314) nmnum ::= ON */ yytestcase(yyruleno==314);
136324
+ /* (315) nmnum ::= DELETE */ yytestcase(yyruleno==315);
136325
+ /* (316) nmnum ::= DEFAULT */ yytestcase(yyruleno==316);
136326
+ /* (317) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==317);
136327
+ /* (318) foreach_clause ::= */ yytestcase(yyruleno==318);
136328
+ /* (319) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==319);
136329
+ /* (320) trnm ::= nm */ yytestcase(yyruleno==320);
136330
+ /* (321) tridxby ::= */ yytestcase(yyruleno==321);
136331
+ /* (322) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==322);
136332
+ /* (323) database_kw_opt ::= */ yytestcase(yyruleno==323);
136333
+ /* (324) kwcolumn_opt ::= */ yytestcase(yyruleno==324);
136334
+ /* (325) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==325);
136335
+ /* (326) vtabarglist ::= vtabarg */ yytestcase(yyruleno==326);
136336
+ /* (327) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==327);
136337
+ /* (328) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==328);
136338
+ /* (329) anylist ::= */ yytestcase(yyruleno==329);
136339
+ /* (330) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==330);
136340
+ /* (331) anylist ::= anylist ANY */ yytestcase(yyruleno==331);
136264136341
break;
136265136342
/********** End reduce actions ************************************************/
136266136343
};
136267136344
assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
136268136345
yygoto = yyRuleInfo[yyruleno].lhs;
@@ -136449,11 +136526,11 @@
136449136526
}
136450136527
#endif
136451136528
yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
136452136529
yymajor = YYNOCODE;
136453136530
}else{
136454
- while( yypParser->yytos >= &yypParser->yystack
136531
+ while( yypParser->yytos >= yypParser->yystack
136455136532
&& yymx != YYERRORSYMBOL
136456136533
&& (yyact = yy_find_reduce_action(
136457136534
yypParser->yytos->stateno,
136458136535
YYERRORSYMBOL)) >= YY_MIN_REDUCE
136459136536
){
@@ -138617,10 +138694,11 @@
138617138694
} aFlagOp[] = {
138618138695
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
138619138696
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
138620138697
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
138621138698
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
138699
+ { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
138622138700
};
138623138701
unsigned int i;
138624138702
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
138625138703
for(i=0; i<ArraySize(aFlagOp); i++){
138626138704
if( aFlagOp[i].op==op ){
@@ -139913,10 +139991,17 @@
139913139991
db->busyHandler.nBusy = 0;
139914139992
rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
139915139993
sqlite3Error(db, rc);
139916139994
}
139917139995
rc = sqlite3ApiExit(db, rc);
139996
+
139997
+ /* If there are no active statements, clear the interrupt flag at this
139998
+ ** point. */
139999
+ if( db->nVdbeActive==0 ){
140000
+ db->u1.isInterrupted = 0;
140001
+ }
140002
+
139918140003
sqlite3_mutex_leave(db->mutex);
139919140004
return rc;
139920140005
#endif
139921140006
}
139922140007
@@ -140415,10 +140500,11 @@
140415140500
int octet = (sqlite3HexToInt(zUri[iIn++]) << 4);
140416140501
octet += sqlite3HexToInt(zUri[iIn++]);
140417140502
140418140503
assert( octet>=0 && octet<256 );
140419140504
if( octet==0 ){
140505
+#ifndef SQLITE_ENABLE_URI_00_ERROR
140420140506
/* This branch is taken when "%00" appears within the URI. In this
140421140507
** case we ignore all text in the remainder of the path, name or
140422140508
** value currently being parsed. So ignore the current character
140423140509
** and skip to the next "?", "=" or "&", as appropriate. */
140424140510
while( (c = zUri[iIn])!=0 && c!='#'
@@ -140427,10 +140513,16 @@
140427140513
&& (eState!=2 || c!='&')
140428140514
){
140429140515
iIn++;
140430140516
}
140431140517
continue;
140518
+#else
140519
+ /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
140520
+ *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
140521
+ rc = SQLITE_ERROR;
140522
+ goto parse_uri_out;
140523
+#endif
140432140524
}
140433140525
c = octet;
140434140526
}else if( eState==1 && (c=='&' || c=='=') ){
140435140527
if( zFile[iOut-1]==0 ){
140436140528
/* An empty option name. Ignore this option altogether. */
@@ -164306,14 +164398,16 @@
164306164398
char *zSql;
164307164399
sqlite3_stmt *p;
164308164400
int rc;
164309164401
i64 nRow = 0;
164310164402
164311
- if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1",
164312
- 0,0,0,0,0,0)==SQLITE_ERROR ){
164403
+ rc = sqlite3_table_column_metadata(
164404
+ db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
164405
+ );
164406
+ if( rc!=SQLITE_OK ){
164313164407
pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
164314
- return SQLITE_OK;
164408
+ return rc==SQLITE_ERROR ? SQLITE_OK : rc;
164315164409
}
164316164410
zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
164317164411
if( zSql==0 ){
164318164412
rc = SQLITE_NOMEM;
164319164413
}else{
@@ -165210,11 +165304,11 @@
165210165304
** of the locale to use. Passing an empty string ("") or SQL NULL value
165211165305
** as the second argument is the same as invoking the 1 argument version
165212165306
** of upper() or lower().
165213165307
**
165214165308
** lower('I', 'en_us') -> 'i'
165215
-** lower('I', 'tr_tr') -> 'ı' (small dotless i)
165309
+** lower('I', 'tr_tr') -> '\u131' (small dotless i)
165216165310
**
165217165311
** http://www.icu-project.org/userguide/posix.html#case_mappings
165218165312
*/
165219165313
static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
165220165314
const UChar *zInput; /* Pointer to input string */
@@ -181140,11 +181234,11 @@
181140181234
}
181141181235
#endif
181142181236
fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
181143181237
fts5yymajor = fts5YYNOCODE;
181144181238
}else{
181145
- while( fts5yypParser->fts5yytos >= &fts5yypParser->fts5yystack
181239
+ while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
181146181240
&& fts5yymx != fts5YYERRORSYMBOL
181147181241
&& (fts5yyact = fts5yy_find_reduce_action(
181148181242
fts5yypParser->fts5yytos->stateno,
181149181243
fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
181150181244
){
@@ -181506,10 +181600,13 @@
181506181600
int nToken, /* Size of token in bytes */
181507181601
int iStartOff, /* Start offset of token */
181508181602
int iEndOff /* End offset of token */
181509181603
){
181510181604
int rc = SQLITE_OK;
181605
+
181606
+ UNUSED_PARAM2(pToken, nToken);
181607
+ UNUSED_PARAM(iEndOff);
181511181608
181512181609
if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
181513181610
Fts5SFinder *p = (Fts5SFinder*)pContext;
181514181611
if( p->iPos>0 ){
181515181612
int i;
@@ -181662,11 +181759,10 @@
181662181759
for(jj=0; jj<(sFinder.nFirst-1); jj++){
181663181760
if( sFinder.aFirst[jj+1]>io ) break;
181664181761
}
181665181762
181666181763
if( sFinder.aFirst[jj]<io ){
181667
- int nScore;
181668181764
memset(aSeen, 0, nPhrase);
181669181765
rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
181670181766
sFinder.aFirst[jj], nToken, &nScore, 0
181671181767
);
181672181768
@@ -195597,11 +195693,11 @@
195597195693
int nArg, /* Number of args */
195598195694
sqlite3_value **apUnused /* Function arguments */
195599195695
){
195600195696
assert( nArg==0 );
195601195697
UNUSED_PARAM2(nArg, apUnused);
195602
- sqlite3_result_text(pCtx, "fts5: 2016-09-21 19:43:34 0741812d7fcd558479e4849fbb3ba8d03738d018", -1, SQLITE_TRANSIENT);
195698
+ sqlite3_result_text(pCtx, "fts5: 2016-10-26 16:05:10 ec9dab8054c71d112c68f58a45821b38c2a45677", -1, SQLITE_TRANSIENT);
195603195699
}
195604195700
195605195701
static int fts5Init(sqlite3 *db){
195606195702
static const sqlite3_module fts5Mod = {
195607195703
/* iVersion */ 2,
195608195704
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.15.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -379,13 +379,13 @@
379 **
380 ** See also: [sqlite3_libversion()],
381 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
382 ** [sqlite_version()] and [sqlite_source_id()].
383 */
384 #define SQLITE_VERSION "3.15.0"
385 #define SQLITE_VERSION_NUMBER 3015000
386 #define SQLITE_SOURCE_ID "2016-09-22 18:53:13 c3774c6a5fe48af91fda28e9e18c6ed9053ea992"
387
388 /*
389 ** CAPI3REF: Run-Time Library Version Numbers
390 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
391 **
@@ -1235,10 +1235,16 @@
1235 ** <li>[[SQLITE_FCNTL_HAS_MOVED]]
1236 ** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
1237 ** pointer to an integer and it writes a boolean into that integer depending
1238 ** on whether or not the file has been renamed, moved, or deleted since it
1239 ** was first opened.
 
 
 
 
 
 
1240 **
1241 ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
1242 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1243 ** opcode causes the xFileControl method to swap the file handle with the one
1244 ** pointed to by the pArg argument. This capability is used during testing
@@ -1286,10 +1292,12 @@
1286 #define SQLITE_FCNTL_WAL_BLOCK 24
1287 #define SQLITE_FCNTL_ZIPVFS 25
1288 #define SQLITE_FCNTL_RBU 26
1289 #define SQLITE_FCNTL_VFS_POINTER 27
1290 #define SQLITE_FCNTL_JOURNAL_POINTER 28
 
 
1291
1292 /* deprecated names */
1293 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1294 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1295 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2238,18 +2246,31 @@
2238 ** does not make a copy of the new main schema name string, so the application
2239 ** must ensure that the argument passed into this DBCONFIG option is unchanged
2240 ** until after the database connection closes.
2241 ** </dd>
2242 **
 
 
 
 
 
 
 
 
 
 
 
 
2243 ** </dl>
2244 */
2245 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
2246 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
2247 #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
2248 #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
2249 #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
2250 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
 
2251
2252
2253 /*
2254 ** CAPI3REF: Enable Or Disable Extended Result Codes
2255 ** METHOD: sqlite3
@@ -8915,11 +8936,11 @@
8915
8916 /*
8917 ** CAPI3REF: Set a table filter on a Session Object.
8918 **
8919 ** The second argument (xFilter) is the "filter callback". For changes to rows
8920 ** in tables that are not attached to the Session oject, the filter is called
8921 ** to determine whether changes to the table's rows should be tracked or not.
8922 ** If xFilter returns 0, changes is not tracked. Note that once a table is
8923 ** attached, xFilter will not be called again.
8924 */
8925 void sqlite3session_table_filter(
@@ -9181,11 +9202,11 @@
9181 ** Assuming the changeset blob was created by one of the
9182 ** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
9183 ** [sqlite3changeset_invert()] functions, all changes within the changeset
9184 ** that apply to a single table are grouped together. This means that when
9185 ** an application iterates through a changeset using an iterator created by
9186 ** this function, all changes that relate to a single table are visted
9187 ** consecutively. There is no chance that the iterator will visit a change
9188 ** the applies to table X, then one for table Y, and then later on visit
9189 ** another change for table X.
9190 */
9191 int sqlite3changeset_start(
@@ -9268,11 +9289,11 @@
9268 ** If successful, *pabPK is set to point to an array of nCol entries, where
9269 ** nCol is the number of columns in the table. Elements of *pabPK are set to
9270 ** 0x01 if the corresponding column is part of the tables primary key, or
9271 ** 0x00 if it is not.
9272 **
9273 ** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
9274 ** in the table.
9275 **
9276 ** If this function is called when the iterator does not point to a valid
9277 ** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
9278 ** SQLITE_OK is returned and the output variables populated as described
@@ -9543,11 +9564,11 @@
9543 ** Rows within the changeset and changegroup are identified by the values in
9544 ** their PRIMARY KEY columns. A change in the changeset is considered to
9545 ** apply to the same row as a change already present in the changegroup if
9546 ** the two rows have the same primary key.
9547 **
9548 ** Changes to rows that that do not already appear in the changegroup are
9549 ** simply copied into it. Or, if both the new changeset and the changegroup
9550 ** contain changes that apply to a single row, the final contents of the
9551 ** changegroup depends on the type of each change, as follows:
9552 **
9553 ** <table border=1 style="margin-left:8ex;margin-right:8ex">
@@ -11411,13 +11432,13 @@
11411 #define TK_GROUP 127
11412 #define TK_HAVING 128
11413 #define TK_LIMIT 129
11414 #define TK_WHERE 130
11415 #define TK_INTO 131
11416 #define TK_INTEGER 132
11417 #define TK_FLOAT 133
11418 #define TK_BLOB 134
11419 #define TK_VARIABLE 135
11420 #define TK_CASE 136
11421 #define TK_WHEN 137
11422 #define TK_THEN 138
11423 #define TK_ELSE 139
@@ -12675,19 +12696,19 @@
12675 #define OP_SorterData 120 /* synopsis: r[P2]=data */
12676 #define OP_RowKey 121 /* synopsis: r[P2]=key */
12677 #define OP_RowData 122 /* synopsis: r[P2]=data */
12678 #define OP_Rowid 123 /* synopsis: r[P2]=rowid */
12679 #define OP_NullRow 124
12680 #define OP_SorterInsert 125
12681 #define OP_IdxInsert 126 /* synopsis: key=r[P2] */
12682 #define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */
12683 #define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */
12684 #define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */
12685 #define OP_Destroy 130
12686 #define OP_Clear 131
12687 #define OP_ResetSorter 132
12688 #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
12689 #define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */
12690 #define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */
12691 #define OP_ParseSchema 136
12692 #define OP_LoadAnalysis 137
12693 #define OP_DropTable 138
@@ -12741,11 +12762,11 @@
12741 /* 88 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
12742 /* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
12743 /* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
12744 /* 112 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
12745 /* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
12746 /* 128 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10,\
12747 /* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\
12748 /* 144 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\
12749 /* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
12750 /* 160 */ 0x00, 0x00, 0x00,}
12751
@@ -13030,11 +13051,11 @@
13030 int,
13031 int,
13032 int,
13033 void(*)(DbPage*)
13034 );
13035 SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
13036 SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
13037
13038 /* Functions used to configure a Pager object. */
13039 SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
13040 SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
@@ -13081,19 +13102,22 @@
13081 SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
13082 SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
13083 SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
13084
13085 #ifndef SQLITE_OMIT_WAL
13086 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
13087 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
13088 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
13089 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
13090 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
 
13091 # ifdef SQLITE_ENABLE_SNAPSHOT
13092 SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
13093 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
13094 # endif
 
 
13095 #endif
13096
13097 #ifdef SQLITE_ENABLE_ZIPVFS
13098 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
13099 #endif
@@ -14060,10 +14084,11 @@
14060 #define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
14061 #define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
14062 #define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
14063 #define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
14064 #define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
 
14065
14066
14067 /*
14068 ** Bits of the sqlite3.dbOptFlags field that are used by the
14069 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -14963,10 +14988,11 @@
14963 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
14964 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
14965 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
14966 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
14967 #define EP_Alias 0x400000 /* Is an alias for a result set column */
 
14968
14969 /*
14970 ** Combinations of two or more EP_* flags
14971 */
14972 #define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
@@ -15514,39 +15540,27 @@
15514 u8 mayAbort; /* True if statement may throw an ABORT exception */
15515 u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
15516 u8 okConstFactor; /* OK to factor out constants */
15517 u8 disableLookaside; /* Number of times lookaside has been disabled */
15518 u8 nColCache; /* Number of entries in aColCache[] */
15519 int aTempReg[8]; /* Holding area for temporary registers */
15520 int nRangeReg; /* Size of the temporary register block */
15521 int iRangeReg; /* First register in temporary register block */
15522 int nErr; /* Number of errors seen */
15523 int nTab; /* Number of previously allocated VDBE cursors */
15524 int nMem; /* Number of memory cells used so far */
15525 int nSet; /* Number of sets used so far */
15526 int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
15527 int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
15528 int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
15529 int ckBase; /* Base register of data during check constraints */
15530 int iSelfTab; /* Table of an index whose exprs are being coded */
15531 int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
15532 int iCacheCnt; /* Counter used to generate aColCache[].lru values */
15533 int nLabel; /* Number of labels used */
15534 int *aLabel; /* Space to hold the labels */
15535 struct yColCache {
15536 int iTable; /* Table cursor number */
15537 i16 iColumn; /* Table column number */
15538 u8 tempReg; /* iReg is a temp register that needs to be freed */
15539 int iLevel; /* Nesting level */
15540 int iReg; /* Reg with value of this column. 0 means none. */
15541 int lru; /* Least recently used entry has the smallest value */
15542 } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
15543 ExprList *pConstExpr;/* Constant expressions */
15544 Token constraintName;/* Name of the constraint currently being parsed */
15545 yDbMask writeMask; /* Start a write transaction on these databases */
15546 yDbMask cookieMask; /* Bitmask of schema verified databases */
15547 int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
15548 int regRowid; /* Register holding rowid of CREATE TABLE entry */
15549 int regRoot; /* Register holding root page number for new objects */
15550 int nMaxArg; /* Max args passed to user function by sub-program */
15551 #if SELECTTRACE_ENABLED
15552 int nSelect; /* Number of SELECT statements seen */
@@ -15555,21 +15569,38 @@
15555 #ifndef SQLITE_OMIT_SHARED_CACHE
15556 int nTableLock; /* Number of locks in aTableLock */
15557 TableLock *aTableLock; /* Required table locks for shared-cache mode */
15558 #endif
15559 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
15560
15561 /* Information used while coding trigger programs. */
15562 Parse *pToplevel; /* Parse structure for main program (or NULL) */
15563 Table *pTriggerTab; /* Table triggers are being coded for */
15564 int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
15565 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
15566 u32 oldmask; /* Mask of old.* columns referenced */
15567 u32 newmask; /* Mask of new.* columns referenced */
15568 u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
15569 u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
15570 u8 disableTriggers; /* True to disable triggers */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15571
15572 /************************************************************************
15573 ** Above is constant between recursions. Below is reset before and after
15574 ** each recursion. The boundary between these two regions is determined
15575 ** using offsetof(Parse,nVar) so the nVar field must be the first field
@@ -15582,11 +15613,10 @@
15582 u8 explain; /* True if the EXPLAIN flag is found on the query */
15583 #ifndef SQLITE_OMIT_VIRTUALTABLE
15584 u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
15585 int nVtabLock; /* Number of virtual tables to lock */
15586 #endif
15587 int nAlias; /* Number of aliased result set columns */
15588 int nHeight; /* Expression tree height of current sub-select */
15589 #ifndef SQLITE_OMIT_EXPLAIN
15590 int iSelectId; /* ID of current select for EXPLAIN output */
15591 int iNextSelectId; /* Next available select ID for EXPLAIN output */
15592 #endif
@@ -15594,12 +15624,10 @@
15594 Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
15595 const char *zTail; /* All SQL text past the last semicolon parsed */
15596 Table *pNewTable; /* A table being constructed by CREATE TABLE */
15597 Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
15598 const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
15599 Token sNameToken; /* Token with unqualified schema object name */
15600 Token sLastToken; /* The last token parsed */
15601 #ifndef SQLITE_OMIT_VIRTUALTABLE
15602 Token sArg; /* Complete text of a module argument */
15603 Table **apVtabLock; /* Pointer to virtual tables needing locking */
15604 #endif
15605 Table *pZombieTab; /* List of Table objects to delete after code gen */
@@ -15606,10 +15634,18 @@
15606 TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
15607 With *pWith; /* Current WITH clause, or NULL */
15608 With *pWithToFree; /* Free this WITH object at the end of the parse */
15609 };
15610
 
 
 
 
 
 
 
 
15611 /*
15612 ** Return true if currently inside an sqlite3_declare_vtab() call.
15613 */
15614 #ifdef SQLITE_OMIT_VIRTUALTABLE
15615 #define IN_DECLARE_VTAB 0
@@ -16169,11 +16205,11 @@
16169 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
16170 SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
16171 SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
16172 SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
16173 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
16174 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
16175 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
16176 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
16177 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
16178 SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
16179 SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
@@ -16989,20 +17025,17 @@
16989 ** If x is a lower-case ASCII character, then its upper-case equivalent
16990 ** is (x - 0x20). Therefore toupper() can be implemented as:
16991 **
16992 ** (x & ~(map[x]&0x20))
16993 **
16994 ** Standard function tolower() is implemented using the sqlite3UpperToLower[]
16995 ** array. tolower() is used more often than toupper() by SQLite.
16996 **
16997 ** Bit 0x40 is set if the character non-alphanumeric and can be used in an
16998 ** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
16999 ** non-ASCII UTF character. Hence the test for whether or not a character is
17000 ** part of an identifier is 0x46.
17001 **
17002 ** SQLite's versions are identical to the standard versions assuming a
17003 ** locale of "C". They are implemented as macros in sqliteInt.h.
17004 */
17005 #ifdef SQLITE_ASCII
17006 SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
17007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
17008 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
@@ -17071,11 +17104,11 @@
17071 #ifndef SQLITE_SORTER_PMASZ
17072 # define SQLITE_SORTER_PMASZ 250
17073 #endif
17074
17075 /* Statement journals spill to disk when their size exceeds the following
17076 ** threashold (in bytes). 0 means that statement journals are created and
17077 ** written to disk immediately (the default behavior for SQLite versions
17078 ** before 3.12.0). -1 means always keep the entire statement journal in
17079 ** memory. (The statement journal is also always held entirely in memory
17080 ** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
17081 ** setting.)
@@ -17159,11 +17192,11 @@
17159
17160 /*
17161 ** The value of the "pending" byte must be 0x40000000 (1 byte past the
17162 ** 1-gibabyte boundary) in a compatible database. SQLite never uses
17163 ** the database page that contains the pending byte. It never attempts
17164 ** to read or write that page. The pending byte page is set assign
17165 ** for use by the VFS layers as space for managing file locks.
17166 **
17167 ** During testing, it is often desirable to move the pending byte to
17168 ** a different position in the file. This allows code that has to
17169 ** deal with the pending byte to run on files that are much smaller
@@ -17260,10 +17293,13 @@
17260 #if SQLITE_DEFAULT_LOCKING_MODE
17261 "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
17262 #endif
17263 #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
17264 "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
 
 
 
17265 #endif
17266 #if SQLITE_DISABLE_DIRSYNC
17267 "DISABLE_DIRSYNC",
17268 #endif
17269 #if SQLITE_DISABLE_LFS
@@ -17346,10 +17382,13 @@
17346 #if SQLITE_ENABLE_UNLOCK_NOTIFY
17347 "ENABLE_UNLOCK_NOTIFY",
17348 #endif
17349 #if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
17350 "ENABLE_UPDATE_DELETE_LIMIT",
 
 
 
17351 #endif
17352 #if SQLITE_HAS_CODEC
17353 "HAS_CODEC",
17354 #endif
17355 #if HAVE_ISNAN || SQLITE_HAVE_ISNAN
@@ -17719,13 +17758,10 @@
17719 typedef unsigned Bool;
17720
17721 /* Opaque type used by code in vdbesort.c */
17722 typedef struct VdbeSorter VdbeSorter;
17723
17724 /* Opaque type used by the explainer */
17725 typedef struct Explain Explain;
17726
17727 /* Elements of the linked list at Vdbe.pAuxData */
17728 typedef struct AuxData AuxData;
17729
17730 /* Types of VDBE cursors */
17731 #define CURTYPE_BTREE 0
@@ -17796,10 +17832,16 @@
17796 /* 2*nField extra array elements allocated for aType[], beyond the one
17797 ** static element declared in the structure. nField total array slots for
17798 ** aType[] and nField+1 array slots for aOffset[] */
17799 };
17800
 
 
 
 
 
 
17801 /*
17802 ** When a sub-program is executed (OP_Program), a structure of this type
17803 ** is allocated to store the current value of the program counter, as
17804 ** well as the current memory cell array and various other frame specific
17805 ** values stored in the Vdbe struct. When the sub-program is finished,
@@ -17840,15 +17882,10 @@
17840 int nDbChange; /* Value of db->nChange */
17841 };
17842
17843 #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
17844
17845 /*
17846 ** A value for VdbeCursor.cacheValid that means the cache is always invalid.
17847 */
17848 #define CACHE_STALE 0
17849
17850 /*
17851 ** Internally, the vdbe manipulates nearly all SQL values as Mem
17852 ** structures. Each Mem struct may cache multiple representations (string,
17853 ** integer etc.) of the same value.
17854 */
@@ -17985,22 +18022,10 @@
17985 u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
17986 u8 argc; /* Number of arguments */
17987 sqlite3_value *argv[1]; /* Argument set */
17988 };
17989
17990 /*
17991 ** An Explain object accumulates indented output which is helpful
17992 ** in describing recursive data structures.
17993 */
17994 struct Explain {
17995 Vdbe *pVdbe; /* Attach the explanation to this Vdbe */
17996 StrAccum str; /* The string being accumulated */
17997 int nIndent; /* Number of elements in aIndent */
17998 u16 aIndent[100]; /* Levels of indentation */
17999 char zBase[100]; /* Initial space */
18000 };
18001
18002 /* A bitfield type for use inside of structures. Always follow with :N where
18003 ** N is the number of bits.
18004 */
18005 typedef unsigned bft; /* Bit Field Type */
18006
@@ -18021,57 +18046,61 @@
18021 ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
18022 ** is really a pointer to an instance of this structure.
18023 */
18024 struct Vdbe {
18025 sqlite3 *db; /* The database connection that owns this statement */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18026 Op *aOp; /* Space to hold the virtual machine's program */
18027 Mem *aMem; /* The memory locations */
18028 Mem **apArg; /* Arguments to currently executing user function */
18029 Mem *aColName; /* Column names to return */
18030 Mem *pResultSet; /* Pointer to an array of results */
18031 Parse *pParse; /* Parsing context used to create this Vdbe */
18032 int nMem; /* Number of memory locations currently allocated */
18033 int nOp; /* Number of instructions in the program */
18034 int nCursor; /* Number of slots in apCsr[] */
18035 u32 magic; /* Magic number for sanity checking */
18036 char *zErrMsg; /* Error message written here */
18037 Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
18038 VdbeCursor **apCsr; /* One element of this array for each open cursor */
18039 Mem *aVar; /* Values for the OP_Variable opcode. */
18040 char **azVar; /* Name of variables */
18041 ynVar nVar; /* Number of entries in aVar[] */
18042 ynVar nzVar; /* Number of entries in azVar[] */
18043 u32 cacheCtr; /* VdbeCursor row cache generation counter */
18044 int pc; /* The program counter */
18045 int rc; /* Value to return */
18046 #ifdef SQLITE_DEBUG
18047 int rcApp; /* errcode set by sqlite3_result_error_code() */
18048 #endif
18049 u16 nResColumn; /* Number of columns in one row of the result set */
18050 u8 errorAction; /* Recovery action to do in case of an error */
 
18051 bft expired:1; /* True if the VM needs to be recompiled */
18052 bft doingRerun:1; /* True if rerunning after an auto-reprepare */
18053 u8 minWriteFileFormat; /* Minimum file format for writable database files */
18054 bft explain:2; /* True if EXPLAIN present on SQL command */
18055 bft changeCntOn:1; /* True to update the change-counter */
18056 bft runOnlyOnce:1; /* Automatically expire on reset */
18057 bft usesStmtJournal:1; /* True if uses a statement journal */
18058 bft readOnly:1; /* True for statements that do not write */
18059 bft bIsReader:1; /* True for statements that read */
18060 bft isPrepareV2:1; /* True if prepared with prepare_v2() */
18061 int nChange; /* Number of db changes made since last reset */
18062 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
18063 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
18064 int iStatement; /* Statement number (or 0 if has not opened stmt) */
18065 u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
18066 #ifndef SQLITE_OMIT_TRACE
18067 i64 startTime; /* Time when query started - used for profiling */
18068 #endif
18069 i64 iCurrentTime; /* Value of julianday('now') for this statement */
18070 i64 nFkConstraint; /* Number of imm. FK constraints this VM */
18071 i64 nStmtDefCons; /* Number of def. constraints when stmt started */
18072 i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
18073 char *zSql; /* Text of the SQL statement that generated this */
18074 void *pFree; /* Free this when deleting the vdbe */
18075 VdbeFrame *pFrame; /* Parent frame */
18076 VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
18077 int nFrame; /* Number of frames in pFrame list */
@@ -18086,14 +18115,15 @@
18086 };
18087
18088 /*
18089 ** The following are allowed values for Vdbe.magic
18090 */
18091 #define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
18092 #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
18093 #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
18094 #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
 
18095
18096 /*
18097 ** Structure used to store the context required by the
18098 ** sqlite3_preupdate_*() API functions.
18099 */
@@ -18106,12 +18136,12 @@
18106 UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
18107 UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
18108 int iNewReg; /* Register for new.* values */
18109 i64 iKey1; /* First key value passed to hook */
18110 i64 iKey2; /* Second key value passed to hook */
18111 int iPKey; /* If not negative index of IPK column */
18112 Mem *aNew; /* Array of new.* values */
 
18113 };
18114
18115 /*
18116 ** Function prototypes
18117 */
@@ -24599,13 +24629,12 @@
24599 char *zNew;
24600 size_t n;
24601 if( z==0 ){
24602 return 0;
24603 }
24604 n = sqlite3Strlen30(z) + 1;
24605 assert( (n&0x7fffffff)==n );
24606 zNew = sqlite3DbMallocRaw(db, (int)n);
24607 if( zNew ){
24608 memcpy(zNew, z, n);
24609 }
24610 return zNew;
24611 }
@@ -28775,11 +28804,15 @@
28775 */
28776 static unsigned int strHash(const char *z){
28777 unsigned int h = 0;
28778 unsigned char c;
28779 while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
28780 h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
 
 
 
 
28781 }
28782 return h;
28783 }
28784
28785
@@ -29124,19 +29157,19 @@
29124 /* 120 */ "SorterData" OpHelp("r[P2]=data"),
29125 /* 121 */ "RowKey" OpHelp("r[P2]=key"),
29126 /* 122 */ "RowData" OpHelp("r[P2]=data"),
29127 /* 123 */ "Rowid" OpHelp("r[P2]=rowid"),
29128 /* 124 */ "NullRow" OpHelp(""),
29129 /* 125 */ "SorterInsert" OpHelp(""),
29130 /* 126 */ "IdxInsert" OpHelp("key=r[P2]"),
29131 /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
29132 /* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"),
29133 /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"),
29134 /* 130 */ "Destroy" OpHelp(""),
29135 /* 131 */ "Clear" OpHelp(""),
29136 /* 132 */ "ResetSorter" OpHelp(""),
29137 /* 133 */ "Real" OpHelp("r[P2]=P4"),
29138 /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
29139 /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
29140 /* 136 */ "ParseSchema" OpHelp(""),
29141 /* 137 */ "LoadAnalysis" OpHelp(""),
29142 /* 138 */ "DropTable" OpHelp(""),
@@ -40671,10 +40704,16 @@
40671 a[1] = winIoerrRetryDelay;
40672 }
40673 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
40674 return SQLITE_OK;
40675 }
 
 
 
 
 
 
40676 #ifdef SQLITE_TEST
40677 case SQLITE_FCNTL_WIN32_SET_HANDLE: {
40678 LPHANDLE phFile = (LPHANDLE)pArg;
40679 HANDLE hOldFile = pFile->h;
40680 pFile->h = *phFile;
@@ -44018,11 +44057,11 @@
44018 ){
44019 PgHdr *pPgHdr;
44020 assert( pPage!=0 );
44021 pPgHdr = (PgHdr*)pPage->pExtra;
44022 assert( pPgHdr->pPage==0 );
44023 memset(pPgHdr, 0, sizeof(PgHdr));
44024 pPgHdr->pPage = pPage;
44025 pPgHdr->pData = pPage->pBuf;
44026 pPgHdr->pExtra = (void *)&pPgHdr[1];
44027 memset(pPgHdr->pExtra, 0, pCache->szExtra);
44028 pPgHdr->pCache = pCache;
@@ -44712,11 +44751,11 @@
44712 szBulk = pCache->szAlloc * (i64)pcache1.nInitPage;
44713 }else{
44714 szBulk = -1024 * (i64)pcache1.nInitPage;
44715 }
44716 if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
44717 szBulk = pCache->szAlloc*pCache->nMax;
44718 }
44719 zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
44720 sqlite3EndBenignMalloc();
44721 if( zBulk ){
44722 int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
@@ -46246,21 +46285,21 @@
46246 #define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */
46247
46248 #ifdef SQLITE_OMIT_WAL
46249 # define sqlite3WalOpen(x,y,z) 0
46250 # define sqlite3WalLimit(x,y)
46251 # define sqlite3WalClose(w,x,y,z) 0
46252 # define sqlite3WalBeginReadTransaction(y,z) 0
46253 # define sqlite3WalEndReadTransaction(z)
46254 # define sqlite3WalDbsize(y) 0
46255 # define sqlite3WalBeginWriteTransaction(y) 0
46256 # define sqlite3WalEndWriteTransaction(x) 0
46257 # define sqlite3WalUndo(x,y,z) 0
46258 # define sqlite3WalSavepoint(y,z)
46259 # define sqlite3WalSavepointUndo(y,z) 0
46260 # define sqlite3WalFrames(u,v,w,x,y,z) 0
46261 # define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
46262 # define sqlite3WalCallback(z) 0
46263 # define sqlite3WalExclusiveMode(y,z) 0
46264 # define sqlite3WalHeapMemory(z) 0
46265 # define sqlite3WalFramesize(z) 0
46266 # define sqlite3WalFindFrame(x,y,z) 0
@@ -46274,11 +46313,11 @@
46274 */
46275 typedef struct Wal Wal;
46276
46277 /* Open and close a connection to a write-ahead log. */
46278 SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
46279 SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
46280
46281 /* Set the limiting size of a WAL file. */
46282 SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
46283
46284 /* Used by readers to open (lock) and close (unlock) a snapshot. A
@@ -46317,10 +46356,11 @@
46317 SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
46318
46319 /* Copy pages from the log to the database file */
46320 SQLITE_PRIVATE int sqlite3WalCheckpoint(
46321 Wal *pWal, /* Write-ahead log connection */
 
46322 int eMode, /* One of PASSIVE, FULL and RESTART */
46323 int (*xBusy)(void*), /* Function to call when busy */
46324 void *pBusyArg, /* Context argument for xBusyHandler */
46325 int sync_flags, /* Flags to sync db file with (or 0) */
46326 int nBuf, /* Size of buffer nBuf */
@@ -47161,13 +47201,14 @@
47161 /*
47162 ** Return true if this pager uses a write-ahead log instead of the usual
47163 ** rollback journal. Otherwise false.
47164 */
47165 #ifndef SQLITE_OMIT_WAL
47166 static int pagerUseWal(Pager *pPager){
47167 return (pPager->pWal!=0);
47168 }
 
47169 #else
47170 # define pagerUseWal(x) 0
47171 # define pagerRollbackWal(x) 0
47172 # define pagerWalFrames(v,w,x,y) 0
47173 # define pagerOpenWalIfPresent(z) SQLITE_OK
@@ -50365,21 +50406,22 @@
50365 ** This function always succeeds. If a transaction is active an attempt
50366 ** is made to roll it back. If an error occurs during the rollback
50367 ** a hot journal may be left in the filesystem but no error is returned
50368 ** to the caller.
50369 */
50370 SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
50371 u8 *pTmp = (u8 *)pPager->pTmpSpace;
50372
 
50373 assert( assert_pager_state(pPager) );
50374 disable_simulated_io_errors();
50375 sqlite3BeginBenignMalloc();
50376 pagerFreeMapHdrs(pPager);
50377 /* pPager->errCode = 0; */
50378 pPager->exclusiveMode = 0;
50379 #ifndef SQLITE_OMIT_WAL
50380 sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
50381 pPager->pWal = 0;
50382 #endif
50383 pager_reset(pPager);
50384 if( MEMDB ){
50385 pager_unlock(pPager);
@@ -53538,14 +53580,20 @@
53538 ** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
53539 ** or wal_blocking_checkpoint() API functions.
53540 **
53541 ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
53542 */
53543 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
 
 
 
 
 
 
53544 int rc = SQLITE_OK;
53545 if( pPager->pWal ){
53546 rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
53547 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
53548 pPager->pBusyHandlerArg,
53549 pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
53550 pnLog, pnCkpt
53551 );
@@ -53673,11 +53721,11 @@
53673 ** Before closing the log file, this function attempts to take an
53674 ** EXCLUSIVE lock on the database file. If this cannot be obtained, an
53675 ** error (SQLITE_BUSY) is returned and the log connection is not closed.
53676 ** If successful, the EXCLUSIVE lock is not released before returning.
53677 */
53678 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
53679 int rc = SQLITE_OK;
53680
53681 assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
53682
53683 /* If the log file is not already open, but does exist in the file-system,
@@ -53701,11 +53749,11 @@
53701 ** the database file, the log and log-summary files will be deleted.
53702 */
53703 if( rc==SQLITE_OK && pPager->pWal ){
53704 rc = pagerExclusiveLock(pPager);
53705 if( rc==SQLITE_OK ){
53706 rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
53707 pPager->pageSize, (u8*)pPager->pTmpSpace);
53708 pPager->pWal = 0;
53709 pagerFixMaplimit(pPager);
53710 if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
53711 }
@@ -55484,10 +55532,11 @@
55484 ** checkpoint is running (in any other thread or process) at the same
55485 ** time.
55486 */
55487 static int walCheckpoint(
55488 Wal *pWal, /* Wal connection */
 
55489 int eMode, /* One of PASSIVE, FULL or RESTART */
55490 int (*xBusy)(void*), /* Function to call when busy */
55491 void *pBusyArg, /* Context argument for xBusyHandler */
55492 int sync_flags, /* Flags for OsSync() (or 0) */
55493 u8 *zBuf /* Temporary buffer to use */
@@ -55578,10 +55627,14 @@
55578
55579 /* Iterate through the contents of the WAL, copying data to the db file */
55580 while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
55581 i64 iOffset;
55582 assert( walFramePgno(pWal, iFrame)==iDbpage );
 
 
 
 
55583 if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
55584 continue;
55585 }
55586 iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
55587 /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
@@ -55682,10 +55735,11 @@
55682 /*
55683 ** Close a connection to a log file.
55684 */
55685 SQLITE_PRIVATE int sqlite3WalClose(
55686 Wal *pWal, /* Wal to close */
 
55687 int sync_flags, /* Flags to pass to OsSync() (or 0) */
55688 int nBuf,
55689 u8 *zBuf /* Buffer of at least nBuf bytes */
55690 ){
55691 int rc = SQLITE_OK;
@@ -55698,17 +55752,18 @@
55698 ** the database. In this case checkpoint the database and unlink both
55699 ** the wal and wal-index files.
55700 **
55701 ** The EXCLUSIVE lock is not released before returning.
55702 */
55703 rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
55704 if( rc==SQLITE_OK ){
 
55705 if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
55706 pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
55707 }
55708 rc = sqlite3WalCheckpoint(
55709 pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
55710 );
55711 if( rc==SQLITE_OK ){
55712 int bPersist = -1;
55713 sqlite3OsFileControlHint(
55714 pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist
@@ -56952,10 +57007,11 @@
56952 ** If parameter xBusy is not NULL, it is a pointer to a busy-handler
56953 ** callback. In this case this function runs a blocking checkpoint.
56954 */
56955 SQLITE_PRIVATE int sqlite3WalCheckpoint(
56956 Wal *pWal, /* Wal connection */
 
56957 int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
56958 int (*xBusy)(void*), /* Function to call when busy */
56959 void *pBusyArg, /* Context argument for xBusyHandler */
56960 int sync_flags, /* Flags to sync db file with (or 0) */
56961 int nBuf, /* Size of temporary buffer */
@@ -57026,11 +57082,11 @@
57026 if( rc==SQLITE_OK ){
57027
57028 if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
57029 rc = SQLITE_CORRUPT_BKPT;
57030 }else{
57031 rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
57032 }
57033
57034 /* If no error occurred, set the output variables. */
57035 if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
57036 if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
@@ -58984,11 +59040,11 @@
58984 int bias, /* Bias search to the high end */
58985 int *pRes /* Write search results here */
58986 ){
58987 int rc; /* Status code */
58988 UnpackedRecord *pIdxKey; /* Unpacked index key */
58989 char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */
58990 char *pFree = 0;
58991
58992 if( pKey ){
58993 assert( nKey==(i64)(int)nKey );
58994 pIdxKey = sqlite3VdbeAllocUnpackedRecord(
@@ -60616,23 +60672,30 @@
60616 *ppBtree = p;
60617
60618 btree_open_out:
60619 if( rc!=SQLITE_OK ){
60620 if( pBt && pBt->pPager ){
60621 sqlite3PagerClose(pBt->pPager);
60622 }
60623 sqlite3_free(pBt);
60624 sqlite3_free(p);
60625 *ppBtree = 0;
60626 }else{
 
 
60627 /* If the B-Tree was successfully opened, set the pager-cache size to the
60628 ** default value. Except, when opening on an existing shared pager-cache,
60629 ** do not change the pager-cache size.
60630 */
60631 if( sqlite3BtreeSchema(p, 0, 0)==0 ){
60632 sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
60633 }
 
 
 
 
 
60634 }
60635 if( mutexOpen ){
60636 assert( sqlite3_mutex_held(mutexOpen) );
60637 sqlite3_mutex_leave(mutexOpen);
60638 }
@@ -60758,11 +60821,11 @@
60758 ** it without having to hold the mutex.
60759 **
60760 ** Clean out and delete the BtShared object.
60761 */
60762 assert( !pBt->pCursor );
60763 sqlite3PagerClose(pBt->pPager);
60764 if( pBt->xFreeSchema && pBt->pSchema ){
60765 pBt->xFreeSchema(pBt->pSchema);
60766 }
60767 sqlite3DbFree(0, pBt->pSchema);
60768 freeTempSpace(pBt);
@@ -62822,11 +62885,11 @@
62822 if( (eOp&0x01)==0 /* (1) */
62823 && offset==0 /* (2) */
62824 && (bEnd || a==ovflSize) /* (6) */
62825 && pBt->inTransaction==TRANS_READ /* (4) */
62826 && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
62827 && pBt->pPage1->aData[19]==0x01 /* (5) */
62828 && &pBuf[-4]>=pBufStart /* (7) */
62829 ){
62830 u8 aSave[4];
62831 u8 *aWrite = &pBuf[-4];
62832 assert( aWrite>=pBufStart ); /* hence (7) */
@@ -63078,13 +63141,16 @@
63078 }
63079 sqlite3BtreeClearCursor(pCur);
63080 }
63081
63082 if( pCur->iPage>=0 ){
63083 while( pCur->iPage ){
63084 assert( pCur->apPage[pCur->iPage]!=0 );
63085 releasePageNotNull(pCur->apPage[pCur->iPage--]);
 
 
 
63086 }
63087 }else if( pCur->pgnoRoot==0 ){
63088 pCur->eState = CURSOR_INVALID;
63089 return SQLITE_OK;
63090 }else{
@@ -63091,11 +63157,11 @@
63091 assert( pCur->iPage==(-1) );
63092 rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
63093 0, pCur->curPagerFlags);
63094 if( rc!=SQLITE_OK ){
63095 pCur->eState = CURSOR_INVALID;
63096 return rc;
63097 }
63098 pCur->iPage = 0;
63099 pCur->curIntKey = pCur->apPage[0]->intKey;
63100 }
63101 pRoot = pCur->apPage[0];
@@ -63114,14 +63180,16 @@
63114 assert( pRoot->intKey==1 || pRoot->intKey==0 );
63115 if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
63116 return SQLITE_CORRUPT_BKPT;
63117 }
63118
 
63119 pCur->aiIdx[0] = 0;
63120 pCur->info.nSize = 0;
63121 pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
63122
 
63123 if( pRoot->nCell>0 ){
63124 pCur->eState = CURSOR_VALID;
63125 }else if( !pRoot->leaf ){
63126 Pgno subpage;
63127 if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
@@ -64321,12 +64389,10 @@
64321 nSrc = pX->nData;
64322 assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
64323 nHeader += putVarint32(&pCell[nHeader], nPayload);
64324 nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
64325 }else{
64326 assert( pX->nData==0 );
64327 assert( pX->nZero==0 );
64328 assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
64329 nSrc = nPayload = (int)pX->nKey;
64330 pSrc = pX->pKey;
64331 nHeader += putVarint32(&pCell[nHeader], nPayload);
64332 }
@@ -67700,11 +67766,11 @@
67700 BtShared *pBt = p->pBt;
67701 sqlite3BtreeEnter(p);
67702 if( pBt->inTransaction!=TRANS_NONE ){
67703 rc = SQLITE_LOCKED;
67704 }else{
67705 rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
67706 }
67707 sqlite3BtreeLeave(p);
67708 }
67709 return rc;
67710 }
@@ -68022,26 +68088,20 @@
68022 */
68023 static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
68024 int i = sqlite3FindDbName(pDb, zDb);
68025
68026 if( i==1 ){
68027 Parse *pParse;
68028 int rc = 0;
68029 pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
68030 if( pParse==0 ){
68031 sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
68032 rc = SQLITE_NOMEM_BKPT;
68033 }else{
68034 pParse->db = pDb;
68035 if( sqlite3OpenTempDatabase(pParse) ){
68036 sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
68037 rc = SQLITE_ERROR;
68038 }
68039 sqlite3DbFree(pErrorDb, pParse->zErrMsg);
68040 sqlite3ParserReset(pParse);
68041 sqlite3StackFree(pErrorDb, pParse);
68042 }
68043 if( rc ){
68044 return 0;
68045 }
68046 }
68047
@@ -69041,10 +69101,11 @@
69041 assert( (pMem->flags&MEM_RowSet)==0 );
69042 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
69043
69044
69045 if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
 
69046 return SQLITE_NOMEM_BKPT;
69047 }
69048
69049 /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
69050 ** string representation of the value. Then, if the required encoding
@@ -69340,11 +69401,11 @@
69340 switch( aff ){
69341 case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */
69342 if( (pMem->flags & MEM_Blob)==0 ){
69343 sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
69344 assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
69345 MemSetTypeFlag(pMem, MEM_Blob);
69346 }else{
69347 pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
69348 }
69349 break;
69350 }
@@ -70017,14 +70078,11 @@
70017 sqlite3_value *pVal = 0;
70018 int negInt = 1;
70019 const char *zNeg = "";
70020 int rc = SQLITE_OK;
70021
70022 if( !pExpr ){
70023 *ppVal = 0;
70024 return SQLITE_OK;
70025 }
70026 while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
70027 if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
70028
70029 /* Compressed expressions only appear when parsing the DEFAULT clause
70030 ** on a table column definition, and hence only when pCtx==0. This
@@ -70144,11 +70202,11 @@
70144 Expr *pExpr, /* The expression to evaluate */
70145 u8 enc, /* Encoding to use */
70146 u8 affinity, /* Affinity to use */
70147 sqlite3_value **ppVal /* Write the new value here */
70148 ){
70149 return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
70150 }
70151
70152 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
70153 /*
70154 ** The implementation of the sqlite_record() function. This function accepts
@@ -70487,12 +70545,13 @@
70487 ** Create a new virtual database engine.
70488 */
70489 SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
70490 sqlite3 *db = pParse->db;
70491 Vdbe *p;
70492 p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
70493 if( p==0 ) return 0;
 
70494 p->db = db;
70495 if( db->pVdbe ){
70496 db->pVdbe->pPrev = p;
70497 }
70498 p->pNext = db->pVdbe;
@@ -70650,13 +70709,12 @@
70650 #endif
70651 #ifdef SQLITE_DEBUG
70652 if( p->db->flags & SQLITE_VdbeAddopTrace ){
70653 int jj, kk;
70654 Parse *pParse = p->pParse;
70655 for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
70656 struct yColCache *x = pParse->aColCache + jj;
70657 if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
70658 printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
70659 kk++;
70660 }
70661 if( kk ) printf("\n");
70662 sqlite3VdbePrintOp(0, i, &p->aOp[i]);
@@ -70840,11 +70898,10 @@
70840 assert( j<p->nLabel );
70841 assert( j>=0 );
70842 if( p->aLabel ){
70843 p->aLabel[j] = v->nOp;
70844 }
70845 p->iFixedOp = v->nOp - 1;
70846 }
70847
70848 /*
70849 ** Mark the VDBE as one that can only be run one time.
70850 */
@@ -71231,19 +71288,19 @@
71231 }
71232 SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
71233 sqlite3VdbeGetOp(p,addr)->p3 = val;
71234 }
71235 SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
71236 if( !p->db->mallocFailed ) p->aOp[p->nOp-1].p5 = p5;
 
71237 }
71238
71239 /*
71240 ** Change the P2 operand of instruction addr so that it points to
71241 ** the address of the next instruction to be coded.
71242 */
71243 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
71244 p->pParse->iFixedOp = p->nOp - 1;
71245 sqlite3VdbeChangeP2(p, addr, p->nOp);
71246 }
71247
71248
71249 /*
@@ -71362,11 +71419,11 @@
71362 /*
71363 ** If the last opcode is "op" and it is not a jump destination,
71364 ** then remove it. Return true if and only if an opcode was removed.
71365 */
71366 SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
71367 if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
71368 return sqlite3VdbeChangeToNoop(p, p->nOp-1);
71369 }else{
71370 return 0;
71371 }
71372 }
@@ -71924,10 +71981,25 @@
71924 zCom
71925 );
71926 fflush(pOut);
71927 }
71928 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71929
71930 /*
71931 ** Release an array of N Mem elements
71932 */
71933 static void releaseMemArray(Mem *p, int N){
@@ -72136,10 +72208,11 @@
72136 return SQLITE_ERROR;
72137 }
72138 pMem->flags = MEM_Str|MEM_Term;
72139 zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
72140 if( zP4!=pMem->z ){
 
72141 sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
72142 }else{
72143 assert( pMem->z!=0 );
72144 pMem->n = sqlite3Strlen30(pMem->z);
72145 pMem->enc = SQLITE_UTF8;
@@ -72278,11 +72351,11 @@
72278 SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
72279 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
72280 int i;
72281 #endif
72282 assert( p!=0 );
72283 assert( p->magic==VDBE_MAGIC_INIT );
72284
72285 /* There should be at least one opcode.
72286 */
72287 assert( p->nOp>0 );
72288
@@ -72367,14 +72440,11 @@
72367 n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
72368 x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
72369 assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
72370 x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
72371 assert( x.nFree>=0 );
72372 if( x.nFree>0 ){
72373 memset(x.pSpace, 0, x.nFree);
72374 assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
72375 }
72376
72377 resolveP2Values(p, &nArg);
72378 p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
72379 if( pParse->explain && nMem<10 ){
72380 nMem = 10;
@@ -72399,34 +72469,34 @@
72399 p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
72400 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
72401 p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
72402 #endif
72403 if( x.nNeeded==0 ) break;
72404 x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
72405 x.nFree = x.nNeeded;
72406 }while( !db->mallocFailed );
72407
72408 p->nCursor = nCursor;
72409 if( p->aVar ){
72410 p->nVar = (ynVar)nVar;
72411 for(n=0; n<nVar; n++){
72412 p->aVar[n].flags = MEM_Null;
72413 p->aVar[n].db = db;
72414 }
72415 }
72416 p->nzVar = pParse->nzVar;
72417 p->azVar = pParse->azVar;
72418 pParse->nzVar = 0;
72419 pParse->azVar = 0;
72420 if( p->aMem ){
72421 p->nMem = nMem;
72422 for(n=0; n<nMem; n++){
72423 p->aMem[n].flags = MEM_Undefined;
72424 p->aMem[n].db = db;
72425 }
72426 }
72427 p->explain = pParse->explain;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72428 sqlite3VdbeRewind(p);
72429 }
72430
72431 /*
72432 ** Close a VDBE cursor and release all the resources that cursor
@@ -72574,17 +72644,13 @@
72574
72575 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
72576 sqlite3DbFree(db, p->aColName);
72577 n = nResColumn*COLNAME_N;
72578 p->nResColumn = (u16)nResColumn;
72579 p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
72580 if( p->aColName==0 ) return;
72581 while( n-- > 0 ){
72582 pColName->flags = MEM_Null;
72583 pColName->db = p->db;
72584 pColName++;
72585 }
72586 }
72587
72588 /*
72589 ** Set the name of the idx'th column to be returned by the SQL statement.
72590 ** zName must be a pointer to a nul terminated string.
@@ -73342,11 +73408,11 @@
73342 fclose(out);
73343 }
73344 }
73345 #endif
73346 p->iCurrentTime = 0;
73347 p->magic = VDBE_MAGIC_INIT;
73348 return p->rc & db->errMask;
73349 }
73350
73351 /*
73352 ** Clean up and delete a VDBE after execution. Return an integer which is
@@ -73406,23 +73472,25 @@
73406 */
73407 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
73408 SubProgram *pSub, *pNext;
73409 int i;
73410 assert( p->db==0 || p->db==db );
73411 releaseMemArray(p->aVar, p->nVar);
73412 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
73413 for(pSub=p->pProgram; pSub; pSub=pNext){
73414 pNext = pSub->pNext;
73415 vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
73416 sqlite3DbFree(db, pSub);
73417 }
73418 for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
73419 sqlite3DbFree(db, p->azVar);
 
 
 
 
73420 vdbeFreeOpArray(db, p->aOp, p->nOp);
73421 sqlite3DbFree(db, p->aColName);
73422 sqlite3DbFree(db, p->zSql);
73423 sqlite3DbFree(db, p->pFree);
73424 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
73425 for(i=0; i<p->nScan; i++){
73426 sqlite3DbFree(db, p->aScan[i].zName);
73427 }
73428 sqlite3DbFree(db, p->aScan);
@@ -75073,11 +75141,11 @@
75073 preupdate.keyinfo.enc = ENC(db);
75074 preupdate.keyinfo.nField = pTab->nCol;
75075 preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
75076 preupdate.iKey1 = iKey1;
75077 preupdate.iKey2 = iKey2;
75078 preupdate.iPKey = pTab->iPKey;
75079
75080 db->pPreUpdate = &preupdate;
75081 db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
75082 db->pPreUpdate = 0;
75083 sqlite3DbFree(db, preupdate.aRecord);
@@ -76047,18 +76115,17 @@
76047 static Mem *columnMem(sqlite3_stmt *pStmt, int i){
76048 Vdbe *pVm;
76049 Mem *pOut;
76050
76051 pVm = (Vdbe *)pStmt;
76052 if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
76053 sqlite3_mutex_enter(pVm->db->mutex);
 
 
76054 pOut = &pVm->pResultSet[i];
76055 }else{
76056 if( pVm && ALWAYS(pVm->db) ){
76057 sqlite3_mutex_enter(pVm->db->mutex);
76058 sqlite3Error(pVm->db, SQLITE_RANGE);
76059 }
76060 pOut = (Mem*)columnNullValue();
76061 }
76062 return pOut;
76063 }
76064
@@ -76087,10 +76154,12 @@
76087 ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
76088 ** and _finalize() will return NOMEM.
76089 */
76090 Vdbe *p = (Vdbe *)pStmt;
76091 if( p ){
 
 
76092 p->rc = sqlite3ApiExit(p->db, p->rc);
76093 sqlite3_mutex_leave(p->db->mutex);
76094 }
76095 }
76096
@@ -76663,11 +76732,11 @@
76663 /*
76664 ** Return true if the prepared statement is in need of being reset.
76665 */
76666 SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
76667 Vdbe *v = (Vdbe*)pStmt;
76668 return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
76669 }
76670
76671 /*
76672 ** Return a pointer to the next prepared statement after pStmt associated
76673 ** with database connection pDb. If pStmt is NULL, return the first
@@ -76804,13 +76873,18 @@
76804 }
76805
76806 if( iIdx>=p->pUnpacked->nField ){
76807 *ppValue = (sqlite3_value *)columnNullValue();
76808 }else{
 
76809 *ppValue = &p->pUnpacked->aMem[iIdx];
76810 if( iIdx==p->iPKey ){
76811 sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);
 
 
 
 
76812 }
76813 }
76814
76815 preupdate_old_out:
76816 sqlite3Error(db, rc);
@@ -76883,11 +76957,11 @@
76883 }
76884 if( iIdx>=pUnpack->nField ){
76885 pMem = (sqlite3_value *)columnNullValue();
76886 }else{
76887 pMem = &pUnpack->aMem[iIdx];
76888 if( iIdx==p->iPKey ){
76889 sqlite3VdbeMemSetInt64(pMem, p->iKey2);
76890 }
76891 }
76892 }else{
76893 /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
@@ -76904,11 +76978,11 @@
76904 }
76905 }
76906 assert( iIdx>=0 && iIdx<p->pCsr->nField );
76907 pMem = &p->aNew[iIdx];
76908 if( pMem->flags==0 ){
76909 if( iIdx==p->iPKey ){
76910 sqlite3VdbeMemSetInt64(pMem, p->iKey2);
76911 }else{
76912 rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
76913 if( rc!=SQLITE_OK ) goto preupdate_new_out;
76914 }
@@ -78415,15 +78489,17 @@
78415 u16 nullFlag;
78416 pOut = out2Prerelease(p, pOp);
78417 cnt = pOp->p3-pOp->p2;
78418 assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
78419 pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
 
78420 while( cnt>0 ){
78421 pOut++;
78422 memAboutToChange(p, pOut);
78423 sqlite3VdbeMemSetNull(pOut);
78424 pOut->flags = nullFlag;
 
78425 cnt--;
78426 }
78427 break;
78428 }
78429
@@ -79280,12 +79356,11 @@
79280 ** or not both operands are null.
79281 */
79282 assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
79283 assert( (flags1 & MEM_Cleared)==0 );
79284 assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
79285 if( (flags1&MEM_Null)!=0
79286 && (flags3&MEM_Null)!=0
79287 && (flags3&MEM_Cleared)==0
79288 ){
79289 res = 0; /* Operands are equal */
79290 }else{
79291 res = 1; /* Operands are not equal */
@@ -80487,14 +80562,13 @@
80487 p->nStmtDefCons = db->nDeferredCons;
80488 p->nStmtDefImmCons = db->nDeferredImmCons;
80489 }
80490
80491 /* Gather the schema version number for checking:
80492 ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
80493 ** each time a query is executed to ensure that the internal cache of the
80494 ** schema used when compiling the SQL query matches the schema of the
80495 ** database against which the compiled query is actually executed.
80496 */
80497 sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
80498 iGen = db->aDb[pOp->p1].pSchema->iGeneration;
80499 }else{
80500 iGen = iMeta = 0;
@@ -81549,11 +81623,11 @@
81549
81550 REGISTER_TRACE(pOp->p3, pMem);
81551 sqlite3VdbeMemIntegerify(pMem);
81552 assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
81553 if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
81554 rc = SQLITE_FULL; /* IMP: R-12275-61338 */
81555 goto abort_due_to_error;
81556 }
81557 if( v<pMem->u.i+1 ){
81558 v = pMem->u.i + 1;
81559 }
@@ -81746,11 +81820,11 @@
81746 ** change count is incremented (otherwise not).
81747 **
81748 ** P1 must not be pseudo-table. It has to be a real table with
81749 ** multiple rows.
81750 **
81751 ** If P4 is not NULL then it points to a Table struture. In this case either
81752 ** the update or pre-update hook, or both, may be invoked. The P1 cursor must
81753 ** have been positioned using OP_NotFound prior to invoking this opcode in
81754 ** this case. Specifically, if one is configured, the pre-update hook is
81755 ** invoked if P4 is not NULL. The update-hook is invoked if one is configured,
81756 ** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
@@ -82316,10 +82390,17 @@
82316 ** This flag avoids doing an extra seek.
82317 **
82318 ** This instruction only works for indices. The equivalent instruction
82319 ** for tables is OP_Insert.
82320 */
 
 
 
 
 
 
 
82321 case OP_SorterInsert: /* in2 */
82322 case OP_IdxInsert: { /* in2 */
82323 VdbeCursor *pC;
82324 BtreePayload x;
82325
@@ -82337,13 +82418,10 @@
82337 if( pOp->opcode==OP_SorterInsert ){
82338 rc = sqlite3VdbeSorterWrite(pC, pIn2);
82339 }else{
82340 x.nKey = pIn2->n;
82341 x.pKey = pIn2->z;
82342 x.nData = 0;
82343 x.nZero = 0;
82344 x.pData = 0;
82345 rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3,
82346 ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
82347 );
82348 assert( pC->deferredMoveto==0 );
82349 pC->cacheStatus = CACHE_STALE;
@@ -83547,11 +83625,11 @@
83547 /* If leaving WAL mode, close the log file. If successful, the call
83548 ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
83549 ** file. An EXCLUSIVE lock may still be held on the database file
83550 ** after a successful return.
83551 */
83552 rc = sqlite3PagerCloseWal(pPager);
83553 if( rc==SQLITE_OK ){
83554 sqlite3PagerSetJournalMode(pPager, eNew);
83555 }
83556 }else if( eOld==PAGER_JOURNALMODE_MEMORY ){
83557 /* Cannot transition directly from MEMORY to WAL. Use mode OFF
@@ -88036,11 +88114,13 @@
88036 static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
88037 int rc;
88038 testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
88039 testcase( ExprHasProperty(pExpr, EP_Reduced) );
88040 rc = pWalker->xExprCallback(pWalker, pExpr);
88041 if( rc || ExprHasProperty(pExpr,EP_TokenOnly) ) return rc & WRC_Abort;
 
 
88042 if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
88043 if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
88044 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
88045 if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
88046 }else if( pExpr->x.pList ){
@@ -88780,11 +88860,10 @@
88780 const char *zDb;
88781 Expr *pRight;
88782
88783 /* if( pSrcList==0 ) break; */
88784 notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
88785 /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/
88786 pRight = pExpr->pRight;
88787 if( pRight->op==TK_ID ){
88788 zDb = 0;
88789 zTable = pExpr->pLeft->u.zToken;
88790 zColumn = pRight->u.zToken;
@@ -88809,11 +88888,10 @@
88809 const char *zId; /* The function name. */
88810 FuncDef *pDef; /* Information about the function */
88811 u8 enc = ENC(pParse->db); /* The database encoding */
88812
88813 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
88814 notValid(pParse, pNC, "functions", NC_PartIdx);
88815 zId = pExpr->u.zToken;
88816 nId = sqlite3Strlen30(zId);
88817 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
88818 if( pDef==0 ){
88819 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
@@ -88869,11 +88947,12 @@
88869 }
88870 if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
88871 /* Date/time functions that use 'now', and other functions like
88872 ** sqlite_version() that might change over time cannot be used
88873 ** in an index. */
88874 notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr);
 
88875 }
88876 }
88877 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
88878 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
88879 pNC->nErr++;
@@ -90409,11 +90488,11 @@
90409 ** stored in u.zToken. Instead, the integer values is written
90410 ** into u.iValue and the EP_IntValue flag is set. No extra storage
90411 ** is allocated to hold the integer text and the dequote flag is ignored.
90412 */
90413 SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
90414 sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
90415 int op, /* Expression opcode */
90416 const Token *pToken, /* Token argument. Might be NULL */
90417 int dequote /* True to dequote */
90418 ){
90419 Expr *pNew;
@@ -90627,40 +90706,40 @@
90627 ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
90628 ** as the previous instance of the same wildcard. Or if this is the first
90629 ** instance of the wildcard, the next sequential variable number is
90630 ** assigned.
90631 */
90632 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
90633 sqlite3 *db = pParse->db;
90634 const char *z;
90635
90636 if( pExpr==0 ) return;
90637 assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
90638 z = pExpr->u.zToken;
90639 assert( z!=0 );
90640 assert( z[0]!=0 );
 
90641 if( z[1]==0 ){
90642 /* Wildcard of the form "?". Assign the next variable number */
90643 assert( z[0]=='?' );
90644 pExpr->iColumn = (ynVar)(++pParse->nVar);
90645 }else{
90646 ynVar x = 0;
90647 u32 n = sqlite3Strlen30(z);
90648 if( z[0]=='?' ){
90649 /* Wildcard of the form "?nnn". Convert "nnn" to an integer and
90650 ** use it as the variable number */
90651 i64 i;
90652 int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
90653 pExpr->iColumn = x = (ynVar)i;
90654 testcase( i==0 );
90655 testcase( i==1 );
90656 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
90657 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
90658 if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
90659 sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
90660 db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
90661 x = 0;
90662 }
90663 if( i>pParse->nVar ){
90664 pParse->nVar = (int)i;
90665 }
90666 }else{
@@ -90667,37 +90746,35 @@
90667 /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
90668 ** number as the prior appearance of the same name, or if the name
90669 ** has never appeared before, reuse the same variable number
90670 */
90671 ynVar i;
90672 for(i=0; i<pParse->nzVar; i++){
90673 if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
90674 pExpr->iColumn = x = (ynVar)i+1;
90675 break;
90676 }
90677 }
90678 if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
90679 }
90680 if( x>0 ){
90681 if( x>pParse->nzVar ){
90682 char **a;
90683 a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
90684 if( a==0 ){
90685 assert( db->mallocFailed ); /* Error reported through mallocFailed */
90686 return;
90687 }
90688 pParse->azVar = a;
90689 memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
90690 pParse->nzVar = x;
90691 }
90692 if( z[0]!='?' || pParse->azVar[x-1]==0 ){
90693 sqlite3DbFree(db, pParse->azVar[x-1]);
90694 pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
90695 }
90696 }
90697 }
90698 if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
90699 sqlite3ErrorMsg(pParse, "too many SQL variables");
90700 }
90701 }
90702
90703 /*
@@ -90705,22 +90782,29 @@
90705 */
90706 static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
90707 assert( p!=0 );
90708 /* Sanity check: Assert that the IntValue is non-negative if it exists */
90709 assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
90710 if( !ExprHasProperty(p, EP_TokenOnly) ){
 
 
 
 
 
 
 
90711 /* The Expr.x union is never used at the same time as Expr.pRight */
90712 assert( p->x.pList==0 || p->pRight==0 );
90713 if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
90714 sqlite3ExprDelete(db, p->pRight);
90715 if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
90716 if( ExprHasProperty(p, EP_xIsSelect) ){
90717 sqlite3SelectDelete(db, p->x.pSelect);
90718 }else{
90719 sqlite3ExprListDelete(db, p->x.pList);
90720 }
90721 }
 
90722 if( !ExprHasProperty(p, EP_Static) ){
90723 sqlite3DbFree(db, p);
90724 }
90725 }
90726 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -90893,11 +90977,11 @@
90893 if( nToken ){
90894 char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
90895 memcpy(zToken, p->u.zToken, nToken);
90896 }
90897
90898 if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
90899 /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
90900 if( ExprHasProperty(p, EP_xIsSelect) ){
90901 pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
90902 }else{
90903 pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
@@ -90905,21 +90989,21 @@
90905 }
90906
90907 /* Fill in pNew->pLeft and pNew->pRight. */
90908 if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
90909 zAlloc += dupedExprNodeSize(p, dupFlags);
90910 if( ExprHasProperty(pNew, EP_Reduced) ){
90911 pNew->pLeft = p->pLeft ?
90912 exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
90913 pNew->pRight = p->pRight ?
90914 exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
90915 }
90916 if( pzBuffer ){
90917 *pzBuffer = zAlloc;
90918 }
90919 }else{
90920 if( !ExprHasProperty(p, EP_TokenOnly) ){
90921 if( pNew->op==TK_SELECT_COLUMN ){
90922 pNew->pLeft = p->pLeft;
90923 }else{
90924 pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
90925 }
@@ -92276,12 +92360,12 @@
92276 dest.eDest = SRT_Exists;
92277 sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
92278 VdbeComment((v, "Init EXISTS result"));
92279 }
92280 sqlite3ExprDelete(pParse->db, pSel->pLimit);
92281 pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
92282 &sqlite3IntTokens[1]);
92283 pSel->iLimit = 0;
92284 pSel->selFlags &= ~SF_MultiValue;
92285 if( sqlite3Select(pParse, pSel, &dest) ){
92286 return 0;
92287 }
@@ -92646,36 +92730,23 @@
92646 #endif
92647 }
92648 }
92649 }
92650
92651 #if defined(SQLITE_DEBUG)
92652 /*
92653 ** Verify the consistency of the column cache
92654 */
92655 static int cacheIsValid(Parse *pParse){
92656 int i, n;
92657 for(i=n=0; i<SQLITE_N_COLCACHE; i++){
92658 if( pParse->aColCache[i].iReg>0 ) n++;
92659 }
92660 return n==pParse->nColCache;
92661 }
92662 #endif
92663
92664 /*
92665 ** Clear a cache entry.
92666 */
92667 static void cacheEntryClear(Parse *pParse, struct yColCache *p){
92668 if( p->tempReg ){
92669 if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
92670 pParse->aTempReg[pParse->nTempReg++] = p->iReg;
92671 }
92672 p->tempReg = 0;
92673 }
92674 p->iReg = 0;
92675 pParse->nColCache--;
92676 assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
 
 
92677 }
92678
92679
92680 /*
92681 ** Record in the column cache that a particular column from a
@@ -92701,64 +92772,52 @@
92701 **
92702 ** Actually, the way the column cache is currently used, we are guaranteed
92703 ** that the object will never already be in cache. Verify this guarantee.
92704 */
92705 #ifndef NDEBUG
92706 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92707 assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
92708 }
92709 #endif
92710
92711 /* Find an empty slot and replace it */
92712 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92713 if( p->iReg==0 ){
92714 p->iLevel = pParse->iCacheLevel;
92715 p->iTable = iTab;
92716 p->iColumn = iCol;
92717 p->iReg = iReg;
92718 p->tempReg = 0;
92719 p->lru = pParse->iCacheCnt++;
92720 pParse->nColCache++;
92721 assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
92722 return;
92723 }
92724 }
92725
92726 /* Replace the last recently used */
92727 minLru = 0x7fffffff;
92728 idxLru = -1;
92729 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92730 if( p->lru<minLru ){
92731 idxLru = i;
92732 minLru = p->lru;
92733 }
92734 }
92735 if( ALWAYS(idxLru>=0) ){
92736 p = &pParse->aColCache[idxLru];
92737 p->iLevel = pParse->iCacheLevel;
92738 p->iTable = iTab;
92739 p->iColumn = iCol;
92740 p->iReg = iReg;
92741 p->tempReg = 0;
92742 p->lru = pParse->iCacheCnt++;
92743 assert( cacheIsValid(pParse) );
92744 return;
92745 }
 
 
92746 }
92747
92748 /*
92749 ** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
92750 ** Purge the range of registers from the column cache.
92751 */
92752 SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
92753 struct yColCache *p;
92754 if( iReg<=0 || pParse->nColCache==0 ) return;
92755 p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
92756 while(1){
92757 if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
92758 if( p==pParse->aColCache ) break;
92759 p--;
 
92760 }
92761 }
92762
92763 /*
92764 ** Remember the current column cache context. Any new entries added
@@ -92778,22 +92837,23 @@
92778 ** Remove from the column cache any entries that were added since the
92779 ** the previous sqlite3ExprCachePush operation. In other words, restore
92780 ** the cache to the state it was in prior the most recent Push.
92781 */
92782 SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
92783 int i;
92784 struct yColCache *p;
92785 assert( pParse->iCacheLevel>=1 );
92786 pParse->iCacheLevel--;
92787 #ifdef SQLITE_DEBUG
92788 if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
92789 printf("POP to %d\n", pParse->iCacheLevel);
92790 }
92791 #endif
92792 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92793 if( p->iReg && p->iLevel>pParse->iCacheLevel ){
92794 cacheEntryClear(pParse, p);
 
 
92795 }
92796 }
92797 }
92798
92799 /*
@@ -92803,11 +92863,11 @@
92803 ** get them all.
92804 */
92805 static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
92806 int i;
92807 struct yColCache *p;
92808 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92809 if( p->iReg==iReg ){
92810 p->tempReg = 0;
92811 }
92812 }
92813 }
@@ -92881,12 +92941,12 @@
92881 ){
92882 Vdbe *v = pParse->pVdbe;
92883 int i;
92884 struct yColCache *p;
92885
92886 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92887 if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
92888 p->lru = pParse->iCacheCnt++;
92889 sqlite3ExprCachePinRegister(pParse, p->iReg);
92890 return p->iReg;
92891 }
92892 }
@@ -92914,22 +92974,24 @@
92914 /*
92915 ** Clear all column cache entries.
92916 */
92917 SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
92918 int i;
92919 struct yColCache *p;
92920
92921 #if SQLITE_DEBUG
92922 if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
92923 printf("CLEAR\n");
92924 }
92925 #endif
92926 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92927 if( p->iReg ){
92928 cacheEntryClear(pParse, p);
 
 
92929 }
92930 }
 
92931 }
92932
92933 /*
92934 ** Record the fact that an affinity change has occurred on iCount
92935 ** registers starting with iStart.
@@ -92957,11 +93019,11 @@
92957 ** and does not appear in a normal build.
92958 */
92959 static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
92960 int i;
92961 struct yColCache *p;
92962 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92963 int r = p->iReg;
92964 if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
92965 }
92966 return 0;
92967 }
@@ -94306,15 +94368,14 @@
94306 && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
94307 || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
94308 ){
94309 return 1;
94310 }
94311 if( pE2->op==TK_NOTNULL
94312 && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
94313 && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
94314 ){
94315 return 1;
94316 }
94317 return 0;
94318 }
94319
94320 /*
@@ -94653,11 +94714,11 @@
94653 */
94654 SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
94655 if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
94656 int i;
94657 struct yColCache *p;
94658 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
94659 if( p->iReg==iReg ){
94660 p->tempReg = 1;
94661 return;
94662 }
94663 }
@@ -97959,11 +98020,11 @@
97959 }else{
97960 sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
97961 return 1;
97962 }
97963 }
97964 if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
97965 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
97966 if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
97967 }else{
97968 if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
97969 }
@@ -98423,11 +98484,10 @@
98423 */
98424 v = sqlite3GetVdbe(pParse);
98425 assert( !pParse->isMultiWrite
98426 || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
98427 if( v ){
98428 while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
98429 sqlite3VdbeAddOp0(v, OP_Halt);
98430
98431 #if SQLITE_USER_AUTHENTICATION
98432 if( pParse->nTableLock>0 && db->init.busy==0 ){
98433 sqlite3UserAuthInit(db);
@@ -98450,18 +98510,20 @@
98450 ){
98451 int iDb, i;
98452 assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
98453 sqlite3VdbeJumpHere(v, 0);
98454 for(iDb=0; iDb<db->nDb; iDb++){
 
98455 if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
98456 sqlite3VdbeUsesBtree(v, iDb);
 
98457 sqlite3VdbeAddOp4Int(v,
98458 OP_Transaction, /* Opcode */
98459 iDb, /* P1 */
98460 DbMaskTest(pParse->writeMask,iDb), /* P2 */
98461 pParse->cookieValue[iDb], /* P3 */
98462 db->aDb[iDb].pSchema->iGeneration /* P4 */
98463 );
98464 if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
98465 VdbeComment((v,
98466 "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
98467 }
@@ -98508,20 +98570,10 @@
98508 sqlite3VdbeMakeReady(v, pParse);
98509 pParse->rc = SQLITE_DONE;
98510 }else{
98511 pParse->rc = SQLITE_ERROR;
98512 }
98513
98514 /* We are done with this Parse object. There is no need to de-initialize it */
98515 #if 0
98516 pParse->colNamesSet = 0;
98517 pParse->nTab = 0;
98518 pParse->nMem = 0;
98519 pParse->nSet = 0;
98520 pParse->nVar = 0;
98521 DbMaskZero(pParse->cookieMask);
98522 #endif
98523 }
98524
98525 /*
98526 ** Run the parser and code generator recursively in order to generate
98527 ** code for the SQL statement given onto the end of the pParse context
@@ -98537,12 +98589,11 @@
98537 SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
98538 va_list ap;
98539 char *zSql;
98540 char *zErrMsg = 0;
98541 sqlite3 *db = pParse->db;
98542 # define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
98543 char saveBuf[SAVE_SZ];
98544
98545 if( pParse->nErr ) return;
98546 assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
98547 va_start(ap, zFormat);
98548 zSql = sqlite3VMPrintf(db, zFormat, ap);
@@ -98549,16 +98600,16 @@
98549 va_end(ap);
98550 if( zSql==0 ){
98551 return; /* A malloc must have failed */
98552 }
98553 pParse->nested++;
98554 memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
98555 memset(&pParse->nVar, 0, SAVE_SZ);
98556 sqlite3RunParser(pParse, zSql, &zErrMsg);
98557 sqlite3DbFree(db, zErrMsg);
98558 sqlite3DbFree(db, zSql);
98559 memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
98560 pParse->nested--;
98561 }
98562
98563 #if SQLITE_USER_AUTHENTICATION
98564 /*
@@ -99735,10 +99786,13 @@
99735 ** This plan is not completely bullet-proof. It is possible for
99736 ** the schema to change multiple times and for the cookie to be
99737 ** set back to prior value. But schema changes are infrequent
99738 ** and the probability of hitting the same cookie value is only
99739 ** 1 chance in 2^32. So we're safe enough.
 
 
 
99740 */
99741 SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
99742 sqlite3 *db = pParse->db;
99743 Vdbe *v = pParse->pVdbe;
99744 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
@@ -102318,19 +102372,17 @@
102318 ** will occur at the end of the top-level VDBE and will be generated
102319 ** later, by sqlite3FinishCoding().
102320 */
102321 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
102322 Parse *pToplevel = sqlite3ParseToplevel(pParse);
102323 sqlite3 *db = pToplevel->db;
102324
102325 assert( iDb>=0 && iDb<db->nDb );
102326 assert( db->aDb[iDb].pBt!=0 || iDb==1 );
102327 assert( iDb<SQLITE_MAX_ATTACHED+2 );
102328 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
102329 if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
102330 DbMaskSet(pToplevel->cookieMask, iDb);
102331 pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
102332 if( !OMIT_TEMPDB && iDb==1 ){
102333 sqlite3OpenTempDatabase(pToplevel);
102334 }
102335 }
102336 }
@@ -107192,14 +107244,14 @@
107192 }else if( action==OE_SetDflt ){
107193 Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
107194 if( pDflt ){
107195 pNew = sqlite3ExprDup(db, pDflt, 0);
107196 }else{
107197 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
107198 }
107199 }else{
107200 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
107201 }
107202 pList = sqlite3ExprListAppend(pParse, pList, pNew);
107203 sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
107204 }
107205 }
@@ -109538,10 +109590,11 @@
109538 }
109539 if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
109540 sqlite3ReleaseTempReg(pParse, regRowid);
109541 sqlite3ReleaseTempReg(pParse, regData);
109542 if( emptyDestTest ){
 
109543 sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
109544 sqlite3VdbeJumpHere(v, emptyDestTest);
109545 sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
109546 return 0;
109547 }else{
@@ -114034,22 +114087,18 @@
114034 int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
114035 Vdbe *pReprepare, /* VM being reprepared */
114036 sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
114037 const char **pzTail /* OUT: End of parsed string */
114038 ){
114039 Parse *pParse; /* Parsing context */
114040 char *zErrMsg = 0; /* Error message */
114041 int rc = SQLITE_OK; /* Result code */
114042 int i; /* Loop counter */
114043
114044 /* Allocate the parsing context */
114045 pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
114046 if( pParse==0 ){
114047 rc = SQLITE_NOMEM_BKPT;
114048 goto end_prepare;
114049 }
114050 pParse->pReprepare = pReprepare;
114051 assert( ppStmt && *ppStmt==0 );
114052 /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
114053 assert( sqlite3_mutex_held(db->mutex) );
114054
114055 /* Check to verify that it is possible to get a read lock on all
@@ -114089,12 +114138,11 @@
114089 }
114090 }
114091
114092 sqlite3VtabUnlockList(db);
114093
114094 pParse->db = db;
114095 pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */
114096 if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
114097 char *zSqlCopy;
114098 int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
114099 testcase( nBytes==mxLen );
114100 testcase( nBytes==mxLen+1 );
@@ -114103,65 +114151,65 @@
114103 rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
114104 goto end_prepare;
114105 }
114106 zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
114107 if( zSqlCopy ){
114108 sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
114109 pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
114110 sqlite3DbFree(db, zSqlCopy);
114111 }else{
114112 pParse->zTail = &zSql[nBytes];
114113 }
114114 }else{
114115 sqlite3RunParser(pParse, zSql, &zErrMsg);
114116 }
114117 assert( 0==pParse->nQueryLoop );
114118
114119 if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
114120 if( pParse->checkSchema ){
114121 schemaIsValid(pParse);
114122 }
114123 if( db->mallocFailed ){
114124 pParse->rc = SQLITE_NOMEM_BKPT;
114125 }
114126 if( pzTail ){
114127 *pzTail = pParse->zTail;
114128 }
114129 rc = pParse->rc;
114130
114131 #ifndef SQLITE_OMIT_EXPLAIN
114132 if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
114133 static const char * const azColName[] = {
114134 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
114135 "selectid", "order", "from", "detail"
114136 };
114137 int iFirst, mx;
114138 if( pParse->explain==2 ){
114139 sqlite3VdbeSetNumCols(pParse->pVdbe, 4);
114140 iFirst = 8;
114141 mx = 12;
114142 }else{
114143 sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
114144 iFirst = 0;
114145 mx = 8;
114146 }
114147 for(i=iFirst; i<mx; i++){
114148 sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
114149 azColName[i], SQLITE_STATIC);
114150 }
114151 }
114152 #endif
114153
114154 if( db->init.busy==0 ){
114155 Vdbe *pVdbe = pParse->pVdbe;
114156 sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
114157 }
114158 if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
114159 sqlite3VdbeFinalize(pParse->pVdbe);
114160 assert(!(*ppStmt));
114161 }else{
114162 *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
114163 }
114164
114165 if( zErrMsg ){
114166 sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
114167 sqlite3DbFree(db, zErrMsg);
@@ -114168,20 +114216,19 @@
114168 }else{
114169 sqlite3Error(db, rc);
114170 }
114171
114172 /* Delete any TriggerPrg structures allocated while parsing this statement. */
114173 while( pParse->pTriggerPrg ){
114174 TriggerPrg *pT = pParse->pTriggerPrg;
114175 pParse->pTriggerPrg = pT->pNext;
114176 sqlite3DbFree(db, pT);
114177 }
114178
114179 end_prepare:
114180
114181 sqlite3ParserReset(pParse);
114182 sqlite3StackFree(db, pParse);
114183 rc = sqlite3ApiExit(db, rc);
114184 assert( (rc&db->errMask)==rc );
114185 return rc;
114186 }
114187 static int sqlite3LockAndPrepare(
@@ -115382,11 +115429,11 @@
115382 ** Allocate a KeyInfo object sufficient for an index of N key columns and
115383 ** X extra columns.
115384 */
115385 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
115386 int nExtra = (N+X)*(sizeof(CollSeq*)+1);
115387 KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra);
115388 if( p ){
115389 p->aSortOrder = (u8*)&p->aColl[N+X];
115390 p->nField = (u16)N;
115391 p->nXField = (u16)X;
115392 p->enc = ENC(db);
@@ -118072,16 +118119,17 @@
118072 pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
118073 if( subqueryIsAgg ){
118074 assert( pParent->pHaving==0 );
118075 pParent->pHaving = pParent->pWhere;
118076 pParent->pWhere = pWhere;
118077 pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
118078 sqlite3ExprDup(db, pSub->pHaving, 0));
 
118079 assert( pParent->pGroupBy==0 );
118080 pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
118081 }else{
118082 pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
118083 }
118084 substSelect(db, pParent, iParent, pSub->pEList, 0);
118085
118086 /* The flattened query is distinct if either the inner or the
118087 ** outer query is distinct.
@@ -122381,11 +122429,11 @@
122381 }
122382 #endif
122383
122384 sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
122385 sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
122386 sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF);
122387
122388 /* Begin a transaction and take an exclusive lock on the main database
122389 ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
122390 ** to ensure that we do not try to change the page-size on a WAL database.
122391 */
@@ -124041,24 +124089,24 @@
124041 ** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
124042 ** is only able to process joins with 64 or fewer tables.
124043 */
124044 struct WhereTerm {
124045 Expr *pExpr; /* Pointer to the subexpression that is this term */
 
 
 
 
 
 
124046 int iParent; /* Disable pWC->a[iParent] when this term disabled */
124047 int leftCursor; /* Cursor number of X in "X <op> <expr>" */
124048 int iField; /* Field in (?,?,?) IN (SELECT...) vector */
124049 union {
124050 int leftColumn; /* Column number of X in "X <op> <expr>" */
124051 WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
124052 WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
124053 } u;
124054 LogEst truthProb; /* Probability of truth for this expression */
124055 u16 eOperator; /* A WO_xx value describing <op> */
124056 u16 wtFlags; /* TERM_xxx bit flags. See below */
124057 u8 nChild; /* Number of children that must disable us */
124058 u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
124059 WhereClause *pWC; /* The clause this term is part of */
124060 Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
124061 Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
124062 };
124063
124064 /*
@@ -124207,29 +124255,29 @@
124207 struct WhereInfo {
124208 Parse *pParse; /* Parsing and code generating context */
124209 SrcList *pTabList; /* List of tables in the join */
124210 ExprList *pOrderBy; /* The ORDER BY clause or NULL */
124211 ExprList *pDistinctSet; /* DISTINCT over all these values */
124212 WhereLoop *pLoops; /* List of all WhereLoop objects */
124213 Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
124214 LogEst nRowOut; /* Estimated number of output rows */
124215 LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
 
 
 
 
124216 u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
 
124217 i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
124218 u8 sorted; /* True if really sorted (not just grouped) */
124219 u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
124220 u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
124221 u8 eDistinct; /* One of the WHERE_DISTINCT_* values */
124222 u8 nLevel; /* Number of nested loop */
124223 u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */
124224 int iTop; /* The very beginning of the WHERE loop */
124225 int iContinue; /* Jump here to continue with next record */
124226 int iBreak; /* Jump here to break out of the loop */
124227 int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
124228 int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
124229 WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
124230 WhereClause sWC; /* Decomposition of the WHERE clause */
 
124231 WhereLevel a[1]; /* Information about each nest loop in WHERE */
124232 };
124233
124234 /*
124235 ** Private interfaces - callable only by other where.c routines.
@@ -124689,11 +124737,10 @@
124689 **
124690 ** * the comparison will be performed with no affinity, or
124691 ** * the affinity change in zAff is guaranteed not to change the value.
124692 */
124693 static void updateRangeAffinityStr(
124694 Parse *pParse, /* Parse context */
124695 Expr *pRight, /* RHS of comparison */
124696 int n, /* Number of vector elements in comparison */
124697 char *zAff /* Affinity string to modify */
124698 ){
124699 int i;
@@ -125775,15 +125822,15 @@
125775 assert( (bRev & ~1)==0 );
125776 pLevel->iLikeRepCntr <<=1;
125777 pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
125778 }
125779 #endif
125780 if( pRangeStart==0
125781 && (j = pIdx->aiColumn[nEq])>=0
125782 && pIdx->pTable->aCol[j].notNull==0
125783 ){
125784 bSeekPastNull = 1;
125785 }
125786 }
125787 assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
125788
125789 /* If we are doing a reverse order scan on an ascending index, or
@@ -125829,11 +125876,11 @@
125829 ){
125830 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
125831 VdbeCoverage(v);
125832 }
125833 if( zStartAff ){
125834 updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]);
125835 }
125836 nConstraint += nBtm;
125837 testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
125838 if( sqlite3ExprIsVector(pRight)==0 ){
125839 disableTerm(pLevel, pRangeStart);
@@ -125879,11 +125926,11 @@
125879 ){
125880 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
125881 VdbeCoverage(v);
125882 }
125883 if( zEndAff ){
125884 updateRangeAffinityStr(pParse, pRight, nTop, zEndAff);
125885 codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
125886 }else{
125887 assert( pParse->db->mallocFailed );
125888 }
125889 nConstraint += nTop;
@@ -126315,11 +126362,11 @@
126315 ** and we are coding the t1 loop and the t2 loop has not yet coded,
126316 ** then we cannot use the "t1.a=t2.b" constraint, but we can code
126317 ** the implied "t1.a=123" constraint.
126318 */
126319 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
126320 Expr *pE, *pEAlt;
126321 WhereTerm *pAlt;
126322 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
126323 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
126324 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
126325 if( pTerm->leftCursor!=iCur ) continue;
@@ -126333,17 +126380,13 @@
126333 if( pAlt->wtFlags & (TERM_CODED) ) continue;
126334 testcase( pAlt->eOperator & WO_EQ );
126335 testcase( pAlt->eOperator & WO_IS );
126336 testcase( pAlt->eOperator & WO_IN );
126337 VdbeModuleComment((v, "begin transitive constraint"));
126338 pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
126339 if( pEAlt ){
126340 *pEAlt = *pAlt->pExpr;
126341 pEAlt->pLeft = pE->pLeft;
126342 sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
126343 sqlite3StackFree(db, pEAlt);
126344 }
126345 }
126346
126347 /* For a LEFT OUTER JOIN, generate code that will record the fact that
126348 ** at least one row of the right table has matched the left table.
126349 */
@@ -126448,11 +126491,10 @@
126448 memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
126449 if( pOld!=pWC->aStatic ){
126450 sqlite3DbFree(db, pOld);
126451 }
126452 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
126453 memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
126454 }
126455 pTerm = &pWC->a[idx = pWC->nTerm++];
126456 if( p && ExprHasProperty(p, EP_Unlikely) ){
126457 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
126458 }else{
@@ -126460,10 +126502,12 @@
126460 }
126461 pTerm->pExpr = sqlite3ExprSkipCollate(p);
126462 pTerm->wtFlags = wtFlags;
126463 pTerm->pWC = pWC;
126464 pTerm->iParent = -1;
 
 
126465 return idx;
126466 }
126467
126468 /*
126469 ** Return TRUE if the given operator is one of the operators that is
@@ -127568,10 +127612,11 @@
127568 Expr *pNew;
127569 Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
127570 Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
127571
127572 pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
 
127573 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
127574 exprAnalyze(pSrc, pWC, idxNew);
127575 }
127576 pTerm = &pWC->a[idxTerm];
127577 pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
@@ -127618,11 +127663,11 @@
127618 int idxNew;
127619 WhereTerm *pNewTerm;
127620
127621 pNewExpr = sqlite3PExpr(pParse, TK_GT,
127622 sqlite3ExprDup(db, pLeft, 0),
127623 sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);
127624
127625 idxNew = whereClauseInsert(pWC, pNewExpr,
127626 TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
127627 if( idxNew ){
127628 pNewTerm = &pWC->a[idxNew];
@@ -127796,11 +127841,11 @@
127796 if( k>=pTab->nCol ){
127797 sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
127798 pTab->zName, j);
127799 return;
127800 }
127801 pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
127802 if( pColRef==0 ) return;
127803 pColRef->iTable = pItem->iCursor;
127804 pColRef->iColumn = k++;
127805 pColRef->pTab = pTab;
127806 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
@@ -128009,15 +128054,17 @@
128009 Expr *pX; /* An expression being tested */
128010 WhereClause *pWC; /* Shorthand for pScan->pWC */
128011 WhereTerm *pTerm; /* The term being tested */
128012 int k = pScan->k; /* Where to start scanning */
128013
128014 while( pScan->iEquiv<=pScan->nEquiv ){
128015 iCur = pScan->aiCur[pScan->iEquiv-1];
 
128016 iColumn = pScan->aiColumn[pScan->iEquiv-1];
128017 if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0;
128018 while( (pWC = pScan->pWC)!=0 ){
 
128019 for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
128020 if( pTerm->leftCursor==iCur
128021 && pTerm->u.leftColumn==iColumn
128022 && (iColumn!=XN_EXPR
128023 || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
@@ -128063,19 +128110,21 @@
128063 && pX->iColumn==pScan->aiColumn[0]
128064 ){
128065 testcase( pTerm->eOperator & WO_IS );
128066 continue;
128067 }
 
128068 pScan->k = k+1;
128069 return pTerm;
128070 }
128071 }
128072 }
128073 pScan->pWC = pScan->pWC->pOuter;
128074 k = 0;
128075 }
128076 pScan->pWC = pScan->pOrigWC;
 
128077 k = 0;
128078 pScan->iEquiv++;
128079 }
128080 return 0;
128081 }
@@ -128105,28 +128154,28 @@
128105 int iCur, /* Cursor to scan for */
128106 int iColumn, /* Column to scan for */
128107 u32 opMask, /* Operator(s) to scan for */
128108 Index *pIdx /* Must be compatible with this index */
128109 ){
128110 int j = 0;
128111
128112 /* memset(pScan, 0, sizeof(*pScan)); */
128113 pScan->pOrigWC = pWC;
128114 pScan->pWC = pWC;
128115 pScan->pIdxExpr = 0;
 
 
128116 if( pIdx ){
128117 j = iColumn;
128118 iColumn = pIdx->aiColumn[j];
128119 if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
128120 if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID;
128121 }
128122 if( pIdx && iColumn>=0 ){
128123 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
128124 pScan->zCollName = pIdx->azColl[j];
128125 }else{
128126 pScan->idxaff = 0;
128127 pScan->zCollName = 0;
 
128128 }
128129 pScan->opMask = opMask;
128130 pScan->k = 0;
128131 pScan->aiCur[0] = iCur;
128132 pScan->aiColumn[0] = iColumn;
@@ -130034,11 +130083,11 @@
130034 ** CREATE INDEX ... ON (a, b, c, d, e)
130035 **
130036 ** then this function would be invoked with nEq=1. The value returned in
130037 ** this case is 3.
130038 */
130039 int whereRangeVectorLen(
130040 Parse *pParse, /* Parsing context */
130041 int iCur, /* Cursor open on pIdx */
130042 Index *pIdx, /* The index to be used for a inequality constraint */
130043 int nEq, /* Number of prior equality constraints on same index */
130044 WhereTerm *pTerm /* The vector inequality constraint */
@@ -131480,11 +131529,11 @@
131480 if( rev ) *pRevMask |= MASKBIT(iLoop);
131481 revSet = 1;
131482 }
131483 }
131484 if( isMatch ){
131485 if( iColumn<0 ){
131486 testcase( distinctColumns==0 );
131487 distinctColumns = 1;
131488 }
131489 obSat |= MASKBIT(i);
131490 }else{
@@ -131935,17 +131984,24 @@
131935 }else{
131936 pWInfo->nOBSat = pFrom->isOrdered;
131937 pWInfo->revMask = pFrom->revLoop;
131938 if( pWInfo->nOBSat<=0 ){
131939 pWInfo->nOBSat = 0;
131940 if( nLoop>0 && (pFrom->aLoop[nLoop-1]->wsFlags & WHERE_ONEROW)==0 ){
131941 Bitmask m = 0;
131942 int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
 
 
 
 
131943 WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
131944 if( rc==pWInfo->pOrderBy->nExpr ){
131945 pWInfo->bOrderedInnerLoop = 1;
131946 pWInfo->revMask = m;
 
 
 
131947 }
131948 }
131949 }
131950 }
131951 if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
@@ -132218,26 +132274,29 @@
132218 ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
132219 ** field (type Bitmask) it must be aligned on an 8-byte boundary on
132220 ** some architectures. Hence the ROUND8() below.
132221 */
132222 nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
132223 pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
132224 if( db->mallocFailed ){
132225 sqlite3DbFree(db, pWInfo);
132226 pWInfo = 0;
132227 goto whereBeginError;
132228 }
132229 pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
132230 pWInfo->nLevel = nTabList;
132231 pWInfo->pParse = pParse;
132232 pWInfo->pTabList = pTabList;
132233 pWInfo->pOrderBy = pOrderBy;
132234 pWInfo->pDistinctSet = pDistinctSet;
 
 
132235 pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
132236 pWInfo->wctrlFlags = wctrlFlags;
132237 pWInfo->iLimit = iAuxArg;
132238 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
 
 
 
132239 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
132240 pMaskSet = &pWInfo->sMaskSet;
132241 sWLB.pWInfo = pWInfo;
132242 sWLB.pWC = &pWInfo->sWC;
132243 sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
@@ -132661,17 +132720,19 @@
132661 pLevel->addrLikeRep);
132662 VdbeCoverage(v);
132663 }
132664 #endif
132665 if( pLevel->iLeftJoin ){
 
132666 addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
132667 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
132668 || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
132669 if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
132670 sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
132671 }
132672 if( pLoop->wsFlags & WHERE_INDEXED ){
 
 
132673 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
132674 }
132675 if( pLevel->op==OP_Return ){
132676 sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
132677 }else{
@@ -132844,19 +132905,10 @@
132844 struct LimitVal {
132845 Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
132846 Expr *pOffset; /* The OFFSET expression. NULL if there is none */
132847 };
132848
132849 /*
132850 ** An instance of this structure is used to store the LIKE,
132851 ** GLOB, NOT LIKE, and NOT GLOB operators.
132852 */
132853 struct LikeOp {
132854 Token eOperator; /* "like" or "glob" or "regexp" */
132855 int bNot; /* True if the NOT keyword is present */
132856 };
132857
132858 /*
132859 ** An instance of the following structure describes the event of a
132860 ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
132861 ** TK_DELETE, or TK_INSTEAD. If the event is of the form
132862 **
@@ -132864,15 +132916,10 @@
132864 **
132865 ** Then the "b" IdList records the list "a,b,c".
132866 */
132867 struct TrigEvent { int a; IdList * b; };
132868
132869 /*
132870 ** An instance of this structure holds the ATTACH key and the key type.
132871 */
132872 struct AttachKey { int type; Token key; };
132873
132874 /*
132875 ** Disable lookaside memory allocation for objects that might be
132876 ** shared across database connections.
132877 */
132878 static void disableLookaside(Parse *pParse){
@@ -132915,11 +132962,28 @@
132915 /* Construct a new Expr object from a single identifier. Use the
132916 ** new Expr to populate pOut. Set the span of pOut to be the identifier
132917 ** that created the expression.
132918 */
132919 static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
132920 pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132921 pOut->zStart = t.z;
132922 pOut->zEnd = &t.z[t.n];
132923 }
132924
132925 /* This routine constructs a binary expression node out of two ExprSpan
@@ -133078,11 +133142,10 @@
133078 Select* yy243;
133079 IdList* yy254;
133080 With* yy285;
133081 struct TrigEvent yy332;
133082 struct LimitVal yy354;
133083 struct LikeOp yy392;
133084 struct {int value; int mask;} yy497;
133085 } YYMINORTYPE;
133086 #ifndef YYSTACKDEPTH
133087 #define YYSTACKDEPTH 100
133088 #endif
@@ -133090,19 +133153,19 @@
133090 #define sqlite3ParserARG_PDECL ,Parse *pParse
133091 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
133092 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
133093 #define YYFALLBACK 1
133094 #define YYNSTATE 456
133095 #define YYNRULE 331
133096 #define YY_MAX_SHIFT 455
133097 #define YY_MIN_SHIFTREDUCE 667
133098 #define YY_MAX_SHIFTREDUCE 997
133099 #define YY_MIN_REDUCE 998
133100 #define YY_MAX_REDUCE 1328
133101 #define YY_ERROR_ACTION 1329
133102 #define YY_ACCEPT_ACTION 1330
133103 #define YY_NO_ACTION 1331
133104 /************* End control #defines *******************************************/
133105
133106 /* Define the yytestcase() macro to be a no-op if is not already defined
133107 ** otherwise.
133108 **
@@ -133170,170 +133233,169 @@
133170 ** yy_reduce_ofst[] For each state, the offset into yy_action for
133171 ** shifting non-terminals after a reduce.
133172 ** yy_default[] Default action for each state.
133173 **
133174 *********** Begin parsing tables **********************************************/
133175 #define YY_ACTTAB_COUNT (1571)
133176 static const YYACTIONTYPE yy_action[] = {
133177 /* 0 */ 325, 830, 351, 824, 5, 203, 203, 818, 99, 100,
133178 /* 10 */ 90, 840, 840, 852, 855, 844, 844, 97, 97, 98,
133179 /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95,
133180 /* 30 */ 94, 94, 94, 93, 351, 325, 975, 975, 823, 823,
133181 /* 40 */ 823, 945, 354, 99, 100, 90, 840, 840, 852, 855,
133182 /* 50 */ 844, 844, 97, 97, 98, 98, 98, 98, 338, 96,
133183 /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
133184 /* 70 */ 95, 95, 94, 94, 94, 93, 351, 790, 975, 975,
133185 /* 80 */ 325, 94, 94, 94, 93, 351, 791, 75, 99, 100,
133186 /* 90 */ 90, 840, 840, 852, 855, 844, 844, 97, 97, 98,
133187 /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95,
133188 /* 110 */ 94, 94, 94, 93, 351, 1330, 155, 155, 2, 325,
133189 /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90,
133190 /* 130 */ 840, 840, 852, 855, 844, 844, 97, 97, 98, 98,
133191 /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94,
133192 /* 150 */ 94, 94, 93, 351, 956, 956, 325, 268, 428, 413,
133193 /* 160 */ 411, 61, 751, 751, 99, 100, 90, 840, 840, 852,
133194 /* 170 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 60,
133195 /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133196 /* 190 */ 351, 325, 270, 329, 273, 277, 957, 958, 250, 99,
133197 /* 200 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133198 /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95,
133199 /* 220 */ 95, 94, 94, 94, 93, 351, 325, 936, 1323, 697,
133200 /* 230 */ 705, 1323, 242, 412, 99, 100, 90, 840, 840, 852,
133201 /* 240 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 347,
133202 /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133203 /* 260 */ 351, 325, 936, 1324, 384, 698, 1324, 381, 379, 99,
133204 /* 270 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133205 /* 280 */ 98, 98, 98, 98, 700, 96, 96, 96, 96, 95,
133206 /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178,
133207 /* 300 */ 831, 934, 373, 699, 99, 100, 90, 840, 840, 852,
133208 /* 310 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 375,
133209 /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133210 /* 330 */ 351, 325, 1273, 945, 354, 817, 934, 738, 738, 99,
133211 /* 340 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133212 /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95,
133213 /* 360 */ 95, 94, 94, 94, 93, 351, 325, 967, 227, 92,
133214 /* 370 */ 89, 178, 373, 300, 99, 100, 90, 840, 840, 852,
133215 /* 380 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 919,
133216 /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133217 /* 400 */ 351, 325, 449, 447, 447, 447, 147, 736, 736, 99,
133218 /* 410 */ 100, 90, 840, 840, 852, 855, 844, 844, 97, 97,
133219 /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95,
133220 /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 956,
133221 /* 440 */ 956, 158, 25, 422, 99, 100, 90, 840, 840, 852,
133222 /* 450 */ 855, 844, 844, 97, 97, 98, 98, 98, 98, 450,
133223 /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133224 /* 470 */ 351, 443, 224, 224, 420, 956, 956, 960, 325, 52,
133225 /* 480 */ 52, 957, 958, 176, 415, 78, 99, 100, 90, 840,
133226 /* 490 */ 840, 852, 855, 844, 844, 97, 97, 98, 98, 98,
133227 /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94,
133228 /* 510 */ 94, 93, 351, 325, 428, 418, 298, 957, 958, 960,
133229 /* 520 */ 81, 99, 88, 90, 840, 840, 852, 855, 844, 844,
133230 /* 530 */ 97, 97, 98, 98, 98, 98, 716, 96, 96, 96,
133231 /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 841,
133232 /* 550 */ 841, 853, 856, 994, 318, 343, 379, 100, 90, 840,
133233 /* 560 */ 840, 852, 855, 844, 844, 97, 97, 98, 98, 98,
133234 /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94,
133235 /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340,
133236 /* 590 */ 927, 52, 52, 90, 840, 840, 852, 855, 844, 844,
133237 /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96,
133238 /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445,
133239 /* 620 */ 845, 3, 1200, 361, 360, 378, 344, 812, 956, 956,
133240 /* 630 */ 1297, 86, 445, 728, 3, 212, 169, 287, 405, 282,
133241 /* 640 */ 404, 199, 232, 450, 300, 759, 83, 84, 280, 245,
133242 /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83,
133243 /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246,
133244 /* 670 */ 957, 958, 194, 455, 669, 402, 399, 398, 448, 243,
133245 /* 680 */ 221, 114, 434, 775, 361, 450, 397, 268, 746, 224,
133246 /* 690 */ 224, 132, 132, 198, 830, 434, 452, 451, 428, 427,
133247 /* 700 */ 818, 415, 733, 712, 132, 52, 52, 830, 268, 452,
133248 /* 710 */ 451, 733, 194, 818, 363, 402, 399, 398, 450, 1268,
133249 /* 720 */ 1268, 23, 956, 956, 86, 445, 397, 3, 228, 429,
133250 /* 730 */ 893, 823, 823, 823, 825, 19, 203, 719, 52, 52,
133251 /* 740 */ 428, 408, 439, 249, 823, 823, 823, 825, 19, 229,
133252 /* 750 */ 403, 153, 83, 84, 760, 177, 241, 450, 720, 85,
133253 /* 760 */ 352, 352, 120, 157, 957, 958, 58, 975, 409, 355,
133254 /* 770 */ 330, 448, 268, 428, 430, 320, 789, 32, 32, 86,
133255 /* 780 */ 445, 775, 3, 341, 98, 98, 98, 98, 434, 96,
133256 /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
133257 /* 800 */ 830, 120, 452, 451, 812, 885, 818, 83, 84, 975,
133258 /* 810 */ 812, 132, 410, 918, 85, 352, 352, 132, 407, 788,
133259 /* 820 */ 956, 956, 92, 89, 178, 915, 448, 262, 370, 261,
133260 /* 830 */ 82, 912, 80, 262, 370, 261, 932, 823, 823, 823,
133261 /* 840 */ 825, 19, 257, 434, 96, 96, 96, 96, 95, 95,
133262 /* 850 */ 94, 94, 94, 93, 351, 830, 268, 452, 451, 956,
133263 /* 860 */ 956, 818, 957, 958, 120, 92, 89, 178, 943, 2,
133264 /* 870 */ 916, 963, 268, 1, 766, 76, 445, 761, 3, 707,
133265 /* 880 */ 899, 899, 387, 956, 956, 756, 917, 371, 739, 777,
133266 /* 890 */ 755, 907, 823, 823, 823, 825, 19, 883, 740, 450,
133267 /* 900 */ 24, 957, 958, 83, 84, 369, 956, 956, 708, 226,
133268 /* 910 */ 85, 352, 352, 745, 315, 314, 313, 215, 311, 10,
133269 /* 920 */ 10, 682, 448, 349, 348, 957, 958, 887, 776, 691,
133270 /* 930 */ 331, 956, 956, 337, 157, 450, 268, 103, 450, 434,
133271 /* 940 */ 450, 816, 310, 906, 887, 889, 321, 450, 957, 958,
133272 /* 950 */ 708, 830, 775, 452, 451, 10, 10, 818, 10, 10,
133273 /* 960 */ 52, 52, 171, 170, 180, 225, 248, 10, 10, 339,
133274 /* 970 */ 701, 701, 233, 957, 958, 247, 982, 741, 450, 956,
133275 /* 980 */ 956, 425, 157, 980, 685, 981, 182, 912, 823, 823,
133276 /* 990 */ 823, 825, 19, 183, 324, 423, 132, 181, 51, 51,
133277 /* 1000 */ 715, 349, 348, 394, 256, 887, 334, 915, 983, 983,
133278 /* 1010 */ 830, 417, 824, 234, 198, 234, 818, 268, 326, 382,
133279 /* 1020 */ 120, 957, 958, 264, 177, 98, 98, 98, 98, 91,
133280 /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133281 /* 1040 */ 351, 816, 416, 371, 120, 359, 816, 823, 823, 823,
133282 /* 1050 */ 775, 299, 916, 450, 368, 197, 196, 195, 358, 200,
133283 /* 1060 */ 175, 380, 9, 9, 450, 1287, 875, 714, 917, 450,
133284 /* 1070 */ 433, 237, 450, 36, 36, 132, 253, 450, 255, 450,
133285 /* 1080 */ 117, 450, 809, 362, 37, 37, 983, 983, 450, 12,
133286 /* 1090 */ 12, 330, 27, 27, 446, 331, 280, 38, 38, 39,
133287 /* 1100 */ 39, 40, 40, 1207, 450, 816, 335, 356, 41, 41,
133288 /* 1110 */ 450, 336, 450, 695, 450, 120, 450, 332, 133, 450,
133289 /* 1120 */ 268, 450, 269, 450, 42, 42, 450, 816, 254, 450,
133290 /* 1130 */ 28, 28, 29, 29, 31, 31, 43, 43, 450, 44,
133291 /* 1140 */ 44, 45, 45, 11, 11, 450, 46, 46, 450, 105,
133292 /* 1150 */ 105, 450, 748, 713, 450, 695, 450, 910, 47, 47,
133293 /* 1160 */ 450, 267, 450, 415, 450, 48, 48, 450, 33, 33,
133294 /* 1170 */ 386, 49, 49, 450, 50, 50, 34, 34, 450, 172,
133295 /* 1180 */ 122, 122, 123, 123, 124, 124, 450, 56, 56, 450,
133296 /* 1190 */ 120, 450, 345, 35, 35, 450, 790, 450, 106, 106,
133297 /* 1200 */ 450, 74, 450, 974, 450, 791, 53, 53, 432, 107,
133298 /* 1210 */ 107, 108, 108, 450, 272, 104, 104, 121, 121, 450,
133299 /* 1220 */ 119, 119, 112, 112, 111, 111, 450, 317, 996, 450,
133300 /* 1230 */ 118, 450, 162, 109, 109, 317, 935, 450, 896, 110,
133301 /* 1240 */ 110, 450, 895, 744, 688, 436, 55, 55, 20, 57,
133302 /* 1250 */ 57, 54, 54, 440, 444, 756, 385, 26, 26, 274,
133303 /* 1260 */ 755, 30, 30, 21, 672, 673, 674, 223, 175, 931,
133304 /* 1270 */ 814, 372, 319, 202, 202, 882, 120, 120, 120, 374,
133305 /* 1280 */ 826, 710, 202, 72, 276, 263, 120, 120, 74, 395,
133306 /* 1290 */ 278, 286, 208, 74, 718, 717, 725, 726, 892, 892,
133307 /* 1300 */ 167, 997, 285, 753, 729, 784, 77, 878, 202, 997,
133308 /* 1310 */ 208, 693, 891, 891, 116, 281, 782, 882, 390, 815,
133309 /* 1320 */ 762, 773, 826, 431, 302, 303, 822, 218, 696, 289,
133310 /* 1330 */ 690, 291, 293, 679, 678, 680, 950, 159, 316, 7,
133311 /* 1340 */ 364, 252, 259, 804, 909, 376, 400, 295, 308, 173,
133312 /* 1350 */ 435, 953, 168, 991, 135, 205, 926, 924, 59, 988,
133313 /* 1360 */ 62, 284, 880, 333, 879, 712, 144, 156, 130, 72,
133314 /* 1370 */ 366, 367, 393, 185, 189, 160, 383, 67, 389, 266,
133315 /* 1380 */ 137, 894, 774, 219, 154, 139, 190, 140, 391, 271,
133316 /* 1390 */ 191, 141, 142, 801, 681, 148, 811, 342, 322, 192,
133317 /* 1400 */ 406, 732, 911, 874, 723, 731, 323, 710, 730, 71,
133318 /* 1410 */ 704, 204, 283, 703, 6, 79, 421, 702, 965, 770,
133319 /* 1420 */ 297, 346, 426, 102, 722, 288, 73, 424, 213, 951,
133320 /* 1430 */ 771, 438, 22, 290, 687, 769, 442, 453, 239, 217,
133321 /* 1440 */ 214, 668, 125, 353, 126, 216, 454, 166, 676, 115,
133322 /* 1450 */ 675, 235, 244, 179, 670, 357, 810, 113, 890, 888,
133323 /* 1460 */ 292, 136, 128, 752, 304, 768, 294, 305, 138, 742,
133324 /* 1470 */ 306, 307, 127, 184, 860, 258, 905, 145, 143, 238,
133325 /* 1480 */ 63, 64, 65, 66, 240, 129, 908, 186, 187, 904,
133326 /* 1490 */ 8, 13, 188, 265, 897, 149, 202, 985, 388, 684,
133327 /* 1500 */ 150, 161, 392, 285, 193, 279, 151, 396, 68, 14,
133328 /* 1510 */ 401, 15, 327, 721, 328, 134, 69, 70, 236, 131,
133329 /* 1520 */ 829, 828, 858, 750, 16, 201, 754, 4, 783, 220,
133330 /* 1530 */ 414, 174, 222, 152, 77, 778, 74, 17, 18, 873,
133331 /* 1540 */ 859, 857, 914, 862, 913, 207, 206, 940, 163, 437,
133332 /* 1550 */ 946, 941, 164, 209, 210, 441, 861, 165, 312, 827,
133333 /* 1560 */ 694, 87, 1000, 309, 211, 1000, 1000, 1000, 1000, 1289,
133334 /* 1570 */ 1288,
133335 };
133336 static const YYCODETYPE yy_lookahead[] = {
133337 /* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28,
133338 /* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
133339 /* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
@@ -133415,87 +133477,86 @@
133415 /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43,
133416 /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
133417 /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97,
133418 /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175,
133419 /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110,
133420 /* 830 */ 137, 163, 139, 108, 109, 110, 152, 132, 133, 134,
133421 /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48,
133422 /* 850 */ 49, 50, 51, 52, 53, 95, 152, 97, 98, 55,
133423 /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147,
133424 /* 870 */ 57, 171, 152, 22, 213, 19, 20, 49, 22, 179,
133425 /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124,
133426 /* 890 */ 121, 152, 132, 133, 134, 135, 136, 193, 85, 152,
133427 /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 55, 5,
133428 /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172,
133429 /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 166,
133430 /* 930 */ 167, 55, 56, 186, 152, 152, 152, 22, 152, 83,
133431 /* 940 */ 152, 152, 160, 152, 169, 170, 164, 152, 97, 98,
133432 /* 950 */ 97, 95, 26, 97, 98, 172, 173, 101, 172, 173,
133433 /* 960 */ 172, 173, 47, 48, 60, 22, 62, 172, 173, 186,
133434 /* 970 */ 55, 56, 186, 97, 98, 71, 100, 193, 152, 55,
133435 /* 980 */ 56, 186, 152, 107, 21, 109, 82, 163, 132, 133,
133436 /* 990 */ 134, 135, 136, 89, 164, 207, 92, 93, 172, 173,
133437 /* 1000 */ 181, 47, 48, 19, 16, 230, 217, 12, 132, 133,
133438 /* 1010 */ 95, 163, 97, 183, 30, 185, 101, 152, 114, 152,
133439 /* 1020 */ 196, 97, 98, 152, 98, 38, 39, 40, 41, 42,
133440 /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
133441 /* 1040 */ 53, 152, 152, 219, 196, 141, 152, 132, 133, 134,
133442 /* 1050 */ 124, 225, 57, 152, 91, 108, 109, 110, 193, 211,
133443 /* 1060 */ 212, 237, 172, 173, 152, 122, 103, 181, 73, 152,
133444 /* 1070 */ 75, 210, 152, 172, 173, 92, 88, 152, 90, 152,
133445 /* 1080 */ 22, 152, 163, 100, 172, 173, 132, 133, 152, 172,
133446 /* 1090 */ 173, 107, 172, 173, 166, 167, 112, 172, 173, 172,
133447 /* 1100 */ 173, 172, 173, 140, 152, 152, 217, 242, 172, 173,
133448 /* 1110 */ 152, 217, 152, 55, 152, 196, 152, 245, 246, 152,
133449 /* 1120 */ 152, 152, 152, 152, 172, 173, 152, 152, 140, 152,
133450 /* 1130 */ 172, 173, 172, 173, 172, 173, 172, 173, 152, 172,
133451 /* 1140 */ 173, 172, 173, 172, 173, 152, 172, 173, 152, 172,
133452 /* 1150 */ 173, 152, 195, 152, 152, 97, 152, 163, 172, 173,
133453 /* 1160 */ 152, 193, 152, 206, 152, 172, 173, 152, 172, 173,
133454 /* 1170 */ 217, 172, 173, 152, 172, 173, 172, 173, 152, 26,
133455 /* 1180 */ 172, 173, 172, 173, 172, 173, 152, 172, 173, 152,
133456 /* 1190 */ 196, 152, 217, 172, 173, 152, 61, 152, 172, 173,
133457 /* 1200 */ 152, 26, 152, 26, 152, 70, 172, 173, 191, 172,
133458 /* 1210 */ 173, 172, 173, 152, 152, 172, 173, 172, 173, 152,
133459 /* 1220 */ 172, 173, 172, 173, 172, 173, 152, 22, 23, 152,
133460 /* 1230 */ 22, 152, 24, 172, 173, 22, 23, 152, 59, 172,
133461 /* 1240 */ 173, 152, 63, 163, 163, 163, 172, 173, 22, 172,
133462 /* 1250 */ 173, 172, 173, 163, 163, 116, 77, 172, 173, 152,
133463 /* 1260 */ 121, 172, 173, 37, 7, 8, 9, 211, 212, 23,
133464 /* 1270 */ 23, 23, 26, 26, 26, 55, 196, 196, 196, 23,
133465 /* 1280 */ 55, 106, 26, 130, 152, 23, 196, 196, 26, 23,
133466 /* 1290 */ 23, 101, 26, 26, 100, 101, 7, 8, 132, 133,
133467 /* 1300 */ 123, 96, 112, 23, 152, 23, 26, 23, 26, 96,
133468 /* 1310 */ 26, 23, 132, 133, 26, 152, 152, 97, 234, 152,
133469 /* 1320 */ 152, 152, 97, 152, 152, 152, 152, 233, 152, 210,
133470 /* 1330 */ 152, 210, 210, 152, 152, 152, 152, 197, 150, 198,
133471 /* 1340 */ 214, 214, 239, 201, 201, 239, 176, 214, 200, 184,
133472 /* 1350 */ 227, 155, 198, 67, 243, 122, 159, 159, 240, 69,
133473 /* 1360 */ 240, 175, 175, 159, 175, 180, 22, 220, 27, 130,
133474 /* 1370 */ 18, 159, 18, 158, 158, 220, 159, 137, 74, 235,
133475 /* 1380 */ 189, 236, 159, 159, 22, 192, 158, 192, 177, 159,
133476 /* 1390 */ 158, 192, 192, 201, 159, 189, 189, 76, 177, 158,
133477 /* 1400 */ 107, 174, 201, 201, 182, 174, 177, 106, 174, 107,
133478 /* 1410 */ 174, 159, 174, 176, 22, 137, 125, 174, 174, 216,
133479 /* 1420 */ 159, 53, 126, 129, 182, 215, 128, 127, 25, 13,
133480 /* 1430 */ 216, 177, 26, 215, 162, 216, 177, 161, 229, 6,
133481 /* 1440 */ 153, 4, 165, 3, 165, 153, 151, 22, 151, 178,
133482 /* 1450 */ 151, 178, 142, 15, 151, 94, 120, 16, 23, 23,
133483 /* 1460 */ 215, 131, 111, 205, 204, 216, 215, 203, 123, 20,
133484 /* 1470 */ 202, 201, 165, 125, 224, 16, 1, 131, 123, 226,
133485 /* 1480 */ 37, 37, 37, 37, 229, 111, 56, 64, 122, 1,
133486 /* 1490 */ 5, 22, 107, 140, 80, 80, 26, 87, 72, 20,
133487 /* 1500 */ 107, 24, 19, 112, 105, 23, 22, 79, 22, 22,
133488 /* 1510 */ 79, 22, 249, 58, 249, 246, 22, 26, 79, 68,
133489 /* 1520 */ 23, 23, 23, 116, 22, 64, 23, 22, 56, 23,
133490 /* 1530 */ 26, 122, 23, 22, 26, 124, 26, 64, 64, 23,
133491 /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24,
133492 /* 1550 */ 1, 23, 22, 26, 122, 24, 23, 22, 15, 23,
133493 /* 1560 */ 23, 22, 251, 23, 122, 251, 251, 251, 251, 122,
133494 /* 1570 */ 122,
133495 };
133496 #define YY_SHIFT_USE_DFLT (1571)
133497 #define YY_SHIFT_COUNT (455)
133498 #define YY_SHIFT_MIN (-94)
133499 #define YY_SHIFT_MAX (1549)
133500 static const short yy_shift_ofst[] = {
133501 /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19,
@@ -133507,132 +133568,132 @@
133507 /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133508 /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133509 /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133510 /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133511 /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746,
133512 /* 110 */ 801, 23, 32, 924, 963, 984, 954, 954, 924, 73,
133513 /* 120 */ 113, -51, 1571, 1571, 1571, 536, 536, 536, 99, 99,
133514 /* 130 */ 813, 813, 667, 205, 240, 924, 924, 924, 924, 924,
133515 /* 140 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
133516 /* 150 */ 924, 924, 924, 924, 924, 332, 983, 422, 422, 113,
133517 /* 160 */ 30, 30, 30, 30, 30, 30, 1571, 1571, 1571, 915,
133518 /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 924,
133519 /* 180 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
133520 /* 190 */ 924, 924, 924, 924, 924, 672, 672, 672, 924, 924,
133521 /* 200 */ 657, 924, 924, 924, -18, 924, 924, 995, 924, 924,
133522 /* 210 */ 924, 924, 924, 924, 924, 924, 924, 924, 772, 1179,
133523 /* 220 */ 712, 712, 712, 926, 45, 769, 1257, 1153, 418, 418,
133524 /* 230 */ 569, 1153, 569, 1175, 607, 663, 1135, 418, 693, 1135,
133525 /* 240 */ 1135, 1177, 1139, 1208, 1286, 1233, 1233, 1290, 1290, 1233,
133526 /* 250 */ 1344, 1341, 1239, 1352, 1352, 1352, 1352, 1233, 1354, 1239,
133527 /* 260 */ 1344, 1341, 1341, 1239, 1233, 1354, 1240, 1304, 1233, 1233,
133528 /* 270 */ 1354, 1362, 1233, 1354, 1233, 1354, 1362, 1293, 1293, 1293,
133529 /* 280 */ 1321, 1362, 1293, 1301, 1293, 1321, 1293, 1293, 1291, 1302,
133530 /* 290 */ 1291, 1302, 1291, 1302, 1291, 1302, 1233, 1392, 1233, 1278,
133531 /* 300 */ 1362, 1368, 1368, 1362, 1294, 1296, 1298, 1300, 1239, 1403,
133532 /* 310 */ 1406, 1416, 1416, 1433, 1433, 1433, 1433, 1571, 1571, 1571,
133533 /* 320 */ 1571, 1571, 1571, 1571, 1571, 519, 988, 1205, 1213, 104,
133534 /* 330 */ 947, 1058, 1246, 1226, 1247, 1248, 1256, 1262, 1266, 1267,
133535 /* 340 */ 853, 1194, 1289, 1190, 1280, 1282, 1220, 1284, 1166, 1180,
133536 /* 350 */ 1288, 1225, 943, 1437, 1440, 1425, 1310, 1438, 1361, 1441,
133537 /* 360 */ 1435, 1436, 1336, 1330, 1351, 1345, 1449, 1348, 1459, 1475,
133538 /* 370 */ 1355, 1346, 1443, 1444, 1445, 1446, 1374, 1430, 1423, 1366,
133539 /* 380 */ 1488, 1485, 1469, 1385, 1353, 1414, 1470, 1415, 1410, 1426,
133540 /* 390 */ 1393, 1477, 1479, 1483, 1391, 1399, 1484, 1428, 1486, 1487,
133541 /* 400 */ 1482, 1489, 1431, 1455, 1494, 1439, 1451, 1497, 1498, 1499,
133542 /* 410 */ 1491, 1407, 1502, 1503, 1505, 1504, 1409, 1506, 1509, 1472,
133543 /* 420 */ 1461, 1511, 1411, 1508, 1473, 1510, 1474, 1516, 1508, 1517,
133544 /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527,
133545 /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1432,
133546 /* 450 */ 1442, 1447, 1448, 1540, 1543, 1549,
133547 };
133548 #define YY_REDUCE_USE_DFLT (-130)
133549 #define YY_REDUCE_COUNT (324)
133550 #define YY_REDUCE_MIN (-129)
133551 #define YY_REDUCE_MAX (1307)
133552 static const short yy_reduce_ofst[] = {
133553 /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435,
133554 /* 10 */ 601, 644, 148, 747, 783, 786, 419, 788, 795, 826,
133555 /* 20 */ 454, 775, 830, 495, 824, 848, 76, 76, 76, 76,
133556 /* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
133557 /* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
133558 /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 890, 901,
133559 /* 60 */ 912, 917, 920, 925, 927, 929, 936, 952, 958, 960,
133560 /* 70 */ 962, 964, 967, 969, 971, 974, 977, 986, 993, 996,
133561 /* 80 */ 999, 1002, 1004, 1008, 1010, 1012, 1015, 1021, 1026, 1034,
133562 /* 90 */ 1037, 1039, 1043, 1045, 1048, 1050, 1052, 1061, 1067, 1074,
133563 /* 100 */ 1077, 1079, 1085, 1089, 76, 76, 76, 76, 76, 76,
133564 /* 110 */ 76, 76, 76, 865, 36, 523, 235, 416, 782, 76,
133565 /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220,
133566 /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620,
133567 /* 140 */ 704, 720, 784, 116, 789, 349, 889, 894, 404, 953,
133568 /* 150 */ 968, -129, 975, 492, 62, 722, 919, 763, 928, 957,
133569 /* 160 */ 994, 1080, 1081, 1082, 1090, 1091, 872, 1056, 557, 57,
133570 /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438,
133571 /* 180 */ 497, 517, 591, 653, 684, 690, 739, 791, 867, 871,
133572 /* 190 */ 970, 1062, 1107, 1132, 1152, 355, 819, 886, 1001, 1163,
133573 /* 200 */ 661, 1164, 1167, 1168, 861, 1169, 1171, 1017, 1172, 1173,
133574 /* 210 */ 1174, 250, 1176, 1178, 1181, 1182, 1183, 1184, 1084, 1094,
133575 /* 220 */ 1119, 1121, 1122, 661, 1140, 1141, 1188, 1142, 1126, 1127,
133576 /* 230 */ 1103, 1143, 1106, 1170, 1165, 1185, 1186, 1133, 1123, 1187,
133577 /* 240 */ 1189, 1148, 1154, 1196, 1111, 1197, 1198, 1118, 1120, 1204,
133578 /* 250 */ 1147, 1191, 1192, 1193, 1195, 1199, 1200, 1212, 1215, 1201,
133579 /* 260 */ 1155, 1206, 1207, 1202, 1217, 1216, 1145, 1144, 1223, 1224,
133580 /* 270 */ 1228, 1211, 1230, 1232, 1235, 1241, 1221, 1227, 1231, 1234,
133581 /* 280 */ 1222, 1229, 1236, 1237, 1238, 1242, 1243, 1244, 1203, 1210,
133582 /* 290 */ 1214, 1218, 1219, 1245, 1249, 1251, 1252, 1250, 1261, 1253,
133583 /* 300 */ 1254, 1209, 1255, 1259, 1258, 1260, 1264, 1268, 1270, 1272,
133584 /* 310 */ 1276, 1287, 1292, 1295, 1297, 1299, 1303, 1263, 1265, 1269,
133585 /* 320 */ 1277, 1279, 1271, 1273, 1307,
133586 };
133587 static const YYACTIONTYPE yy_default[] = {
133588 /* 0 */ 1278, 1268, 1268, 1268, 1200, 1200, 1200, 1200, 1268, 1094,
133589 /* 10 */ 1123, 1123, 1252, 1329, 1329, 1329, 1329, 1329, 1329, 1199,
133590 /* 20 */ 1329, 1329, 1329, 1329, 1268, 1098, 1129, 1329, 1329, 1329,
133591 /* 30 */ 1329, 1201, 1202, 1329, 1329, 1329, 1251, 1253, 1139, 1138,
133592 /* 40 */ 1137, 1136, 1234, 1110, 1134, 1127, 1131, 1201, 1195, 1196,
133593 /* 50 */ 1194, 1198, 1202, 1329, 1130, 1164, 1179, 1163, 1329, 1329,
133594 /* 60 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133595 /* 70 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133596 /* 80 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133597 /* 90 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133598 /* 100 */ 1329, 1329, 1329, 1329, 1173, 1178, 1185, 1177, 1174, 1166,
133599 /* 110 */ 1165, 1167, 1168, 1329, 1017, 1065, 1329, 1329, 1329, 1169,
133600 /* 120 */ 1329, 1170, 1182, 1181, 1180, 1259, 1286, 1285, 1329, 1329,
133601 /* 130 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133602 /* 140 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133603 /* 150 */ 1329, 1329, 1329, 1329, 1329, 1278, 1268, 1023, 1023, 1329,
133604 /* 160 */ 1268, 1268, 1268, 1268, 1268, 1268, 1264, 1098, 1089, 1329,
133605 /* 170 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133606 /* 180 */ 1256, 1254, 1329, 1215, 1329, 1329, 1329, 1329, 1329, 1329,
133607 /* 190 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133608 /* 200 */ 1329, 1329, 1329, 1329, 1094, 1329, 1329, 1329, 1329, 1329,
133609 /* 210 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1280, 1329, 1229,
133610 /* 220 */ 1094, 1094, 1094, 1096, 1078, 1088, 1002, 1133, 1112, 1112,
133611 /* 230 */ 1318, 1133, 1318, 1040, 1300, 1037, 1123, 1112, 1197, 1123,
133612 /* 240 */ 1123, 1095, 1088, 1329, 1321, 1103, 1103, 1320, 1320, 1103,
133613 /* 250 */ 1144, 1068, 1133, 1074, 1074, 1074, 1074, 1103, 1014, 1133,
133614 /* 260 */ 1144, 1068, 1068, 1133, 1103, 1014, 1233, 1315, 1103, 1103,
133615 /* 270 */ 1014, 1208, 1103, 1014, 1103, 1014, 1208, 1066, 1066, 1066,
133616 /* 280 */ 1055, 1208, 1066, 1040, 1066, 1055, 1066, 1066, 1116, 1111,
133617 /* 290 */ 1116, 1111, 1116, 1111, 1116, 1111, 1103, 1203, 1103, 1329,
133618 /* 300 */ 1208, 1212, 1212, 1208, 1128, 1117, 1126, 1124, 1133, 1020,
133619 /* 310 */ 1058, 1283, 1283, 1279, 1279, 1279, 1279, 1326, 1326, 1264,
133620 /* 320 */ 1295, 1295, 1042, 1042, 1295, 1329, 1329, 1329, 1329, 1329,
133621 /* 330 */ 1329, 1290, 1329, 1217, 1329, 1329, 1329, 1329, 1329, 1329,
133622 /* 340 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133623 /* 350 */ 1329, 1329, 1150, 1329, 998, 1261, 1329, 1329, 1260, 1329,
133624 /* 360 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133625 /* 370 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1317,
133626 /* 380 */ 1329, 1329, 1329, 1329, 1329, 1329, 1232, 1231, 1329, 1329,
133627 /* 390 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133628 /* 400 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
133629 /* 410 */ 1329, 1080, 1329, 1329, 1329, 1304, 1329, 1329, 1329, 1329,
133630 /* 420 */ 1329, 1329, 1329, 1125, 1329, 1118, 1329, 1329, 1308, 1329,
133631 /* 430 */ 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1270,
133632 /* 440 */ 1329, 1329, 1329, 1269, 1329, 1329, 1329, 1329, 1329, 1152,
133633 /* 450 */ 1329, 1151, 1155, 1329, 1008, 1329,
133634 };
133635 /********** End of lemon-generated parsing tables *****************************/
133636
133637 /* The next table maps tokens (terminal symbols) into fallback tokens.
133638 ** If a construct like the following:
@@ -133862,11 +133923,11 @@
133862 "DEFERRABLE", "FOREIGN", "DROP", "UNION",
133863 "ALL", "EXCEPT", "INTERSECT", "SELECT",
133864 "VALUES", "DISTINCT", "DOT", "FROM",
133865 "JOIN", "USING", "ORDER", "GROUP",
133866 "HAVING", "LIMIT", "WHERE", "INTO",
133867 "INTEGER", "FLOAT", "BLOB", "VARIABLE",
133868 "CASE", "WHEN", "THEN", "ELSE",
133869 "INDEX", "ALTER", "ADD", "error",
133870 "input", "cmdlist", "ecmd", "explain",
133871 "cmdx", "cmd", "transtype", "trans_opt",
133872 "nm", "savepoint_opt", "create_table", "create_table_args",
@@ -134055,185 +134116,186 @@
134055 /* 151 */ "term ::= NULL",
134056 /* 152 */ "expr ::= ID|INDEXED",
134057 /* 153 */ "expr ::= JOIN_KW",
134058 /* 154 */ "expr ::= nm DOT nm",
134059 /* 155 */ "expr ::= nm DOT nm DOT nm",
134060 /* 156 */ "term ::= INTEGER|FLOAT|BLOB",
134061 /* 157 */ "term ::= STRING",
134062 /* 158 */ "expr ::= VARIABLE",
134063 /* 159 */ "expr ::= expr COLLATE ID|STRING",
134064 /* 160 */ "expr ::= CAST LP expr AS typetoken RP",
134065 /* 161 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
134066 /* 162 */ "expr ::= ID|INDEXED LP STAR RP",
134067 /* 163 */ "term ::= CTIME_KW",
134068 /* 164 */ "expr ::= LP nexprlist COMMA expr RP",
134069 /* 165 */ "expr ::= expr AND expr",
134070 /* 166 */ "expr ::= expr OR expr",
134071 /* 167 */ "expr ::= expr LT|GT|GE|LE expr",
134072 /* 168 */ "expr ::= expr EQ|NE expr",
134073 /* 169 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
134074 /* 170 */ "expr ::= expr PLUS|MINUS expr",
134075 /* 171 */ "expr ::= expr STAR|SLASH|REM expr",
134076 /* 172 */ "expr ::= expr CONCAT expr",
134077 /* 173 */ "likeop ::= LIKE_KW|MATCH",
134078 /* 174 */ "likeop ::= NOT LIKE_KW|MATCH",
134079 /* 175 */ "expr ::= expr likeop expr",
134080 /* 176 */ "expr ::= expr likeop expr ESCAPE expr",
134081 /* 177 */ "expr ::= expr ISNULL|NOTNULL",
134082 /* 178 */ "expr ::= expr NOT NULL",
134083 /* 179 */ "expr ::= expr IS expr",
134084 /* 180 */ "expr ::= expr IS NOT expr",
134085 /* 181 */ "expr ::= NOT expr",
134086 /* 182 */ "expr ::= BITNOT expr",
134087 /* 183 */ "expr ::= MINUS expr",
134088 /* 184 */ "expr ::= PLUS expr",
134089 /* 185 */ "between_op ::= BETWEEN",
134090 /* 186 */ "between_op ::= NOT BETWEEN",
134091 /* 187 */ "expr ::= expr between_op expr AND expr",
134092 /* 188 */ "in_op ::= IN",
134093 /* 189 */ "in_op ::= NOT IN",
134094 /* 190 */ "expr ::= expr in_op LP exprlist RP",
134095 /* 191 */ "expr ::= LP select RP",
134096 /* 192 */ "expr ::= expr in_op LP select RP",
134097 /* 193 */ "expr ::= expr in_op nm dbnm paren_exprlist",
134098 /* 194 */ "expr ::= EXISTS LP select RP",
134099 /* 195 */ "expr ::= CASE case_operand case_exprlist case_else END",
134100 /* 196 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
134101 /* 197 */ "case_exprlist ::= WHEN expr THEN expr",
134102 /* 198 */ "case_else ::= ELSE expr",
134103 /* 199 */ "case_else ::=",
134104 /* 200 */ "case_operand ::= expr",
134105 /* 201 */ "case_operand ::=",
134106 /* 202 */ "exprlist ::=",
134107 /* 203 */ "nexprlist ::= nexprlist COMMA expr",
134108 /* 204 */ "nexprlist ::= expr",
134109 /* 205 */ "paren_exprlist ::=",
134110 /* 206 */ "paren_exprlist ::= LP exprlist RP",
134111 /* 207 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
134112 /* 208 */ "uniqueflag ::= UNIQUE",
134113 /* 209 */ "uniqueflag ::=",
134114 /* 210 */ "eidlist_opt ::=",
134115 /* 211 */ "eidlist_opt ::= LP eidlist RP",
134116 /* 212 */ "eidlist ::= eidlist COMMA nm collate sortorder",
134117 /* 213 */ "eidlist ::= nm collate sortorder",
134118 /* 214 */ "collate ::=",
134119 /* 215 */ "collate ::= COLLATE ID|STRING",
134120 /* 216 */ "cmd ::= DROP INDEX ifexists fullname",
134121 /* 217 */ "cmd ::= VACUUM",
134122 /* 218 */ "cmd ::= VACUUM nm",
134123 /* 219 */ "cmd ::= PRAGMA nm dbnm",
134124 /* 220 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
134125 /* 221 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
134126 /* 222 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
134127 /* 223 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
134128 /* 224 */ "plus_num ::= PLUS INTEGER|FLOAT",
134129 /* 225 */ "minus_num ::= MINUS INTEGER|FLOAT",
134130 /* 226 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
134131 /* 227 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
134132 /* 228 */ "trigger_time ::= BEFORE",
134133 /* 229 */ "trigger_time ::= AFTER",
134134 /* 230 */ "trigger_time ::= INSTEAD OF",
134135 /* 231 */ "trigger_time ::=",
134136 /* 232 */ "trigger_event ::= DELETE|INSERT",
134137 /* 233 */ "trigger_event ::= UPDATE",
134138 /* 234 */ "trigger_event ::= UPDATE OF idlist",
134139 /* 235 */ "when_clause ::=",
134140 /* 236 */ "when_clause ::= WHEN expr",
134141 /* 237 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
134142 /* 238 */ "trigger_cmd_list ::= trigger_cmd SEMI",
134143 /* 239 */ "trnm ::= nm DOT nm",
134144 /* 240 */ "tridxby ::= INDEXED BY nm",
134145 /* 241 */ "tridxby ::= NOT INDEXED",
134146 /* 242 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
134147 /* 243 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
134148 /* 244 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
134149 /* 245 */ "trigger_cmd ::= select",
134150 /* 246 */ "expr ::= RAISE LP IGNORE RP",
134151 /* 247 */ "expr ::= RAISE LP raisetype COMMA nm RP",
134152 /* 248 */ "raisetype ::= ROLLBACK",
134153 /* 249 */ "raisetype ::= ABORT",
134154 /* 250 */ "raisetype ::= FAIL",
134155 /* 251 */ "cmd ::= DROP TRIGGER ifexists fullname",
134156 /* 252 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
134157 /* 253 */ "cmd ::= DETACH database_kw_opt expr",
134158 /* 254 */ "key_opt ::=",
134159 /* 255 */ "key_opt ::= KEY expr",
134160 /* 256 */ "cmd ::= REINDEX",
134161 /* 257 */ "cmd ::= REINDEX nm dbnm",
134162 /* 258 */ "cmd ::= ANALYZE",
134163 /* 259 */ "cmd ::= ANALYZE nm dbnm",
134164 /* 260 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
134165 /* 261 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
134166 /* 262 */ "add_column_fullname ::= fullname",
134167 /* 263 */ "cmd ::= create_vtab",
134168 /* 264 */ "cmd ::= create_vtab LP vtabarglist RP",
134169 /* 265 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
134170 /* 266 */ "vtabarg ::=",
134171 /* 267 */ "vtabargtoken ::= ANY",
134172 /* 268 */ "vtabargtoken ::= lp anylist RP",
134173 /* 269 */ "lp ::= LP",
134174 /* 270 */ "with ::=",
134175 /* 271 */ "with ::= WITH wqlist",
134176 /* 272 */ "with ::= WITH RECURSIVE wqlist",
134177 /* 273 */ "wqlist ::= nm eidlist_opt AS LP select RP",
134178 /* 274 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
134179 /* 275 */ "input ::= cmdlist",
134180 /* 276 */ "cmdlist ::= cmdlist ecmd",
134181 /* 277 */ "cmdlist ::= ecmd",
134182 /* 278 */ "ecmd ::= SEMI",
134183 /* 279 */ "ecmd ::= explain cmdx SEMI",
134184 /* 280 */ "explain ::=",
134185 /* 281 */ "trans_opt ::=",
134186 /* 282 */ "trans_opt ::= TRANSACTION",
134187 /* 283 */ "trans_opt ::= TRANSACTION nm",
134188 /* 284 */ "savepoint_opt ::= SAVEPOINT",
134189 /* 285 */ "savepoint_opt ::=",
134190 /* 286 */ "cmd ::= create_table create_table_args",
134191 /* 287 */ "columnlist ::= columnlist COMMA columnname carglist",
134192 /* 288 */ "columnlist ::= columnname carglist",
134193 /* 289 */ "nm ::= ID|INDEXED",
134194 /* 290 */ "nm ::= STRING",
134195 /* 291 */ "nm ::= JOIN_KW",
134196 /* 292 */ "typetoken ::= typename",
134197 /* 293 */ "typename ::= ID|STRING",
134198 /* 294 */ "signed ::= plus_num",
134199 /* 295 */ "signed ::= minus_num",
134200 /* 296 */ "carglist ::= carglist ccons",
134201 /* 297 */ "carglist ::=",
134202 /* 298 */ "ccons ::= NULL onconf",
134203 /* 299 */ "conslist_opt ::= COMMA conslist",
134204 /* 300 */ "conslist ::= conslist tconscomma tcons",
134205 /* 301 */ "conslist ::= tcons",
134206 /* 302 */ "tconscomma ::=",
134207 /* 303 */ "defer_subclause_opt ::= defer_subclause",
134208 /* 304 */ "resolvetype ::= raisetype",
134209 /* 305 */ "selectnowith ::= oneselect",
134210 /* 306 */ "oneselect ::= values",
134211 /* 307 */ "sclp ::= selcollist COMMA",
134212 /* 308 */ "as ::= ID|STRING",
134213 /* 309 */ "expr ::= term",
134214 /* 310 */ "exprlist ::= nexprlist",
134215 /* 311 */ "nmnum ::= plus_num",
134216 /* 312 */ "nmnum ::= nm",
134217 /* 313 */ "nmnum ::= ON",
134218 /* 314 */ "nmnum ::= DELETE",
134219 /* 315 */ "nmnum ::= DEFAULT",
134220 /* 316 */ "plus_num ::= INTEGER|FLOAT",
134221 /* 317 */ "foreach_clause ::=",
134222 /* 318 */ "foreach_clause ::= FOR EACH ROW",
134223 /* 319 */ "trnm ::= nm",
134224 /* 320 */ "tridxby ::=",
134225 /* 321 */ "database_kw_opt ::= DATABASE",
134226 /* 322 */ "database_kw_opt ::=",
134227 /* 323 */ "kwcolumn_opt ::=",
134228 /* 324 */ "kwcolumn_opt ::= COLUMNKW",
134229 /* 325 */ "vtabarglist ::= vtabarg",
134230 /* 326 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
134231 /* 327 */ "vtabarg ::= vtabarg vtabargtoken",
134232 /* 328 */ "anylist ::=",
134233 /* 329 */ "anylist ::= anylist LP anylist RP",
134234 /* 330 */ "anylist ::= anylist ANY",
 
134235 };
134236 #endif /* NDEBUG */
134237
134238
134239 #if YYSTACKDEPTH<=0
@@ -134811,10 +134873,11 @@
134811 { 173, 1 },
134812 { 173, 3 },
134813 { 173, 5 },
134814 { 172, 1 },
134815 { 172, 1 },
 
134816 { 173, 1 },
134817 { 173, 3 },
134818 { 173, 6 },
134819 { 173, 5 },
134820 { 173, 4 },
@@ -135105,11 +135168,11 @@
135105 case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
135106 case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
135107 case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
135108 case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
135109 case 90: /* distinct ::= */ yytestcase(yyruleno==90);
135110 case 214: /* collate ::= */ yytestcase(yyruleno==214);
135111 {yymsp[1].minor.yy194 = 0;}
135112 break;
135113 case 17: /* ifnotexists ::= IF NOT EXISTS */
135114 {yymsp[-2].minor.yy194 = 1;}
135115 break;
@@ -135249,13 +135312,13 @@
135249 case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144);
135250 {yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
135251 break;
135252 case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
135253 case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
135254 case 186: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==186);
135255 case 189: /* in_op ::= NOT IN */ yytestcase(yyruleno==189);
135256 case 215: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==215);
135257 {yymsp[-1].minor.yy194 = 1;}
135258 break;
135259 case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
135260 {yymsp[-1].minor.yy194 = 0;}
135261 break;
@@ -135415,13 +135478,13 @@
135415 {yymsp[0].minor.yy194 = SF_All;}
135416 break;
135417 case 91: /* sclp ::= */
135418 case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
135419 case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
135420 case 202: /* exprlist ::= */ yytestcase(yyruleno==202);
135421 case 205: /* paren_exprlist ::= */ yytestcase(yyruleno==205);
135422 case 210: /* eidlist_opt ::= */ yytestcase(yyruleno==210);
135423 {yymsp[1].minor.yy148 = 0;}
135424 break;
135425 case 92: /* selcollist ::= sclp expr as */
135426 {
135427 yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
@@ -135435,20 +135498,20 @@
135435 yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
135436 }
135437 break;
135438 case 94: /* selcollist ::= sclp nm DOT STAR */
135439 {
135440 Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &yymsp[0].minor.yy0);
135441 Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135442 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
135443 yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
135444 }
135445 break;
135446 case 95: /* as ::= AS nm */
135447 case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
135448 case 224: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==224);
135449 case 225: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
135450 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
135451 break;
135452 case 97: /* from ::= */
135453 {yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
135454 break;
@@ -135527,18 +135590,18 @@
135527 {yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
135528 break;
135529 case 112: /* on_opt ::= ON expr */
135530 case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
135531 case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
135532 case 198: /* case_else ::= ELSE expr */ yytestcase(yyruleno==198);
135533 {yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
135534 break;
135535 case 113: /* on_opt ::= */
135536 case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
135537 case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
135538 case 199: /* case_else ::= */ yytestcase(yyruleno==199);
135539 case 201: /* case_operand ::= */ yytestcase(yyruleno==201);
135540 {yymsp[1].minor.yy72 = 0;}
135541 break;
135542 case 115: /* indexed_opt ::= INDEXED BY nm */
135543 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
135544 break;
@@ -135650,41 +135713,51 @@
135650 break;
135651 case 150: /* expr ::= LP expr RP */
135652 {spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
135653 break;
135654 case 151: /* term ::= NULL */
135655 case 156: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==156);
135656 case 157: /* term ::= STRING */ yytestcase(yyruleno==157);
135657 {spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/}
135658 break;
135659 case 152: /* expr ::= ID|INDEXED */
135660 case 153: /* expr ::= JOIN_KW */ yytestcase(yyruleno==153);
135661 {spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
135662 break;
135663 case 154: /* expr ::= nm DOT nm */
135664 {
135665 Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135666 Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
135667 spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135668 yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
135669 }
135670 break;
135671 case 155: /* expr ::= nm DOT nm DOT nm */
135672 {
135673 Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
135674 Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135675 Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
135676 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
135677 spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135678 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
135679 }
135680 break;
135681 case 158: /* expr ::= VARIABLE */
 
 
 
 
 
 
 
 
 
135682 {
135683 if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
 
135684 spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
135685 sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr);
135686 }else{
135687 /* When doing a nested parse, one can include terms in an expression
135688 ** that look like this: #1 #2 ... These terms refer to registers
135689 ** in the virtual machine. #N is the N-th register. */
135690 Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
@@ -135692,29 +135765,29 @@
135692 spanSet(&yymsp[0].minor.yy190, &t, &t);
135693 if( pParse->nested==0 ){
135694 sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
135695 yymsp[0].minor.yy190.pExpr = 0;
135696 }else{
135697 yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
135698 if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
135699 }
135700 }
135701 }
135702 break;
135703 case 159: /* expr ::= expr COLLATE ID|STRING */
135704 {
135705 yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1);
135706 yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135707 }
135708 break;
135709 case 160: /* expr ::= CAST LP expr AS typetoken RP */
135710 {
135711 spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135712 yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0);
135713 }
135714 break;
135715 case 161: /* expr ::= ID|INDEXED LP distinct exprlist RP */
135716 {
135717 if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
135718 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
135719 }
135720 yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
@@ -135723,25 +135796,25 @@
135723 yylhsminor.yy190.pExpr->flags |= EP_Distinct;
135724 }
135725 }
135726 yymsp[-4].minor.yy190 = yylhsminor.yy190;
135727 break;
135728 case 162: /* expr ::= ID|INDEXED LP STAR RP */
135729 {
135730 yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
135731 spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
135732 }
135733 yymsp[-3].minor.yy190 = yylhsminor.yy190;
135734 break;
135735 case 163: /* term ::= CTIME_KW */
135736 {
135737 yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
135738 spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
135739 }
135740 yymsp[0].minor.yy190 = yylhsminor.yy190;
135741 break;
135742 case 164: /* expr ::= LP nexprlist COMMA expr RP */
135743 {
135744 ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
135745 yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0);
135746 if( yylhsminor.yy190.pExpr ){
135747 yylhsminor.yy190.pExpr->x.pList = pList;
@@ -135750,82 +135823,86 @@
135750 sqlite3ExprListDelete(pParse->db, pList);
135751 }
135752 }
135753 yymsp[-4].minor.yy190 = yylhsminor.yy190;
135754 break;
135755 case 165: /* expr ::= expr AND expr */
135756 case 166: /* expr ::= expr OR expr */ yytestcase(yyruleno==166);
135757 case 167: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==167);
135758 case 168: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==168);
135759 case 169: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==169);
135760 case 170: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==170);
135761 case 171: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==171);
135762 case 172: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==172);
135763 {spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
135764 break;
135765 case 173: /* likeop ::= LIKE_KW|MATCH */
135766 {yymsp[0].minor.yy392.eOperator = yymsp[0].minor.yy0; yymsp[0].minor.yy392.bNot = 0;/*A-overwrites-X*/}
135767 break;
135768 case 174: /* likeop ::= NOT LIKE_KW|MATCH */
135769 {yymsp[-1].minor.yy392.eOperator = yymsp[0].minor.yy0; yymsp[-1].minor.yy392.bNot = 1;}
135770 break;
135771 case 175: /* expr ::= expr likeop expr */
135772 {
135773 ExprList *pList;
 
 
135774 pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr);
135775 pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr);
135776 yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy392.eOperator);
135777 exprNot(pParse, yymsp[-1].minor.yy392.bNot, &yymsp[-2].minor.yy190);
135778 yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135779 if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
135780 }
135781 break;
135782 case 176: /* expr ::= expr likeop expr ESCAPE expr */
135783 {
135784 ExprList *pList;
 
 
135785 pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135786 pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr);
135787 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
135788 yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy392.eOperator);
135789 exprNot(pParse, yymsp[-3].minor.yy392.bNot, &yymsp[-4].minor.yy190);
135790 yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135791 if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
135792 }
135793 break;
135794 case 177: /* expr ::= expr ISNULL|NOTNULL */
135795 {spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
135796 break;
135797 case 178: /* expr ::= expr NOT NULL */
135798 {spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
135799 break;
135800 case 179: /* expr ::= expr IS expr */
135801 {
135802 spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
135803 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
135804 }
135805 break;
135806 case 180: /* expr ::= expr IS NOT expr */
135807 {
135808 spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
135809 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
135810 }
135811 break;
135812 case 181: /* expr ::= NOT expr */
135813 case 182: /* expr ::= BITNOT expr */ yytestcase(yyruleno==182);
135814 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135815 break;
135816 case 183: /* expr ::= MINUS expr */
135817 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135818 break;
135819 case 184: /* expr ::= PLUS expr */
135820 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135821 break;
135822 case 185: /* between_op ::= BETWEEN */
135823 case 188: /* in_op ::= IN */ yytestcase(yyruleno==188);
135824 {yymsp[0].minor.yy194 = 0;}
135825 break;
135826 case 187: /* expr ::= expr between_op expr AND expr */
135827 {
135828 ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135829 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
135830 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0);
135831 if( yymsp[-4].minor.yy190.pExpr ){
@@ -135835,11 +135912,11 @@
135835 }
135836 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135837 yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135838 }
135839 break;
135840 case 190: /* expr ::= expr in_op LP exprlist RP */
135841 {
135842 if( yymsp[-1].minor.yy148==0 ){
135843 /* Expressions of the form
135844 **
135845 ** expr1 IN ()
@@ -135888,26 +135965,26 @@
135888 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135889 }
135890 yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135891 }
135892 break;
135893 case 191: /* expr ::= LP select RP */
135894 {
135895 spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
135896 yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
135897 sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
135898 }
135899 break;
135900 case 192: /* expr ::= expr in_op LP select RP */
135901 {
135902 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
135903 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
135904 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135905 yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135906 }
135907 break;
135908 case 193: /* expr ::= expr in_op nm dbnm paren_exprlist */
135909 {
135910 SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
135911 Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
135912 if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148);
135913 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
@@ -135914,19 +135991,19 @@
135914 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect);
135915 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135916 yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
135917 }
135918 break;
135919 case 194: /* expr ::= EXISTS LP select RP */
135920 {
135921 Expr *p;
135922 spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
135923 p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
135924 sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
135925 }
135926 break;
135927 case 195: /* expr ::= CASE case_operand case_exprlist case_else END */
135928 {
135929 spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/
135930 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0, 0);
135931 if( yymsp[-4].minor.yy190.pExpr ){
135932 yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148;
@@ -135935,334 +136012,334 @@
135935 sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
135936 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
135937 }
135938 }
135939 break;
135940 case 196: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
135941 {
135942 yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
135943 yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
135944 }
135945 break;
135946 case 197: /* case_exprlist ::= WHEN expr THEN expr */
135947 {
135948 yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135949 yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
135950 }
135951 break;
135952 case 200: /* case_operand ::= expr */
135953 {yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
135954 break;
135955 case 203: /* nexprlist ::= nexprlist COMMA expr */
135956 {yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
135957 break;
135958 case 204: /* nexprlist ::= expr */
135959 {yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
135960 break;
135961 case 206: /* paren_exprlist ::= LP exprlist RP */
135962 case 211: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==211);
135963 {yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
135964 break;
135965 case 207: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
135966 {
135967 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
135968 sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194,
135969 &yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF);
135970 }
135971 break;
135972 case 208: /* uniqueflag ::= UNIQUE */
135973 case 249: /* raisetype ::= ABORT */ yytestcase(yyruleno==249);
135974 {yymsp[0].minor.yy194 = OE_Abort;}
135975 break;
135976 case 209: /* uniqueflag ::= */
135977 {yymsp[1].minor.yy194 = OE_None;}
135978 break;
135979 case 212: /* eidlist ::= eidlist COMMA nm collate sortorder */
135980 {
135981 yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
135982 }
135983 break;
135984 case 213: /* eidlist ::= nm collate sortorder */
135985 {
135986 yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
135987 }
135988 break;
135989 case 216: /* cmd ::= DROP INDEX ifexists fullname */
135990 {sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
135991 break;
135992 case 217: /* cmd ::= VACUUM */
135993 {sqlite3Vacuum(pParse,0);}
135994 break;
135995 case 218: /* cmd ::= VACUUM nm */
135996 {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
135997 break;
135998 case 219: /* cmd ::= PRAGMA nm dbnm */
135999 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
136000 break;
136001 case 220: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
136002 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
136003 break;
136004 case 221: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
136005 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
136006 break;
136007 case 222: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
136008 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
136009 break;
136010 case 223: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
136011 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
136012 break;
136013 case 226: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
136014 {
136015 Token all;
136016 all.z = yymsp[-3].minor.yy0.z;
136017 all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
136018 sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
136019 }
136020 break;
136021 case 227: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
136022 {
136023 sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
136024 yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
136025 }
136026 break;
136027 case 228: /* trigger_time ::= BEFORE */
136028 { yymsp[0].minor.yy194 = TK_BEFORE; }
136029 break;
136030 case 229: /* trigger_time ::= AFTER */
136031 { yymsp[0].minor.yy194 = TK_AFTER; }
136032 break;
136033 case 230: /* trigger_time ::= INSTEAD OF */
136034 { yymsp[-1].minor.yy194 = TK_INSTEAD;}
136035 break;
136036 case 231: /* trigger_time ::= */
136037 { yymsp[1].minor.yy194 = TK_BEFORE; }
136038 break;
136039 case 232: /* trigger_event ::= DELETE|INSERT */
136040 case 233: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==233);
136041 {yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
136042 break;
136043 case 234: /* trigger_event ::= UPDATE OF idlist */
136044 {yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
136045 break;
136046 case 235: /* when_clause ::= */
136047 case 254: /* key_opt ::= */ yytestcase(yyruleno==254);
136048 { yymsp[1].minor.yy72 = 0; }
136049 break;
136050 case 236: /* when_clause ::= WHEN expr */
136051 case 255: /* key_opt ::= KEY expr */ yytestcase(yyruleno==255);
136052 { yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
136053 break;
136054 case 237: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
136055 {
136056 assert( yymsp[-2].minor.yy145!=0 );
136057 yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
136058 yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
136059 }
136060 break;
136061 case 238: /* trigger_cmd_list ::= trigger_cmd SEMI */
136062 {
136063 assert( yymsp[-1].minor.yy145!=0 );
136064 yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
136065 }
136066 break;
136067 case 239: /* trnm ::= nm DOT nm */
136068 {
136069 yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
136070 sqlite3ErrorMsg(pParse,
136071 "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
136072 "statements within triggers");
136073 }
136074 break;
136075 case 240: /* tridxby ::= INDEXED BY nm */
136076 {
136077 sqlite3ErrorMsg(pParse,
136078 "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
136079 "within triggers");
136080 }
136081 break;
136082 case 241: /* tridxby ::= NOT INDEXED */
136083 {
136084 sqlite3ErrorMsg(pParse,
136085 "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
136086 "within triggers");
136087 }
136088 break;
136089 case 242: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
136090 {yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
136091 break;
136092 case 243: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
136093 {yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
136094 break;
136095 case 244: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
136096 {yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
136097 break;
136098 case 245: /* trigger_cmd ::= select */
136099 {yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
136100 break;
136101 case 246: /* expr ::= RAISE LP IGNORE RP */
136102 {
136103 spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
136104 yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
136105 if( yymsp[-3].minor.yy190.pExpr ){
136106 yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
136107 }
136108 }
136109 break;
136110 case 247: /* expr ::= RAISE LP raisetype COMMA nm RP */
136111 {
136112 spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
136113 yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
136114 if( yymsp[-5].minor.yy190.pExpr ) {
136115 yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
136116 }
136117 }
136118 break;
136119 case 248: /* raisetype ::= ROLLBACK */
136120 {yymsp[0].minor.yy194 = OE_Rollback;}
136121 break;
136122 case 250: /* raisetype ::= FAIL */
136123 {yymsp[0].minor.yy194 = OE_Fail;}
136124 break;
136125 case 251: /* cmd ::= DROP TRIGGER ifexists fullname */
136126 {
136127 sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
136128 }
136129 break;
136130 case 252: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
136131 {
136132 sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
136133 }
136134 break;
136135 case 253: /* cmd ::= DETACH database_kw_opt expr */
136136 {
136137 sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
136138 }
136139 break;
136140 case 256: /* cmd ::= REINDEX */
136141 {sqlite3Reindex(pParse, 0, 0);}
136142 break;
136143 case 257: /* cmd ::= REINDEX nm dbnm */
136144 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
136145 break;
136146 case 258: /* cmd ::= ANALYZE */
136147 {sqlite3Analyze(pParse, 0, 0);}
136148 break;
136149 case 259: /* cmd ::= ANALYZE nm dbnm */
136150 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
136151 break;
136152 case 260: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
136153 {
136154 sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
136155 }
136156 break;
136157 case 261: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
136158 {
136159 yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
136160 sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
136161 }
136162 break;
136163 case 262: /* add_column_fullname ::= fullname */
136164 {
136165 disableLookaside(pParse);
136166 sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
136167 }
136168 break;
136169 case 263: /* cmd ::= create_vtab */
136170 {sqlite3VtabFinishParse(pParse,0);}
136171 break;
136172 case 264: /* cmd ::= create_vtab LP vtabarglist RP */
136173 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
136174 break;
136175 case 265: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
136176 {
136177 sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194);
136178 }
136179 break;
136180 case 266: /* vtabarg ::= */
136181 {sqlite3VtabArgInit(pParse);}
136182 break;
136183 case 267: /* vtabargtoken ::= ANY */
136184 case 268: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==268);
136185 case 269: /* lp ::= LP */ yytestcase(yyruleno==269);
136186 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
136187 break;
136188 case 270: /* with ::= */
136189 {yymsp[1].minor.yy285 = 0;}
136190 break;
136191 case 271: /* with ::= WITH wqlist */
136192 { yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
136193 break;
136194 case 272: /* with ::= WITH RECURSIVE wqlist */
136195 { yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
136196 break;
136197 case 273: /* wqlist ::= nm eidlist_opt AS LP select RP */
136198 {
136199 yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
136200 }
136201 break;
136202 case 274: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
136203 {
136204 yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
136205 }
136206 break;
136207 default:
136208 /* (275) input ::= cmdlist */ yytestcase(yyruleno==275);
136209 /* (276) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==276);
136210 /* (277) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=277);
136211 /* (278) ecmd ::= SEMI */ yytestcase(yyruleno==278);
136212 /* (279) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==279);
136213 /* (280) explain ::= */ yytestcase(yyruleno==280);
136214 /* (281) trans_opt ::= */ yytestcase(yyruleno==281);
136215 /* (282) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==282);
136216 /* (283) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==283);
136217 /* (284) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==284);
136218 /* (285) savepoint_opt ::= */ yytestcase(yyruleno==285);
136219 /* (286) cmd ::= create_table create_table_args */ yytestcase(yyruleno==286);
136220 /* (287) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==287);
136221 /* (288) columnlist ::= columnname carglist */ yytestcase(yyruleno==288);
136222 /* (289) nm ::= ID|INDEXED */ yytestcase(yyruleno==289);
136223 /* (290) nm ::= STRING */ yytestcase(yyruleno==290);
136224 /* (291) nm ::= JOIN_KW */ yytestcase(yyruleno==291);
136225 /* (292) typetoken ::= typename */ yytestcase(yyruleno==292);
136226 /* (293) typename ::= ID|STRING */ yytestcase(yyruleno==293);
136227 /* (294) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=294);
136228 /* (295) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
136229 /* (296) carglist ::= carglist ccons */ yytestcase(yyruleno==296);
136230 /* (297) carglist ::= */ yytestcase(yyruleno==297);
136231 /* (298) ccons ::= NULL onconf */ yytestcase(yyruleno==298);
136232 /* (299) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==299);
136233 /* (300) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==300);
136234 /* (301) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=301);
136235 /* (302) tconscomma ::= */ yytestcase(yyruleno==302);
136236 /* (303) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=303);
136237 /* (304) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=304);
136238 /* (305) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=305);
136239 /* (306) oneselect ::= values */ yytestcase(yyruleno==306);
136240 /* (307) sclp ::= selcollist COMMA */ yytestcase(yyruleno==307);
136241 /* (308) as ::= ID|STRING */ yytestcase(yyruleno==308);
136242 /* (309) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=309);
136243 /* (310) exprlist ::= nexprlist */ yytestcase(yyruleno==310);
136244 /* (311) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=311);
136245 /* (312) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=312);
136246 /* (313) nmnum ::= ON */ yytestcase(yyruleno==313);
136247 /* (314) nmnum ::= DELETE */ yytestcase(yyruleno==314);
136248 /* (315) nmnum ::= DEFAULT */ yytestcase(yyruleno==315);
136249 /* (316) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==316);
136250 /* (317) foreach_clause ::= */ yytestcase(yyruleno==317);
136251 /* (318) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==318);
136252 /* (319) trnm ::= nm */ yytestcase(yyruleno==319);
136253 /* (320) tridxby ::= */ yytestcase(yyruleno==320);
136254 /* (321) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==321);
136255 /* (322) database_kw_opt ::= */ yytestcase(yyruleno==322);
136256 /* (323) kwcolumn_opt ::= */ yytestcase(yyruleno==323);
136257 /* (324) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==324);
136258 /* (325) vtabarglist ::= vtabarg */ yytestcase(yyruleno==325);
136259 /* (326) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==326);
136260 /* (327) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==327);
136261 /* (328) anylist ::= */ yytestcase(yyruleno==328);
136262 /* (329) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==329);
136263 /* (330) anylist ::= anylist ANY */ yytestcase(yyruleno==330);
136264 break;
136265 /********** End reduce actions ************************************************/
136266 };
136267 assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
136268 yygoto = yyRuleInfo[yyruleno].lhs;
@@ -136449,11 +136526,11 @@
136449 }
136450 #endif
136451 yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
136452 yymajor = YYNOCODE;
136453 }else{
136454 while( yypParser->yytos >= &yypParser->yystack
136455 && yymx != YYERRORSYMBOL
136456 && (yyact = yy_find_reduce_action(
136457 yypParser->yytos->stateno,
136458 YYERRORSYMBOL)) >= YY_MIN_REDUCE
136459 ){
@@ -138617,10 +138694,11 @@
138617 } aFlagOp[] = {
138618 { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
138619 { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
138620 { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
138621 { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
 
138622 };
138623 unsigned int i;
138624 rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
138625 for(i=0; i<ArraySize(aFlagOp); i++){
138626 if( aFlagOp[i].op==op ){
@@ -139913,10 +139991,17 @@
139913 db->busyHandler.nBusy = 0;
139914 rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
139915 sqlite3Error(db, rc);
139916 }
139917 rc = sqlite3ApiExit(db, rc);
 
 
 
 
 
 
 
139918 sqlite3_mutex_leave(db->mutex);
139919 return rc;
139920 #endif
139921 }
139922
@@ -140415,10 +140500,11 @@
140415 int octet = (sqlite3HexToInt(zUri[iIn++]) << 4);
140416 octet += sqlite3HexToInt(zUri[iIn++]);
140417
140418 assert( octet>=0 && octet<256 );
140419 if( octet==0 ){
 
140420 /* This branch is taken when "%00" appears within the URI. In this
140421 ** case we ignore all text in the remainder of the path, name or
140422 ** value currently being parsed. So ignore the current character
140423 ** and skip to the next "?", "=" or "&", as appropriate. */
140424 while( (c = zUri[iIn])!=0 && c!='#'
@@ -140427,10 +140513,16 @@
140427 && (eState!=2 || c!='&')
140428 ){
140429 iIn++;
140430 }
140431 continue;
 
 
 
 
 
 
140432 }
140433 c = octet;
140434 }else if( eState==1 && (c=='&' || c=='=') ){
140435 if( zFile[iOut-1]==0 ){
140436 /* An empty option name. Ignore this option altogether. */
@@ -164306,14 +164398,16 @@
164306 char *zSql;
164307 sqlite3_stmt *p;
164308 int rc;
164309 i64 nRow = 0;
164310
164311 if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1",
164312 0,0,0,0,0,0)==SQLITE_ERROR ){
 
 
164313 pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
164314 return SQLITE_OK;
164315 }
164316 zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
164317 if( zSql==0 ){
164318 rc = SQLITE_NOMEM;
164319 }else{
@@ -165210,11 +165304,11 @@
165210 ** of the locale to use. Passing an empty string ("") or SQL NULL value
165211 ** as the second argument is the same as invoking the 1 argument version
165212 ** of upper() or lower().
165213 **
165214 ** lower('I', 'en_us') -> 'i'
165215 ** lower('I', 'tr_tr') -> 'ı' (small dotless i)
165216 **
165217 ** http://www.icu-project.org/userguide/posix.html#case_mappings
165218 */
165219 static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
165220 const UChar *zInput; /* Pointer to input string */
@@ -181140,11 +181234,11 @@
181140 }
181141 #endif
181142 fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
181143 fts5yymajor = fts5YYNOCODE;
181144 }else{
181145 while( fts5yypParser->fts5yytos >= &fts5yypParser->fts5yystack
181146 && fts5yymx != fts5YYERRORSYMBOL
181147 && (fts5yyact = fts5yy_find_reduce_action(
181148 fts5yypParser->fts5yytos->stateno,
181149 fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
181150 ){
@@ -181506,10 +181600,13 @@
181506 int nToken, /* Size of token in bytes */
181507 int iStartOff, /* Start offset of token */
181508 int iEndOff /* End offset of token */
181509 ){
181510 int rc = SQLITE_OK;
 
 
 
181511
181512 if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
181513 Fts5SFinder *p = (Fts5SFinder*)pContext;
181514 if( p->iPos>0 ){
181515 int i;
@@ -181662,11 +181759,10 @@
181662 for(jj=0; jj<(sFinder.nFirst-1); jj++){
181663 if( sFinder.aFirst[jj+1]>io ) break;
181664 }
181665
181666 if( sFinder.aFirst[jj]<io ){
181667 int nScore;
181668 memset(aSeen, 0, nPhrase);
181669 rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
181670 sFinder.aFirst[jj], nToken, &nScore, 0
181671 );
181672
@@ -195597,11 +195693,11 @@
195597 int nArg, /* Number of args */
195598 sqlite3_value **apUnused /* Function arguments */
195599 ){
195600 assert( nArg==0 );
195601 UNUSED_PARAM2(nArg, apUnused);
195602 sqlite3_result_text(pCtx, "fts5: 2016-09-21 19:43:34 0741812d7fcd558479e4849fbb3ba8d03738d018", -1, SQLITE_TRANSIENT);
195603 }
195604
195605 static int fts5Init(sqlite3 *db){
195606 static const sqlite3_module fts5Mod = {
195607 /* iVersion */ 2,
195608
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.16.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -379,13 +379,13 @@
379 **
380 ** See also: [sqlite3_libversion()],
381 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
382 ** [sqlite_version()] and [sqlite_source_id()].
383 */
384 #define SQLITE_VERSION "3.16.0"
385 #define SQLITE_VERSION_NUMBER 3016000
386 #define SQLITE_SOURCE_ID "2016-11-02 14:50:19 3028845329c9b7acdec2ec8b01d00d782347454c"
387
388 /*
389 ** CAPI3REF: Run-Time Library Version Numbers
390 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
391 **
@@ -1235,10 +1235,16 @@
1235 ** <li>[[SQLITE_FCNTL_HAS_MOVED]]
1236 ** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
1237 ** pointer to an integer and it writes a boolean into that integer depending
1238 ** on whether or not the file has been renamed, moved, or deleted since it
1239 ** was first opened.
1240 **
1241 ** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
1242 ** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
1243 ** underlying native file handle associated with a file handle. This file
1244 ** control interprets its argument as a pointer to a native file handle and
1245 ** writes the resulting value there.
1246 **
1247 ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
1248 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1249 ** opcode causes the xFileControl method to swap the file handle with the one
1250 ** pointed to by the pArg argument. This capability is used during testing
@@ -1286,10 +1292,12 @@
1292 #define SQLITE_FCNTL_WAL_BLOCK 24
1293 #define SQLITE_FCNTL_ZIPVFS 25
1294 #define SQLITE_FCNTL_RBU 26
1295 #define SQLITE_FCNTL_VFS_POINTER 27
1296 #define SQLITE_FCNTL_JOURNAL_POINTER 28
1297 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29
1298 #define SQLITE_FCNTL_PDB 30
1299
1300 /* deprecated names */
1301 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1302 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1303 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2238,18 +2246,31 @@
2246 ** does not make a copy of the new main schema name string, so the application
2247 ** must ensure that the argument passed into this DBCONFIG option is unchanged
2248 ** until after the database connection closes.
2249 ** </dd>
2250 **
2251 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
2252 ** <dd> Usually, when a database in wal mode is closed or detached from a
2253 ** database handle, SQLite checks if this will mean that there are now no
2254 ** connections at all to the database. If so, it performs a checkpoint
2255 ** operation before closing the connection. This option may be used to
2256 ** override this behaviour. The first parameter passed to this operation
2257 ** is an integer - non-zero to disable checkpoints-on-close, or zero (the
2258 ** default) to enable them. The second parameter is a pointer to an integer
2259 ** into which is written 0 or 1 to indicate whether checkpoints-on-close
2260 ** have been disabled - 0 if they are not disabled, 1 if they are.
2261 ** </dd>
2262 **
2263 ** </dl>
2264 */
2265 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
2266 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
2267 #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
2268 #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
2269 #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
2270 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
2271 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
2272
2273
2274 /*
2275 ** CAPI3REF: Enable Or Disable Extended Result Codes
2276 ** METHOD: sqlite3
@@ -8915,11 +8936,11 @@
8936
8937 /*
8938 ** CAPI3REF: Set a table filter on a Session Object.
8939 **
8940 ** The second argument (xFilter) is the "filter callback". For changes to rows
8941 ** in tables that are not attached to the Session object, the filter is called
8942 ** to determine whether changes to the table's rows should be tracked or not.
8943 ** If xFilter returns 0, changes is not tracked. Note that once a table is
8944 ** attached, xFilter will not be called again.
8945 */
8946 void sqlite3session_table_filter(
@@ -9181,11 +9202,11 @@
9202 ** Assuming the changeset blob was created by one of the
9203 ** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
9204 ** [sqlite3changeset_invert()] functions, all changes within the changeset
9205 ** that apply to a single table are grouped together. This means that when
9206 ** an application iterates through a changeset using an iterator created by
9207 ** this function, all changes that relate to a single table are visited
9208 ** consecutively. There is no chance that the iterator will visit a change
9209 ** the applies to table X, then one for table Y, and then later on visit
9210 ** another change for table X.
9211 */
9212 int sqlite3changeset_start(
@@ -9268,11 +9289,11 @@
9289 ** If successful, *pabPK is set to point to an array of nCol entries, where
9290 ** nCol is the number of columns in the table. Elements of *pabPK are set to
9291 ** 0x01 if the corresponding column is part of the tables primary key, or
9292 ** 0x00 if it is not.
9293 **
9294 ** If argument pnCol is not NULL, then *pnCol is set to the number of columns
9295 ** in the table.
9296 **
9297 ** If this function is called when the iterator does not point to a valid
9298 ** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
9299 ** SQLITE_OK is returned and the output variables populated as described
@@ -9543,11 +9564,11 @@
9564 ** Rows within the changeset and changegroup are identified by the values in
9565 ** their PRIMARY KEY columns. A change in the changeset is considered to
9566 ** apply to the same row as a change already present in the changegroup if
9567 ** the two rows have the same primary key.
9568 **
9569 ** Changes to rows that do not already appear in the changegroup are
9570 ** simply copied into it. Or, if both the new changeset and the changegroup
9571 ** contain changes that apply to a single row, the final contents of the
9572 ** changegroup depends on the type of each change, as follows:
9573 **
9574 ** <table border=1 style="margin-left:8ex;margin-right:8ex">
@@ -11411,13 +11432,13 @@
11432 #define TK_GROUP 127
11433 #define TK_HAVING 128
11434 #define TK_LIMIT 129
11435 #define TK_WHERE 130
11436 #define TK_INTO 131
11437 #define TK_FLOAT 132
11438 #define TK_BLOB 133
11439 #define TK_INTEGER 134
11440 #define TK_VARIABLE 135
11441 #define TK_CASE 136
11442 #define TK_WHEN 137
11443 #define TK_THEN 138
11444 #define TK_ELSE 139
@@ -12675,19 +12696,19 @@
12696 #define OP_SorterData 120 /* synopsis: r[P2]=data */
12697 #define OP_RowKey 121 /* synopsis: r[P2]=key */
12698 #define OP_RowData 122 /* synopsis: r[P2]=data */
12699 #define OP_Rowid 123 /* synopsis: r[P2]=rowid */
12700 #define OP_NullRow 124
12701 #define OP_SorterInsert 125 /* synopsis: key=r[P2] */
12702 #define OP_IdxInsert 126 /* synopsis: key=r[P2] */
12703 #define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */
12704 #define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */
12705 #define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */
12706 #define OP_Destroy 130
12707 #define OP_Clear 131
12708 #define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
12709 #define OP_ResetSorter 133
12710 #define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */
12711 #define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */
12712 #define OP_ParseSchema 136
12713 #define OP_LoadAnalysis 137
12714 #define OP_DropTable 138
@@ -12741,11 +12762,11 @@
12762 /* 88 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
12763 /* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
12764 /* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
12765 /* 112 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
12766 /* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
12767 /* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
12768 /* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\
12769 /* 144 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\
12770 /* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
12771 /* 160 */ 0x00, 0x00, 0x00,}
12772
@@ -13030,11 +13051,11 @@
13051 int,
13052 int,
13053 int,
13054 void(*)(DbPage*)
13055 );
13056 SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*);
13057 SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
13058
13059 /* Functions used to configure a Pager object. */
13060 SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
13061 SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
@@ -13081,19 +13102,22 @@
13102 SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
13103 SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
13104 SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
13105
13106 #ifndef SQLITE_OMIT_WAL
13107 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
13108 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
13109 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
13110 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
13111 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
13112 SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager);
13113 # ifdef SQLITE_ENABLE_SNAPSHOT
13114 SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
13115 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
13116 # endif
13117 #else
13118 # define sqlite3PagerUseWal(x) 0
13119 #endif
13120
13121 #ifdef SQLITE_ENABLE_ZIPVFS
13122 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
13123 #endif
@@ -14060,10 +14084,11 @@
14084 #define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
14085 #define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
14086 #define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
14087 #define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
14088 #define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
14089 #define SQLITE_NoCkptOnClose 0x80000000 /* No checkpoint on close()/DETACH */
14090
14091
14092 /*
14093 ** Bits of the sqlite3.dbOptFlags field that are used by the
14094 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -14963,10 +14988,11 @@
14988 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
14989 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
14990 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
14991 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
14992 #define EP_Alias 0x400000 /* Is an alias for a result set column */
14993 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
14994
14995 /*
14996 ** Combinations of two or more EP_* flags
14997 */
14998 #define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
@@ -15514,39 +15540,27 @@
15540 u8 mayAbort; /* True if statement may throw an ABORT exception */
15541 u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
15542 u8 okConstFactor; /* OK to factor out constants */
15543 u8 disableLookaside; /* Number of times lookaside has been disabled */
15544 u8 nColCache; /* Number of entries in aColCache[] */
 
15545 int nRangeReg; /* Size of the temporary register block */
15546 int iRangeReg; /* First register in temporary register block */
15547 int nErr; /* Number of errors seen */
15548 int nTab; /* Number of previously allocated VDBE cursors */
15549 int nMem; /* Number of memory cells used so far */
 
15550 int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
15551 int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
 
15552 int ckBase; /* Base register of data during check constraints */
15553 int iSelfTab; /* Table of an index whose exprs are being coded */
15554 int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
15555 int iCacheCnt; /* Counter used to generate aColCache[].lru values */
15556 int nLabel; /* Number of labels used */
15557 int *aLabel; /* Space to hold the labels */
 
 
 
 
 
 
 
 
15558 ExprList *pConstExpr;/* Constant expressions */
15559 Token constraintName;/* Name of the constraint currently being parsed */
15560 yDbMask writeMask; /* Start a write transaction on these databases */
15561 yDbMask cookieMask; /* Bitmask of schema verified databases */
 
15562 int regRowid; /* Register holding rowid of CREATE TABLE entry */
15563 int regRoot; /* Register holding root page number for new objects */
15564 int nMaxArg; /* Max args passed to user function by sub-program */
15565 #if SELECTTRACE_ENABLED
15566 int nSelect; /* Number of SELECT statements seen */
@@ -15555,21 +15569,38 @@
15569 #ifndef SQLITE_OMIT_SHARED_CACHE
15570 int nTableLock; /* Number of locks in aTableLock */
15571 TableLock *aTableLock; /* Required table locks for shared-cache mode */
15572 #endif
15573 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
 
 
15574 Parse *pToplevel; /* Parse structure for main program (or NULL) */
15575 Table *pTriggerTab; /* Table triggers are being coded for */
15576 int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
15577 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
15578 u32 oldmask; /* Mask of old.* columns referenced */
15579 u32 newmask; /* Mask of new.* columns referenced */
15580 u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
15581 u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
15582 u8 disableTriggers; /* True to disable triggers */
15583
15584 /**************************************************************************
15585 ** Fields above must be initialized to zero. The fields that follow,
15586 ** down to the beginning of the recursive section, do not need to be
15587 ** initialized as they will be set before being used. The boundary is
15588 ** determined by offsetof(Parse,aColCache).
15589 **************************************************************************/
15590
15591 struct yColCache {
15592 int iTable; /* Table cursor number */
15593 i16 iColumn; /* Table column number */
15594 u8 tempReg; /* iReg is a temp register that needs to be freed */
15595 int iLevel; /* Nesting level */
15596 int iReg; /* Reg with value of this column. 0 means none. */
15597 int lru; /* Least recently used entry has the smallest value */
15598 } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
15599 int aTempReg[8]; /* Holding area for temporary registers */
15600 Token sNameToken; /* Token with unqualified schema object name */
15601 Token sLastToken; /* The last token parsed */
15602
15603 /************************************************************************
15604 ** Above is constant between recursions. Below is reset before and after
15605 ** each recursion. The boundary between these two regions is determined
15606 ** using offsetof(Parse,nVar) so the nVar field must be the first field
@@ -15582,11 +15613,10 @@
15613 u8 explain; /* True if the EXPLAIN flag is found on the query */
15614 #ifndef SQLITE_OMIT_VIRTUALTABLE
15615 u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
15616 int nVtabLock; /* Number of virtual tables to lock */
15617 #endif
 
15618 int nHeight; /* Expression tree height of current sub-select */
15619 #ifndef SQLITE_OMIT_EXPLAIN
15620 int iSelectId; /* ID of current select for EXPLAIN output */
15621 int iNextSelectId; /* Next available select ID for EXPLAIN output */
15622 #endif
@@ -15594,12 +15624,10 @@
15624 Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
15625 const char *zTail; /* All SQL text past the last semicolon parsed */
15626 Table *pNewTable; /* A table being constructed by CREATE TABLE */
15627 Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
15628 const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
 
 
15629 #ifndef SQLITE_OMIT_VIRTUALTABLE
15630 Token sArg; /* Complete text of a module argument */
15631 Table **apVtabLock; /* Pointer to virtual tables needing locking */
15632 #endif
15633 Table *pZombieTab; /* List of Table objects to delete after code gen */
@@ -15606,10 +15634,18 @@
15634 TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
15635 With *pWith; /* Current WITH clause, or NULL */
15636 With *pWithToFree; /* Free this WITH object at the end of the parse */
15637 };
15638
15639 /*
15640 ** Sizes and pointers of various parts of the Parse object.
15641 */
15642 #define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
15643 #define PARSE_RECURSE_SZ offsetof(Parse,nVar) /* Recursive part */
15644 #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
15645 #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
15646
15647 /*
15648 ** Return true if currently inside an sqlite3_declare_vtab() call.
15649 */
15650 #ifdef SQLITE_OMIT_VIRTUALTABLE
15651 #define IN_DECLARE_VTAB 0
@@ -16169,11 +16205,11 @@
16205 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
16206 SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
16207 SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
16208 SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
16209 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
16210 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
16211 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
16212 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
16213 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
16214 SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
16215 SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
@@ -16989,20 +17025,17 @@
17025 ** If x is a lower-case ASCII character, then its upper-case equivalent
17026 ** is (x - 0x20). Therefore toupper() can be implemented as:
17027 **
17028 ** (x & ~(map[x]&0x20))
17029 **
17030 ** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
17031 ** array. tolower() is used more often than toupper() by SQLite.
17032 **
17033 ** Bit 0x40 is set if the character is non-alphanumeric and can be used in an
17034 ** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
17035 ** non-ASCII UTF character. Hence the test for whether or not a character is
17036 ** part of an identifier is 0x46.
 
 
 
17037 */
17038 #ifdef SQLITE_ASCII
17039 SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
17040 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
17041 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
@@ -17071,11 +17104,11 @@
17104 #ifndef SQLITE_SORTER_PMASZ
17105 # define SQLITE_SORTER_PMASZ 250
17106 #endif
17107
17108 /* Statement journals spill to disk when their size exceeds the following
17109 ** threshold (in bytes). 0 means that statement journals are created and
17110 ** written to disk immediately (the default behavior for SQLite versions
17111 ** before 3.12.0). -1 means always keep the entire statement journal in
17112 ** memory. (The statement journal is also always held entirely in memory
17113 ** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
17114 ** setting.)
@@ -17159,11 +17192,11 @@
17192
17193 /*
17194 ** The value of the "pending" byte must be 0x40000000 (1 byte past the
17195 ** 1-gibabyte boundary) in a compatible database. SQLite never uses
17196 ** the database page that contains the pending byte. It never attempts
17197 ** to read or write that page. The pending byte page is set aside
17198 ** for use by the VFS layers as space for managing file locks.
17199 **
17200 ** During testing, it is often desirable to move the pending byte to
17201 ** a different position in the file. This allows code that has to
17202 ** deal with the pending byte to run on files that are much smaller
@@ -17260,10 +17293,13 @@
17293 #if SQLITE_DEFAULT_LOCKING_MODE
17294 "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
17295 #endif
17296 #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
17297 "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
17298 #endif
17299 #if SQLITE_DIRECT_OVERFLOW_READ
17300 "DIRECT_OVERFLOW_READ",
17301 #endif
17302 #if SQLITE_DISABLE_DIRSYNC
17303 "DISABLE_DIRSYNC",
17304 #endif
17305 #if SQLITE_DISABLE_LFS
@@ -17346,10 +17382,13 @@
17382 #if SQLITE_ENABLE_UNLOCK_NOTIFY
17383 "ENABLE_UNLOCK_NOTIFY",
17384 #endif
17385 #if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
17386 "ENABLE_UPDATE_DELETE_LIMIT",
17387 #endif
17388 #if defined(SQLITE_ENABLE_URI_00_ERROR)
17389 "ENABLE_URI_00_ERROR",
17390 #endif
17391 #if SQLITE_HAS_CODEC
17392 "HAS_CODEC",
17393 #endif
17394 #if HAVE_ISNAN || SQLITE_HAVE_ISNAN
@@ -17719,13 +17758,10 @@
17758 typedef unsigned Bool;
17759
17760 /* Opaque type used by code in vdbesort.c */
17761 typedef struct VdbeSorter VdbeSorter;
17762
 
 
 
17763 /* Elements of the linked list at Vdbe.pAuxData */
17764 typedef struct AuxData AuxData;
17765
17766 /* Types of VDBE cursors */
17767 #define CURTYPE_BTREE 0
@@ -17796,10 +17832,16 @@
17832 /* 2*nField extra array elements allocated for aType[], beyond the one
17833 ** static element declared in the structure. nField total array slots for
17834 ** aType[] and nField+1 array slots for aOffset[] */
17835 };
17836
17837
17838 /*
17839 ** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
17840 */
17841 #define CACHE_STALE 0
17842
17843 /*
17844 ** When a sub-program is executed (OP_Program), a structure of this type
17845 ** is allocated to store the current value of the program counter, as
17846 ** well as the current memory cell array and various other frame specific
17847 ** values stored in the Vdbe struct. When the sub-program is finished,
@@ -17840,15 +17882,10 @@
17882 int nDbChange; /* Value of db->nChange */
17883 };
17884
17885 #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
17886
 
 
 
 
 
17887 /*
17888 ** Internally, the vdbe manipulates nearly all SQL values as Mem
17889 ** structures. Each Mem struct may cache multiple representations (string,
17890 ** integer etc.) of the same value.
17891 */
@@ -17985,22 +18022,10 @@
18022 u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
18023 u8 argc; /* Number of arguments */
18024 sqlite3_value *argv[1]; /* Argument set */
18025 };
18026
 
 
 
 
 
 
 
 
 
 
 
 
18027 /* A bitfield type for use inside of structures. Always follow with :N where
18028 ** N is the number of bits.
18029 */
18030 typedef unsigned bft; /* Bit Field Type */
18031
@@ -18021,57 +18046,61 @@
18046 ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
18047 ** is really a pointer to an instance of this structure.
18048 */
18049 struct Vdbe {
18050 sqlite3 *db; /* The database connection that owns this statement */
18051 Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
18052 Parse *pParse; /* Parsing context used to create this Vdbe */
18053 ynVar nVar; /* Number of entries in aVar[] */
18054 ynVar nzVar; /* Number of entries in azVar[] */
18055 u32 magic; /* Magic number for sanity checking */
18056 int nMem; /* Number of memory locations currently allocated */
18057 int nCursor; /* Number of slots in apCsr[] */
18058 u32 cacheCtr; /* VdbeCursor row cache generation counter */
18059 int pc; /* The program counter */
18060 int rc; /* Value to return */
18061 int nChange; /* Number of db changes made since last reset */
18062 int iStatement; /* Statement number (or 0 if has not opened stmt) */
18063 i64 iCurrentTime; /* Value of julianday('now') for this statement */
18064 i64 nFkConstraint; /* Number of imm. FK constraints this VM */
18065 i64 nStmtDefCons; /* Number of def. constraints when stmt started */
18066 i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
18067
18068 /* When allocating a new Vdbe object, all of the fields below should be
18069 ** initialized to zero or NULL */
18070
18071 Op *aOp; /* Space to hold the virtual machine's program */
18072 Mem *aMem; /* The memory locations */
18073 Mem **apArg; /* Arguments to currently executing user function */
18074 Mem *aColName; /* Column names to return */
18075 Mem *pResultSet; /* Pointer to an array of results */
 
 
 
 
 
18076 char *zErrMsg; /* Error message written here */
 
18077 VdbeCursor **apCsr; /* One element of this array for each open cursor */
18078 Mem *aVar; /* Values for the OP_Variable opcode. */
18079 char **azVar; /* Name of variables */
18080 #ifndef SQLITE_OMIT_TRACE
18081 i64 startTime; /* Time when query started - used for profiling */
18082 #endif
18083 int nOp; /* Number of instructions in the program */
 
18084 #ifdef SQLITE_DEBUG
18085 int rcApp; /* errcode set by sqlite3_result_error_code() */
18086 #endif
18087 u16 nResColumn; /* Number of columns in one row of the result set */
18088 u8 errorAction; /* Recovery action to do in case of an error */
18089 u8 minWriteFileFormat; /* Minimum file format for writable database files */
18090 bft expired:1; /* True if the VM needs to be recompiled */
18091 bft doingRerun:1; /* True if rerunning after an auto-reprepare */
 
18092 bft explain:2; /* True if EXPLAIN present on SQL command */
18093 bft changeCntOn:1; /* True to update the change-counter */
18094 bft runOnlyOnce:1; /* Automatically expire on reset */
18095 bft usesStmtJournal:1; /* True if uses a statement journal */
18096 bft readOnly:1; /* True for statements that do not write */
18097 bft bIsReader:1; /* True for statements that read */
18098 bft isPrepareV2:1; /* True if prepared with prepare_v2() */
 
18099 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
18100 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
 
18101 u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
 
 
 
 
 
 
 
18102 char *zSql; /* Text of the SQL statement that generated this */
18103 void *pFree; /* Free this when deleting the vdbe */
18104 VdbeFrame *pFrame; /* Parent frame */
18105 VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
18106 int nFrame; /* Number of frames in pFrame list */
@@ -18086,14 +18115,15 @@
18115 };
18116
18117 /*
18118 ** The following are allowed values for Vdbe.magic
18119 */
18120 #define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
18121 #define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
18122 #define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
18123 #define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
18124 #define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
18125
18126 /*
18127 ** Structure used to store the context required by the
18128 ** sqlite3_preupdate_*() API functions.
18129 */
@@ -18106,12 +18136,12 @@
18136 UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
18137 UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
18138 int iNewReg; /* Register for new.* values */
18139 i64 iKey1; /* First key value passed to hook */
18140 i64 iKey2; /* Second key value passed to hook */
 
18141 Mem *aNew; /* Array of new.* values */
18142 Table *pTab; /* Schema object being upated */
18143 };
18144
18145 /*
18146 ** Function prototypes
18147 */
@@ -24599,13 +24629,12 @@
24629 char *zNew;
24630 size_t n;
24631 if( z==0 ){
24632 return 0;
24633 }
24634 n = strlen(z) + 1;
24635 zNew = sqlite3DbMallocRaw(db, n);
 
24636 if( zNew ){
24637 memcpy(zNew, z, n);
24638 }
24639 return zNew;
24640 }
@@ -28775,11 +28804,15 @@
28804 */
28805 static unsigned int strHash(const char *z){
28806 unsigned int h = 0;
28807 unsigned char c;
28808 while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
28809 /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
28810 ** 0x9e3779b1 is 2654435761 which is the closest prime number to
28811 ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
28812 h += sqlite3UpperToLower[c];
28813 h *= 0x9e3779b1;
28814 }
28815 return h;
28816 }
28817
28818
@@ -29124,19 +29157,19 @@
29157 /* 120 */ "SorterData" OpHelp("r[P2]=data"),
29158 /* 121 */ "RowKey" OpHelp("r[P2]=key"),
29159 /* 122 */ "RowData" OpHelp("r[P2]=data"),
29160 /* 123 */ "Rowid" OpHelp("r[P2]=rowid"),
29161 /* 124 */ "NullRow" OpHelp(""),
29162 /* 125 */ "SorterInsert" OpHelp("key=r[P2]"),
29163 /* 126 */ "IdxInsert" OpHelp("key=r[P2]"),
29164 /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
29165 /* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"),
29166 /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"),
29167 /* 130 */ "Destroy" OpHelp(""),
29168 /* 131 */ "Clear" OpHelp(""),
29169 /* 132 */ "Real" OpHelp("r[P2]=P4"),
29170 /* 133 */ "ResetSorter" OpHelp(""),
29171 /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
29172 /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
29173 /* 136 */ "ParseSchema" OpHelp(""),
29174 /* 137 */ "LoadAnalysis" OpHelp(""),
29175 /* 138 */ "DropTable" OpHelp(""),
@@ -40671,10 +40704,16 @@
40704 a[1] = winIoerrRetryDelay;
40705 }
40706 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
40707 return SQLITE_OK;
40708 }
40709 case SQLITE_FCNTL_WIN32_GET_HANDLE: {
40710 LPHANDLE phFile = (LPHANDLE)pArg;
40711 *phFile = pFile->h;
40712 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
40713 return SQLITE_OK;
40714 }
40715 #ifdef SQLITE_TEST
40716 case SQLITE_FCNTL_WIN32_SET_HANDLE: {
40717 LPHANDLE phFile = (LPHANDLE)pArg;
40718 HANDLE hOldFile = pFile->h;
40719 pFile->h = *phFile;
@@ -44018,11 +44057,11 @@
44057 ){
44058 PgHdr *pPgHdr;
44059 assert( pPage!=0 );
44060 pPgHdr = (PgHdr*)pPage->pExtra;
44061 assert( pPgHdr->pPage==0 );
44062 memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
44063 pPgHdr->pPage = pPage;
44064 pPgHdr->pData = pPage->pBuf;
44065 pPgHdr->pExtra = (void *)&pPgHdr[1];
44066 memset(pPgHdr->pExtra, 0, pCache->szExtra);
44067 pPgHdr->pCache = pCache;
@@ -44712,11 +44751,11 @@
44751 szBulk = pCache->szAlloc * (i64)pcache1.nInitPage;
44752 }else{
44753 szBulk = -1024 * (i64)pcache1.nInitPage;
44754 }
44755 if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
44756 szBulk = pCache->szAlloc*(i64)pCache->nMax;
44757 }
44758 zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
44759 sqlite3EndBenignMalloc();
44760 if( zBulk ){
44761 int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
@@ -46246,21 +46285,21 @@
46285 #define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */
46286
46287 #ifdef SQLITE_OMIT_WAL
46288 # define sqlite3WalOpen(x,y,z) 0
46289 # define sqlite3WalLimit(x,y)
46290 # define sqlite3WalClose(v,w,x,y,z) 0
46291 # define sqlite3WalBeginReadTransaction(y,z) 0
46292 # define sqlite3WalEndReadTransaction(z)
46293 # define sqlite3WalDbsize(y) 0
46294 # define sqlite3WalBeginWriteTransaction(y) 0
46295 # define sqlite3WalEndWriteTransaction(x) 0
46296 # define sqlite3WalUndo(x,y,z) 0
46297 # define sqlite3WalSavepoint(y,z)
46298 # define sqlite3WalSavepointUndo(y,z) 0
46299 # define sqlite3WalFrames(u,v,w,x,y,z) 0
46300 # define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
46301 # define sqlite3WalCallback(z) 0
46302 # define sqlite3WalExclusiveMode(y,z) 0
46303 # define sqlite3WalHeapMemory(z) 0
46304 # define sqlite3WalFramesize(z) 0
46305 # define sqlite3WalFindFrame(x,y,z) 0
@@ -46274,11 +46313,11 @@
46313 */
46314 typedef struct Wal Wal;
46315
46316 /* Open and close a connection to a write-ahead log. */
46317 SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
46318 SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
46319
46320 /* Set the limiting size of a WAL file. */
46321 SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
46322
46323 /* Used by readers to open (lock) and close (unlock) a snapshot. A
@@ -46317,10 +46356,11 @@
46356 SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
46357
46358 /* Copy pages from the log to the database file */
46359 SQLITE_PRIVATE int sqlite3WalCheckpoint(
46360 Wal *pWal, /* Write-ahead log connection */
46361 sqlite3 *db, /* Check this handle's interrupt flag */
46362 int eMode, /* One of PASSIVE, FULL and RESTART */
46363 int (*xBusy)(void*), /* Function to call when busy */
46364 void *pBusyArg, /* Context argument for xBusyHandler */
46365 int sync_flags, /* Flags to sync db file with (or 0) */
46366 int nBuf, /* Size of buffer nBuf */
@@ -47161,13 +47201,14 @@
47201 /*
47202 ** Return true if this pager uses a write-ahead log instead of the usual
47203 ** rollback journal. Otherwise false.
47204 */
47205 #ifndef SQLITE_OMIT_WAL
47206 SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager){
47207 return (pPager->pWal!=0);
47208 }
47209 # define pagerUseWal(x) sqlite3PagerUseWal(x)
47210 #else
47211 # define pagerUseWal(x) 0
47212 # define pagerRollbackWal(x) 0
47213 # define pagerWalFrames(v,w,x,y) 0
47214 # define pagerOpenWalIfPresent(z) SQLITE_OK
@@ -50365,21 +50406,22 @@
50406 ** This function always succeeds. If a transaction is active an attempt
50407 ** is made to roll it back. If an error occurs during the rollback
50408 ** a hot journal may be left in the filesystem but no error is returned
50409 ** to the caller.
50410 */
50411 SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
50412 u8 *pTmp = (u8 *)pPager->pTmpSpace;
50413
50414 assert( db || pagerUseWal(pPager)==0 );
50415 assert( assert_pager_state(pPager) );
50416 disable_simulated_io_errors();
50417 sqlite3BeginBenignMalloc();
50418 pagerFreeMapHdrs(pPager);
50419 /* pPager->errCode = 0; */
50420 pPager->exclusiveMode = 0;
50421 #ifndef SQLITE_OMIT_WAL
50422 sqlite3WalClose(pPager->pWal,db,pPager->ckptSyncFlags,pPager->pageSize,pTmp);
50423 pPager->pWal = 0;
50424 #endif
50425 pager_reset(pPager);
50426 if( MEMDB ){
50427 pager_unlock(pPager);
@@ -53538,14 +53580,20 @@
53580 ** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
53581 ** or wal_blocking_checkpoint() API functions.
53582 **
53583 ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
53584 */
53585 SQLITE_PRIVATE int sqlite3PagerCheckpoint(
53586 Pager *pPager, /* Checkpoint on this pager */
53587 sqlite3 *db, /* Db handle used to check for interrupts */
53588 int eMode, /* Type of checkpoint */
53589 int *pnLog, /* OUT: Final number of frames in log */
53590 int *pnCkpt /* OUT: Final number of checkpointed frames */
53591 ){
53592 int rc = SQLITE_OK;
53593 if( pPager->pWal ){
53594 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
53595 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
53596 pPager->pBusyHandlerArg,
53597 pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
53598 pnLog, pnCkpt
53599 );
@@ -53673,11 +53721,11 @@
53721 ** Before closing the log file, this function attempts to take an
53722 ** EXCLUSIVE lock on the database file. If this cannot be obtained, an
53723 ** error (SQLITE_BUSY) is returned and the log connection is not closed.
53724 ** If successful, the EXCLUSIVE lock is not released before returning.
53725 */
53726 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
53727 int rc = SQLITE_OK;
53728
53729 assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
53730
53731 /* If the log file is not already open, but does exist in the file-system,
@@ -53701,11 +53749,11 @@
53749 ** the database file, the log and log-summary files will be deleted.
53750 */
53751 if( rc==SQLITE_OK && pPager->pWal ){
53752 rc = pagerExclusiveLock(pPager);
53753 if( rc==SQLITE_OK ){
53754 rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
53755 pPager->pageSize, (u8*)pPager->pTmpSpace);
53756 pPager->pWal = 0;
53757 pagerFixMaplimit(pPager);
53758 if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
53759 }
@@ -55484,10 +55532,11 @@
55532 ** checkpoint is running (in any other thread or process) at the same
55533 ** time.
55534 */
55535 static int walCheckpoint(
55536 Wal *pWal, /* Wal connection */
55537 sqlite3 *db, /* Check for interrupts on this handle */
55538 int eMode, /* One of PASSIVE, FULL or RESTART */
55539 int (*xBusy)(void*), /* Function to call when busy */
55540 void *pBusyArg, /* Context argument for xBusyHandler */
55541 int sync_flags, /* Flags for OsSync() (or 0) */
55542 u8 *zBuf /* Temporary buffer to use */
@@ -55578,10 +55627,14 @@
55627
55628 /* Iterate through the contents of the WAL, copying data to the db file */
55629 while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
55630 i64 iOffset;
55631 assert( walFramePgno(pWal, iFrame)==iDbpage );
55632 if( db->u1.isInterrupted ){
55633 rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
55634 break;
55635 }
55636 if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
55637 continue;
55638 }
55639 iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
55640 /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
@@ -55682,10 +55735,11 @@
55735 /*
55736 ** Close a connection to a log file.
55737 */
55738 SQLITE_PRIVATE int sqlite3WalClose(
55739 Wal *pWal, /* Wal to close */
55740 sqlite3 *db, /* For interrupt flag */
55741 int sync_flags, /* Flags to pass to OsSync() (or 0) */
55742 int nBuf,
55743 u8 *zBuf /* Buffer of at least nBuf bytes */
55744 ){
55745 int rc = SQLITE_OK;
@@ -55698,17 +55752,18 @@
55752 ** the database. In this case checkpoint the database and unlink both
55753 ** the wal and wal-index files.
55754 **
55755 ** The EXCLUSIVE lock is not released before returning.
55756 */
55757 if( (db->flags & SQLITE_NoCkptOnClose)==0
55758 && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
55759 ){
55760 if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
55761 pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
55762 }
55763 rc = sqlite3WalCheckpoint(pWal, db,
55764 SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
55765 );
55766 if( rc==SQLITE_OK ){
55767 int bPersist = -1;
55768 sqlite3OsFileControlHint(
55769 pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist
@@ -56952,10 +57007,11 @@
57007 ** If parameter xBusy is not NULL, it is a pointer to a busy-handler
57008 ** callback. In this case this function runs a blocking checkpoint.
57009 */
57010 SQLITE_PRIVATE int sqlite3WalCheckpoint(
57011 Wal *pWal, /* Wal connection */
57012 sqlite3 *db, /* Check this handle's interrupt flag */
57013 int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
57014 int (*xBusy)(void*), /* Function to call when busy */
57015 void *pBusyArg, /* Context argument for xBusyHandler */
57016 int sync_flags, /* Flags to sync db file with (or 0) */
57017 int nBuf, /* Size of temporary buffer */
@@ -57026,11 +57082,11 @@
57082 if( rc==SQLITE_OK ){
57083
57084 if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
57085 rc = SQLITE_CORRUPT_BKPT;
57086 }else{
57087 rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
57088 }
57089
57090 /* If no error occurred, set the output variables. */
57091 if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
57092 if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
@@ -58984,11 +59040,11 @@
59040 int bias, /* Bias search to the high end */
59041 int *pRes /* Write search results here */
59042 ){
59043 int rc; /* Status code */
59044 UnpackedRecord *pIdxKey; /* Unpacked index key */
59045 char aSpace[384]; /* Temp space for pIdxKey - to avoid a malloc */
59046 char *pFree = 0;
59047
59048 if( pKey ){
59049 assert( nKey==(i64)(int)nKey );
59050 pIdxKey = sqlite3VdbeAllocUnpackedRecord(
@@ -60616,23 +60672,30 @@
60672 *ppBtree = p;
60673
60674 btree_open_out:
60675 if( rc!=SQLITE_OK ){
60676 if( pBt && pBt->pPager ){
60677 sqlite3PagerClose(pBt->pPager, 0);
60678 }
60679 sqlite3_free(pBt);
60680 sqlite3_free(p);
60681 *ppBtree = 0;
60682 }else{
60683 sqlite3_file *pFile;
60684
60685 /* If the B-Tree was successfully opened, set the pager-cache size to the
60686 ** default value. Except, when opening on an existing shared pager-cache,
60687 ** do not change the pager-cache size.
60688 */
60689 if( sqlite3BtreeSchema(p, 0, 0)==0 ){
60690 sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
60691 }
60692
60693 pFile = sqlite3PagerFile(pBt->pPager);
60694 if( pFile->pMethods ){
60695 sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
60696 }
60697 }
60698 if( mutexOpen ){
60699 assert( sqlite3_mutex_held(mutexOpen) );
60700 sqlite3_mutex_leave(mutexOpen);
60701 }
@@ -60758,11 +60821,11 @@
60821 ** it without having to hold the mutex.
60822 **
60823 ** Clean out and delete the BtShared object.
60824 */
60825 assert( !pBt->pCursor );
60826 sqlite3PagerClose(pBt->pPager, p->db);
60827 if( pBt->xFreeSchema && pBt->pSchema ){
60828 pBt->xFreeSchema(pBt->pSchema);
60829 }
60830 sqlite3DbFree(0, pBt->pSchema);
60831 freeTempSpace(pBt);
@@ -62822,11 +62885,11 @@
62885 if( (eOp&0x01)==0 /* (1) */
62886 && offset==0 /* (2) */
62887 && (bEnd || a==ovflSize) /* (6) */
62888 && pBt->inTransaction==TRANS_READ /* (4) */
62889 && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
62890 && 0==sqlite3PagerUseWal(pBt->pPager) /* (5) */
62891 && &pBuf[-4]>=pBufStart /* (7) */
62892 ){
62893 u8 aSave[4];
62894 u8 *aWrite = &pBuf[-4];
62895 assert( aWrite>=pBufStart ); /* hence (7) */
@@ -63078,13 +63141,16 @@
63141 }
63142 sqlite3BtreeClearCursor(pCur);
63143 }
63144
63145 if( pCur->iPage>=0 ){
63146 if( pCur->iPage ){
63147 do{
63148 assert( pCur->apPage[pCur->iPage]!=0 );
63149 releasePageNotNull(pCur->apPage[pCur->iPage--]);
63150 }while( pCur->iPage);
63151 goto skip_init;
63152 }
63153 }else if( pCur->pgnoRoot==0 ){
63154 pCur->eState = CURSOR_INVALID;
63155 return SQLITE_OK;
63156 }else{
@@ -63091,11 +63157,11 @@
63157 assert( pCur->iPage==(-1) );
63158 rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
63159 0, pCur->curPagerFlags);
63160 if( rc!=SQLITE_OK ){
63161 pCur->eState = CURSOR_INVALID;
63162 return rc;
63163 }
63164 pCur->iPage = 0;
63165 pCur->curIntKey = pCur->apPage[0]->intKey;
63166 }
63167 pRoot = pCur->apPage[0];
@@ -63114,14 +63180,16 @@
63180 assert( pRoot->intKey==1 || pRoot->intKey==0 );
63181 if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
63182 return SQLITE_CORRUPT_BKPT;
63183 }
63184
63185 skip_init:
63186 pCur->aiIdx[0] = 0;
63187 pCur->info.nSize = 0;
63188 pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
63189
63190 pRoot = pCur->apPage[0];
63191 if( pRoot->nCell>0 ){
63192 pCur->eState = CURSOR_VALID;
63193 }else if( !pRoot->leaf ){
63194 Pgno subpage;
63195 if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
@@ -64321,12 +64389,10 @@
64389 nSrc = pX->nData;
64390 assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
64391 nHeader += putVarint32(&pCell[nHeader], nPayload);
64392 nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
64393 }else{
 
 
64394 assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
64395 nSrc = nPayload = (int)pX->nKey;
64396 pSrc = pX->pKey;
64397 nHeader += putVarint32(&pCell[nHeader], nPayload);
64398 }
@@ -67700,11 +67766,11 @@
67766 BtShared *pBt = p->pBt;
67767 sqlite3BtreeEnter(p);
67768 if( pBt->inTransaction!=TRANS_NONE ){
67769 rc = SQLITE_LOCKED;
67770 }else{
67771 rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
67772 }
67773 sqlite3BtreeLeave(p);
67774 }
67775 return rc;
67776 }
@@ -68022,26 +68088,20 @@
68088 */
68089 static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
68090 int i = sqlite3FindDbName(pDb, zDb);
68091
68092 if( i==1 ){
68093 Parse sParse;
68094 int rc = 0;
68095 memset(&sParse, 0, sizeof(sParse));
68096 sParse.db = pDb;
68097 if( sqlite3OpenTempDatabase(&sParse) ){
68098 sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
68099 rc = SQLITE_ERROR;
68100 }
68101 sqlite3DbFree(pErrorDb, sParse.zErrMsg);
68102 sqlite3ParserReset(&sParse);
 
 
 
 
 
 
68103 if( rc ){
68104 return 0;
68105 }
68106 }
68107
@@ -69041,10 +69101,11 @@
69101 assert( (pMem->flags&MEM_RowSet)==0 );
69102 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
69103
69104
69105 if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
69106 pMem->enc = 0;
69107 return SQLITE_NOMEM_BKPT;
69108 }
69109
69110 /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
69111 ** string representation of the value. Then, if the required encoding
@@ -69340,11 +69401,11 @@
69401 switch( aff ){
69402 case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */
69403 if( (pMem->flags & MEM_Blob)==0 ){
69404 sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
69405 assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
69406 if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
69407 }else{
69408 pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
69409 }
69410 break;
69411 }
@@ -70017,14 +70078,11 @@
70078 sqlite3_value *pVal = 0;
70079 int negInt = 1;
70080 const char *zNeg = "";
70081 int rc = SQLITE_OK;
70082
70083 assert( pExpr!=0 );
 
 
 
70084 while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
70085 if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
70086
70087 /* Compressed expressions only appear when parsing the DEFAULT clause
70088 ** on a table column definition, and hence only when pCtx==0. This
@@ -70144,11 +70202,11 @@
70202 Expr *pExpr, /* The expression to evaluate */
70203 u8 enc, /* Encoding to use */
70204 u8 affinity, /* Affinity to use */
70205 sqlite3_value **ppVal /* Write the new value here */
70206 ){
70207 return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
70208 }
70209
70210 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
70211 /*
70212 ** The implementation of the sqlite_record() function. This function accepts
@@ -70487,12 +70545,13 @@
70545 ** Create a new virtual database engine.
70546 */
70547 SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
70548 sqlite3 *db = pParse->db;
70549 Vdbe *p;
70550 p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
70551 if( p==0 ) return 0;
70552 memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
70553 p->db = db;
70554 if( db->pVdbe ){
70555 db->pVdbe->pPrev = p;
70556 }
70557 p->pNext = db->pVdbe;
@@ -70650,13 +70709,12 @@
70709 #endif
70710 #ifdef SQLITE_DEBUG
70711 if( p->db->flags & SQLITE_VdbeAddopTrace ){
70712 int jj, kk;
70713 Parse *pParse = p->pParse;
70714 for(jj=kk=0; jj<pParse->nColCache; jj++){
70715 struct yColCache *x = pParse->aColCache + jj;
 
70716 printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
70717 kk++;
70718 }
70719 if( kk ) printf("\n");
70720 sqlite3VdbePrintOp(0, i, &p->aOp[i]);
@@ -70840,11 +70898,10 @@
70898 assert( j<p->nLabel );
70899 assert( j>=0 );
70900 if( p->aLabel ){
70901 p->aLabel[j] = v->nOp;
70902 }
 
70903 }
70904
70905 /*
70906 ** Mark the VDBE as one that can only be run one time.
70907 */
@@ -71231,19 +71288,19 @@
71288 }
71289 SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
71290 sqlite3VdbeGetOp(p,addr)->p3 = val;
71291 }
71292 SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
71293 assert( p->nOp>0 || p->db->mallocFailed );
71294 if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
71295 }
71296
71297 /*
71298 ** Change the P2 operand of instruction addr so that it points to
71299 ** the address of the next instruction to be coded.
71300 */
71301 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
 
71302 sqlite3VdbeChangeP2(p, addr, p->nOp);
71303 }
71304
71305
71306 /*
@@ -71362,11 +71419,11 @@
71419 /*
71420 ** If the last opcode is "op" and it is not a jump destination,
71421 ** then remove it. Return true if and only if an opcode was removed.
71422 */
71423 SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
71424 if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
71425 return sqlite3VdbeChangeToNoop(p, p->nOp-1);
71426 }else{
71427 return 0;
71428 }
71429 }
@@ -71924,10 +71981,25 @@
71981 zCom
71982 );
71983 fflush(pOut);
71984 }
71985 #endif
71986
71987 /*
71988 ** Initialize an array of N Mem element.
71989 */
71990 static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
71991 while( (N--)>0 ){
71992 p->db = db;
71993 p->flags = flags;
71994 p->szMalloc = 0;
71995 #ifdef SQLITE_DEBUG
71996 p->pScopyFrom = 0;
71997 #endif
71998 p++;
71999 }
72000 }
72001
72002 /*
72003 ** Release an array of N Mem elements
72004 */
72005 static void releaseMemArray(Mem *p, int N){
@@ -72136,10 +72208,11 @@
72208 return SQLITE_ERROR;
72209 }
72210 pMem->flags = MEM_Str|MEM_Term;
72211 zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
72212 if( zP4!=pMem->z ){
72213 pMem->n = 0;
72214 sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
72215 }else{
72216 assert( pMem->z!=0 );
72217 pMem->n = sqlite3Strlen30(pMem->z);
72218 pMem->enc = SQLITE_UTF8;
@@ -72278,11 +72351,11 @@
72351 SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
72352 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
72353 int i;
72354 #endif
72355 assert( p!=0 );
72356 assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );
72357
72358 /* There should be at least one opcode.
72359 */
72360 assert( p->nOp>0 );
72361
@@ -72367,14 +72440,11 @@
72440 n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
72441 x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
72442 assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
72443 x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
72444 assert( x.nFree>=0 );
72445 assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
 
 
 
72446
72447 resolveP2Values(p, &nArg);
72448 p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
72449 if( pParse->explain && nMem<10 ){
72450 nMem = 10;
@@ -72399,34 +72469,34 @@
72469 p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
72470 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
72471 p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
72472 #endif
72473 if( x.nNeeded==0 ) break;
72474 x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
72475 x.nFree = x.nNeeded;
72476 }while( !db->mallocFailed );
72477
 
 
 
 
 
 
 
 
72478 p->nzVar = pParse->nzVar;
72479 p->azVar = pParse->azVar;
72480 pParse->nzVar = 0;
72481 pParse->azVar = 0;
 
 
 
 
 
 
 
72482 p->explain = pParse->explain;
72483 if( db->mallocFailed ){
72484 p->nVar = 0;
72485 p->nCursor = 0;
72486 p->nMem = 0;
72487 }else{
72488 p->nCursor = nCursor;
72489 p->nVar = (ynVar)nVar;
72490 initMemArray(p->aVar, nVar, db, MEM_Null);
72491 p->nMem = nMem;
72492 initMemArray(p->aMem, nMem, db, MEM_Undefined);
72493 memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
72494 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
72495 memset(p->anExec, 0, p->nOp*sizeof(i64));
72496 #endif
72497 }
72498 sqlite3VdbeRewind(p);
72499 }
72500
72501 /*
72502 ** Close a VDBE cursor and release all the resources that cursor
@@ -72574,17 +72644,13 @@
72644
72645 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
72646 sqlite3DbFree(db, p->aColName);
72647 n = nResColumn*COLNAME_N;
72648 p->nResColumn = (u16)nResColumn;
72649 p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
72650 if( p->aColName==0 ) return;
72651 initMemArray(p->aColName, n, p->db, MEM_Null);
 
 
 
 
72652 }
72653
72654 /*
72655 ** Set the name of the idx'th column to be returned by the SQL statement.
72656 ** zName must be a pointer to a nul terminated string.
@@ -73342,11 +73408,11 @@
73408 fclose(out);
73409 }
73410 }
73411 #endif
73412 p->iCurrentTime = 0;
73413 p->magic = VDBE_MAGIC_RESET;
73414 return p->rc & db->errMask;
73415 }
73416
73417 /*
73418 ** Clean up and delete a VDBE after execution. Return an integer which is
@@ -73406,23 +73472,25 @@
73472 */
73473 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
73474 SubProgram *pSub, *pNext;
73475 int i;
73476 assert( p->db==0 || p->db==db );
 
73477 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
73478 for(pSub=p->pProgram; pSub; pSub=pNext){
73479 pNext = pSub->pNext;
73480 vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
73481 sqlite3DbFree(db, pSub);
73482 }
73483 if( p->magic!=VDBE_MAGIC_INIT ){
73484 releaseMemArray(p->aVar, p->nVar);
73485 for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
73486 sqlite3DbFree(db, p->azVar);
73487 sqlite3DbFree(db, p->pFree);
73488 }
73489 vdbeFreeOpArray(db, p->aOp, p->nOp);
73490 sqlite3DbFree(db, p->aColName);
73491 sqlite3DbFree(db, p->zSql);
 
73492 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
73493 for(i=0; i<p->nScan; i++){
73494 sqlite3DbFree(db, p->aScan[i].zName);
73495 }
73496 sqlite3DbFree(db, p->aScan);
@@ -75073,11 +75141,11 @@
75141 preupdate.keyinfo.enc = ENC(db);
75142 preupdate.keyinfo.nField = pTab->nCol;
75143 preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
75144 preupdate.iKey1 = iKey1;
75145 preupdate.iKey2 = iKey2;
75146 preupdate.pTab = pTab;
75147
75148 db->pPreUpdate = &preupdate;
75149 db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
75150 db->pPreUpdate = 0;
75151 sqlite3DbFree(db, preupdate.aRecord);
@@ -76047,18 +76115,17 @@
76115 static Mem *columnMem(sqlite3_stmt *pStmt, int i){
76116 Vdbe *pVm;
76117 Mem *pOut;
76118
76119 pVm = (Vdbe *)pStmt;
76120 if( pVm==0 ) return (Mem*)columnNullValue();
76121 assert( pVm->db );
76122 sqlite3_mutex_enter(pVm->db->mutex);
76123 if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
76124 pOut = &pVm->pResultSet[i];
76125 }else{
76126 sqlite3Error(pVm->db, SQLITE_RANGE);
 
 
 
76127 pOut = (Mem*)columnNullValue();
76128 }
76129 return pOut;
76130 }
76131
@@ -76087,10 +76154,12 @@
76154 ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
76155 ** and _finalize() will return NOMEM.
76156 */
76157 Vdbe *p = (Vdbe *)pStmt;
76158 if( p ){
76159 assert( p->db!=0 );
76160 assert( sqlite3_mutex_held(p->db->mutex) );
76161 p->rc = sqlite3ApiExit(p->db, p->rc);
76162 sqlite3_mutex_leave(p->db->mutex);
76163 }
76164 }
76165
@@ -76663,11 +76732,11 @@
76732 /*
76733 ** Return true if the prepared statement is in need of being reset.
76734 */
76735 SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
76736 Vdbe *v = (Vdbe*)pStmt;
76737 return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
76738 }
76739
76740 /*
76741 ** Return a pointer to the next prepared statement after pStmt associated
76742 ** with database connection pDb. If pStmt is NULL, return the first
@@ -76804,13 +76873,18 @@
76873 }
76874
76875 if( iIdx>=p->pUnpacked->nField ){
76876 *ppValue = (sqlite3_value *)columnNullValue();
76877 }else{
76878 Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
76879 *ppValue = &p->pUnpacked->aMem[iIdx];
76880 if( iIdx==p->pTab->iPKey ){
76881 sqlite3VdbeMemSetInt64(pMem, p->iKey1);
76882 }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
76883 if( pMem->flags & MEM_Int ){
76884 sqlite3VdbeMemRealify(pMem);
76885 }
76886 }
76887 }
76888
76889 preupdate_old_out:
76890 sqlite3Error(db, rc);
@@ -76883,11 +76957,11 @@
76957 }
76958 if( iIdx>=pUnpack->nField ){
76959 pMem = (sqlite3_value *)columnNullValue();
76960 }else{
76961 pMem = &pUnpack->aMem[iIdx];
76962 if( iIdx==p->pTab->iPKey ){
76963 sqlite3VdbeMemSetInt64(pMem, p->iKey2);
76964 }
76965 }
76966 }else{
76967 /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
@@ -76904,11 +76978,11 @@
76978 }
76979 }
76980 assert( iIdx>=0 && iIdx<p->pCsr->nField );
76981 pMem = &p->aNew[iIdx];
76982 if( pMem->flags==0 ){
76983 if( iIdx==p->pTab->iPKey ){
76984 sqlite3VdbeMemSetInt64(pMem, p->iKey2);
76985 }else{
76986 rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
76987 if( rc!=SQLITE_OK ) goto preupdate_new_out;
76988 }
@@ -78415,15 +78489,17 @@
78489 u16 nullFlag;
78490 pOut = out2Prerelease(p, pOp);
78491 cnt = pOp->p3-pOp->p2;
78492 assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
78493 pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
78494 pOut->n = 0;
78495 while( cnt>0 ){
78496 pOut++;
78497 memAboutToChange(p, pOut);
78498 sqlite3VdbeMemSetNull(pOut);
78499 pOut->flags = nullFlag;
78500 pOut->n = 0;
78501 cnt--;
78502 }
78503 break;
78504 }
78505
@@ -79280,12 +79356,11 @@
79356 ** or not both operands are null.
79357 */
79358 assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
79359 assert( (flags1 & MEM_Cleared)==0 );
79360 assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
79361 if( (flags1&flags3&MEM_Null)!=0
 
79362 && (flags3&MEM_Cleared)==0
79363 ){
79364 res = 0; /* Operands are equal */
79365 }else{
79366 res = 1; /* Operands are not equal */
@@ -80487,14 +80562,13 @@
80562 p->nStmtDefCons = db->nDeferredCons;
80563 p->nStmtDefImmCons = db->nDeferredImmCons;
80564 }
80565
80566 /* Gather the schema version number for checking:
80567 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
80568 ** version is checked to ensure that the schema has not changed since the
80569 ** SQL statement was prepared.
 
80570 */
80571 sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
80572 iGen = db->aDb[pOp->p1].pSchema->iGeneration;
80573 }else{
80574 iGen = iMeta = 0;
@@ -81549,11 +81623,11 @@
81623
81624 REGISTER_TRACE(pOp->p3, pMem);
81625 sqlite3VdbeMemIntegerify(pMem);
81626 assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
81627 if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
81628 rc = SQLITE_FULL; /* IMP: R-17817-00630 */
81629 goto abort_due_to_error;
81630 }
81631 if( v<pMem->u.i+1 ){
81632 v = pMem->u.i + 1;
81633 }
@@ -81746,11 +81820,11 @@
81820 ** change count is incremented (otherwise not).
81821 **
81822 ** P1 must not be pseudo-table. It has to be a real table with
81823 ** multiple rows.
81824 **
81825 ** If P4 is not NULL then it points to a Table object. In this case either
81826 ** the update or pre-update hook, or both, may be invoked. The P1 cursor must
81827 ** have been positioned using OP_NotFound prior to invoking this opcode in
81828 ** this case. Specifically, if one is configured, the pre-update hook is
81829 ** invoked if P4 is not NULL. The update-hook is invoked if one is configured,
81830 ** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
@@ -82316,10 +82390,17 @@
82390 ** This flag avoids doing an extra seek.
82391 **
82392 ** This instruction only works for indices. The equivalent instruction
82393 ** for tables is OP_Insert.
82394 */
82395 /* Opcode: SorterInsert P1 P2 * * *
82396 ** Synopsis: key=r[P2]
82397 **
82398 ** Register P2 holds an SQL index key made using the
82399 ** MakeRecord instructions. This opcode writes that key
82400 ** into the sorter P1. Data for the entry is nil.
82401 */
82402 case OP_SorterInsert: /* in2 */
82403 case OP_IdxInsert: { /* in2 */
82404 VdbeCursor *pC;
82405 BtreePayload x;
82406
@@ -82337,13 +82418,10 @@
82418 if( pOp->opcode==OP_SorterInsert ){
82419 rc = sqlite3VdbeSorterWrite(pC, pIn2);
82420 }else{
82421 x.nKey = pIn2->n;
82422 x.pKey = pIn2->z;
 
 
 
82423 rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3,
82424 ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
82425 );
82426 assert( pC->deferredMoveto==0 );
82427 pC->cacheStatus = CACHE_STALE;
@@ -83547,11 +83625,11 @@
83625 /* If leaving WAL mode, close the log file. If successful, the call
83626 ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
83627 ** file. An EXCLUSIVE lock may still be held on the database file
83628 ** after a successful return.
83629 */
83630 rc = sqlite3PagerCloseWal(pPager, db);
83631 if( rc==SQLITE_OK ){
83632 sqlite3PagerSetJournalMode(pPager, eNew);
83633 }
83634 }else if( eOld==PAGER_JOURNALMODE_MEMORY ){
83635 /* Cannot transition directly from MEMORY to WAL. Use mode OFF
@@ -88036,11 +88114,13 @@
88114 static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
88115 int rc;
88116 testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
88117 testcase( ExprHasProperty(pExpr, EP_Reduced) );
88118 rc = pWalker->xExprCallback(pWalker, pExpr);
88119 if( rc || ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
88120 return rc & WRC_Abort;
88121 }
88122 if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
88123 if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
88124 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
88125 if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
88126 }else if( pExpr->x.pList ){
@@ -88780,11 +88860,10 @@
88860 const char *zDb;
88861 Expr *pRight;
88862
88863 /* if( pSrcList==0 ) break; */
88864 notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
 
88865 pRight = pExpr->pRight;
88866 if( pRight->op==TK_ID ){
88867 zDb = 0;
88868 zTable = pExpr->pLeft->u.zToken;
88869 zColumn = pRight->u.zToken;
@@ -88809,11 +88888,10 @@
88888 const char *zId; /* The function name. */
88889 FuncDef *pDef; /* Information about the function */
88890 u8 enc = ENC(pParse->db); /* The database encoding */
88891
88892 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
 
88893 zId = pExpr->u.zToken;
88894 nId = sqlite3Strlen30(zId);
88895 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
88896 if( pDef==0 ){
88897 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
@@ -88869,11 +88947,12 @@
88947 }
88948 if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
88949 /* Date/time functions that use 'now', and other functions like
88950 ** sqlite_version() that might change over time cannot be used
88951 ** in an index. */
88952 notValid(pParse, pNC, "non-deterministic functions",
88953 NC_IdxExpr|NC_PartIdx);
88954 }
88955 }
88956 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
88957 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
88958 pNC->nErr++;
@@ -90409,11 +90488,11 @@
90488 ** stored in u.zToken. Instead, the integer values is written
90489 ** into u.iValue and the EP_IntValue flag is set. No extra storage
90490 ** is allocated to hold the integer text and the dequote flag is ignored.
90491 */
90492 SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
90493 sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */
90494 int op, /* Expression opcode */
90495 const Token *pToken, /* Token argument. Might be NULL */
90496 int dequote /* True to dequote */
90497 ){
90498 Expr *pNew;
@@ -90627,40 +90706,40 @@
90706 ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
90707 ** as the previous instance of the same wildcard. Or if this is the first
90708 ** instance of the wildcard, the next sequential variable number is
90709 ** assigned.
90710 */
90711 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
90712 sqlite3 *db = pParse->db;
90713 const char *z;
90714
90715 if( pExpr==0 ) return;
90716 assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
90717 z = pExpr->u.zToken;
90718 assert( z!=0 );
90719 assert( z[0]!=0 );
90720 assert( n==sqlite3Strlen30(z) );
90721 if( z[1]==0 ){
90722 /* Wildcard of the form "?". Assign the next variable number */
90723 assert( z[0]=='?' );
90724 pExpr->iColumn = (ynVar)(++pParse->nVar);
90725 }else{
90726 ynVar x;
 
90727 if( z[0]=='?' ){
90728 /* Wildcard of the form "?nnn". Convert "nnn" to an integer and
90729 ** use it as the variable number */
90730 i64 i;
90731 int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
90732 x = (ynVar)i;
90733 testcase( i==0 );
90734 testcase( i==1 );
90735 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
90736 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
90737 if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
90738 sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
90739 db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
90740 return;
90741 }
90742 if( i>pParse->nVar ){
90743 pParse->nVar = (int)i;
90744 }
90745 }else{
@@ -90667,37 +90746,35 @@
90746 /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
90747 ** number as the prior appearance of the same name, or if the name
90748 ** has never appeared before, reuse the same variable number
90749 */
90750 ynVar i;
90751 for(i=x=0; i<pParse->nzVar; i++){
90752 if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
90753 x = (ynVar)i+1;
90754 break;
90755 }
90756 }
90757 if( x==0 ) x = (ynVar)(++pParse->nVar);
90758 }
90759 pExpr->iColumn = x;
90760 if( x>pParse->nzVar ){
90761 char **a;
90762 a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
90763 if( a==0 ){
90764 assert( db->mallocFailed ); /* Error reported through mallocFailed */
90765 return;
90766 }
90767 pParse->azVar = a;
90768 memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
90769 pParse->nzVar = x;
90770 }
90771 if( pParse->azVar[x-1]==0 ){
90772 pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
90773 }
90774 }
90775 if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
 
 
90776 sqlite3ErrorMsg(pParse, "too many SQL variables");
90777 }
90778 }
90779
90780 /*
@@ -90705,22 +90782,29 @@
90782 */
90783 static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
90784 assert( p!=0 );
90785 /* Sanity check: Assert that the IntValue is non-negative if it exists */
90786 assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
90787 #ifdef SQLITE_DEBUG
90788 if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
90789 assert( p->pLeft==0 );
90790 assert( p->pRight==0 );
90791 assert( p->x.pSelect==0 );
90792 }
90793 #endif
90794 if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
90795 /* The Expr.x union is never used at the same time as Expr.pRight */
90796 assert( p->x.pList==0 || p->pRight==0 );
90797 if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
90798 sqlite3ExprDelete(db, p->pRight);
 
90799 if( ExprHasProperty(p, EP_xIsSelect) ){
90800 sqlite3SelectDelete(db, p->x.pSelect);
90801 }else{
90802 sqlite3ExprListDelete(db, p->x.pList);
90803 }
90804 }
90805 if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
90806 if( !ExprHasProperty(p, EP_Static) ){
90807 sqlite3DbFree(db, p);
90808 }
90809 }
90810 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -90893,11 +90977,11 @@
90977 if( nToken ){
90978 char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
90979 memcpy(zToken, p->u.zToken, nToken);
90980 }
90981
90982 if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
90983 /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
90984 if( ExprHasProperty(p, EP_xIsSelect) ){
90985 pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
90986 }else{
90987 pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
@@ -90905,21 +90989,21 @@
90989 }
90990
90991 /* Fill in pNew->pLeft and pNew->pRight. */
90992 if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
90993 zAlloc += dupedExprNodeSize(p, dupFlags);
90994 if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
90995 pNew->pLeft = p->pLeft ?
90996 exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
90997 pNew->pRight = p->pRight ?
90998 exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
90999 }
91000 if( pzBuffer ){
91001 *pzBuffer = zAlloc;
91002 }
91003 }else{
91004 if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
91005 if( pNew->op==TK_SELECT_COLUMN ){
91006 pNew->pLeft = p->pLeft;
91007 }else{
91008 pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
91009 }
@@ -92276,12 +92360,12 @@
92360 dest.eDest = SRT_Exists;
92361 sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
92362 VdbeComment((v, "Init EXISTS result"));
92363 }
92364 sqlite3ExprDelete(pParse->db, pSel->pLimit);
92365 pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
92366 &sqlite3IntTokens[1], 0);
92367 pSel->iLimit = 0;
92368 pSel->selFlags &= ~SF_MultiValue;
92369 if( sqlite3Select(pParse, pSel, &dest) ){
92370 return 0;
92371 }
@@ -92646,36 +92730,23 @@
92730 #endif
92731 }
92732 }
92733 }
92734
92735 /*
92736 ** Erase column-cache entry number i
92737 */
92738 static void cacheEntryClear(Parse *pParse, int i){
92739 if( pParse->aColCache[i].tempReg ){
 
 
 
 
 
 
 
 
 
 
 
 
 
92740 if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
92741 pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
92742 }
 
92743 }
 
92744 pParse->nColCache--;
92745 if( i<pParse->nColCache ){
92746 pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
92747 }
92748 }
92749
92750
92751 /*
92752 ** Record in the column cache that a particular column from a
@@ -92701,64 +92772,52 @@
92772 **
92773 ** Actually, the way the column cache is currently used, we are guaranteed
92774 ** that the object will never already be in cache. Verify this guarantee.
92775 */
92776 #ifndef NDEBUG
92777 for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
92778 assert( p->iTable!=iTab || p->iColumn!=iCol );
92779 }
92780 #endif
92781
92782 /* If the cache is already full, delete the least recently used entry */
92783 if( pParse->nColCache>=SQLITE_N_COLCACHE ){
92784 minLru = 0x7fffffff;
92785 idxLru = -1;
92786 for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
92787 if( p->lru<minLru ){
92788 idxLru = i;
92789 minLru = p->lru;
92790 }
92791 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92792 p = &pParse->aColCache[idxLru];
92793 }else{
92794 p = &pParse->aColCache[pParse->nColCache++];
92795 }
92796
92797 /* Add the new entry to the end of the cache */
92798 p->iLevel = pParse->iCacheLevel;
92799 p->iTable = iTab;
92800 p->iColumn = iCol;
92801 p->iReg = iReg;
92802 p->tempReg = 0;
92803 p->lru = pParse->iCacheCnt++;
92804 }
92805
92806 /*
92807 ** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
92808 ** Purge the range of registers from the column cache.
92809 */
92810 SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
92811 int i = 0;
92812 while( i<pParse->nColCache ){
92813 struct yColCache *p = &pParse->aColCache[i];
92814 if( p->iReg >= iReg && p->iReg < iReg+nReg ){
92815 cacheEntryClear(pParse, i);
92816 }else{
92817 i++;
92818 }
92819 }
92820 }
92821
92822 /*
92823 ** Remember the current column cache context. Any new entries added
@@ -92778,22 +92837,23 @@
92837 ** Remove from the column cache any entries that were added since the
92838 ** the previous sqlite3ExprCachePush operation. In other words, restore
92839 ** the cache to the state it was in prior the most recent Push.
92840 */
92841 SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
92842 int i = 0;
 
92843 assert( pParse->iCacheLevel>=1 );
92844 pParse->iCacheLevel--;
92845 #ifdef SQLITE_DEBUG
92846 if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
92847 printf("POP to %d\n", pParse->iCacheLevel);
92848 }
92849 #endif
92850 while( i<pParse->nColCache ){
92851 if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
92852 cacheEntryClear(pParse, i);
92853 }else{
92854 i++;
92855 }
92856 }
92857 }
92858
92859 /*
@@ -92803,11 +92863,11 @@
92863 ** get them all.
92864 */
92865 static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
92866 int i;
92867 struct yColCache *p;
92868 for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
92869 if( p->iReg==iReg ){
92870 p->tempReg = 0;
92871 }
92872 }
92873 }
@@ -92881,12 +92941,12 @@
92941 ){
92942 Vdbe *v = pParse->pVdbe;
92943 int i;
92944 struct yColCache *p;
92945
92946 for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
92947 if( p->iTable==iTable && p->iColumn==iColumn ){
92948 p->lru = pParse->iCacheCnt++;
92949 sqlite3ExprCachePinRegister(pParse, p->iReg);
92950 return p->iReg;
92951 }
92952 }
@@ -92914,22 +92974,24 @@
92974 /*
92975 ** Clear all column cache entries.
92976 */
92977 SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
92978 int i;
 
92979
92980 #if SQLITE_DEBUG
92981 if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
92982 printf("CLEAR\n");
92983 }
92984 #endif
92985 for(i=0; i<pParse->nColCache; i++){
92986 if( pParse->aColCache[i].tempReg
92987 && pParse->nTempReg<ArraySize(pParse->aTempReg)
92988 ){
92989 pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
92990 }
92991 }
92992 pParse->nColCache = 0;
92993 }
92994
92995 /*
92996 ** Record the fact that an affinity change has occurred on iCount
92997 ** registers starting with iStart.
@@ -92957,11 +93019,11 @@
93019 ** and does not appear in a normal build.
93020 */
93021 static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
93022 int i;
93023 struct yColCache *p;
93024 for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
93025 int r = p->iReg;
93026 if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
93027 }
93028 return 0;
93029 }
@@ -94306,15 +94368,14 @@
94368 && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
94369 || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
94370 ){
94371 return 1;
94372 }
94373 if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
94374 Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
94375 testcase( pX!=pE1->pLeft );
94376 if( sqlite3ExprCompare(pX, pE2->pLeft, iTab)==0 ) return 1;
 
94377 }
94378 return 0;
94379 }
94380
94381 /*
@@ -94653,11 +94714,11 @@
94714 */
94715 SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
94716 if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
94717 int i;
94718 struct yColCache *p;
94719 for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
94720 if( p->iReg==iReg ){
94721 p->tempReg = 1;
94722 return;
94723 }
94724 }
@@ -97959,11 +98020,11 @@
98020 }else{
98021 sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
98022 return 1;
98023 }
98024 }
98025 if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break;
98026 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
98027 if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
98028 }else{
98029 if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
98030 }
@@ -98423,11 +98484,10 @@
98484 */
98485 v = sqlite3GetVdbe(pParse);
98486 assert( !pParse->isMultiWrite
98487 || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
98488 if( v ){
 
98489 sqlite3VdbeAddOp0(v, OP_Halt);
98490
98491 #if SQLITE_USER_AUTHENTICATION
98492 if( pParse->nTableLock>0 && db->init.busy==0 ){
98493 sqlite3UserAuthInit(db);
@@ -98450,18 +98510,20 @@
98510 ){
98511 int iDb, i;
98512 assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
98513 sqlite3VdbeJumpHere(v, 0);
98514 for(iDb=0; iDb<db->nDb; iDb++){
98515 Schema *pSchema;
98516 if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
98517 sqlite3VdbeUsesBtree(v, iDb);
98518 pSchema = db->aDb[iDb].pSchema;
98519 sqlite3VdbeAddOp4Int(v,
98520 OP_Transaction, /* Opcode */
98521 iDb, /* P1 */
98522 DbMaskTest(pParse->writeMask,iDb), /* P2 */
98523 pSchema->schema_cookie, /* P3 */
98524 pSchema->iGeneration /* P4 */
98525 );
98526 if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
98527 VdbeComment((v,
98528 "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
98529 }
@@ -98508,20 +98570,10 @@
98570 sqlite3VdbeMakeReady(v, pParse);
98571 pParse->rc = SQLITE_DONE;
98572 }else{
98573 pParse->rc = SQLITE_ERROR;
98574 }
 
 
 
 
 
 
 
 
 
 
98575 }
98576
98577 /*
98578 ** Run the parser and code generator recursively in order to generate
98579 ** code for the SQL statement given onto the end of the pParse context
@@ -98537,12 +98589,11 @@
98589 SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
98590 va_list ap;
98591 char *zSql;
98592 char *zErrMsg = 0;
98593 sqlite3 *db = pParse->db;
98594 char saveBuf[PARSE_TAIL_SZ];
 
98595
98596 if( pParse->nErr ) return;
98597 assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
98598 va_start(ap, zFormat);
98599 zSql = sqlite3VMPrintf(db, zFormat, ap);
@@ -98549,16 +98600,16 @@
98600 va_end(ap);
98601 if( zSql==0 ){
98602 return; /* A malloc must have failed */
98603 }
98604 pParse->nested++;
98605 memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
98606 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
98607 sqlite3RunParser(pParse, zSql, &zErrMsg);
98608 sqlite3DbFree(db, zErrMsg);
98609 sqlite3DbFree(db, zSql);
98610 memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
98611 pParse->nested--;
98612 }
98613
98614 #if SQLITE_USER_AUTHENTICATION
98615 /*
@@ -99735,10 +99786,13 @@
99786 ** This plan is not completely bullet-proof. It is possible for
99787 ** the schema to change multiple times and for the cookie to be
99788 ** set back to prior value. But schema changes are infrequent
99789 ** and the probability of hitting the same cookie value is only
99790 ** 1 chance in 2^32. So we're safe enough.
99791 **
99792 ** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
99793 ** the schema-version whenever the schema changes.
99794 */
99795 SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
99796 sqlite3 *db = pParse->db;
99797 Vdbe *v = pParse->pVdbe;
99798 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
@@ -102318,19 +102372,17 @@
102372 ** will occur at the end of the top-level VDBE and will be generated
102373 ** later, by sqlite3FinishCoding().
102374 */
102375 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
102376 Parse *pToplevel = sqlite3ParseToplevel(pParse);
 
102377
102378 assert( iDb>=0 && iDb<pParse->db->nDb );
102379 assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
102380 assert( iDb<SQLITE_MAX_ATTACHED+2 );
102381 assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
102382 if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
102383 DbMaskSet(pToplevel->cookieMask, iDb);
 
102384 if( !OMIT_TEMPDB && iDb==1 ){
102385 sqlite3OpenTempDatabase(pToplevel);
102386 }
102387 }
102388 }
@@ -107192,14 +107244,14 @@
107244 }else if( action==OE_SetDflt ){
107245 Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
107246 if( pDflt ){
107247 pNew = sqlite3ExprDup(db, pDflt, 0);
107248 }else{
107249 pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
107250 }
107251 }else{
107252 pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
107253 }
107254 pList = sqlite3ExprListAppend(pParse, pList, pNew);
107255 sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
107256 }
107257 }
@@ -109538,10 +109590,11 @@
109590 }
109591 if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
109592 sqlite3ReleaseTempReg(pParse, regRowid);
109593 sqlite3ReleaseTempReg(pParse, regData);
109594 if( emptyDestTest ){
109595 sqlite3AutoincrementEnd(pParse);
109596 sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
109597 sqlite3VdbeJumpHere(v, emptyDestTest);
109598 sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
109599 return 0;
109600 }else{
@@ -114034,22 +114087,18 @@
114087 int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
114088 Vdbe *pReprepare, /* VM being reprepared */
114089 sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
114090 const char **pzTail /* OUT: End of parsed string */
114091 ){
 
114092 char *zErrMsg = 0; /* Error message */
114093 int rc = SQLITE_OK; /* Result code */
114094 int i; /* Loop counter */
114095 Parse sParse; /* Parsing context */
114096
114097 memset(&sParse, 0, PARSE_HDR_SZ);
114098 memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
114099 sParse.pReprepare = pReprepare;
 
 
 
114100 assert( ppStmt && *ppStmt==0 );
114101 /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
114102 assert( sqlite3_mutex_held(db->mutex) );
114103
114104 /* Check to verify that it is possible to get a read lock on all
@@ -114089,12 +114138,11 @@
114138 }
114139 }
114140
114141 sqlite3VtabUnlockList(db);
114142
114143 sParse.db = db;
 
114144 if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
114145 char *zSqlCopy;
114146 int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
114147 testcase( nBytes==mxLen );
114148 testcase( nBytes==mxLen+1 );
@@ -114103,65 +114151,65 @@
114151 rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
114152 goto end_prepare;
114153 }
114154 zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
114155 if( zSqlCopy ){
114156 sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
114157 sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
114158 sqlite3DbFree(db, zSqlCopy);
114159 }else{
114160 sParse.zTail = &zSql[nBytes];
114161 }
114162 }else{
114163 sqlite3RunParser(&sParse, zSql, &zErrMsg);
114164 }
114165 assert( 0==sParse.nQueryLoop );
114166
114167 if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
114168 if( sParse.checkSchema ){
114169 schemaIsValid(&sParse);
114170 }
114171 if( db->mallocFailed ){
114172 sParse.rc = SQLITE_NOMEM_BKPT;
114173 }
114174 if( pzTail ){
114175 *pzTail = sParse.zTail;
114176 }
114177 rc = sParse.rc;
114178
114179 #ifndef SQLITE_OMIT_EXPLAIN
114180 if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
114181 static const char * const azColName[] = {
114182 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
114183 "selectid", "order", "from", "detail"
114184 };
114185 int iFirst, mx;
114186 if( sParse.explain==2 ){
114187 sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
114188 iFirst = 8;
114189 mx = 12;
114190 }else{
114191 sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
114192 iFirst = 0;
114193 mx = 8;
114194 }
114195 for(i=iFirst; i<mx; i++){
114196 sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
114197 azColName[i], SQLITE_STATIC);
114198 }
114199 }
114200 #endif
114201
114202 if( db->init.busy==0 ){
114203 Vdbe *pVdbe = sParse.pVdbe;
114204 sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
114205 }
114206 if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
114207 sqlite3VdbeFinalize(sParse.pVdbe);
114208 assert(!(*ppStmt));
114209 }else{
114210 *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
114211 }
114212
114213 if( zErrMsg ){
114214 sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
114215 sqlite3DbFree(db, zErrMsg);
@@ -114168,20 +114216,19 @@
114216 }else{
114217 sqlite3Error(db, rc);
114218 }
114219
114220 /* Delete any TriggerPrg structures allocated while parsing this statement. */
114221 while( sParse.pTriggerPrg ){
114222 TriggerPrg *pT = sParse.pTriggerPrg;
114223 sParse.pTriggerPrg = pT->pNext;
114224 sqlite3DbFree(db, pT);
114225 }
114226
114227 end_prepare:
114228
114229 sqlite3ParserReset(&sParse);
 
114230 rc = sqlite3ApiExit(db, rc);
114231 assert( (rc&db->errMask)==rc );
114232 return rc;
114233 }
114234 static int sqlite3LockAndPrepare(
@@ -115382,11 +115429,11 @@
115429 ** Allocate a KeyInfo object sufficient for an index of N key columns and
115430 ** X extra columns.
115431 */
115432 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
115433 int nExtra = (N+X)*(sizeof(CollSeq*)+1);
115434 KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
115435 if( p ){
115436 p->aSortOrder = (u8*)&p->aColl[N+X];
115437 p->nField = (u16)N;
115438 p->nXField = (u16)X;
115439 p->enc = ENC(db);
@@ -118072,16 +118119,17 @@
118119 pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
118120 if( subqueryIsAgg ){
118121 assert( pParent->pHaving==0 );
118122 pParent->pHaving = pParent->pWhere;
118123 pParent->pWhere = pWhere;
118124 pParent->pHaving = sqlite3ExprAnd(db,
118125 sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving
118126 );
118127 assert( pParent->pGroupBy==0 );
118128 pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
118129 }else{
118130 pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
118131 }
118132 substSelect(db, pParent, iParent, pSub->pEList, 0);
118133
118134 /* The flattened query is distinct if either the inner or the
118135 ** outer query is distinct.
@@ -122381,11 +122429,11 @@
122429 }
122430 #endif
122431
122432 sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
122433 sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
122434 sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
122435
122436 /* Begin a transaction and take an exclusive lock on the main database
122437 ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
122438 ** to ensure that we do not try to change the page-size on a WAL database.
122439 */
@@ -124041,24 +124089,24 @@
124089 ** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
124090 ** is only able to process joins with 64 or fewer tables.
124091 */
124092 struct WhereTerm {
124093 Expr *pExpr; /* Pointer to the subexpression that is this term */
124094 WhereClause *pWC; /* The clause this term is part of */
124095 LogEst truthProb; /* Probability of truth for this expression */
124096 u16 wtFlags; /* TERM_xxx bit flags. See below */
124097 u16 eOperator; /* A WO_xx value describing <op> */
124098 u8 nChild; /* Number of children that must disable us */
124099 u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
124100 int iParent; /* Disable pWC->a[iParent] when this term disabled */
124101 int leftCursor; /* Cursor number of X in "X <op> <expr>" */
124102 int iField; /* Field in (?,?,?) IN (SELECT...) vector */
124103 union {
124104 int leftColumn; /* Column number of X in "X <op> <expr>" */
124105 WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
124106 WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
124107 } u;
 
 
 
 
 
 
124108 Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
124109 Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
124110 };
124111
124112 /*
@@ -124207,29 +124255,29 @@
124255 struct WhereInfo {
124256 Parse *pParse; /* Parsing and code generating context */
124257 SrcList *pTabList; /* List of tables in the join */
124258 ExprList *pOrderBy; /* The ORDER BY clause or NULL */
124259 ExprList *pDistinctSet; /* DISTINCT over all these values */
 
 
 
124260 LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
124261 int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
124262 int iContinue; /* Jump here to continue with next record */
124263 int iBreak; /* Jump here to break out of the loop */
124264 int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
124265 u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
124266 u8 nLevel; /* Number of nested loop */
124267 i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
124268 u8 sorted; /* True if really sorted (not just grouped) */
124269 u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
124270 u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
124271 u8 eDistinct; /* One of the WHERE_DISTINCT_* values */
 
124272 u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */
124273 int iTop; /* The very beginning of the WHERE loop */
124274 WhereLoop *pLoops; /* List of all WhereLoop objects */
124275 Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
124276 LogEst nRowOut; /* Estimated number of output rows */
 
 
124277 WhereClause sWC; /* Decomposition of the WHERE clause */
124278 WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
124279 WhereLevel a[1]; /* Information about each nest loop in WHERE */
124280 };
124281
124282 /*
124283 ** Private interfaces - callable only by other where.c routines.
@@ -124689,11 +124737,10 @@
124737 **
124738 ** * the comparison will be performed with no affinity, or
124739 ** * the affinity change in zAff is guaranteed not to change the value.
124740 */
124741 static void updateRangeAffinityStr(
 
124742 Expr *pRight, /* RHS of comparison */
124743 int n, /* Number of vector elements in comparison */
124744 char *zAff /* Affinity string to modify */
124745 ){
124746 int i;
@@ -125775,15 +125822,15 @@
125822 assert( (bRev & ~1)==0 );
125823 pLevel->iLikeRepCntr <<=1;
125824 pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
125825 }
125826 #endif
125827 if( pRangeStart==0 ){
125828 j = pIdx->aiColumn[nEq];
125829 if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
125830 bSeekPastNull = 1;
125831 }
125832 }
125833 }
125834 assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
125835
125836 /* If we are doing a reverse order scan on an ascending index, or
@@ -125829,11 +125876,11 @@
125876 ){
125877 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
125878 VdbeCoverage(v);
125879 }
125880 if( zStartAff ){
125881 updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
125882 }
125883 nConstraint += nBtm;
125884 testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
125885 if( sqlite3ExprIsVector(pRight)==0 ){
125886 disableTerm(pLevel, pRangeStart);
@@ -125879,11 +125926,11 @@
125926 ){
125927 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
125928 VdbeCoverage(v);
125929 }
125930 if( zEndAff ){
125931 updateRangeAffinityStr(pRight, nTop, zEndAff);
125932 codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
125933 }else{
125934 assert( pParse->db->mallocFailed );
125935 }
125936 nConstraint += nTop;
@@ -126315,11 +126362,11 @@
126362 ** and we are coding the t1 loop and the t2 loop has not yet coded,
126363 ** then we cannot use the "t1.a=t2.b" constraint, but we can code
126364 ** the implied "t1.a=123" constraint.
126365 */
126366 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
126367 Expr *pE, sEAlt;
126368 WhereTerm *pAlt;
126369 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
126370 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
126371 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
126372 if( pTerm->leftCursor!=iCur ) continue;
@@ -126333,17 +126380,13 @@
126380 if( pAlt->wtFlags & (TERM_CODED) ) continue;
126381 testcase( pAlt->eOperator & WO_EQ );
126382 testcase( pAlt->eOperator & WO_IS );
126383 testcase( pAlt->eOperator & WO_IN );
126384 VdbeModuleComment((v, "begin transitive constraint"));
126385 sEAlt = *pAlt->pExpr;
126386 sEAlt.pLeft = pE->pLeft;
126387 sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
 
 
 
 
126388 }
126389
126390 /* For a LEFT OUTER JOIN, generate code that will record the fact that
126391 ** at least one row of the right table has matched the left table.
126392 */
@@ -126448,11 +126491,10 @@
126491 memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
126492 if( pOld!=pWC->aStatic ){
126493 sqlite3DbFree(db, pOld);
126494 }
126495 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
 
126496 }
126497 pTerm = &pWC->a[idx = pWC->nTerm++];
126498 if( p && ExprHasProperty(p, EP_Unlikely) ){
126499 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
126500 }else{
@@ -126460,10 +126502,12 @@
126502 }
126503 pTerm->pExpr = sqlite3ExprSkipCollate(p);
126504 pTerm->wtFlags = wtFlags;
126505 pTerm->pWC = pWC;
126506 pTerm->iParent = -1;
126507 memset(&pTerm->eOperator, 0,
126508 sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
126509 return idx;
126510 }
126511
126512 /*
126513 ** Return TRUE if the given operator is one of the operators that is
@@ -127568,10 +127612,11 @@
127612 Expr *pNew;
127613 Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
127614 Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
127615
127616 pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
127617 transferJoinMarkings(pNew, pExpr);
127618 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
127619 exprAnalyze(pSrc, pWC, idxNew);
127620 }
127621 pTerm = &pWC->a[idxTerm];
127622 pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
@@ -127618,11 +127663,11 @@
127663 int idxNew;
127664 WhereTerm *pNewTerm;
127665
127666 pNewExpr = sqlite3PExpr(pParse, TK_GT,
127667 sqlite3ExprDup(db, pLeft, 0),
127668 sqlite3ExprAlloc(db, TK_NULL, 0, 0), 0);
127669
127670 idxNew = whereClauseInsert(pWC, pNewExpr,
127671 TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
127672 if( idxNew ){
127673 pNewTerm = &pWC->a[idxNew];
@@ -127796,11 +127841,11 @@
127841 if( k>=pTab->nCol ){
127842 sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
127843 pTab->zName, j);
127844 return;
127845 }
127846 pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
127847 if( pColRef==0 ) return;
127848 pColRef->iTable = pItem->iCursor;
127849 pColRef->iColumn = k++;
127850 pColRef->pTab = pTab;
127851 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
@@ -128009,15 +128054,17 @@
128054 Expr *pX; /* An expression being tested */
128055 WhereClause *pWC; /* Shorthand for pScan->pWC */
128056 WhereTerm *pTerm; /* The term being tested */
128057 int k = pScan->k; /* Where to start scanning */
128058
128059 assert( pScan->iEquiv<=pScan->nEquiv );
128060 pWC = pScan->pWC;
128061 while(1){
128062 iColumn = pScan->aiColumn[pScan->iEquiv-1];
128063 iCur = pScan->aiCur[pScan->iEquiv-1];
128064 assert( pWC!=0 );
128065 do{
128066 for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
128067 if( pTerm->leftCursor==iCur
128068 && pTerm->u.leftColumn==iColumn
128069 && (iColumn!=XN_EXPR
128070 || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
@@ -128063,19 +128110,21 @@
128110 && pX->iColumn==pScan->aiColumn[0]
128111 ){
128112 testcase( pTerm->eOperator & WO_IS );
128113 continue;
128114 }
128115 pScan->pWC = pWC;
128116 pScan->k = k+1;
128117 return pTerm;
128118 }
128119 }
128120 }
128121 pWC = pWC->pOuter;
128122 k = 0;
128123 }while( pWC!=0 );
128124 if( pScan->iEquiv>=pScan->nEquiv ) break;
128125 pWC = pScan->pOrigWC;
128126 k = 0;
128127 pScan->iEquiv++;
128128 }
128129 return 0;
128130 }
@@ -128105,28 +128154,28 @@
128154 int iCur, /* Cursor to scan for */
128155 int iColumn, /* Column to scan for */
128156 u32 opMask, /* Operator(s) to scan for */
128157 Index *pIdx /* Must be compatible with this index */
128158 ){
 
 
 
128159 pScan->pOrigWC = pWC;
128160 pScan->pWC = pWC;
128161 pScan->pIdxExpr = 0;
128162 pScan->idxaff = 0;
128163 pScan->zCollName = 0;
128164 if( pIdx ){
128165 int j = iColumn;
128166 iColumn = pIdx->aiColumn[j];
128167 if( iColumn==XN_EXPR ){
128168 pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
128169 }else if( iColumn==pIdx->pTable->iPKey ){
128170 iColumn = XN_ROWID;
128171 }else if( iColumn>=0 ){
128172 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
128173 pScan->zCollName = pIdx->azColl[j];
128174 }
128175 }else if( iColumn==XN_EXPR ){
128176 return 0;
128177 }
128178 pScan->opMask = opMask;
128179 pScan->k = 0;
128180 pScan->aiCur[0] = iCur;
128181 pScan->aiColumn[0] = iColumn;
@@ -130034,11 +130083,11 @@
130083 ** CREATE INDEX ... ON (a, b, c, d, e)
130084 **
130085 ** then this function would be invoked with nEq=1. The value returned in
130086 ** this case is 3.
130087 */
130088 static int whereRangeVectorLen(
130089 Parse *pParse, /* Parsing context */
130090 int iCur, /* Cursor open on pIdx */
130091 Index *pIdx, /* The index to be used for a inequality constraint */
130092 int nEq, /* Number of prior equality constraints on same index */
130093 WhereTerm *pTerm /* The vector inequality constraint */
@@ -131480,11 +131529,11 @@
131529 if( rev ) *pRevMask |= MASKBIT(iLoop);
131530 revSet = 1;
131531 }
131532 }
131533 if( isMatch ){
131534 if( iColumn==XN_ROWID ){
131535 testcase( distinctColumns==0 );
131536 distinctColumns = 1;
131537 }
131538 obSat |= MASKBIT(i);
131539 }else{
@@ -131935,17 +131984,24 @@
131984 }else{
131985 pWInfo->nOBSat = pFrom->isOrdered;
131986 pWInfo->revMask = pFrom->revLoop;
131987 if( pWInfo->nOBSat<=0 ){
131988 pWInfo->nOBSat = 0;
131989 if( nLoop>0 ){
131990 u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
131991 if( (wsFlags & WHERE_ONEROW)==0
131992 && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
131993 ){
131994 Bitmask m = 0;
131995 int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
131996 WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
131997 testcase( wsFlags & WHERE_IPK );
131998 testcase( wsFlags & WHERE_COLUMN_IN );
131999 if( rc==pWInfo->pOrderBy->nExpr ){
132000 pWInfo->bOrderedInnerLoop = 1;
132001 pWInfo->revMask = m;
132002 }
132003 }
132004 }
132005 }
132006 }
132007 if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
@@ -132218,26 +132274,29 @@
132274 ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
132275 ** field (type Bitmask) it must be aligned on an 8-byte boundary on
132276 ** some architectures. Hence the ROUND8() below.
132277 */
132278 nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
132279 pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
132280 if( db->mallocFailed ){
132281 sqlite3DbFree(db, pWInfo);
132282 pWInfo = 0;
132283 goto whereBeginError;
132284 }
 
 
132285 pWInfo->pParse = pParse;
132286 pWInfo->pTabList = pTabList;
132287 pWInfo->pOrderBy = pOrderBy;
132288 pWInfo->pDistinctSet = pDistinctSet;
132289 pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
132290 pWInfo->nLevel = nTabList;
132291 pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
132292 pWInfo->wctrlFlags = wctrlFlags;
132293 pWInfo->iLimit = iAuxArg;
132294 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
132295 memset(&pWInfo->nOBSat, 0,
132296 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
132297 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
132298 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
132299 pMaskSet = &pWInfo->sMaskSet;
132300 sWLB.pWInfo = pWInfo;
132301 sWLB.pWC = &pWInfo->sWC;
132302 sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
@@ -132661,17 +132720,19 @@
132720 pLevel->addrLikeRep);
132721 VdbeCoverage(v);
132722 }
132723 #endif
132724 if( pLevel->iLeftJoin ){
132725 int ws = pLoop->wsFlags;
132726 addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
132727 assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
132728 if( (ws & WHERE_IDX_ONLY)==0 ){
 
132729 sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
132730 }
132731 if( (ws & WHERE_INDEXED)
132732 || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
132733 ){
132734 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
132735 }
132736 if( pLevel->op==OP_Return ){
132737 sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
132738 }else{
@@ -132844,19 +132905,10 @@
132905 struct LimitVal {
132906 Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
132907 Expr *pOffset; /* The OFFSET expression. NULL if there is none */
132908 };
132909
 
 
 
 
 
 
 
 
 
132910 /*
132911 ** An instance of the following structure describes the event of a
132912 ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
132913 ** TK_DELETE, or TK_INSTEAD. If the event is of the form
132914 **
@@ -132864,15 +132916,10 @@
132916 **
132917 ** Then the "b" IdList records the list "a,b,c".
132918 */
132919 struct TrigEvent { int a; IdList * b; };
132920
 
 
 
 
 
132921 /*
132922 ** Disable lookaside memory allocation for objects that might be
132923 ** shared across database connections.
132924 */
132925 static void disableLookaside(Parse *pParse){
@@ -132915,11 +132962,28 @@
132962 /* Construct a new Expr object from a single identifier. Use the
132963 ** new Expr to populate pOut. Set the span of pOut to be the identifier
132964 ** that created the expression.
132965 */
132966 static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
132967 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
132968 if( p ){
132969 memset(p, 0, sizeof(Expr));
132970 p->op = (u8)op;
132971 p->flags = EP_Leaf;
132972 p->iAgg = -1;
132973 p->u.zToken = (char*)&p[1];
132974 memcpy(p->u.zToken, t.z, t.n);
132975 p->u.zToken[t.n] = 0;
132976 if( sqlite3Isquote(p->u.zToken[0]) ){
132977 if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
132978 sqlite3Dequote(p->u.zToken);
132979 }
132980 #if SQLITE_MAX_EXPR_DEPTH>0
132981 p->nHeight = 1;
132982 #endif
132983 }
132984 pOut->pExpr = p;
132985 pOut->zStart = t.z;
132986 pOut->zEnd = &t.z[t.n];
132987 }
132988
132989 /* This routine constructs a binary expression node out of two ExprSpan
@@ -133078,11 +133142,10 @@
133142 Select* yy243;
133143 IdList* yy254;
133144 With* yy285;
133145 struct TrigEvent yy332;
133146 struct LimitVal yy354;
 
133147 struct {int value; int mask;} yy497;
133148 } YYMINORTYPE;
133149 #ifndef YYSTACKDEPTH
133150 #define YYSTACKDEPTH 100
133151 #endif
@@ -133090,19 +133153,19 @@
133153 #define sqlite3ParserARG_PDECL ,Parse *pParse
133154 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
133155 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
133156 #define YYFALLBACK 1
133157 #define YYNSTATE 456
133158 #define YYNRULE 332
133159 #define YY_MAX_SHIFT 455
133160 #define YY_MIN_SHIFTREDUCE 668
133161 #define YY_MAX_SHIFTREDUCE 999
133162 #define YY_MIN_REDUCE 1000
133163 #define YY_MAX_REDUCE 1331
133164 #define YY_ERROR_ACTION 1332
133165 #define YY_ACCEPT_ACTION 1333
133166 #define YY_NO_ACTION 1334
133167 /************* End control #defines *******************************************/
133168
133169 /* Define the yytestcase() macro to be a no-op if is not already defined
133170 ** otherwise.
133171 **
@@ -133170,170 +133233,169 @@
133233 ** yy_reduce_ofst[] For each state, the offset into yy_action for
133234 ** shifting non-terminals after a reduce.
133235 ** yy_default[] Default action for each state.
133236 **
133237 *********** Begin parsing tables **********************************************/
133238 #define YY_ACTTAB_COUNT (1567)
133239 static const YYACTIONTYPE yy_action[] = {
133240 /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100,
133241 /* 10 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98,
133242 /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95,
133243 /* 30 */ 94, 94, 94, 93, 351, 325, 977, 977, 824, 824,
133244 /* 40 */ 826, 947, 354, 99, 100, 90, 842, 842, 854, 857,
133245 /* 50 */ 846, 846, 97, 97, 98, 98, 98, 98, 338, 96,
133246 /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
133247 /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 977, 977,
133248 /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100,
133249 /* 90 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98,
133250 /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95,
133251 /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325,
133252 /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90,
133253 /* 130 */ 842, 842, 854, 857, 846, 846, 97, 97, 98, 98,
133254 /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94,
133255 /* 150 */ 94, 94, 93, 351, 958, 958, 325, 268, 428, 413,
133256 /* 160 */ 411, 61, 752, 752, 99, 100, 90, 842, 842, 854,
133257 /* 170 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 60,
133258 /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133259 /* 190 */ 351, 325, 270, 329, 273, 277, 959, 960, 250, 99,
133260 /* 200 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133261 /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95,
133262 /* 220 */ 95, 94, 94, 94, 93, 351, 325, 938, 1326, 698,
133263 /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 842, 842, 854,
133264 /* 240 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 347,
133265 /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133266 /* 260 */ 351, 325, 938, 1327, 384, 699, 1327, 381, 379, 99,
133267 /* 270 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133268 /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95,
133269 /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178,
133270 /* 300 */ 833, 936, 373, 700, 99, 100, 90, 842, 842, 854,
133271 /* 310 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 375,
133272 /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133273 /* 330 */ 351, 325, 1276, 947, 354, 818, 936, 739, 739, 99,
133274 /* 340 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133275 /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95,
133276 /* 360 */ 95, 94, 94, 94, 93, 351, 325, 969, 227, 92,
133277 /* 370 */ 89, 178, 373, 300, 99, 100, 90, 842, 842, 854,
133278 /* 380 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 921,
133279 /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133280 /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99,
133281 /* 410 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
133282 /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95,
133283 /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 958,
133284 /* 440 */ 958, 158, 25, 422, 99, 100, 90, 842, 842, 854,
133285 /* 450 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 450,
133286 /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133287 /* 470 */ 351, 443, 224, 224, 420, 958, 958, 962, 325, 52,
133288 /* 480 */ 52, 959, 960, 176, 415, 78, 99, 100, 90, 842,
133289 /* 490 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98,
133290 /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94,
133291 /* 510 */ 94, 93, 351, 325, 428, 418, 298, 959, 960, 962,
133292 /* 520 */ 81, 99, 88, 90, 842, 842, 854, 857, 846, 846,
133293 /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96,
133294 /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 843,
133295 /* 550 */ 843, 855, 858, 996, 318, 343, 379, 100, 90, 842,
133296 /* 560 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98,
133297 /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94,
133298 /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340,
133299 /* 590 */ 929, 52, 52, 90, 842, 842, 854, 857, 846, 846,
133300 /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96,
133301 /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445,
133302 /* 620 */ 847, 3, 1203, 361, 360, 378, 344, 813, 958, 958,
133303 /* 630 */ 1300, 86, 445, 729, 3, 212, 169, 287, 405, 282,
133304 /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245,
133305 /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83,
133306 /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246,
133307 /* 670 */ 959, 960, 194, 455, 670, 402, 399, 398, 448, 243,
133308 /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224,
133309 /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427,
133310 /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452,
133311 /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1271,
133312 /* 720 */ 1271, 23, 958, 958, 86, 445, 397, 3, 228, 429,
133313 /* 730 */ 895, 824, 824, 826, 827, 19, 203, 720, 52, 52,
133314 /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229,
133315 /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85,
133316 /* 760 */ 352, 352, 120, 157, 959, 960, 58, 977, 409, 355,
133317 /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86,
133318 /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96,
133319 /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
133320 /* 800 */ 832, 120, 452, 451, 813, 887, 819, 83, 84, 977,
133321 /* 810 */ 813, 132, 410, 920, 85, 352, 352, 132, 407, 789,
133322 /* 820 */ 958, 958, 92, 89, 178, 917, 448, 262, 370, 261,
133323 /* 830 */ 82, 914, 80, 262, 370, 261, 776, 824, 824, 826,
133324 /* 840 */ 827, 19, 934, 434, 96, 96, 96, 96, 95, 95,
133325 /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 958,
133326 /* 860 */ 958, 819, 959, 960, 120, 92, 89, 178, 945, 2,
133327 /* 870 */ 918, 965, 268, 1, 976, 76, 445, 762, 3, 708,
133328 /* 880 */ 901, 901, 387, 958, 958, 757, 919, 371, 740, 778,
133329 /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450,
133330 /* 900 */ 24, 959, 960, 83, 84, 369, 958, 958, 177, 226,
133331 /* 910 */ 85, 352, 352, 885, 315, 314, 313, 215, 311, 10,
133332 /* 920 */ 10, 683, 448, 349, 348, 959, 960, 909, 777, 157,
133333 /* 930 */ 120, 958, 958, 337, 776, 416, 711, 310, 450, 434,
133334 /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 959, 960,
133335 /* 950 */ 908, 832, 792, 452, 451, 9, 9, 819, 10, 10,
133336 /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171,
133337 /* 970 */ 170, 167, 339, 959, 960, 247, 984, 702, 702, 450,
133338 /* 980 */ 715, 233, 686, 982, 889, 983, 182, 914, 824, 824,
133339 /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10,
133340 /* 1000 */ 10, 889, 891, 749, 958, 958, 917, 268, 985, 198,
133341 /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825,
133342 /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91,
133343 /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
133344 /* 1040 */ 351, 157, 810, 371, 382, 359, 959, 960, 358, 268,
133345 /* 1050 */ 450, 918, 368, 324, 824, 824, 826, 450, 709, 450,
133346 /* 1060 */ 264, 380, 889, 450, 877, 746, 253, 919, 255, 433,
133347 /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12,
133348 /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162,
133349 /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450,
133350 /* 1100 */ 709, 1210, 450, 132, 450, 39, 39, 450, 40, 40,
133351 /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28,
133352 /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450,
133353 /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767,
133354 /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47,
133355 /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172,
133356 /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122,
133357 /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 898, 56, 56,
133358 /* 1180 */ 450, 897, 35, 35, 450, 267, 450, 817, 450, 817,
133359 /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817,
133360 /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119,
133361 /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111,
133362 /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 912,
133363 /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331,
133364 /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 937, 197,
133365 /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436,
133366 /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 933,
133367 /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202,
133368 /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 884,
133369 /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74,
133370 /* 1300 */ 726, 727, 785, 783, 880, 202, 999, 208, 894, 893,
133371 /* 1310 */ 894, 893, 694, 816, 763, 116, 774, 1290, 431, 432,
133372 /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289,
133373 /* 1330 */ 679, 884, 681, 952, 291, 218, 293, 7, 316, 828,
133374 /* 1340 */ 173, 805, 259, 364, 252, 911, 376, 713, 295, 435,
133375 /* 1350 */ 308, 168, 955, 993, 135, 400, 990, 284, 882, 881,
133376 /* 1360 */ 205, 928, 926, 59, 333, 62, 144, 156, 130, 72,
133377 /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383,
133378 /* 1380 */ 67, 896, 140, 141, 142, 148, 389, 812, 775, 266,
133379 /* 1390 */ 219, 190, 154, 391, 913, 876, 271, 406, 191, 322,
133380 /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421,
133381 /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346,
133382 /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 967, 239,
133383 /* 1430 */ 769, 102, 862, 438, 426, 240, 424, 442, 73, 213,
133384 /* 1440 */ 688, 238, 22, 453, 953, 214, 217, 216, 454, 677,
133385 /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166,
133386 /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 892,
133387 /* 1470 */ 327, 890, 811, 328, 134, 128, 136, 138, 743, 258,
133388 /* 1480 */ 907, 184, 143, 129, 910, 186, 63, 64, 145, 187,
133389 /* 1490 */ 906, 65, 8, 66, 13, 188, 202, 899, 265, 149,
133390 /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396,
133391 /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131,
133392 /* 1520 */ 830, 860, 70, 751, 16, 414, 755, 4, 174, 220,
133393 /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 875,
133394 /* 1540 */ 861, 859, 916, 864, 915, 207, 206, 942, 163, 437,
133395 /* 1550 */ 948, 943, 164, 209, 1002, 441, 863, 165, 210, 829,
133396 /* 1560 */ 695, 87, 312, 211, 1292, 1291, 309,
 
133397 };
133398 static const YYCODETYPE yy_lookahead[] = {
133399 /* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28,
133400 /* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
133401 /* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
@@ -133415,87 +133477,86 @@
133477 /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43,
133478 /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
133479 /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97,
133480 /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175,
133481 /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110,
133482 /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134,
133483 /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48,
133484 /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55,
133485 /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147,
133486 /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179,
133487 /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124,
133488 /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152,
133489 /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5,
133490 /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172,
133491 /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152,
133492 /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83,
133493 /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98,
133494 /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173,
133495 /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47,
133496 /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152,
133497 /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133,
133498 /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172,
133499 /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30,
133500 /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97,
133501 /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42,
133502 /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
133503 /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152,
133504 /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152,
133505 /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75,
133506 /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172,
133507 /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24,
133508 /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152,
133509 /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173,
133510 /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172,
133511 /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152,
133512 /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213,
133513 /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172,
133514 /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26,
133515 /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173,
133516 /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173,
133517 /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152,
133518 /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152,
133519 /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173,
133520 /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173,
133521 /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163,
133522 /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167,
133523 /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108,
133524 /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163,
133525 /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23,
133526 /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26,
133527 /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55,
133528 /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26,
133529 /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132,
133530 /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191,
133531 /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210,
133532 /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97,
133533 /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227,
133534 /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175,
133535 /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130,
133536 /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159,
133537 /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235,
133538 /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177,
133539 /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125,
133540 /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53,
133541 /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229,
133542 /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25,
133543 /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151,
133544 /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22,
133545 /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23,
133546 /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16,
133547 /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122,
133548 /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80,
133549 /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79,
133550 /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68,
133551 /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23,
133552 /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23,
133553 /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24,
133554 /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23,
133555 /* 1560 */ 23, 22, 15, 122, 122, 122, 23,
 
133556 };
133557 #define YY_SHIFT_USE_DFLT (1567)
133558 #define YY_SHIFT_COUNT (455)
133559 #define YY_SHIFT_MIN (-94)
133560 #define YY_SHIFT_MAX (1549)
133561 static const short yy_shift_ofst[] = {
133562 /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19,
@@ -133507,132 +133568,132 @@
133568 /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133569 /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133570 /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133571 /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760,
133572 /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746,
133573 /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73,
133574 /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99,
133575 /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949,
133576 /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
133577 /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113,
133578 /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922,
133579 /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949,
133580 /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
133581 /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949,
133582 /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949,
133583 /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118,
133584 /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418,
133585 /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882,
133586 /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238,
133587 /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239,
133588 /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238,
133589 /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290,
133590 /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304,
133591 /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280,
133592 /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414,
133593 /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567,
133594 /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104,
133595 /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273,
133596 /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177,
133597 /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452,
133598 /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479,
133599 /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367,
133600 /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429,
133601 /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491,
133602 /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498,
133603 /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475,
133604 /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517,
133605 /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527,
133606 /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436,
133607 /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549,
133608 };
133609 #define YY_REDUCE_USE_DFLT (-130)
133610 #define YY_REDUCE_COUNT (324)
133611 #define YY_REDUCE_MIN (-129)
133612 #define YY_REDUCE_MAX (1300)
133613 static const short yy_reduce_ofst[] = {
133614 /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435,
133615 /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790,
133616 /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76,
133617 /* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
133618 /* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
133619 /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898,
133620 /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950,
133621 /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984,
133622 /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021,
133623 /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062,
133624 /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76,
133625 /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76,
133626 /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220,
133627 /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620,
133628 /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047,
133629 /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808,
133630 /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57,
133631 /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438,
133632 /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908,
133633 /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101,
133634 /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171,
133635 /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102,
133636 /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130,
133637 /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183,
133638 /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205,
133639 /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193,
133640 /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231,
133641 /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232,
133642 /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201,
133643 /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215,
133644 /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278,
133645 /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228,
133646 /* 320 */ 1288, 1291, 1276, 1277, 1295,
133647 };
133648 static const YYACTIONTYPE yy_default[] = {
133649 /* 0 */ 1281, 1271, 1271, 1271, 1203, 1203, 1203, 1203, 1271, 1096,
133650 /* 10 */ 1125, 1125, 1255, 1332, 1332, 1332, 1332, 1332, 1332, 1202,
133651 /* 20 */ 1332, 1332, 1332, 1332, 1271, 1100, 1131, 1332, 1332, 1332,
133652 /* 30 */ 1332, 1204, 1205, 1332, 1332, 1332, 1254, 1256, 1141, 1140,
133653 /* 40 */ 1139, 1138, 1237, 1112, 1136, 1129, 1133, 1204, 1198, 1199,
133654 /* 50 */ 1197, 1201, 1205, 1332, 1132, 1167, 1182, 1166, 1332, 1332,
133655 /* 60 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133656 /* 70 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133657 /* 80 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133658 /* 90 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133659 /* 100 */ 1332, 1332, 1332, 1332, 1176, 1181, 1188, 1180, 1177, 1169,
133660 /* 110 */ 1168, 1170, 1171, 1332, 1019, 1067, 1332, 1332, 1332, 1172,
133661 /* 120 */ 1332, 1173, 1185, 1184, 1183, 1262, 1289, 1288, 1332, 1332,
133662 /* 130 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133663 /* 140 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133664 /* 150 */ 1332, 1332, 1332, 1332, 1332, 1281, 1271, 1025, 1025, 1332,
133665 /* 160 */ 1271, 1271, 1271, 1271, 1271, 1271, 1267, 1100, 1091, 1332,
133666 /* 170 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133667 /* 180 */ 1259, 1257, 1332, 1218, 1332, 1332, 1332, 1332, 1332, 1332,
133668 /* 190 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133669 /* 200 */ 1332, 1332, 1332, 1332, 1096, 1332, 1332, 1332, 1332, 1332,
133670 /* 210 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1283, 1332, 1232,
133671 /* 220 */ 1096, 1096, 1096, 1098, 1080, 1090, 1004, 1135, 1114, 1114,
133672 /* 230 */ 1321, 1135, 1321, 1042, 1303, 1039, 1125, 1114, 1200, 1125,
133673 /* 240 */ 1125, 1097, 1090, 1332, 1324, 1105, 1105, 1323, 1323, 1105,
133674 /* 250 */ 1146, 1070, 1135, 1076, 1076, 1076, 1076, 1105, 1016, 1135,
133675 /* 260 */ 1146, 1070, 1070, 1135, 1105, 1016, 1236, 1318, 1105, 1105,
133676 /* 270 */ 1016, 1211, 1105, 1016, 1105, 1016, 1211, 1068, 1068, 1068,
133677 /* 280 */ 1057, 1211, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
133678 /* 290 */ 1118, 1113, 1118, 1113, 1118, 1113, 1105, 1206, 1105, 1332,
133679 /* 300 */ 1211, 1215, 1215, 1211, 1130, 1119, 1128, 1126, 1135, 1022,
133680 /* 310 */ 1060, 1286, 1286, 1282, 1282, 1282, 1282, 1329, 1329, 1267,
133681 /* 320 */ 1298, 1298, 1044, 1044, 1298, 1332, 1332, 1332, 1332, 1332,
133682 /* 330 */ 1332, 1293, 1332, 1220, 1332, 1332, 1332, 1332, 1332, 1332,
133683 /* 340 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133684 /* 350 */ 1332, 1332, 1152, 1332, 1000, 1264, 1332, 1332, 1263, 1332,
133685 /* 360 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133686 /* 370 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1320,
133687 /* 380 */ 1332, 1332, 1332, 1332, 1332, 1332, 1235, 1234, 1332, 1332,
133688 /* 390 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133689 /* 400 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
133690 /* 410 */ 1332, 1082, 1332, 1332, 1332, 1307, 1332, 1332, 1332, 1332,
133691 /* 420 */ 1332, 1332, 1332, 1127, 1332, 1120, 1332, 1332, 1311, 1332,
133692 /* 430 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1273,
133693 /* 440 */ 1332, 1332, 1332, 1272, 1332, 1332, 1332, 1332, 1332, 1154,
133694 /* 450 */ 1332, 1153, 1157, 1332, 1010, 1332,
133695 };
133696 /********** End of lemon-generated parsing tables *****************************/
133697
133698 /* The next table maps tokens (terminal symbols) into fallback tokens.
133699 ** If a construct like the following:
@@ -133862,11 +133923,11 @@
133923 "DEFERRABLE", "FOREIGN", "DROP", "UNION",
133924 "ALL", "EXCEPT", "INTERSECT", "SELECT",
133925 "VALUES", "DISTINCT", "DOT", "FROM",
133926 "JOIN", "USING", "ORDER", "GROUP",
133927 "HAVING", "LIMIT", "WHERE", "INTO",
133928 "FLOAT", "BLOB", "INTEGER", "VARIABLE",
133929 "CASE", "WHEN", "THEN", "ELSE",
133930 "INDEX", "ALTER", "ADD", "error",
133931 "input", "cmdlist", "ecmd", "explain",
133932 "cmdx", "cmd", "transtype", "trans_opt",
133933 "nm", "savepoint_opt", "create_table", "create_table_args",
@@ -134055,185 +134116,186 @@
134116 /* 151 */ "term ::= NULL",
134117 /* 152 */ "expr ::= ID|INDEXED",
134118 /* 153 */ "expr ::= JOIN_KW",
134119 /* 154 */ "expr ::= nm DOT nm",
134120 /* 155 */ "expr ::= nm DOT nm DOT nm",
134121 /* 156 */ "term ::= FLOAT|BLOB",
134122 /* 157 */ "term ::= STRING",
134123 /* 158 */ "term ::= INTEGER",
134124 /* 159 */ "expr ::= VARIABLE",
134125 /* 160 */ "expr ::= expr COLLATE ID|STRING",
134126 /* 161 */ "expr ::= CAST LP expr AS typetoken RP",
134127 /* 162 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
134128 /* 163 */ "expr ::= ID|INDEXED LP STAR RP",
134129 /* 164 */ "term ::= CTIME_KW",
134130 /* 165 */ "expr ::= LP nexprlist COMMA expr RP",
134131 /* 166 */ "expr ::= expr AND expr",
134132 /* 167 */ "expr ::= expr OR expr",
134133 /* 168 */ "expr ::= expr LT|GT|GE|LE expr",
134134 /* 169 */ "expr ::= expr EQ|NE expr",
134135 /* 170 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
134136 /* 171 */ "expr ::= expr PLUS|MINUS expr",
134137 /* 172 */ "expr ::= expr STAR|SLASH|REM expr",
134138 /* 173 */ "expr ::= expr CONCAT expr",
134139 /* 174 */ "likeop ::= LIKE_KW|MATCH",
134140 /* 175 */ "likeop ::= NOT LIKE_KW|MATCH",
134141 /* 176 */ "expr ::= expr likeop expr",
134142 /* 177 */ "expr ::= expr likeop expr ESCAPE expr",
134143 /* 178 */ "expr ::= expr ISNULL|NOTNULL",
134144 /* 179 */ "expr ::= expr NOT NULL",
134145 /* 180 */ "expr ::= expr IS expr",
134146 /* 181 */ "expr ::= expr IS NOT expr",
134147 /* 182 */ "expr ::= NOT expr",
134148 /* 183 */ "expr ::= BITNOT expr",
134149 /* 184 */ "expr ::= MINUS expr",
134150 /* 185 */ "expr ::= PLUS expr",
134151 /* 186 */ "between_op ::= BETWEEN",
134152 /* 187 */ "between_op ::= NOT BETWEEN",
134153 /* 188 */ "expr ::= expr between_op expr AND expr",
134154 /* 189 */ "in_op ::= IN",
134155 /* 190 */ "in_op ::= NOT IN",
134156 /* 191 */ "expr ::= expr in_op LP exprlist RP",
134157 /* 192 */ "expr ::= LP select RP",
134158 /* 193 */ "expr ::= expr in_op LP select RP",
134159 /* 194 */ "expr ::= expr in_op nm dbnm paren_exprlist",
134160 /* 195 */ "expr ::= EXISTS LP select RP",
134161 /* 196 */ "expr ::= CASE case_operand case_exprlist case_else END",
134162 /* 197 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
134163 /* 198 */ "case_exprlist ::= WHEN expr THEN expr",
134164 /* 199 */ "case_else ::= ELSE expr",
134165 /* 200 */ "case_else ::=",
134166 /* 201 */ "case_operand ::= expr",
134167 /* 202 */ "case_operand ::=",
134168 /* 203 */ "exprlist ::=",
134169 /* 204 */ "nexprlist ::= nexprlist COMMA expr",
134170 /* 205 */ "nexprlist ::= expr",
134171 /* 206 */ "paren_exprlist ::=",
134172 /* 207 */ "paren_exprlist ::= LP exprlist RP",
134173 /* 208 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
134174 /* 209 */ "uniqueflag ::= UNIQUE",
134175 /* 210 */ "uniqueflag ::=",
134176 /* 211 */ "eidlist_opt ::=",
134177 /* 212 */ "eidlist_opt ::= LP eidlist RP",
134178 /* 213 */ "eidlist ::= eidlist COMMA nm collate sortorder",
134179 /* 214 */ "eidlist ::= nm collate sortorder",
134180 /* 215 */ "collate ::=",
134181 /* 216 */ "collate ::= COLLATE ID|STRING",
134182 /* 217 */ "cmd ::= DROP INDEX ifexists fullname",
134183 /* 218 */ "cmd ::= VACUUM",
134184 /* 219 */ "cmd ::= VACUUM nm",
134185 /* 220 */ "cmd ::= PRAGMA nm dbnm",
134186 /* 221 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
134187 /* 222 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
134188 /* 223 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
134189 /* 224 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
134190 /* 225 */ "plus_num ::= PLUS INTEGER|FLOAT",
134191 /* 226 */ "minus_num ::= MINUS INTEGER|FLOAT",
134192 /* 227 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
134193 /* 228 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
134194 /* 229 */ "trigger_time ::= BEFORE",
134195 /* 230 */ "trigger_time ::= AFTER",
134196 /* 231 */ "trigger_time ::= INSTEAD OF",
134197 /* 232 */ "trigger_time ::=",
134198 /* 233 */ "trigger_event ::= DELETE|INSERT",
134199 /* 234 */ "trigger_event ::= UPDATE",
134200 /* 235 */ "trigger_event ::= UPDATE OF idlist",
134201 /* 236 */ "when_clause ::=",
134202 /* 237 */ "when_clause ::= WHEN expr",
134203 /* 238 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
134204 /* 239 */ "trigger_cmd_list ::= trigger_cmd SEMI",
134205 /* 240 */ "trnm ::= nm DOT nm",
134206 /* 241 */ "tridxby ::= INDEXED BY nm",
134207 /* 242 */ "tridxby ::= NOT INDEXED",
134208 /* 243 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
134209 /* 244 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
134210 /* 245 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
134211 /* 246 */ "trigger_cmd ::= select",
134212 /* 247 */ "expr ::= RAISE LP IGNORE RP",
134213 /* 248 */ "expr ::= RAISE LP raisetype COMMA nm RP",
134214 /* 249 */ "raisetype ::= ROLLBACK",
134215 /* 250 */ "raisetype ::= ABORT",
134216 /* 251 */ "raisetype ::= FAIL",
134217 /* 252 */ "cmd ::= DROP TRIGGER ifexists fullname",
134218 /* 253 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
134219 /* 254 */ "cmd ::= DETACH database_kw_opt expr",
134220 /* 255 */ "key_opt ::=",
134221 /* 256 */ "key_opt ::= KEY expr",
134222 /* 257 */ "cmd ::= REINDEX",
134223 /* 258 */ "cmd ::= REINDEX nm dbnm",
134224 /* 259 */ "cmd ::= ANALYZE",
134225 /* 260 */ "cmd ::= ANALYZE nm dbnm",
134226 /* 261 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
134227 /* 262 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
134228 /* 263 */ "add_column_fullname ::= fullname",
134229 /* 264 */ "cmd ::= create_vtab",
134230 /* 265 */ "cmd ::= create_vtab LP vtabarglist RP",
134231 /* 266 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
134232 /* 267 */ "vtabarg ::=",
134233 /* 268 */ "vtabargtoken ::= ANY",
134234 /* 269 */ "vtabargtoken ::= lp anylist RP",
134235 /* 270 */ "lp ::= LP",
134236 /* 271 */ "with ::=",
134237 /* 272 */ "with ::= WITH wqlist",
134238 /* 273 */ "with ::= WITH RECURSIVE wqlist",
134239 /* 274 */ "wqlist ::= nm eidlist_opt AS LP select RP",
134240 /* 275 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
134241 /* 276 */ "input ::= cmdlist",
134242 /* 277 */ "cmdlist ::= cmdlist ecmd",
134243 /* 278 */ "cmdlist ::= ecmd",
134244 /* 279 */ "ecmd ::= SEMI",
134245 /* 280 */ "ecmd ::= explain cmdx SEMI",
134246 /* 281 */ "explain ::=",
134247 /* 282 */ "trans_opt ::=",
134248 /* 283 */ "trans_opt ::= TRANSACTION",
134249 /* 284 */ "trans_opt ::= TRANSACTION nm",
134250 /* 285 */ "savepoint_opt ::= SAVEPOINT",
134251 /* 286 */ "savepoint_opt ::=",
134252 /* 287 */ "cmd ::= create_table create_table_args",
134253 /* 288 */ "columnlist ::= columnlist COMMA columnname carglist",
134254 /* 289 */ "columnlist ::= columnname carglist",
134255 /* 290 */ "nm ::= ID|INDEXED",
134256 /* 291 */ "nm ::= STRING",
134257 /* 292 */ "nm ::= JOIN_KW",
134258 /* 293 */ "typetoken ::= typename",
134259 /* 294 */ "typename ::= ID|STRING",
134260 /* 295 */ "signed ::= plus_num",
134261 /* 296 */ "signed ::= minus_num",
134262 /* 297 */ "carglist ::= carglist ccons",
134263 /* 298 */ "carglist ::=",
134264 /* 299 */ "ccons ::= NULL onconf",
134265 /* 300 */ "conslist_opt ::= COMMA conslist",
134266 /* 301 */ "conslist ::= conslist tconscomma tcons",
134267 /* 302 */ "conslist ::= tcons",
134268 /* 303 */ "tconscomma ::=",
134269 /* 304 */ "defer_subclause_opt ::= defer_subclause",
134270 /* 305 */ "resolvetype ::= raisetype",
134271 /* 306 */ "selectnowith ::= oneselect",
134272 /* 307 */ "oneselect ::= values",
134273 /* 308 */ "sclp ::= selcollist COMMA",
134274 /* 309 */ "as ::= ID|STRING",
134275 /* 310 */ "expr ::= term",
134276 /* 311 */ "exprlist ::= nexprlist",
134277 /* 312 */ "nmnum ::= plus_num",
134278 /* 313 */ "nmnum ::= nm",
134279 /* 314 */ "nmnum ::= ON",
134280 /* 315 */ "nmnum ::= DELETE",
134281 /* 316 */ "nmnum ::= DEFAULT",
134282 /* 317 */ "plus_num ::= INTEGER|FLOAT",
134283 /* 318 */ "foreach_clause ::=",
134284 /* 319 */ "foreach_clause ::= FOR EACH ROW",
134285 /* 320 */ "trnm ::= nm",
134286 /* 321 */ "tridxby ::=",
134287 /* 322 */ "database_kw_opt ::= DATABASE",
134288 /* 323 */ "database_kw_opt ::=",
134289 /* 324 */ "kwcolumn_opt ::=",
134290 /* 325 */ "kwcolumn_opt ::= COLUMNKW",
134291 /* 326 */ "vtabarglist ::= vtabarg",
134292 /* 327 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
134293 /* 328 */ "vtabarg ::= vtabarg vtabargtoken",
134294 /* 329 */ "anylist ::=",
134295 /* 330 */ "anylist ::= anylist LP anylist RP",
134296 /* 331 */ "anylist ::= anylist ANY",
134297 };
134298 #endif /* NDEBUG */
134299
134300
134301 #if YYSTACKDEPTH<=0
@@ -134811,10 +134873,11 @@
134873 { 173, 1 },
134874 { 173, 3 },
134875 { 173, 5 },
134876 { 172, 1 },
134877 { 172, 1 },
134878 { 172, 1 },
134879 { 173, 1 },
134880 { 173, 3 },
134881 { 173, 6 },
134882 { 173, 5 },
134883 { 173, 4 },
@@ -135105,11 +135168,11 @@
135168 case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
135169 case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
135170 case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
135171 case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
135172 case 90: /* distinct ::= */ yytestcase(yyruleno==90);
135173 case 215: /* collate ::= */ yytestcase(yyruleno==215);
135174 {yymsp[1].minor.yy194 = 0;}
135175 break;
135176 case 17: /* ifnotexists ::= IF NOT EXISTS */
135177 {yymsp[-2].minor.yy194 = 1;}
135178 break;
@@ -135249,13 +135312,13 @@
135312 case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144);
135313 {yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
135314 break;
135315 case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
135316 case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
135317 case 187: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==187);
135318 case 190: /* in_op ::= NOT IN */ yytestcase(yyruleno==190);
135319 case 216: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==216);
135320 {yymsp[-1].minor.yy194 = 1;}
135321 break;
135322 case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
135323 {yymsp[-1].minor.yy194 = 0;}
135324 break;
@@ -135415,13 +135478,13 @@
135478 {yymsp[0].minor.yy194 = SF_All;}
135479 break;
135480 case 91: /* sclp ::= */
135481 case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
135482 case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
135483 case 203: /* exprlist ::= */ yytestcase(yyruleno==203);
135484 case 206: /* paren_exprlist ::= */ yytestcase(yyruleno==206);
135485 case 211: /* eidlist_opt ::= */ yytestcase(yyruleno==211);
135486 {yymsp[1].minor.yy148 = 0;}
135487 break;
135488 case 92: /* selcollist ::= sclp expr as */
135489 {
135490 yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
@@ -135435,20 +135498,20 @@
135498 yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
135499 }
135500 break;
135501 case 94: /* selcollist ::= sclp nm DOT STAR */
135502 {
135503 Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, 0);
135504 Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
135505 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
135506 yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
135507 }
135508 break;
135509 case 95: /* as ::= AS nm */
135510 case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
135511 case 225: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
135512 case 226: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==226);
135513 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
135514 break;
135515 case 97: /* from ::= */
135516 {yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
135517 break;
@@ -135527,18 +135590,18 @@
135590 {yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
135591 break;
135592 case 112: /* on_opt ::= ON expr */
135593 case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
135594 case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
135595 case 199: /* case_else ::= ELSE expr */ yytestcase(yyruleno==199);
135596 {yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
135597 break;
135598 case 113: /* on_opt ::= */
135599 case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
135600 case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
135601 case 200: /* case_else ::= */ yytestcase(yyruleno==200);
135602 case 202: /* case_operand ::= */ yytestcase(yyruleno==202);
135603 {yymsp[1].minor.yy72 = 0;}
135604 break;
135605 case 115: /* indexed_opt ::= INDEXED BY nm */
135606 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
135607 break;
@@ -135650,41 +135713,51 @@
135713 break;
135714 case 150: /* expr ::= LP expr RP */
135715 {spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
135716 break;
135717 case 151: /* term ::= NULL */
135718 case 156: /* term ::= FLOAT|BLOB */ yytestcase(yyruleno==156);
135719 case 157: /* term ::= STRING */ yytestcase(yyruleno==157);
135720 {spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/}
135721 break;
135722 case 152: /* expr ::= ID|INDEXED */
135723 case 153: /* expr ::= JOIN_KW */ yytestcase(yyruleno==153);
135724 {spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
135725 break;
135726 case 154: /* expr ::= nm DOT nm */
135727 {
135728 Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
135729 Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
135730 spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135731 yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
135732 }
135733 break;
135734 case 155: /* expr ::= nm DOT nm DOT nm */
135735 {
135736 Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
135737 Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
135738 Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
135739 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
135740 spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135741 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
135742 }
135743 break;
135744 case 158: /* term ::= INTEGER */
135745 {
135746 yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
135747 yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z;
135748 yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n;
135749 if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf;
135750 }
135751 yymsp[0].minor.yy190 = yylhsminor.yy190;
135752 break;
135753 case 159: /* expr ::= VARIABLE */
135754 {
135755 if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
135756 u32 n = yymsp[0].minor.yy0.n;
135757 spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
135758 sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
135759 }else{
135760 /* When doing a nested parse, one can include terms in an expression
135761 ** that look like this: #1 #2 ... These terms refer to registers
135762 ** in the virtual machine. #N is the N-th register. */
135763 Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
@@ -135692,29 +135765,29 @@
135765 spanSet(&yymsp[0].minor.yy190, &t, &t);
135766 if( pParse->nested==0 ){
135767 sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
135768 yymsp[0].minor.yy190.pExpr = 0;
135769 }else{
135770 yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, 0);
135771 if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
135772 }
135773 }
135774 }
135775 break;
135776 case 160: /* expr ::= expr COLLATE ID|STRING */
135777 {
135778 yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1);
135779 yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135780 }
135781 break;
135782 case 161: /* expr ::= CAST LP expr AS typetoken RP */
135783 {
135784 spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
135785 yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0);
135786 }
135787 break;
135788 case 162: /* expr ::= ID|INDEXED LP distinct exprlist RP */
135789 {
135790 if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
135791 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
135792 }
135793 yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
@@ -135723,25 +135796,25 @@
135796 yylhsminor.yy190.pExpr->flags |= EP_Distinct;
135797 }
135798 }
135799 yymsp[-4].minor.yy190 = yylhsminor.yy190;
135800 break;
135801 case 163: /* expr ::= ID|INDEXED LP STAR RP */
135802 {
135803 yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
135804 spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
135805 }
135806 yymsp[-3].minor.yy190 = yylhsminor.yy190;
135807 break;
135808 case 164: /* term ::= CTIME_KW */
135809 {
135810 yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
135811 spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
135812 }
135813 yymsp[0].minor.yy190 = yylhsminor.yy190;
135814 break;
135815 case 165: /* expr ::= LP nexprlist COMMA expr RP */
135816 {
135817 ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
135818 yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0);
135819 if( yylhsminor.yy190.pExpr ){
135820 yylhsminor.yy190.pExpr->x.pList = pList;
@@ -135750,82 +135823,86 @@
135823 sqlite3ExprListDelete(pParse->db, pList);
135824 }
135825 }
135826 yymsp[-4].minor.yy190 = yylhsminor.yy190;
135827 break;
135828 case 166: /* expr ::= expr AND expr */
135829 case 167: /* expr ::= expr OR expr */ yytestcase(yyruleno==167);
135830 case 168: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==168);
135831 case 169: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==169);
135832 case 170: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==170);
135833 case 171: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==171);
135834 case 172: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==172);
135835 case 173: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==173);
135836 {spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
135837 break;
135838 case 174: /* likeop ::= LIKE_KW|MATCH */
135839 {yymsp[0].minor.yy0=yymsp[0].minor.yy0;/*A-overwrites-X*/}
135840 break;
135841 case 175: /* likeop ::= NOT LIKE_KW|MATCH */
135842 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
135843 break;
135844 case 176: /* expr ::= expr likeop expr */
135845 {
135846 ExprList *pList;
135847 int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
135848 yymsp[-1].minor.yy0.n &= 0x7fffffff;
135849 pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr);
135850 pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr);
135851 yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
135852 exprNot(pParse, bNot, &yymsp[-2].minor.yy190);
135853 yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135854 if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
135855 }
135856 break;
135857 case 177: /* expr ::= expr likeop expr ESCAPE expr */
135858 {
135859 ExprList *pList;
135860 int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
135861 yymsp[-3].minor.yy0.n &= 0x7fffffff;
135862 pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135863 pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr);
135864 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
135865 yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
135866 exprNot(pParse, bNot, &yymsp[-4].minor.yy190);
135867 yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135868 if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
135869 }
135870 break;
135871 case 178: /* expr ::= expr ISNULL|NOTNULL */
135872 {spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
135873 break;
135874 case 179: /* expr ::= expr NOT NULL */
135875 {spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
135876 break;
135877 case 180: /* expr ::= expr IS expr */
135878 {
135879 spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
135880 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
135881 }
135882 break;
135883 case 181: /* expr ::= expr IS NOT expr */
135884 {
135885 spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
135886 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
135887 }
135888 break;
135889 case 182: /* expr ::= NOT expr */
135890 case 183: /* expr ::= BITNOT expr */ yytestcase(yyruleno==183);
135891 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135892 break;
135893 case 184: /* expr ::= MINUS expr */
135894 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135895 break;
135896 case 185: /* expr ::= PLUS expr */
135897 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
135898 break;
135899 case 186: /* between_op ::= BETWEEN */
135900 case 189: /* in_op ::= IN */ yytestcase(yyruleno==189);
135901 {yymsp[0].minor.yy194 = 0;}
135902 break;
135903 case 188: /* expr ::= expr between_op expr AND expr */
135904 {
135905 ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
135906 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
135907 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0);
135908 if( yymsp[-4].minor.yy190.pExpr ){
@@ -135835,11 +135912,11 @@
135912 }
135913 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135914 yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
135915 }
135916 break;
135917 case 191: /* expr ::= expr in_op LP exprlist RP */
135918 {
135919 if( yymsp[-1].minor.yy148==0 ){
135920 /* Expressions of the form
135921 **
135922 ** expr1 IN ()
@@ -135888,26 +135965,26 @@
135965 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135966 }
135967 yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135968 }
135969 break;
135970 case 192: /* expr ::= LP select RP */
135971 {
135972 spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
135973 yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
135974 sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
135975 }
135976 break;
135977 case 193: /* expr ::= expr in_op LP select RP */
135978 {
135979 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
135980 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
135981 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135982 yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
135983 }
135984 break;
135985 case 194: /* expr ::= expr in_op nm dbnm paren_exprlist */
135986 {
135987 SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
135988 Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
135989 if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148);
135990 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
@@ -135914,19 +135991,19 @@
135991 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect);
135992 exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
135993 yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
135994 }
135995 break;
135996 case 195: /* expr ::= EXISTS LP select RP */
135997 {
135998 Expr *p;
135999 spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
136000 p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
136001 sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
136002 }
136003 break;
136004 case 196: /* expr ::= CASE case_operand case_exprlist case_else END */
136005 {
136006 spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/
136007 yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0, 0);
136008 if( yymsp[-4].minor.yy190.pExpr ){
136009 yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148;
@@ -135935,334 +136012,334 @@
136012 sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
136013 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
136014 }
136015 }
136016 break;
136017 case 197: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
136018 {
136019 yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
136020 yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
136021 }
136022 break;
136023 case 198: /* case_exprlist ::= WHEN expr THEN expr */
136024 {
136025 yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
136026 yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
136027 }
136028 break;
136029 case 201: /* case_operand ::= expr */
136030 {yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
136031 break;
136032 case 204: /* nexprlist ::= nexprlist COMMA expr */
136033 {yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
136034 break;
136035 case 205: /* nexprlist ::= expr */
136036 {yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
136037 break;
136038 case 207: /* paren_exprlist ::= LP exprlist RP */
136039 case 212: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==212);
136040 {yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
136041 break;
136042 case 208: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
136043 {
136044 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
136045 sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194,
136046 &yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF);
136047 }
136048 break;
136049 case 209: /* uniqueflag ::= UNIQUE */
136050 case 250: /* raisetype ::= ABORT */ yytestcase(yyruleno==250);
136051 {yymsp[0].minor.yy194 = OE_Abort;}
136052 break;
136053 case 210: /* uniqueflag ::= */
136054 {yymsp[1].minor.yy194 = OE_None;}
136055 break;
136056 case 213: /* eidlist ::= eidlist COMMA nm collate sortorder */
136057 {
136058 yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
136059 }
136060 break;
136061 case 214: /* eidlist ::= nm collate sortorder */
136062 {
136063 yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
136064 }
136065 break;
136066 case 217: /* cmd ::= DROP INDEX ifexists fullname */
136067 {sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
136068 break;
136069 case 218: /* cmd ::= VACUUM */
136070 {sqlite3Vacuum(pParse,0);}
136071 break;
136072 case 219: /* cmd ::= VACUUM nm */
136073 {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
136074 break;
136075 case 220: /* cmd ::= PRAGMA nm dbnm */
136076 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
136077 break;
136078 case 221: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
136079 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
136080 break;
136081 case 222: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
136082 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
136083 break;
136084 case 223: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
136085 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
136086 break;
136087 case 224: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
136088 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
136089 break;
136090 case 227: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
136091 {
136092 Token all;
136093 all.z = yymsp[-3].minor.yy0.z;
136094 all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
136095 sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
136096 }
136097 break;
136098 case 228: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
136099 {
136100 sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
136101 yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
136102 }
136103 break;
136104 case 229: /* trigger_time ::= BEFORE */
136105 { yymsp[0].minor.yy194 = TK_BEFORE; }
136106 break;
136107 case 230: /* trigger_time ::= AFTER */
136108 { yymsp[0].minor.yy194 = TK_AFTER; }
136109 break;
136110 case 231: /* trigger_time ::= INSTEAD OF */
136111 { yymsp[-1].minor.yy194 = TK_INSTEAD;}
136112 break;
136113 case 232: /* trigger_time ::= */
136114 { yymsp[1].minor.yy194 = TK_BEFORE; }
136115 break;
136116 case 233: /* trigger_event ::= DELETE|INSERT */
136117 case 234: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==234);
136118 {yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
136119 break;
136120 case 235: /* trigger_event ::= UPDATE OF idlist */
136121 {yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
136122 break;
136123 case 236: /* when_clause ::= */
136124 case 255: /* key_opt ::= */ yytestcase(yyruleno==255);
136125 { yymsp[1].minor.yy72 = 0; }
136126 break;
136127 case 237: /* when_clause ::= WHEN expr */
136128 case 256: /* key_opt ::= KEY expr */ yytestcase(yyruleno==256);
136129 { yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
136130 break;
136131 case 238: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
136132 {
136133 assert( yymsp[-2].minor.yy145!=0 );
136134 yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
136135 yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
136136 }
136137 break;
136138 case 239: /* trigger_cmd_list ::= trigger_cmd SEMI */
136139 {
136140 assert( yymsp[-1].minor.yy145!=0 );
136141 yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
136142 }
136143 break;
136144 case 240: /* trnm ::= nm DOT nm */
136145 {
136146 yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
136147 sqlite3ErrorMsg(pParse,
136148 "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
136149 "statements within triggers");
136150 }
136151 break;
136152 case 241: /* tridxby ::= INDEXED BY nm */
136153 {
136154 sqlite3ErrorMsg(pParse,
136155 "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
136156 "within triggers");
136157 }
136158 break;
136159 case 242: /* tridxby ::= NOT INDEXED */
136160 {
136161 sqlite3ErrorMsg(pParse,
136162 "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
136163 "within triggers");
136164 }
136165 break;
136166 case 243: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
136167 {yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
136168 break;
136169 case 244: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
136170 {yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
136171 break;
136172 case 245: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
136173 {yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
136174 break;
136175 case 246: /* trigger_cmd ::= select */
136176 {yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
136177 break;
136178 case 247: /* expr ::= RAISE LP IGNORE RP */
136179 {
136180 spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
136181 yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
136182 if( yymsp[-3].minor.yy190.pExpr ){
136183 yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
136184 }
136185 }
136186 break;
136187 case 248: /* expr ::= RAISE LP raisetype COMMA nm RP */
136188 {
136189 spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
136190 yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
136191 if( yymsp[-5].minor.yy190.pExpr ) {
136192 yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
136193 }
136194 }
136195 break;
136196 case 249: /* raisetype ::= ROLLBACK */
136197 {yymsp[0].minor.yy194 = OE_Rollback;}
136198 break;
136199 case 251: /* raisetype ::= FAIL */
136200 {yymsp[0].minor.yy194 = OE_Fail;}
136201 break;
136202 case 252: /* cmd ::= DROP TRIGGER ifexists fullname */
136203 {
136204 sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
136205 }
136206 break;
136207 case 253: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
136208 {
136209 sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
136210 }
136211 break;
136212 case 254: /* cmd ::= DETACH database_kw_opt expr */
136213 {
136214 sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
136215 }
136216 break;
136217 case 257: /* cmd ::= REINDEX */
136218 {sqlite3Reindex(pParse, 0, 0);}
136219 break;
136220 case 258: /* cmd ::= REINDEX nm dbnm */
136221 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
136222 break;
136223 case 259: /* cmd ::= ANALYZE */
136224 {sqlite3Analyze(pParse, 0, 0);}
136225 break;
136226 case 260: /* cmd ::= ANALYZE nm dbnm */
136227 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
136228 break;
136229 case 261: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
136230 {
136231 sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
136232 }
136233 break;
136234 case 262: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
136235 {
136236 yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
136237 sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
136238 }
136239 break;
136240 case 263: /* add_column_fullname ::= fullname */
136241 {
136242 disableLookaside(pParse);
136243 sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
136244 }
136245 break;
136246 case 264: /* cmd ::= create_vtab */
136247 {sqlite3VtabFinishParse(pParse,0);}
136248 break;
136249 case 265: /* cmd ::= create_vtab LP vtabarglist RP */
136250 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
136251 break;
136252 case 266: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
136253 {
136254 sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194);
136255 }
136256 break;
136257 case 267: /* vtabarg ::= */
136258 {sqlite3VtabArgInit(pParse);}
136259 break;
136260 case 268: /* vtabargtoken ::= ANY */
136261 case 269: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==269);
136262 case 270: /* lp ::= LP */ yytestcase(yyruleno==270);
136263 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
136264 break;
136265 case 271: /* with ::= */
136266 {yymsp[1].minor.yy285 = 0;}
136267 break;
136268 case 272: /* with ::= WITH wqlist */
136269 { yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
136270 break;
136271 case 273: /* with ::= WITH RECURSIVE wqlist */
136272 { yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
136273 break;
136274 case 274: /* wqlist ::= nm eidlist_opt AS LP select RP */
136275 {
136276 yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
136277 }
136278 break;
136279 case 275: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
136280 {
136281 yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
136282 }
136283 break;
136284 default:
136285 /* (276) input ::= cmdlist */ yytestcase(yyruleno==276);
136286 /* (277) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==277);
136287 /* (278) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=278);
136288 /* (279) ecmd ::= SEMI */ yytestcase(yyruleno==279);
136289 /* (280) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==280);
136290 /* (281) explain ::= */ yytestcase(yyruleno==281);
136291 /* (282) trans_opt ::= */ yytestcase(yyruleno==282);
136292 /* (283) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==283);
136293 /* (284) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==284);
136294 /* (285) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==285);
136295 /* (286) savepoint_opt ::= */ yytestcase(yyruleno==286);
136296 /* (287) cmd ::= create_table create_table_args */ yytestcase(yyruleno==287);
136297 /* (288) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==288);
136298 /* (289) columnlist ::= columnname carglist */ yytestcase(yyruleno==289);
136299 /* (290) nm ::= ID|INDEXED */ yytestcase(yyruleno==290);
136300 /* (291) nm ::= STRING */ yytestcase(yyruleno==291);
136301 /* (292) nm ::= JOIN_KW */ yytestcase(yyruleno==292);
136302 /* (293) typetoken ::= typename */ yytestcase(yyruleno==293);
136303 /* (294) typename ::= ID|STRING */ yytestcase(yyruleno==294);
136304 /* (295) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
136305 /* (296) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=296);
136306 /* (297) carglist ::= carglist ccons */ yytestcase(yyruleno==297);
136307 /* (298) carglist ::= */ yytestcase(yyruleno==298);
136308 /* (299) ccons ::= NULL onconf */ yytestcase(yyruleno==299);
136309 /* (300) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==300);
136310 /* (301) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==301);
136311 /* (302) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=302);
136312 /* (303) tconscomma ::= */ yytestcase(yyruleno==303);
136313 /* (304) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=304);
136314 /* (305) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=305);
136315 /* (306) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=306);
136316 /* (307) oneselect ::= values */ yytestcase(yyruleno==307);
136317 /* (308) sclp ::= selcollist COMMA */ yytestcase(yyruleno==308);
136318 /* (309) as ::= ID|STRING */ yytestcase(yyruleno==309);
136319 /* (310) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=310);
136320 /* (311) exprlist ::= nexprlist */ yytestcase(yyruleno==311);
136321 /* (312) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=312);
136322 /* (313) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=313);
136323 /* (314) nmnum ::= ON */ yytestcase(yyruleno==314);
136324 /* (315) nmnum ::= DELETE */ yytestcase(yyruleno==315);
136325 /* (316) nmnum ::= DEFAULT */ yytestcase(yyruleno==316);
136326 /* (317) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==317);
136327 /* (318) foreach_clause ::= */ yytestcase(yyruleno==318);
136328 /* (319) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==319);
136329 /* (320) trnm ::= nm */ yytestcase(yyruleno==320);
136330 /* (321) tridxby ::= */ yytestcase(yyruleno==321);
136331 /* (322) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==322);
136332 /* (323) database_kw_opt ::= */ yytestcase(yyruleno==323);
136333 /* (324) kwcolumn_opt ::= */ yytestcase(yyruleno==324);
136334 /* (325) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==325);
136335 /* (326) vtabarglist ::= vtabarg */ yytestcase(yyruleno==326);
136336 /* (327) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==327);
136337 /* (328) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==328);
136338 /* (329) anylist ::= */ yytestcase(yyruleno==329);
136339 /* (330) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==330);
136340 /* (331) anylist ::= anylist ANY */ yytestcase(yyruleno==331);
136341 break;
136342 /********** End reduce actions ************************************************/
136343 };
136344 assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
136345 yygoto = yyRuleInfo[yyruleno].lhs;
@@ -136449,11 +136526,11 @@
136526 }
136527 #endif
136528 yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
136529 yymajor = YYNOCODE;
136530 }else{
136531 while( yypParser->yytos >= yypParser->yystack
136532 && yymx != YYERRORSYMBOL
136533 && (yyact = yy_find_reduce_action(
136534 yypParser->yytos->stateno,
136535 YYERRORSYMBOL)) >= YY_MIN_REDUCE
136536 ){
@@ -138617,10 +138694,11 @@
138694 } aFlagOp[] = {
138695 { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
138696 { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
138697 { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
138698 { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
138699 { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
138700 };
138701 unsigned int i;
138702 rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
138703 for(i=0; i<ArraySize(aFlagOp); i++){
138704 if( aFlagOp[i].op==op ){
@@ -139913,10 +139991,17 @@
139991 db->busyHandler.nBusy = 0;
139992 rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
139993 sqlite3Error(db, rc);
139994 }
139995 rc = sqlite3ApiExit(db, rc);
139996
139997 /* If there are no active statements, clear the interrupt flag at this
139998 ** point. */
139999 if( db->nVdbeActive==0 ){
140000 db->u1.isInterrupted = 0;
140001 }
140002
140003 sqlite3_mutex_leave(db->mutex);
140004 return rc;
140005 #endif
140006 }
140007
@@ -140415,10 +140500,11 @@
140500 int octet = (sqlite3HexToInt(zUri[iIn++]) << 4);
140501 octet += sqlite3HexToInt(zUri[iIn++]);
140502
140503 assert( octet>=0 && octet<256 );
140504 if( octet==0 ){
140505 #ifndef SQLITE_ENABLE_URI_00_ERROR
140506 /* This branch is taken when "%00" appears within the URI. In this
140507 ** case we ignore all text in the remainder of the path, name or
140508 ** value currently being parsed. So ignore the current character
140509 ** and skip to the next "?", "=" or "&", as appropriate. */
140510 while( (c = zUri[iIn])!=0 && c!='#'
@@ -140427,10 +140513,16 @@
140513 && (eState!=2 || c!='&')
140514 ){
140515 iIn++;
140516 }
140517 continue;
140518 #else
140519 /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
140520 *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
140521 rc = SQLITE_ERROR;
140522 goto parse_uri_out;
140523 #endif
140524 }
140525 c = octet;
140526 }else if( eState==1 && (c=='&' || c=='=') ){
140527 if( zFile[iOut-1]==0 ){
140528 /* An empty option name. Ignore this option altogether. */
@@ -164306,14 +164398,16 @@
164398 char *zSql;
164399 sqlite3_stmt *p;
164400 int rc;
164401 i64 nRow = 0;
164402
164403 rc = sqlite3_table_column_metadata(
164404 db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
164405 );
164406 if( rc!=SQLITE_OK ){
164407 pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
164408 return rc==SQLITE_ERROR ? SQLITE_OK : rc;
164409 }
164410 zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
164411 if( zSql==0 ){
164412 rc = SQLITE_NOMEM;
164413 }else{
@@ -165210,11 +165304,11 @@
165304 ** of the locale to use. Passing an empty string ("") or SQL NULL value
165305 ** as the second argument is the same as invoking the 1 argument version
165306 ** of upper() or lower().
165307 **
165308 ** lower('I', 'en_us') -> 'i'
165309 ** lower('I', 'tr_tr') -> '\u131' (small dotless i)
165310 **
165311 ** http://www.icu-project.org/userguide/posix.html#case_mappings
165312 */
165313 static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
165314 const UChar *zInput; /* Pointer to input string */
@@ -181140,11 +181234,11 @@
181234 }
181235 #endif
181236 fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
181237 fts5yymajor = fts5YYNOCODE;
181238 }else{
181239 while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
181240 && fts5yymx != fts5YYERRORSYMBOL
181241 && (fts5yyact = fts5yy_find_reduce_action(
181242 fts5yypParser->fts5yytos->stateno,
181243 fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
181244 ){
@@ -181506,10 +181600,13 @@
181600 int nToken, /* Size of token in bytes */
181601 int iStartOff, /* Start offset of token */
181602 int iEndOff /* End offset of token */
181603 ){
181604 int rc = SQLITE_OK;
181605
181606 UNUSED_PARAM2(pToken, nToken);
181607 UNUSED_PARAM(iEndOff);
181608
181609 if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
181610 Fts5SFinder *p = (Fts5SFinder*)pContext;
181611 if( p->iPos>0 ){
181612 int i;
@@ -181662,11 +181759,10 @@
181759 for(jj=0; jj<(sFinder.nFirst-1); jj++){
181760 if( sFinder.aFirst[jj+1]>io ) break;
181761 }
181762
181763 if( sFinder.aFirst[jj]<io ){
 
181764 memset(aSeen, 0, nPhrase);
181765 rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
181766 sFinder.aFirst[jj], nToken, &nScore, 0
181767 );
181768
@@ -195597,11 +195693,11 @@
195693 int nArg, /* Number of args */
195694 sqlite3_value **apUnused /* Function arguments */
195695 ){
195696 assert( nArg==0 );
195697 UNUSED_PARAM2(nArg, apUnused);
195698 sqlite3_result_text(pCtx, "fts5: 2016-10-26 16:05:10 ec9dab8054c71d112c68f58a45821b38c2a45677", -1, SQLITE_TRANSIENT);
195699 }
195700
195701 static int fts5Init(sqlite3 *db){
195702 static const sqlite3_module fts5Mod = {
195703 /* iVersion */ 2,
195704
+28 -7
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -119,13 +119,13 @@
119119
**
120120
** See also: [sqlite3_libversion()],
121121
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
122122
** [sqlite_version()] and [sqlite_source_id()].
123123
*/
124
-#define SQLITE_VERSION "3.15.0"
125
-#define SQLITE_VERSION_NUMBER 3015000
126
-#define SQLITE_SOURCE_ID "2016-09-22 18:53:13 c3774c6a5fe48af91fda28e9e18c6ed9053ea992"
124
+#define SQLITE_VERSION "3.16.0"
125
+#define SQLITE_VERSION_NUMBER 3016000
126
+#define SQLITE_SOURCE_ID "2016-11-02 14:50:19 3028845329c9b7acdec2ec8b01d00d782347454c"
127127
128128
/*
129129
** CAPI3REF: Run-Time Library Version Numbers
130130
** KEYWORDS: sqlite3_version, sqlite3_sourceid
131131
**
@@ -975,10 +975,16 @@
975975
** <li>[[SQLITE_FCNTL_HAS_MOVED]]
976976
** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
977977
** pointer to an integer and it writes a boolean into that integer depending
978978
** on whether or not the file has been renamed, moved, or deleted since it
979979
** was first opened.
980
+**
981
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
982
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
983
+** underlying native file handle associated with a file handle. This file
984
+** control interprets its argument as a pointer to a native file handle and
985
+** writes the resulting value there.
980986
**
981987
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
982988
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
983989
** opcode causes the xFileControl method to swap the file handle with the one
984990
** pointed to by the pArg argument. This capability is used during testing
@@ -1026,10 +1032,12 @@
10261032
#define SQLITE_FCNTL_WAL_BLOCK 24
10271033
#define SQLITE_FCNTL_ZIPVFS 25
10281034
#define SQLITE_FCNTL_RBU 26
10291035
#define SQLITE_FCNTL_VFS_POINTER 27
10301036
#define SQLITE_FCNTL_JOURNAL_POINTER 28
1037
+#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
1038
+#define SQLITE_FCNTL_PDB 30
10311039
10321040
/* deprecated names */
10331041
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
10341042
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
10351043
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -1978,18 +1986,31 @@
19781986
** does not make a copy of the new main schema name string, so the application
19791987
** must ensure that the argument passed into this DBCONFIG option is unchanged
19801988
** until after the database connection closes.
19811989
** </dd>
19821990
**
1991
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
1992
+** <dd> Usually, when a database in wal mode is closed or detached from a
1993
+** database handle, SQLite checks if this will mean that there are now no
1994
+** connections at all to the database. If so, it performs a checkpoint
1995
+** operation before closing the connection. This option may be used to
1996
+** override this behaviour. The first parameter passed to this operation
1997
+** is an integer - non-zero to disable checkpoints-on-close, or zero (the
1998
+** default) to enable them. The second parameter is a pointer to an integer
1999
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
2000
+** have been disabled - 0 if they are not disabled, 1 if they are.
2001
+** </dd>
2002
+**
19832003
** </dl>
19842004
*/
19852005
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
19862006
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
19872007
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
19882008
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
19892009
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
19902010
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
2011
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
19912012
19922013
19932014
/*
19942015
** CAPI3REF: Enable Or Disable Extended Result Codes
19952016
** METHOD: sqlite3
@@ -8655,11 +8676,11 @@
86558676
86568677
/*
86578678
** CAPI3REF: Set a table filter on a Session Object.
86588679
**
86598680
** The second argument (xFilter) is the "filter callback". For changes to rows
8660
-** in tables that are not attached to the Session oject, the filter is called
8681
+** in tables that are not attached to the Session object, the filter is called
86618682
** to determine whether changes to the table's rows should be tracked or not.
86628683
** If xFilter returns 0, changes is not tracked. Note that once a table is
86638684
** attached, xFilter will not be called again.
86648685
*/
86658686
void sqlite3session_table_filter(
@@ -8921,11 +8942,11 @@
89218942
** Assuming the changeset blob was created by one of the
89228943
** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
89238944
** [sqlite3changeset_invert()] functions, all changes within the changeset
89248945
** that apply to a single table are grouped together. This means that when
89258946
** an application iterates through a changeset using an iterator created by
8926
-** this function, all changes that relate to a single table are visted
8947
+** this function, all changes that relate to a single table are visited
89278948
** consecutively. There is no chance that the iterator will visit a change
89288949
** the applies to table X, then one for table Y, and then later on visit
89298950
** another change for table X.
89308951
*/
89318952
int sqlite3changeset_start(
@@ -9008,11 +9029,11 @@
90089029
** If successful, *pabPK is set to point to an array of nCol entries, where
90099030
** nCol is the number of columns in the table. Elements of *pabPK are set to
90109031
** 0x01 if the corresponding column is part of the tables primary key, or
90119032
** 0x00 if it is not.
90129033
**
9013
-** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
9034
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
90149035
** in the table.
90159036
**
90169037
** If this function is called when the iterator does not point to a valid
90179038
** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
90189039
** SQLITE_OK is returned and the output variables populated as described
@@ -9283,11 +9304,11 @@
92839304
** Rows within the changeset and changegroup are identified by the values in
92849305
** their PRIMARY KEY columns. A change in the changeset is considered to
92859306
** apply to the same row as a change already present in the changegroup if
92869307
** the two rows have the same primary key.
92879308
**
9288
-** Changes to rows that that do not already appear in the changegroup are
9309
+** Changes to rows that do not already appear in the changegroup are
92899310
** simply copied into it. Or, if both the new changeset and the changegroup
92909311
** contain changes that apply to a single row, the final contents of the
92919312
** changegroup depends on the type of each change, as follows:
92929313
**
92939314
** <table border=1 style="margin-left:8ex;margin-right:8ex">
92949315
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -119,13 +119,13 @@
119 **
120 ** See also: [sqlite3_libversion()],
121 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
122 ** [sqlite_version()] and [sqlite_source_id()].
123 */
124 #define SQLITE_VERSION "3.15.0"
125 #define SQLITE_VERSION_NUMBER 3015000
126 #define SQLITE_SOURCE_ID "2016-09-22 18:53:13 c3774c6a5fe48af91fda28e9e18c6ed9053ea992"
127
128 /*
129 ** CAPI3REF: Run-Time Library Version Numbers
130 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
131 **
@@ -975,10 +975,16 @@
975 ** <li>[[SQLITE_FCNTL_HAS_MOVED]]
976 ** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
977 ** pointer to an integer and it writes a boolean into that integer depending
978 ** on whether or not the file has been renamed, moved, or deleted since it
979 ** was first opened.
 
 
 
 
 
 
980 **
981 ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
982 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
983 ** opcode causes the xFileControl method to swap the file handle with the one
984 ** pointed to by the pArg argument. This capability is used during testing
@@ -1026,10 +1032,12 @@
1026 #define SQLITE_FCNTL_WAL_BLOCK 24
1027 #define SQLITE_FCNTL_ZIPVFS 25
1028 #define SQLITE_FCNTL_RBU 26
1029 #define SQLITE_FCNTL_VFS_POINTER 27
1030 #define SQLITE_FCNTL_JOURNAL_POINTER 28
 
 
1031
1032 /* deprecated names */
1033 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1034 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1035 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -1978,18 +1986,31 @@
1978 ** does not make a copy of the new main schema name string, so the application
1979 ** must ensure that the argument passed into this DBCONFIG option is unchanged
1980 ** until after the database connection closes.
1981 ** </dd>
1982 **
 
 
 
 
 
 
 
 
 
 
 
 
1983 ** </dl>
1984 */
1985 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
1986 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
1987 #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
1988 #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
1989 #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
1990 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
 
1991
1992
1993 /*
1994 ** CAPI3REF: Enable Or Disable Extended Result Codes
1995 ** METHOD: sqlite3
@@ -8655,11 +8676,11 @@
8655
8656 /*
8657 ** CAPI3REF: Set a table filter on a Session Object.
8658 **
8659 ** The second argument (xFilter) is the "filter callback". For changes to rows
8660 ** in tables that are not attached to the Session oject, the filter is called
8661 ** to determine whether changes to the table's rows should be tracked or not.
8662 ** If xFilter returns 0, changes is not tracked. Note that once a table is
8663 ** attached, xFilter will not be called again.
8664 */
8665 void sqlite3session_table_filter(
@@ -8921,11 +8942,11 @@
8921 ** Assuming the changeset blob was created by one of the
8922 ** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
8923 ** [sqlite3changeset_invert()] functions, all changes within the changeset
8924 ** that apply to a single table are grouped together. This means that when
8925 ** an application iterates through a changeset using an iterator created by
8926 ** this function, all changes that relate to a single table are visted
8927 ** consecutively. There is no chance that the iterator will visit a change
8928 ** the applies to table X, then one for table Y, and then later on visit
8929 ** another change for table X.
8930 */
8931 int sqlite3changeset_start(
@@ -9008,11 +9029,11 @@
9008 ** If successful, *pabPK is set to point to an array of nCol entries, where
9009 ** nCol is the number of columns in the table. Elements of *pabPK are set to
9010 ** 0x01 if the corresponding column is part of the tables primary key, or
9011 ** 0x00 if it is not.
9012 **
9013 ** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
9014 ** in the table.
9015 **
9016 ** If this function is called when the iterator does not point to a valid
9017 ** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
9018 ** SQLITE_OK is returned and the output variables populated as described
@@ -9283,11 +9304,11 @@
9283 ** Rows within the changeset and changegroup are identified by the values in
9284 ** their PRIMARY KEY columns. A change in the changeset is considered to
9285 ** apply to the same row as a change already present in the changegroup if
9286 ** the two rows have the same primary key.
9287 **
9288 ** Changes to rows that that do not already appear in the changegroup are
9289 ** simply copied into it. Or, if both the new changeset and the changegroup
9290 ** contain changes that apply to a single row, the final contents of the
9291 ** changegroup depends on the type of each change, as follows:
9292 **
9293 ** <table border=1 style="margin-left:8ex;margin-right:8ex">
9294
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -119,13 +119,13 @@
119 **
120 ** See also: [sqlite3_libversion()],
121 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
122 ** [sqlite_version()] and [sqlite_source_id()].
123 */
124 #define SQLITE_VERSION "3.16.0"
125 #define SQLITE_VERSION_NUMBER 3016000
126 #define SQLITE_SOURCE_ID "2016-11-02 14:50:19 3028845329c9b7acdec2ec8b01d00d782347454c"
127
128 /*
129 ** CAPI3REF: Run-Time Library Version Numbers
130 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
131 **
@@ -975,10 +975,16 @@
975 ** <li>[[SQLITE_FCNTL_HAS_MOVED]]
976 ** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
977 ** pointer to an integer and it writes a boolean into that integer depending
978 ** on whether or not the file has been renamed, moved, or deleted since it
979 ** was first opened.
980 **
981 ** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
982 ** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
983 ** underlying native file handle associated with a file handle. This file
984 ** control interprets its argument as a pointer to a native file handle and
985 ** writes the resulting value there.
986 **
987 ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
988 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
989 ** opcode causes the xFileControl method to swap the file handle with the one
990 ** pointed to by the pArg argument. This capability is used during testing
@@ -1026,10 +1032,12 @@
1032 #define SQLITE_FCNTL_WAL_BLOCK 24
1033 #define SQLITE_FCNTL_ZIPVFS 25
1034 #define SQLITE_FCNTL_RBU 26
1035 #define SQLITE_FCNTL_VFS_POINTER 27
1036 #define SQLITE_FCNTL_JOURNAL_POINTER 28
1037 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29
1038 #define SQLITE_FCNTL_PDB 30
1039
1040 /* deprecated names */
1041 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1042 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1043 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -1978,18 +1986,31 @@
1986 ** does not make a copy of the new main schema name string, so the application
1987 ** must ensure that the argument passed into this DBCONFIG option is unchanged
1988 ** until after the database connection closes.
1989 ** </dd>
1990 **
1991 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
1992 ** <dd> Usually, when a database in wal mode is closed or detached from a
1993 ** database handle, SQLite checks if this will mean that there are now no
1994 ** connections at all to the database. If so, it performs a checkpoint
1995 ** operation before closing the connection. This option may be used to
1996 ** override this behaviour. The first parameter passed to this operation
1997 ** is an integer - non-zero to disable checkpoints-on-close, or zero (the
1998 ** default) to enable them. The second parameter is a pointer to an integer
1999 ** into which is written 0 or 1 to indicate whether checkpoints-on-close
2000 ** have been disabled - 0 if they are not disabled, 1 if they are.
2001 ** </dd>
2002 **
2003 ** </dl>
2004 */
2005 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
2006 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
2007 #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
2008 #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
2009 #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
2010 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
2011 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
2012
2013
2014 /*
2015 ** CAPI3REF: Enable Or Disable Extended Result Codes
2016 ** METHOD: sqlite3
@@ -8655,11 +8676,11 @@
8676
8677 /*
8678 ** CAPI3REF: Set a table filter on a Session Object.
8679 **
8680 ** The second argument (xFilter) is the "filter callback". For changes to rows
8681 ** in tables that are not attached to the Session object, the filter is called
8682 ** to determine whether changes to the table's rows should be tracked or not.
8683 ** If xFilter returns 0, changes is not tracked. Note that once a table is
8684 ** attached, xFilter will not be called again.
8685 */
8686 void sqlite3session_table_filter(
@@ -8921,11 +8942,11 @@
8942 ** Assuming the changeset blob was created by one of the
8943 ** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
8944 ** [sqlite3changeset_invert()] functions, all changes within the changeset
8945 ** that apply to a single table are grouped together. This means that when
8946 ** an application iterates through a changeset using an iterator created by
8947 ** this function, all changes that relate to a single table are visited
8948 ** consecutively. There is no chance that the iterator will visit a change
8949 ** the applies to table X, then one for table Y, and then later on visit
8950 ** another change for table X.
8951 */
8952 int sqlite3changeset_start(
@@ -9008,11 +9029,11 @@
9029 ** If successful, *pabPK is set to point to an array of nCol entries, where
9030 ** nCol is the number of columns in the table. Elements of *pabPK are set to
9031 ** 0x01 if the corresponding column is part of the tables primary key, or
9032 ** 0x00 if it is not.
9033 **
9034 ** If argument pnCol is not NULL, then *pnCol is set to the number of columns
9035 ** in the table.
9036 **
9037 ** If this function is called when the iterator does not point to a valid
9038 ** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
9039 ** SQLITE_OK is returned and the output variables populated as described
@@ -9283,11 +9304,11 @@
9304 ** Rows within the changeset and changegroup are identified by the values in
9305 ** their PRIMARY KEY columns. A change in the changeset is considered to
9306 ** apply to the same row as a change already present in the changegroup if
9307 ** the two rows have the same primary key.
9308 **
9309 ** Changes to rows that do not already appear in the changegroup are
9310 ** simply copied into it. Or, if both the new changeset and the changegroup
9311 ** contain changes that apply to a single row, the final contents of the
9312 ** changegroup depends on the type of each change, as follows:
9313 **
9314 ** <table border=1 style="margin-left:8ex;margin-right:8ex">
9315
+42 -31
--- src/stash.c
+++ src/stash.c
@@ -25,11 +25,11 @@
2525
** SQL code to implement the tables needed by the stash.
2626
*/
2727
static const char zStashInit[] =
2828
@ CREATE TABLE IF NOT EXISTS localdb.stash(
2929
@ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
30
-@ vid INTEGER, -- The baseline check-out for this stash
30
+@ vid INTEGER, -- The baseline checkout for this stash
3131
@ comment TEXT, -- Comment for this stash. Or NULL
3232
@ ctime TIMESTAMP -- When the stash was created
3333
@ );
3434
@ CREATE TABLE IF NOT EXISTS localdb.stashfile(
3535
@ stashid INTEGER REFERENCES stash, -- Stash that contains this file
@@ -39,11 +39,11 @@
3939
@ isExec BOOLEAN, -- True if file is executable
4040
@ isLink BOOLEAN, -- True if file is a symlink
4141
@ origname TEXT, -- Original filename
4242
@ newname TEXT, -- New name for file at next check-in
4343
@ delta BLOB, -- Delta from baseline. Content if rid=0
44
-@ PRIMARY KEY(origname, stashid)
44
+@ PRIMARY KEY(newname, stashid)
4545
@ );
4646
@ INSERT OR IGNORE INTO vvar(name, value) VALUES('stash-next', 1);
4747
;
4848
4949
/*
@@ -196,11 +196,11 @@
196196
}
197197
return stashid;
198198
}
199199
200200
/*
201
-** Apply a stash to the current check-out.
201
+** Apply a stash to the current checkout.
202202
*/
203203
static void stash_apply(int stashid, int nConflict){
204204
int vid;
205205
Stmt q;
206206
db_prepare(&q,
@@ -278,10 +278,15 @@
278278
}
279279
blob_reset(&delta);
280280
if( fossil_strcmp(zOrig,zNew)!=0 ){
281281
undo_save(zOrig);
282282
file_delete(zOPath);
283
+ db_multi_exec(
284
+ "UPDATE vfile SET pathname='%q', origname='%q'"
285
+ " WHERE pathname='%q' %s AND vid=%d",
286
+ zNew, zOrig, zOrig, filename_collation(), vid
287
+ );
283288
}
284289
}
285290
stash_add_files_in_sfile(vid);
286291
db_finalize(&q);
287292
if( nConflict ){
@@ -393,18 +398,18 @@
393398
** return that number. Or throw a fatal error if it is not a valid
394399
** stash number. If it is NULL, return the most recent stash or
395400
** throw an error if the stash is empty.
396401
*/
397402
static int stash_get_id(const char *zStashId){
398
- int stashid = 0;
403
+ int stashid;
399404
if( zStashId==0 ){
400405
stashid = db_int(0, "SELECT max(stashid) FROM stash");
401406
if( stashid==0 ) fossil_fatal("empty stash");
402407
}else{
403408
stashid = atoi(zStashId);
404409
if( !db_exists("SELECT 1 FROM stash WHERE stashid=%d", stashid) ){
405
- fossil_fatal("no such stash: %d\n", stashid);
410
+ fossil_fatal("no such stash: %s", zStashId);
406411
}
407412
}
408413
return stashid;
409414
}
410415
@@ -420,70 +425,83 @@
420425
** Save the current changes in the working tree as a new stash.
421426
** Then revert the changes back to the last check-in. If FILES
422427
** are listed, then only stash and revert the named files. The
423428
** "save" verb can be omitted if and only if there are no other
424429
** arguments. The "snapshot" verb works the same as "save" but
425
-** omits the revert, keeping the check-out unchanged.
430
+** omits the revert, keeping the checkout unchanged.
426431
**
427
-** fossil stash list ?-v|--verbose?
428
-** fossil stash ls ?-v|--verbose?
432
+** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
429433
**
430434
** List all changes sets currently stashed. Show information about
431435
** individual files in each changeset if -v or --verbose is used.
432436
**
433
-** fossil stash show|cat ?STASHID? ?DIFF-FLAGS?
437
+** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
434438
**
435
-** Show the content of a stash
439
+** Show the contents of a stash.
436440
**
437441
** fossil stash pop
438442
** fossil stash apply ?STASHID?
439443
**
440444
** Apply STASHID or the most recently create stash to the current
441
-** working check-out. The "pop" command deletes that changeset from
445
+** working checkout. The "pop" command deletes that changeset from
442446
** the stash after applying it but the "apply" command retains the
443447
** changeset.
444448
**
445449
** fossil stash goto ?STASHID?
446450
**
447451
** Update to the baseline checkout for STASHID then apply the
448452
** changes of STASHID. Keep STASHID so that it can be reused
449453
** This command is undoable.
450454
**
451
-** fossil stash drop ?STASHID? ?-a|--all?
452
-** fossil stash rm ?STASHID? ?-a|--all?
455
+** fossil stash drop|rm ?STASHID? ?-a|--all?
453456
**
454457
** Forget everything about STASHID. Forget the whole stash if the
455458
** -a|--all flag is used. Individual drops are undoable but -a|--all
456459
** is not.
457460
**
458
-** fossil stash diff ?STASHID?
459
-** fossil stash gdiff ?STASHID?
461
+** fossil stash diff ?STASHID? ?DIFF-OPTIONS?
462
+** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
460463
**
461464
** Show diffs of the current working directory and what that
462465
** directory would be if STASHID were applied.
463466
**
464467
** SUMMARY:
465468
** fossil stash
466469
** fossil stash save ?-m|--comment COMMENT? ?FILES...?
467470
** fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
468
-** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
471
+** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
469472
** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
470473
** fossil stash pop
471
-** fossil stash apply ?STASHID?
472
-** fossil stash goto ?STASHID?
473
-** fossil stash rm|drop ?STASHID? ?-a|--all?
474
-** fossil stash [g]diff ?STASHID? ?DIFF-OPTIONS?
474
+** fossil stash apply|goto ?STASHID?
475
+** fossil stash drop|rm ?STASHID? ?-a|--all?
476
+** fossil stash diff ?STASHID? ?DIFF-OPTIONS?
477
+** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
475478
*/
476479
void stash_cmd(void){
477480
const char *zCmd;
478481
int nCmd;
479482
int stashid = 0;
483
+ int rc;
480484
undo_capture_command_line();
481485
db_must_be_within_tree();
482486
db_open_config(0, 0);
483487
db_begin_transaction();
484488
db_multi_exec(zStashInit /*works-like:""*/);
489
+ rc = db_exists("SELECT 1 FROM sqlite_master"
490
+ " WHERE name='stashfile'"
491
+ " AND sql GLOB '* PRIMARY KEY(origname, stashid)*'");
492
+ if( rc!=0 ){
493
+ db_multi_exec(
494
+ "CREATE TABLE localdb.stashfile_tmp AS SELECT * FROM stashfile;"
495
+ "DROP TABLE stashfile;"
496
+ );
497
+ db_multi_exec(zStashInit /*works-like:""*/);
498
+ db_multi_exec(
499
+ "INSERT INTO stashfile SELECT * FROM stashfile_tmp;"
500
+ "DROP TABLE stashfile_tmp;"
501
+ );
502
+ }
485503
if( g.argc<=2 ){
486504
zCmd = "save";
487505
}else{
488506
zCmd = g.argv[2];
489507
}
@@ -641,37 +659,30 @@
641659
|| memcmp(zCmd, "cat", nCmd)==0
642660
){
643661
const char *zDiffCmd = 0;
644662
const char *zBinGlob = 0;
645663
int fIncludeBinary = 0;
664
+ int fBaseline = zCmd[0]=='s' || zCmd[0]=='c';
646665
u64 diffFlags;
647666
648667
if( find_option("tk",0,0)!=0 ){
649668
db_close(0);
650
- switch (zCmd[0]) {
651
- case 's':
652
- case 'c':
653
- diff_tk("stash show", 3);
654
- break;
655
-
656
- default:
657
- diff_tk("stash diff", 3);
658
- }
669
+ diff_tk(fBaseline ? "stash show" : "stash diff", 3);
659670
return;
660671
}
661672
if( find_option("internal","i",0)==0 ){
662673
zDiffCmd = diff_command_external(memcmp(zCmd, "gdiff", nCmd)==0);
663674
}
664675
diffFlags = diff_options();
665676
if( find_option("verbose","v",0)!=0 ) diffFlags |= DIFF_VERBOSE;
666
- if( g.argc>4 ) usage(mprintf("%s STASHID", zCmd));
677
+ if( g.argc>4 ) usage(mprintf("%s ?STASHID? ?DIFF-OPTIONS?", zCmd));
667678
if( zDiffCmd ){
668679
zBinGlob = diff_get_binary_glob();
669680
fIncludeBinary = diff_include_binary_files();
670681
}
671682
stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
672
- stash_diff(stashid, zDiffCmd, zBinGlob, zCmd[0]=='s', fIncludeBinary,
683
+ stash_diff(stashid, zDiffCmd, zBinGlob, fBaseline, fIncludeBinary,
673684
diffFlags);
674685
}else
675686
if( memcmp(zCmd, "help", nCmd)==0 ){
676687
g.argv[1] = "help";
677688
g.argv[2] = "stash";
678689
--- src/stash.c
+++ src/stash.c
@@ -25,11 +25,11 @@
25 ** SQL code to implement the tables needed by the stash.
26 */
27 static const char zStashInit[] =
28 @ CREATE TABLE IF NOT EXISTS localdb.stash(
29 @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
30 @ vid INTEGER, -- The baseline check-out for this stash
31 @ comment TEXT, -- Comment for this stash. Or NULL
32 @ ctime TIMESTAMP -- When the stash was created
33 @ );
34 @ CREATE TABLE IF NOT EXISTS localdb.stashfile(
35 @ stashid INTEGER REFERENCES stash, -- Stash that contains this file
@@ -39,11 +39,11 @@
39 @ isExec BOOLEAN, -- True if file is executable
40 @ isLink BOOLEAN, -- True if file is a symlink
41 @ origname TEXT, -- Original filename
42 @ newname TEXT, -- New name for file at next check-in
43 @ delta BLOB, -- Delta from baseline. Content if rid=0
44 @ PRIMARY KEY(origname, stashid)
45 @ );
46 @ INSERT OR IGNORE INTO vvar(name, value) VALUES('stash-next', 1);
47 ;
48
49 /*
@@ -196,11 +196,11 @@
196 }
197 return stashid;
198 }
199
200 /*
201 ** Apply a stash to the current check-out.
202 */
203 static void stash_apply(int stashid, int nConflict){
204 int vid;
205 Stmt q;
206 db_prepare(&q,
@@ -278,10 +278,15 @@
278 }
279 blob_reset(&delta);
280 if( fossil_strcmp(zOrig,zNew)!=0 ){
281 undo_save(zOrig);
282 file_delete(zOPath);
 
 
 
 
 
283 }
284 }
285 stash_add_files_in_sfile(vid);
286 db_finalize(&q);
287 if( nConflict ){
@@ -393,18 +398,18 @@
393 ** return that number. Or throw a fatal error if it is not a valid
394 ** stash number. If it is NULL, return the most recent stash or
395 ** throw an error if the stash is empty.
396 */
397 static int stash_get_id(const char *zStashId){
398 int stashid = 0;
399 if( zStashId==0 ){
400 stashid = db_int(0, "SELECT max(stashid) FROM stash");
401 if( stashid==0 ) fossil_fatal("empty stash");
402 }else{
403 stashid = atoi(zStashId);
404 if( !db_exists("SELECT 1 FROM stash WHERE stashid=%d", stashid) ){
405 fossil_fatal("no such stash: %d\n", stashid);
406 }
407 }
408 return stashid;
409 }
410
@@ -420,70 +425,83 @@
420 ** Save the current changes in the working tree as a new stash.
421 ** Then revert the changes back to the last check-in. If FILES
422 ** are listed, then only stash and revert the named files. The
423 ** "save" verb can be omitted if and only if there are no other
424 ** arguments. The "snapshot" verb works the same as "save" but
425 ** omits the revert, keeping the check-out unchanged.
426 **
427 ** fossil stash list ?-v|--verbose?
428 ** fossil stash ls ?-v|--verbose?
429 **
430 ** List all changes sets currently stashed. Show information about
431 ** individual files in each changeset if -v or --verbose is used.
432 **
433 ** fossil stash show|cat ?STASHID? ?DIFF-FLAGS?
434 **
435 ** Show the content of a stash
436 **
437 ** fossil stash pop
438 ** fossil stash apply ?STASHID?
439 **
440 ** Apply STASHID or the most recently create stash to the current
441 ** working check-out. The "pop" command deletes that changeset from
442 ** the stash after applying it but the "apply" command retains the
443 ** changeset.
444 **
445 ** fossil stash goto ?STASHID?
446 **
447 ** Update to the baseline checkout for STASHID then apply the
448 ** changes of STASHID. Keep STASHID so that it can be reused
449 ** This command is undoable.
450 **
451 ** fossil stash drop ?STASHID? ?-a|--all?
452 ** fossil stash rm ?STASHID? ?-a|--all?
453 **
454 ** Forget everything about STASHID. Forget the whole stash if the
455 ** -a|--all flag is used. Individual drops are undoable but -a|--all
456 ** is not.
457 **
458 ** fossil stash diff ?STASHID?
459 ** fossil stash gdiff ?STASHID?
460 **
461 ** Show diffs of the current working directory and what that
462 ** directory would be if STASHID were applied.
463 **
464 ** SUMMARY:
465 ** fossil stash
466 ** fossil stash save ?-m|--comment COMMENT? ?FILES...?
467 ** fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
468 ** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
469 ** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
470 ** fossil stash pop
471 ** fossil stash apply ?STASHID?
472 ** fossil stash goto ?STASHID?
473 ** fossil stash rm|drop ?STASHID? ?-a|--all?
474 ** fossil stash [g]diff ?STASHID? ?DIFF-OPTIONS?
475 */
476 void stash_cmd(void){
477 const char *zCmd;
478 int nCmd;
479 int stashid = 0;
 
480 undo_capture_command_line();
481 db_must_be_within_tree();
482 db_open_config(0, 0);
483 db_begin_transaction();
484 db_multi_exec(zStashInit /*works-like:""*/);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485 if( g.argc<=2 ){
486 zCmd = "save";
487 }else{
488 zCmd = g.argv[2];
489 }
@@ -641,37 +659,30 @@
641 || memcmp(zCmd, "cat", nCmd)==0
642 ){
643 const char *zDiffCmd = 0;
644 const char *zBinGlob = 0;
645 int fIncludeBinary = 0;
 
646 u64 diffFlags;
647
648 if( find_option("tk",0,0)!=0 ){
649 db_close(0);
650 switch (zCmd[0]) {
651 case 's':
652 case 'c':
653 diff_tk("stash show", 3);
654 break;
655
656 default:
657 diff_tk("stash diff", 3);
658 }
659 return;
660 }
661 if( find_option("internal","i",0)==0 ){
662 zDiffCmd = diff_command_external(memcmp(zCmd, "gdiff", nCmd)==0);
663 }
664 diffFlags = diff_options();
665 if( find_option("verbose","v",0)!=0 ) diffFlags |= DIFF_VERBOSE;
666 if( g.argc>4 ) usage(mprintf("%s STASHID", zCmd));
667 if( zDiffCmd ){
668 zBinGlob = diff_get_binary_glob();
669 fIncludeBinary = diff_include_binary_files();
670 }
671 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
672 stash_diff(stashid, zDiffCmd, zBinGlob, zCmd[0]=='s', fIncludeBinary,
673 diffFlags);
674 }else
675 if( memcmp(zCmd, "help", nCmd)==0 ){
676 g.argv[1] = "help";
677 g.argv[2] = "stash";
678
--- src/stash.c
+++ src/stash.c
@@ -25,11 +25,11 @@
25 ** SQL code to implement the tables needed by the stash.
26 */
27 static const char zStashInit[] =
28 @ CREATE TABLE IF NOT EXISTS localdb.stash(
29 @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
30 @ vid INTEGER, -- The baseline checkout for this stash
31 @ comment TEXT, -- Comment for this stash. Or NULL
32 @ ctime TIMESTAMP -- When the stash was created
33 @ );
34 @ CREATE TABLE IF NOT EXISTS localdb.stashfile(
35 @ stashid INTEGER REFERENCES stash, -- Stash that contains this file
@@ -39,11 +39,11 @@
39 @ isExec BOOLEAN, -- True if file is executable
40 @ isLink BOOLEAN, -- True if file is a symlink
41 @ origname TEXT, -- Original filename
42 @ newname TEXT, -- New name for file at next check-in
43 @ delta BLOB, -- Delta from baseline. Content if rid=0
44 @ PRIMARY KEY(newname, stashid)
45 @ );
46 @ INSERT OR IGNORE INTO vvar(name, value) VALUES('stash-next', 1);
47 ;
48
49 /*
@@ -196,11 +196,11 @@
196 }
197 return stashid;
198 }
199
200 /*
201 ** Apply a stash to the current checkout.
202 */
203 static void stash_apply(int stashid, int nConflict){
204 int vid;
205 Stmt q;
206 db_prepare(&q,
@@ -278,10 +278,15 @@
278 }
279 blob_reset(&delta);
280 if( fossil_strcmp(zOrig,zNew)!=0 ){
281 undo_save(zOrig);
282 file_delete(zOPath);
283 db_multi_exec(
284 "UPDATE vfile SET pathname='%q', origname='%q'"
285 " WHERE pathname='%q' %s AND vid=%d",
286 zNew, zOrig, zOrig, filename_collation(), vid
287 );
288 }
289 }
290 stash_add_files_in_sfile(vid);
291 db_finalize(&q);
292 if( nConflict ){
@@ -393,18 +398,18 @@
398 ** return that number. Or throw a fatal error if it is not a valid
399 ** stash number. If it is NULL, return the most recent stash or
400 ** throw an error if the stash is empty.
401 */
402 static int stash_get_id(const char *zStashId){
403 int stashid;
404 if( zStashId==0 ){
405 stashid = db_int(0, "SELECT max(stashid) FROM stash");
406 if( stashid==0 ) fossil_fatal("empty stash");
407 }else{
408 stashid = atoi(zStashId);
409 if( !db_exists("SELECT 1 FROM stash WHERE stashid=%d", stashid) ){
410 fossil_fatal("no such stash: %s", zStashId);
411 }
412 }
413 return stashid;
414 }
415
@@ -420,70 +425,83 @@
425 ** Save the current changes in the working tree as a new stash.
426 ** Then revert the changes back to the last check-in. If FILES
427 ** are listed, then only stash and revert the named files. The
428 ** "save" verb can be omitted if and only if there are no other
429 ** arguments. The "snapshot" verb works the same as "save" but
430 ** omits the revert, keeping the checkout unchanged.
431 **
432 ** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
 
433 **
434 ** List all changes sets currently stashed. Show information about
435 ** individual files in each changeset if -v or --verbose is used.
436 **
437 ** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
438 **
439 ** Show the contents of a stash.
440 **
441 ** fossil stash pop
442 ** fossil stash apply ?STASHID?
443 **
444 ** Apply STASHID or the most recently create stash to the current
445 ** working checkout. The "pop" command deletes that changeset from
446 ** the stash after applying it but the "apply" command retains the
447 ** changeset.
448 **
449 ** fossil stash goto ?STASHID?
450 **
451 ** Update to the baseline checkout for STASHID then apply the
452 ** changes of STASHID. Keep STASHID so that it can be reused
453 ** This command is undoable.
454 **
455 ** fossil stash drop|rm ?STASHID? ?-a|--all?
 
456 **
457 ** Forget everything about STASHID. Forget the whole stash if the
458 ** -a|--all flag is used. Individual drops are undoable but -a|--all
459 ** is not.
460 **
461 ** fossil stash diff ?STASHID? ?DIFF-OPTIONS?
462 ** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
463 **
464 ** Show diffs of the current working directory and what that
465 ** directory would be if STASHID were applied.
466 **
467 ** SUMMARY:
468 ** fossil stash
469 ** fossil stash save ?-m|--comment COMMENT? ?FILES...?
470 ** fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
471 ** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
472 ** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
473 ** fossil stash pop
474 ** fossil stash apply|goto ?STASHID?
475 ** fossil stash drop|rm ?STASHID? ?-a|--all?
476 ** fossil stash diff ?STASHID? ?DIFF-OPTIONS?
477 ** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
478 */
479 void stash_cmd(void){
480 const char *zCmd;
481 int nCmd;
482 int stashid = 0;
483 int rc;
484 undo_capture_command_line();
485 db_must_be_within_tree();
486 db_open_config(0, 0);
487 db_begin_transaction();
488 db_multi_exec(zStashInit /*works-like:""*/);
489 rc = db_exists("SELECT 1 FROM sqlite_master"
490 " WHERE name='stashfile'"
491 " AND sql GLOB '* PRIMARY KEY(origname, stashid)*'");
492 if( rc!=0 ){
493 db_multi_exec(
494 "CREATE TABLE localdb.stashfile_tmp AS SELECT * FROM stashfile;"
495 "DROP TABLE stashfile;"
496 );
497 db_multi_exec(zStashInit /*works-like:""*/);
498 db_multi_exec(
499 "INSERT INTO stashfile SELECT * FROM stashfile_tmp;"
500 "DROP TABLE stashfile_tmp;"
501 );
502 }
503 if( g.argc<=2 ){
504 zCmd = "save";
505 }else{
506 zCmd = g.argv[2];
507 }
@@ -641,37 +659,30 @@
659 || memcmp(zCmd, "cat", nCmd)==0
660 ){
661 const char *zDiffCmd = 0;
662 const char *zBinGlob = 0;
663 int fIncludeBinary = 0;
664 int fBaseline = zCmd[0]=='s' || zCmd[0]=='c';
665 u64 diffFlags;
666
667 if( find_option("tk",0,0)!=0 ){
668 db_close(0);
669 diff_tk(fBaseline ? "stash show" : "stash diff", 3);
 
 
 
 
 
 
 
 
670 return;
671 }
672 if( find_option("internal","i",0)==0 ){
673 zDiffCmd = diff_command_external(memcmp(zCmd, "gdiff", nCmd)==0);
674 }
675 diffFlags = diff_options();
676 if( find_option("verbose","v",0)!=0 ) diffFlags |= DIFF_VERBOSE;
677 if( g.argc>4 ) usage(mprintf("%s ?STASHID? ?DIFF-OPTIONS?", zCmd));
678 if( zDiffCmd ){
679 zBinGlob = diff_get_binary_glob();
680 fIncludeBinary = diff_include_binary_files();
681 }
682 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
683 stash_diff(stashid, zDiffCmd, zBinGlob, fBaseline, fIncludeBinary,
684 diffFlags);
685 }else
686 if( memcmp(zCmd, "help", nCmd)==0 ){
687 g.argv[1] = "help";
688 g.argv[2] = "stash";
689
+4 -7
--- src/stat.c
+++ src/stat.c
@@ -422,19 +422,18 @@
422422
style_submenu_element("Stat", "Repository Stats", "stat");
423423
if( g.perm.Admin ){
424424
style_submenu_element("Schema", "Repository Schema", "repo_schema");
425425
}
426426
db_multi_exec(
427
- "CREATE VIRTUAL TABLE temp.dbx USING dbstat(repository);"
428427
"CREATE TEMP TABLE trans(name TEXT PRIMARY KEY,tabname TEXT)WITHOUT ROWID;"
429428
"INSERT INTO trans(name,tabname)"
430429
" SELECT name, tbl_name FROM repository.sqlite_master;"
431430
"CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
432431
"INSERT INTO piechart(amt,label)"
433432
" SELECT count(*), "
434
- " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
435
- " FROM dbx"
433
+ " coalesce((SELECT tabname FROM trans WHERE trans.name=dbstat.name),name)"
434
+ " FROM dbstat('repository')"
436435
" GROUP BY 2 ORDER BY 2;"
437436
);
438437
nPageFree = db_int(0, "PRAGMA repository.freelist_count");
439438
if( nPageFree>0 ){
440439
db_multi_exec(
@@ -449,20 +448,18 @@
449448
piechart_render(800,500,PIE_OTHER|PIE_PERCENT);
450449
@ </svg></center>
451450
452451
if( g.localOpen ){
453452
db_multi_exec(
454
- "DROP TABLE temp.dbx;"
455
- "CREATE VIRTUAL TABLE temp.dbx USING dbstat(localdb);"
456453
"DELETE FROM trans;"
457454
"INSERT INTO trans(name,tabname)"
458455
" SELECT name, tbl_name FROM localdb.sqlite_master;"
459456
"DELETE FROM piechart;"
460457
"INSERT INTO piechart(amt,label)"
461458
" SELECT count(*), "
462
- " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
463
- " FROM dbx"
459
+ " coalesce((SELECT tabname FROM trans WHERE trans.name=dbstat.name),name)"
460
+ " FROM dbstat('localdb')"
464461
" GROUP BY 2 ORDER BY 2;"
465462
);
466463
nPageFree = db_int(0, "PRAGMA localdb.freelist_count");
467464
if( nPageFree>0 ){
468465
db_multi_exec(
469466
--- src/stat.c
+++ src/stat.c
@@ -422,19 +422,18 @@
422 style_submenu_element("Stat", "Repository Stats", "stat");
423 if( g.perm.Admin ){
424 style_submenu_element("Schema", "Repository Schema", "repo_schema");
425 }
426 db_multi_exec(
427 "CREATE VIRTUAL TABLE temp.dbx USING dbstat(repository);"
428 "CREATE TEMP TABLE trans(name TEXT PRIMARY KEY,tabname TEXT)WITHOUT ROWID;"
429 "INSERT INTO trans(name,tabname)"
430 " SELECT name, tbl_name FROM repository.sqlite_master;"
431 "CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
432 "INSERT INTO piechart(amt,label)"
433 " SELECT count(*), "
434 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
435 " FROM dbx"
436 " GROUP BY 2 ORDER BY 2;"
437 );
438 nPageFree = db_int(0, "PRAGMA repository.freelist_count");
439 if( nPageFree>0 ){
440 db_multi_exec(
@@ -449,20 +448,18 @@
449 piechart_render(800,500,PIE_OTHER|PIE_PERCENT);
450 @ </svg></center>
451
452 if( g.localOpen ){
453 db_multi_exec(
454 "DROP TABLE temp.dbx;"
455 "CREATE VIRTUAL TABLE temp.dbx USING dbstat(localdb);"
456 "DELETE FROM trans;"
457 "INSERT INTO trans(name,tabname)"
458 " SELECT name, tbl_name FROM localdb.sqlite_master;"
459 "DELETE FROM piechart;"
460 "INSERT INTO piechart(amt,label)"
461 " SELECT count(*), "
462 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
463 " FROM dbx"
464 " GROUP BY 2 ORDER BY 2;"
465 );
466 nPageFree = db_int(0, "PRAGMA localdb.freelist_count");
467 if( nPageFree>0 ){
468 db_multi_exec(
469
--- src/stat.c
+++ src/stat.c
@@ -422,19 +422,18 @@
422 style_submenu_element("Stat", "Repository Stats", "stat");
423 if( g.perm.Admin ){
424 style_submenu_element("Schema", "Repository Schema", "repo_schema");
425 }
426 db_multi_exec(
 
427 "CREATE TEMP TABLE trans(name TEXT PRIMARY KEY,tabname TEXT)WITHOUT ROWID;"
428 "INSERT INTO trans(name,tabname)"
429 " SELECT name, tbl_name FROM repository.sqlite_master;"
430 "CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
431 "INSERT INTO piechart(amt,label)"
432 " SELECT count(*), "
433 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbstat.name),name)"
434 " FROM dbstat('repository')"
435 " GROUP BY 2 ORDER BY 2;"
436 );
437 nPageFree = db_int(0, "PRAGMA repository.freelist_count");
438 if( nPageFree>0 ){
439 db_multi_exec(
@@ -449,20 +448,18 @@
448 piechart_render(800,500,PIE_OTHER|PIE_PERCENT);
449 @ </svg></center>
450
451 if( g.localOpen ){
452 db_multi_exec(
 
 
453 "DELETE FROM trans;"
454 "INSERT INTO trans(name,tabname)"
455 " SELECT name, tbl_name FROM localdb.sqlite_master;"
456 "DELETE FROM piechart;"
457 "INSERT INTO piechart(amt,label)"
458 " SELECT count(*), "
459 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbstat.name),name)"
460 " FROM dbstat('localdb')"
461 " GROUP BY 2 ORDER BY 2;"
462 );
463 nPageFree = db_int(0, "PRAGMA localdb.freelist_count");
464 if( nPageFree>0 ){
465 db_multi_exec(
466
--- src/style.c
+++ src/style.c
@@ -400,10 +400,11 @@
400400
401401
if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
402402
403403
/* Generate the header up through the main menu */
404404
Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
405
+ Th_Store("project_description", db_get("project-description",""));
405406
Th_Store("title", zTitle);
406407
Th_Store("baseurl", g.zBaseURL);
407408
Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL);
408409
Th_Store("home", g.zTop);
409410
Th_Store("index_page", db_get("index-page","/home"));
410411
--- src/style.c
+++ src/style.c
@@ -400,10 +400,11 @@
400
401 if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
402
403 /* Generate the header up through the main menu */
404 Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
 
405 Th_Store("title", zTitle);
406 Th_Store("baseurl", g.zBaseURL);
407 Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL);
408 Th_Store("home", g.zTop);
409 Th_Store("index_page", db_get("index-page","/home"));
410
--- src/style.c
+++ src/style.c
@@ -400,10 +400,11 @@
400
401 if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
402
403 /* Generate the header up through the main menu */
404 Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
405 Th_Store("project_description", db_get("project-description",""));
406 Th_Store("title", zTitle);
407 Th_Store("baseurl", g.zBaseURL);
408 Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL);
409 Th_Store("home", g.zTop);
410 Th_Store("index_page", db_get("index-page","/home"));
411
+1
--- src/tag.c
+++ src/tag.c
@@ -359,10 +359,11 @@
359359
}else{
360360
nrid = content_put(&ctrl);
361361
manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
362362
}
363363
assert( blob_is_reset(&ctrl) );
364
+ manifest_to_disk(rid);
364365
}
365366
366367
/*
367368
** COMMAND: tag
368369
**
369370
--- src/tag.c
+++ src/tag.c
@@ -359,10 +359,11 @@
359 }else{
360 nrid = content_put(&ctrl);
361 manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
362 }
363 assert( blob_is_reset(&ctrl) );
 
364 }
365
366 /*
367 ** COMMAND: tag
368 **
369
--- src/tag.c
+++ src/tag.c
@@ -359,10 +359,11 @@
359 }else{
360 nrid = content_put(&ctrl);
361 manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
362 }
363 assert( blob_is_reset(&ctrl) );
364 manifest_to_disk(rid);
365 }
366
367 /*
368 ** COMMAND: tag
369 **
370
+52 -16
--- src/tar.c
+++ src/tar.c
@@ -475,11 +475,11 @@
475475
Blob mfile, hash, file;
476476
Manifest *pManifest;
477477
ManifestFile *pFile;
478478
Blob filename;
479479
int nPrefix;
480
- char *zName;
480
+ char *zName = 0;
481481
unsigned int mTime;
482482
483483
content_get(rid, &mfile);
484484
if( blob_size(&mfile)==0 ){
485485
blob_zero(pTar);
@@ -493,28 +493,64 @@
493493
}
494494
nPrefix = blob_size(&filename);
495495
496496
pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
497497
if( pManifest ){
498
+ int flg, eflg = 0;
498499
mTime = (pManifest->rDate - 2440587.5)*86400.0;
499500
tar_begin(mTime);
500
- if( (pInclude==0 || glob_match(pInclude, "manifest"))
501
- && !glob_match(pExclude, "manifest")
502
- && db_get_boolean("manifest", 0)
503
- ){
504
- blob_append(&filename, "manifest", -1);
505
- zName = blob_str(&filename);
506
- sha1sum_blob(&mfile, &hash);
507
- sterilize_manifest(&mfile);
508
- tar_add_file(zName, &mfile, 0, mTime);
501
+ flg = db_get_manifest_setting();
502
+ if( flg ){
503
+ /* eflg is the effective flags, taking include/exclude into account */
504
+ if( (pInclude==0 || glob_match(pInclude, "manifest"))
505
+ && !glob_match(pExclude, "manifest")
506
+ && (flg & MFESTFLG_RAW) ){
507
+ eflg |= MFESTFLG_RAW;
508
+ }
509
+ if( (pInclude==0 || glob_match(pInclude, "manifest.uuid"))
510
+ && !glob_match(pExclude, "manifest.uuid")
511
+ && (flg & MFESTFLG_UUID) ){
512
+ eflg |= MFESTFLG_UUID;
513
+ }
514
+ if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
515
+ && !glob_match(pExclude, "manifest.tags")
516
+ && (flg & MFESTFLG_TAGS) ){
517
+ eflg |= MFESTFLG_TAGS;
518
+ }
519
+
520
+ if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
521
+ if( eflg & MFESTFLG_RAW ){
522
+ blob_append(&filename, "manifest", -1);
523
+ zName = blob_str(&filename);
524
+ }
525
+ if( eflg & MFESTFLG_UUID ){
526
+ sha1sum_blob(&mfile, &hash);
527
+ }
528
+ if( eflg & MFESTFLG_RAW ) {
529
+ sterilize_manifest(&mfile);
530
+ tar_add_file(zName, &mfile, 0, mTime);
531
+ }
532
+ }
509533
blob_reset(&mfile);
510
- blob_append(&hash, "\n", 1);
511
- blob_resize(&filename, nPrefix);
512
- blob_append(&filename, "manifest.uuid", -1);
513
- zName = blob_str(&filename);
514
- tar_add_file(zName, &hash, 0, mTime);
515
- blob_reset(&hash);
534
+ if( eflg & MFESTFLG_UUID ){
535
+ blob_append(&hash, "\n", 1);
536
+ blob_resize(&filename, nPrefix);
537
+ blob_append(&filename, "manifest.uuid", -1);
538
+ zName = blob_str(&filename);
539
+ tar_add_file(zName, &hash, 0, mTime);
540
+ blob_reset(&hash);
541
+ }
542
+ if( eflg & MFESTFLG_TAGS ){
543
+ Blob tagslist;
544
+ blob_zero(&tagslist);
545
+ get_checkin_taglist(rid, &tagslist);
546
+ blob_resize(&filename, nPrefix);
547
+ blob_append(&filename, "manifest.tags", -1);
548
+ zName = blob_str(&filename);
549
+ tar_add_file(zName, &tagslist, 0, mTime);
550
+ blob_reset(&tagslist);
551
+ }
516552
}
517553
manifest_file_rewind(pManifest);
518554
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
519555
int fid;
520556
if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
521557
--- src/tar.c
+++ src/tar.c
@@ -475,11 +475,11 @@
475 Blob mfile, hash, file;
476 Manifest *pManifest;
477 ManifestFile *pFile;
478 Blob filename;
479 int nPrefix;
480 char *zName;
481 unsigned int mTime;
482
483 content_get(rid, &mfile);
484 if( blob_size(&mfile)==0 ){
485 blob_zero(pTar);
@@ -493,28 +493,64 @@
493 }
494 nPrefix = blob_size(&filename);
495
496 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
497 if( pManifest ){
 
498 mTime = (pManifest->rDate - 2440587.5)*86400.0;
499 tar_begin(mTime);
500 if( (pInclude==0 || glob_match(pInclude, "manifest"))
501 && !glob_match(pExclude, "manifest")
502 && db_get_boolean("manifest", 0)
503 ){
504 blob_append(&filename, "manifest", -1);
505 zName = blob_str(&filename);
506 sha1sum_blob(&mfile, &hash);
507 sterilize_manifest(&mfile);
508 tar_add_file(zName, &mfile, 0, mTime);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
509 blob_reset(&mfile);
510 blob_append(&hash, "\n", 1);
511 blob_resize(&filename, nPrefix);
512 blob_append(&filename, "manifest.uuid", -1);
513 zName = blob_str(&filename);
514 tar_add_file(zName, &hash, 0, mTime);
515 blob_reset(&hash);
 
 
 
 
 
 
 
 
 
 
 
 
516 }
517 manifest_file_rewind(pManifest);
518 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
519 int fid;
520 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
521
--- src/tar.c
+++ src/tar.c
@@ -475,11 +475,11 @@
475 Blob mfile, hash, file;
476 Manifest *pManifest;
477 ManifestFile *pFile;
478 Blob filename;
479 int nPrefix;
480 char *zName = 0;
481 unsigned int mTime;
482
483 content_get(rid, &mfile);
484 if( blob_size(&mfile)==0 ){
485 blob_zero(pTar);
@@ -493,28 +493,64 @@
493 }
494 nPrefix = blob_size(&filename);
495
496 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
497 if( pManifest ){
498 int flg, eflg = 0;
499 mTime = (pManifest->rDate - 2440587.5)*86400.0;
500 tar_begin(mTime);
501 flg = db_get_manifest_setting();
502 if( flg ){
503 /* eflg is the effective flags, taking include/exclude into account */
504 if( (pInclude==0 || glob_match(pInclude, "manifest"))
505 && !glob_match(pExclude, "manifest")
506 && (flg & MFESTFLG_RAW) ){
507 eflg |= MFESTFLG_RAW;
508 }
509 if( (pInclude==0 || glob_match(pInclude, "manifest.uuid"))
510 && !glob_match(pExclude, "manifest.uuid")
511 && (flg & MFESTFLG_UUID) ){
512 eflg |= MFESTFLG_UUID;
513 }
514 if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
515 && !glob_match(pExclude, "manifest.tags")
516 && (flg & MFESTFLG_TAGS) ){
517 eflg |= MFESTFLG_TAGS;
518 }
519
520 if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
521 if( eflg & MFESTFLG_RAW ){
522 blob_append(&filename, "manifest", -1);
523 zName = blob_str(&filename);
524 }
525 if( eflg & MFESTFLG_UUID ){
526 sha1sum_blob(&mfile, &hash);
527 }
528 if( eflg & MFESTFLG_RAW ) {
529 sterilize_manifest(&mfile);
530 tar_add_file(zName, &mfile, 0, mTime);
531 }
532 }
533 blob_reset(&mfile);
534 if( eflg & MFESTFLG_UUID ){
535 blob_append(&hash, "\n", 1);
536 blob_resize(&filename, nPrefix);
537 blob_append(&filename, "manifest.uuid", -1);
538 zName = blob_str(&filename);
539 tar_add_file(zName, &hash, 0, mTime);
540 blob_reset(&hash);
541 }
542 if( eflg & MFESTFLG_TAGS ){
543 Blob tagslist;
544 blob_zero(&tagslist);
545 get_checkin_taglist(rid, &tagslist);
546 blob_resize(&filename, nPrefix);
547 blob_append(&filename, "manifest.tags", -1);
548 zName = blob_str(&filename);
549 tar_add_file(zName, &tagslist, 0, mTime);
550 blob_reset(&tagslist);
551 }
552 }
553 manifest_file_rewind(pManifest);
554 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
555 int fid;
556 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
557
+84 -1
--- src/th_main.c
+++ src/th_main.c
@@ -1317,10 +1317,92 @@
13171317
}else{
13181318
Th_SetResult(interp, "repository unavailable", -1);
13191319
return TH_ERROR;
13201320
}
13211321
}
1322
+
1323
+/*
1324
+** TH1 command: unversioned content FILENAME
1325
+**
1326
+** Attempts to locate the specified unversioned file and return its contents.
1327
+** An error is generated if the repository is not open or the unversioned file
1328
+** cannot be found.
1329
+*/
1330
+static int unversionedContentCmd(
1331
+ Th_Interp *interp,
1332
+ void *p,
1333
+ int argc,
1334
+ const char **argv,
1335
+ int *argl
1336
+){
1337
+ if( argc!=3 ){
1338
+ return Th_WrongNumArgs(interp, "unversioned content FILENAME");
1339
+ }
1340
+ if( Th_IsRepositoryOpen() ){
1341
+ Blob content;
1342
+ if( unversioned_content(argv[2], &content)==0 ){
1343
+ Th_SetResult(interp, blob_str(&content), blob_size(&content));
1344
+ blob_reset(&content);
1345
+ return TH_OK;
1346
+ }else{
1347
+ return TH_ERROR;
1348
+ }
1349
+ }else{
1350
+ Th_SetResult(interp, "repository unavailable", -1);
1351
+ return TH_ERROR;
1352
+ }
1353
+}
1354
+
1355
+/*
1356
+** TH1 command: unversioned list
1357
+**
1358
+** Returns a list of the names of all unversioned files held in the local
1359
+** repository. An error is generated if the repository is not open.
1360
+*/
1361
+static int unversionedListCmd(
1362
+ Th_Interp *interp,
1363
+ void *p,
1364
+ int argc,
1365
+ const char **argv,
1366
+ int *argl
1367
+){
1368
+ if( argc!=2 ){
1369
+ return Th_WrongNumArgs(interp, "unversioned list");
1370
+ }
1371
+ if( Th_IsRepositoryOpen() ){
1372
+ Stmt q;
1373
+ char *zList = 0;
1374
+ int nList = 0;
1375
+ db_prepare(&q, "SELECT name FROM unversioned WHERE hash IS NOT NULL"
1376
+ " ORDER BY name");
1377
+ while( db_step(&q)==SQLITE_ROW ){
1378
+ Th_ListAppend(interp, &zList, &nList, db_column_text(&q,0), -1);
1379
+ }
1380
+ db_finalize(&q);
1381
+ Th_SetResult(interp, zList, nList);
1382
+ Th_Free(interp, zList);
1383
+ return TH_OK;
1384
+ }else{
1385
+ Th_SetResult(interp, "repository unavailable", -1);
1386
+ return TH_ERROR;
1387
+ }
1388
+}
1389
+
1390
+static int unversionedCmd(
1391
+ Th_Interp *interp,
1392
+ void *p,
1393
+ int argc,
1394
+ const char **argv,
1395
+ int *argl
1396
+){
1397
+ static const Th_SubCommand aSub[] = {
1398
+ { "content", unversionedContentCmd },
1399
+ { "list", unversionedListCmd },
1400
+ { 0, 0 }
1401
+ };
1402
+ return Th_CallSubCommand(interp, p, argc, argv, argl, aSub);
1403
+}
13221404
13231405
#ifdef _WIN32
13241406
# include <windows.h>
13251407
#else
13261408
# include <sys/time.h>
@@ -1886,10 +1968,11 @@
18861968
{"styleHeader", styleHeaderCmd, 0},
18871969
{"styleFooter", styleFooterCmd, 0},
18881970
{"tclReady", tclReadyCmd, 0},
18891971
{"trace", traceCmd, 0},
18901972
{"stime", stimeCmd, 0},
1973
+ {"unversioned", unversionedCmd, 0},
18911974
{"utime", utimeCmd, 0},
18921975
{"verifyCsrf", verifyCsrfCmd, 0},
18931976
{"wiki", wikiCmd, (void*)&aFlags[0]},
18941977
{0, 0, 0}
18951978
};
@@ -2593,11 +2676,11 @@
25932676
}else if( fossil_stricmp(g.argv[2], "webhook")==0 ){
25942677
rc = Th_WebpageHook(g.argv[3], (unsigned int)atoi(g.argv[4]));
25952678
}else if( fossil_stricmp(g.argv[2], "webnotify")==0 ){
25962679
rc = Th_WebpageNotify(g.argv[3], (unsigned int)atoi(g.argv[4]));
25972680
}else{
2598
- fossil_fatal("Unknown TH1 hook %s\n", g.argv[2]);
2681
+ fossil_fatal("Unknown TH1 hook %s", g.argv[2]);
25992682
}
26002683
if( g.interp ){
26012684
zResult = (char*)Th_GetResult(g.interp, &nResult);
26022685
}
26032686
sendText("RESULT (", -1, 0);
26042687
--- src/th_main.c
+++ src/th_main.c
@@ -1317,10 +1317,92 @@
1317 }else{
1318 Th_SetResult(interp, "repository unavailable", -1);
1319 return TH_ERROR;
1320 }
1321 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1322
1323 #ifdef _WIN32
1324 # include <windows.h>
1325 #else
1326 # include <sys/time.h>
@@ -1886,10 +1968,11 @@
1886 {"styleHeader", styleHeaderCmd, 0},
1887 {"styleFooter", styleFooterCmd, 0},
1888 {"tclReady", tclReadyCmd, 0},
1889 {"trace", traceCmd, 0},
1890 {"stime", stimeCmd, 0},
 
1891 {"utime", utimeCmd, 0},
1892 {"verifyCsrf", verifyCsrfCmd, 0},
1893 {"wiki", wikiCmd, (void*)&aFlags[0]},
1894 {0, 0, 0}
1895 };
@@ -2593,11 +2676,11 @@
2593 }else if( fossil_stricmp(g.argv[2], "webhook")==0 ){
2594 rc = Th_WebpageHook(g.argv[3], (unsigned int)atoi(g.argv[4]));
2595 }else if( fossil_stricmp(g.argv[2], "webnotify")==0 ){
2596 rc = Th_WebpageNotify(g.argv[3], (unsigned int)atoi(g.argv[4]));
2597 }else{
2598 fossil_fatal("Unknown TH1 hook %s\n", g.argv[2]);
2599 }
2600 if( g.interp ){
2601 zResult = (char*)Th_GetResult(g.interp, &nResult);
2602 }
2603 sendText("RESULT (", -1, 0);
2604
--- src/th_main.c
+++ src/th_main.c
@@ -1317,10 +1317,92 @@
1317 }else{
1318 Th_SetResult(interp, "repository unavailable", -1);
1319 return TH_ERROR;
1320 }
1321 }
1322
1323 /*
1324 ** TH1 command: unversioned content FILENAME
1325 **
1326 ** Attempts to locate the specified unversioned file and return its contents.
1327 ** An error is generated if the repository is not open or the unversioned file
1328 ** cannot be found.
1329 */
1330 static int unversionedContentCmd(
1331 Th_Interp *interp,
1332 void *p,
1333 int argc,
1334 const char **argv,
1335 int *argl
1336 ){
1337 if( argc!=3 ){
1338 return Th_WrongNumArgs(interp, "unversioned content FILENAME");
1339 }
1340 if( Th_IsRepositoryOpen() ){
1341 Blob content;
1342 if( unversioned_content(argv[2], &content)==0 ){
1343 Th_SetResult(interp, blob_str(&content), blob_size(&content));
1344 blob_reset(&content);
1345 return TH_OK;
1346 }else{
1347 return TH_ERROR;
1348 }
1349 }else{
1350 Th_SetResult(interp, "repository unavailable", -1);
1351 return TH_ERROR;
1352 }
1353 }
1354
1355 /*
1356 ** TH1 command: unversioned list
1357 **
1358 ** Returns a list of the names of all unversioned files held in the local
1359 ** repository. An error is generated if the repository is not open.
1360 */
1361 static int unversionedListCmd(
1362 Th_Interp *interp,
1363 void *p,
1364 int argc,
1365 const char **argv,
1366 int *argl
1367 ){
1368 if( argc!=2 ){
1369 return Th_WrongNumArgs(interp, "unversioned list");
1370 }
1371 if( Th_IsRepositoryOpen() ){
1372 Stmt q;
1373 char *zList = 0;
1374 int nList = 0;
1375 db_prepare(&q, "SELECT name FROM unversioned WHERE hash IS NOT NULL"
1376 " ORDER BY name");
1377 while( db_step(&q)==SQLITE_ROW ){
1378 Th_ListAppend(interp, &zList, &nList, db_column_text(&q,0), -1);
1379 }
1380 db_finalize(&q);
1381 Th_SetResult(interp, zList, nList);
1382 Th_Free(interp, zList);
1383 return TH_OK;
1384 }else{
1385 Th_SetResult(interp, "repository unavailable", -1);
1386 return TH_ERROR;
1387 }
1388 }
1389
1390 static int unversionedCmd(
1391 Th_Interp *interp,
1392 void *p,
1393 int argc,
1394 const char **argv,
1395 int *argl
1396 ){
1397 static const Th_SubCommand aSub[] = {
1398 { "content", unversionedContentCmd },
1399 { "list", unversionedListCmd },
1400 { 0, 0 }
1401 };
1402 return Th_CallSubCommand(interp, p, argc, argv, argl, aSub);
1403 }
1404
1405 #ifdef _WIN32
1406 # include <windows.h>
1407 #else
1408 # include <sys/time.h>
@@ -1886,10 +1968,11 @@
1968 {"styleHeader", styleHeaderCmd, 0},
1969 {"styleFooter", styleFooterCmd, 0},
1970 {"tclReady", tclReadyCmd, 0},
1971 {"trace", traceCmd, 0},
1972 {"stime", stimeCmd, 0},
1973 {"unversioned", unversionedCmd, 0},
1974 {"utime", utimeCmd, 0},
1975 {"verifyCsrf", verifyCsrfCmd, 0},
1976 {"wiki", wikiCmd, (void*)&aFlags[0]},
1977 {0, 0, 0}
1978 };
@@ -2593,11 +2676,11 @@
2676 }else if( fossil_stricmp(g.argv[2], "webhook")==0 ){
2677 rc = Th_WebpageHook(g.argv[3], (unsigned int)atoi(g.argv[4]));
2678 }else if( fossil_stricmp(g.argv[2], "webnotify")==0 ){
2679 rc = Th_WebpageNotify(g.argv[3], (unsigned int)atoi(g.argv[4]));
2680 }else{
2681 fossil_fatal("Unknown TH1 hook %s", g.argv[2]);
2682 }
2683 if( g.interp ){
2684 zResult = (char*)Th_GetResult(g.interp, &nResult);
2685 }
2686 sendText("RESULT (", -1, 0);
2687
+36 -18
--- src/timeline.c
+++ src/timeline.c
@@ -26,10 +26,19 @@
2626
/*
2727
** The value of one second in julianday notation
2828
*/
2929
#define ONE_SECOND (1.0/86400.0)
3030
31
+/*
32
+** timeline mode options
33
+*/
34
+#define TIMELINE_MODE_NONE 0
35
+#define TIMELINE_MODE_BEFORE 1
36
+#define TIMELINE_MODE_AFTER 2
37
+#define TIMELINE_MODE_CHILDREN 3
38
+#define TIMELINE_MODE_PARENTS 4
39
+
3140
/*
3241
** Add an appropriate tag to the output if "rid" is unpublished (private)
3342
*/
3443
#define UNPUB_TAG "<em>(unpublished)</em>"
3544
void tag_private_status(int rid){
@@ -728,11 +737,11 @@
728737
pRow->mergeOut, /* mo */
729738
pRow->mergeUpto, /* mu */
730739
pRow->aiRiser[pRow->iRail], /* u */
731740
pRow->isLeaf ? 1 : 0 /* f */
732741
);
733
- /* u */
742
+ /* au */
734743
cSep = '[';
735744
for(i=0; i<GR_MAX_RAIL; i++){
736745
if( i==pRow->iRail ) continue;
737746
if( pRow->aiRiser[i]>0 ){
738747
cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
@@ -748,11 +757,11 @@
748757
cgi_printf("mi:");
749758
cSep = '[';
750759
for(i=0; i<GR_MAX_RAIL; i++){
751760
if( pRow->mergeIn[i] ){
752761
int mi = i;
753
- if( pRow->mergeDown & (1<<i) ) mi = -mi;
762
+ if( (pRow->mergeDown >> i) & 1 ) mi = -mi;
754763
cgi_printf("%c%d", cSep, mi);
755764
cSep = ',';
756765
}
757766
}
758767
if( cSep=='[' ) cgi_printf("[");
@@ -2029,10 +2038,17 @@
20292038
&& z[4]=='-'
20302039
&& z[7]=='-'
20312040
&& fossil_isdigit(z[0])
20322041
&& fossil_isdigit(z[5]);
20332042
}
2043
+
2044
+/*
2045
+** Return true if the input string can be converted to a julianday.
2046
+*/
2047
+static int fossil_is_julianday(const char *zDate){
2048
+ return db_int(0, "SELECT EXISTS (SELECT julianday(%Q) AS jd WHERE jd IS NOT NULL)", zDate);
2049
+}
20342050
20352051
/*
20362052
** COMMAND: timeline
20372053
**
20382054
** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
@@ -2087,11 +2103,11 @@
20872103
char *zOrigin;
20882104
char *zDate;
20892105
Blob sql;
20902106
int objid = 0;
20912107
Blob uuid;
2092
- int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
2108
+ int mode = TIMELINE_MODE_NONE;
20932109
int verboseFlag = 0 ;
20942110
int iOffset;
20952111
const char *zFilePattern = 0;
20962112
Blob treeName;
20972113
@@ -2128,21 +2144,21 @@
21282144
verify_all_options();
21292145
21302146
if( g.argc>=4 ){
21312147
k = strlen(g.argv[2]);
21322148
if( strncmp(g.argv[2],"before",k)==0 ){
2133
- mode = 1;
2149
+ mode = TIMELINE_MODE_BEFORE;
21342150
}else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
2135
- mode = 2;
2151
+ mode = TIMELINE_MODE_AFTER;
21362152
}else if( strncmp(g.argv[2],"descendants",k)==0 ){
2137
- mode = 3;
2153
+ mode = TIMELINE_MODE_CHILDREN;
21382154
}else if( strncmp(g.argv[2],"children",k)==0 ){
2139
- mode = 3;
2155
+ mode = TIMELINE_MODE_CHILDREN;
21402156
}else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
2141
- mode = 4;
2157
+ mode = TIMELINE_MODE_PARENTS;
21422158
}else if( strncmp(g.argv[2],"parents",k)==0 ){
2143
- mode = 4;
2159
+ mode = TIMELINE_MODE_PARENTS;
21442160
}else if(!zType && !zLimit){
21452161
usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
21462162
"?-W|--width WIDTH? ?-p|--path PATH");
21472163
}
21482164
if( '-' != *g.argv[3] ){
@@ -2157,11 +2173,11 @@
21572173
}
21582174
k = strlen(zOrigin);
21592175
blob_zero(&uuid);
21602176
blob_append(&uuid, zOrigin, -1);
21612177
if( fossil_strcmp(zOrigin, "now")==0 ){
2162
- if( mode==3 || mode==4 ){
2178
+ if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
21632179
fossil_fatal("cannot compute descendants or ancestors of a date");
21642180
}
21652181
zDate = mprintf("(SELECT datetime('now'))");
21662182
}else if( strncmp(zOrigin, "current", k)==0 ){
21672183
if( !g.localOpen ){
@@ -2170,19 +2186,21 @@
21702186
objid = db_lget_int("checkout",0);
21712187
zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid);
21722188
}else if( name_to_uuid(&uuid, 0, "*")==0 ){
21732189
objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
21742190
zDate = mprintf("(SELECT mtime FROM event WHERE objid=%d)", objid);
2175
- }else{
2191
+ }else if( fossil_is_julianday(zOrigin) ){
21762192
const char *zShift = "";
2177
- if( mode==3 || mode==4 ){
2193
+ if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
21782194
fossil_fatal("cannot compute descendants or ancestors of a date");
21792195
}
2180
- if( mode==0 ){
2196
+ if( mode==TIMELINE_MODE_NONE ){
21812197
if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
21822198
}
21832199
zDate = mprintf("(SELECT julianday(%Q%s, fromLocal()))", zOrigin, zShift);
2200
+ }else{
2201
+ fossil_fatal("unknown check-in or invalid date: %s", zOrigin);
21842202
}
21852203
21862204
if( zFilePattern ){
21872205
if( zType==0 ){
21882206
/* When zFilePattern is specified and type is not specified, only show
@@ -2195,21 +2213,21 @@
21952213
* zFilePattern. */
21962214
zFilePattern = 0;
21972215
}
21982216
}
21992217
2200
- if( mode==0 ) mode = 1;
2218
+ if( mode==TIMELINE_MODE_NONE ) mode = TIMELINE_MODE_BEFORE;
22012219
blob_zero(&sql);
22022220
blob_append(&sql, timeline_query_for_tty(), -1);
22032221
blob_append_sql(&sql, "\n AND event.mtime %s %s",
2204
- (mode==1 || mode==4) ? "<=" : ">=",
2205
- zDate /*safe-for-%s*/
2222
+ ( mode==TIMELINE_MODE_BEFORE ||
2223
+ mode==TIMELINE_MODE_PARENTS ) ? "<=" : ">=", zDate /*safe-for-%s*/
22062224
);
22072225
2208
- if( mode==3 || mode==4 ){
2226
+ if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
22092227
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
2210
- if( mode==3 ){
2228
+ if( mode==TIMELINE_MODE_CHILDREN ){
22112229
compute_descendants(objid, n);
22122230
}else{
22132231
compute_ancestors(objid, n, 0);
22142232
}
22152233
blob_append_sql(&sql, "\n AND blob.rid IN ok");
22162234
--- src/timeline.c
+++ src/timeline.c
@@ -26,10 +26,19 @@
26 /*
27 ** The value of one second in julianday notation
28 */
29 #define ONE_SECOND (1.0/86400.0)
30
 
 
 
 
 
 
 
 
 
31 /*
32 ** Add an appropriate tag to the output if "rid" is unpublished (private)
33 */
34 #define UNPUB_TAG "<em>(unpublished)</em>"
35 void tag_private_status(int rid){
@@ -728,11 +737,11 @@
728 pRow->mergeOut, /* mo */
729 pRow->mergeUpto, /* mu */
730 pRow->aiRiser[pRow->iRail], /* u */
731 pRow->isLeaf ? 1 : 0 /* f */
732 );
733 /* u */
734 cSep = '[';
735 for(i=0; i<GR_MAX_RAIL; i++){
736 if( i==pRow->iRail ) continue;
737 if( pRow->aiRiser[i]>0 ){
738 cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
@@ -748,11 +757,11 @@
748 cgi_printf("mi:");
749 cSep = '[';
750 for(i=0; i<GR_MAX_RAIL; i++){
751 if( pRow->mergeIn[i] ){
752 int mi = i;
753 if( pRow->mergeDown & (1<<i) ) mi = -mi;
754 cgi_printf("%c%d", cSep, mi);
755 cSep = ',';
756 }
757 }
758 if( cSep=='[' ) cgi_printf("[");
@@ -2029,10 +2038,17 @@
2029 && z[4]=='-'
2030 && z[7]=='-'
2031 && fossil_isdigit(z[0])
2032 && fossil_isdigit(z[5]);
2033 }
 
 
 
 
 
 
 
2034
2035 /*
2036 ** COMMAND: timeline
2037 **
2038 ** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
@@ -2087,11 +2103,11 @@
2087 char *zOrigin;
2088 char *zDate;
2089 Blob sql;
2090 int objid = 0;
2091 Blob uuid;
2092 int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
2093 int verboseFlag = 0 ;
2094 int iOffset;
2095 const char *zFilePattern = 0;
2096 Blob treeName;
2097
@@ -2128,21 +2144,21 @@
2128 verify_all_options();
2129
2130 if( g.argc>=4 ){
2131 k = strlen(g.argv[2]);
2132 if( strncmp(g.argv[2],"before",k)==0 ){
2133 mode = 1;
2134 }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
2135 mode = 2;
2136 }else if( strncmp(g.argv[2],"descendants",k)==0 ){
2137 mode = 3;
2138 }else if( strncmp(g.argv[2],"children",k)==0 ){
2139 mode = 3;
2140 }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
2141 mode = 4;
2142 }else if( strncmp(g.argv[2],"parents",k)==0 ){
2143 mode = 4;
2144 }else if(!zType && !zLimit){
2145 usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
2146 "?-W|--width WIDTH? ?-p|--path PATH");
2147 }
2148 if( '-' != *g.argv[3] ){
@@ -2157,11 +2173,11 @@
2157 }
2158 k = strlen(zOrigin);
2159 blob_zero(&uuid);
2160 blob_append(&uuid, zOrigin, -1);
2161 if( fossil_strcmp(zOrigin, "now")==0 ){
2162 if( mode==3 || mode==4 ){
2163 fossil_fatal("cannot compute descendants or ancestors of a date");
2164 }
2165 zDate = mprintf("(SELECT datetime('now'))");
2166 }else if( strncmp(zOrigin, "current", k)==0 ){
2167 if( !g.localOpen ){
@@ -2170,19 +2186,21 @@
2170 objid = db_lget_int("checkout",0);
2171 zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid);
2172 }else if( name_to_uuid(&uuid, 0, "*")==0 ){
2173 objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
2174 zDate = mprintf("(SELECT mtime FROM event WHERE objid=%d)", objid);
2175 }else{
2176 const char *zShift = "";
2177 if( mode==3 || mode==4 ){
2178 fossil_fatal("cannot compute descendants or ancestors of a date");
2179 }
2180 if( mode==0 ){
2181 if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
2182 }
2183 zDate = mprintf("(SELECT julianday(%Q%s, fromLocal()))", zOrigin, zShift);
 
 
2184 }
2185
2186 if( zFilePattern ){
2187 if( zType==0 ){
2188 /* When zFilePattern is specified and type is not specified, only show
@@ -2195,21 +2213,21 @@
2195 * zFilePattern. */
2196 zFilePattern = 0;
2197 }
2198 }
2199
2200 if( mode==0 ) mode = 1;
2201 blob_zero(&sql);
2202 blob_append(&sql, timeline_query_for_tty(), -1);
2203 blob_append_sql(&sql, "\n AND event.mtime %s %s",
2204 (mode==1 || mode==4) ? "<=" : ">=",
2205 zDate /*safe-for-%s*/
2206 );
2207
2208 if( mode==3 || mode==4 ){
2209 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
2210 if( mode==3 ){
2211 compute_descendants(objid, n);
2212 }else{
2213 compute_ancestors(objid, n, 0);
2214 }
2215 blob_append_sql(&sql, "\n AND blob.rid IN ok");
2216
--- src/timeline.c
+++ src/timeline.c
@@ -26,10 +26,19 @@
26 /*
27 ** The value of one second in julianday notation
28 */
29 #define ONE_SECOND (1.0/86400.0)
30
31 /*
32 ** timeline mode options
33 */
34 #define TIMELINE_MODE_NONE 0
35 #define TIMELINE_MODE_BEFORE 1
36 #define TIMELINE_MODE_AFTER 2
37 #define TIMELINE_MODE_CHILDREN 3
38 #define TIMELINE_MODE_PARENTS 4
39
40 /*
41 ** Add an appropriate tag to the output if "rid" is unpublished (private)
42 */
43 #define UNPUB_TAG "<em>(unpublished)</em>"
44 void tag_private_status(int rid){
@@ -728,11 +737,11 @@
737 pRow->mergeOut, /* mo */
738 pRow->mergeUpto, /* mu */
739 pRow->aiRiser[pRow->iRail], /* u */
740 pRow->isLeaf ? 1 : 0 /* f */
741 );
742 /* au */
743 cSep = '[';
744 for(i=0; i<GR_MAX_RAIL; i++){
745 if( i==pRow->iRail ) continue;
746 if( pRow->aiRiser[i]>0 ){
747 cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
@@ -748,11 +757,11 @@
757 cgi_printf("mi:");
758 cSep = '[';
759 for(i=0; i<GR_MAX_RAIL; i++){
760 if( pRow->mergeIn[i] ){
761 int mi = i;
762 if( (pRow->mergeDown >> i) & 1 ) mi = -mi;
763 cgi_printf("%c%d", cSep, mi);
764 cSep = ',';
765 }
766 }
767 if( cSep=='[' ) cgi_printf("[");
@@ -2029,10 +2038,17 @@
2038 && z[4]=='-'
2039 && z[7]=='-'
2040 && fossil_isdigit(z[0])
2041 && fossil_isdigit(z[5]);
2042 }
2043
2044 /*
2045 ** Return true if the input string can be converted to a julianday.
2046 */
2047 static int fossil_is_julianday(const char *zDate){
2048 return db_int(0, "SELECT EXISTS (SELECT julianday(%Q) AS jd WHERE jd IS NOT NULL)", zDate);
2049 }
2050
2051 /*
2052 ** COMMAND: timeline
2053 **
2054 ** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
@@ -2087,11 +2103,11 @@
2103 char *zOrigin;
2104 char *zDate;
2105 Blob sql;
2106 int objid = 0;
2107 Blob uuid;
2108 int mode = TIMELINE_MODE_NONE;
2109 int verboseFlag = 0 ;
2110 int iOffset;
2111 const char *zFilePattern = 0;
2112 Blob treeName;
2113
@@ -2128,21 +2144,21 @@
2144 verify_all_options();
2145
2146 if( g.argc>=4 ){
2147 k = strlen(g.argv[2]);
2148 if( strncmp(g.argv[2],"before",k)==0 ){
2149 mode = TIMELINE_MODE_BEFORE;
2150 }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
2151 mode = TIMELINE_MODE_AFTER;
2152 }else if( strncmp(g.argv[2],"descendants",k)==0 ){
2153 mode = TIMELINE_MODE_CHILDREN;
2154 }else if( strncmp(g.argv[2],"children",k)==0 ){
2155 mode = TIMELINE_MODE_CHILDREN;
2156 }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
2157 mode = TIMELINE_MODE_PARENTS;
2158 }else if( strncmp(g.argv[2],"parents",k)==0 ){
2159 mode = TIMELINE_MODE_PARENTS;
2160 }else if(!zType && !zLimit){
2161 usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
2162 "?-W|--width WIDTH? ?-p|--path PATH");
2163 }
2164 if( '-' != *g.argv[3] ){
@@ -2157,11 +2173,11 @@
2173 }
2174 k = strlen(zOrigin);
2175 blob_zero(&uuid);
2176 blob_append(&uuid, zOrigin, -1);
2177 if( fossil_strcmp(zOrigin, "now")==0 ){
2178 if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
2179 fossil_fatal("cannot compute descendants or ancestors of a date");
2180 }
2181 zDate = mprintf("(SELECT datetime('now'))");
2182 }else if( strncmp(zOrigin, "current", k)==0 ){
2183 if( !g.localOpen ){
@@ -2170,19 +2186,21 @@
2186 objid = db_lget_int("checkout",0);
2187 zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid);
2188 }else if( name_to_uuid(&uuid, 0, "*")==0 ){
2189 objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
2190 zDate = mprintf("(SELECT mtime FROM event WHERE objid=%d)", objid);
2191 }else if( fossil_is_julianday(zOrigin) ){
2192 const char *zShift = "";
2193 if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
2194 fossil_fatal("cannot compute descendants or ancestors of a date");
2195 }
2196 if( mode==TIMELINE_MODE_NONE ){
2197 if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
2198 }
2199 zDate = mprintf("(SELECT julianday(%Q%s, fromLocal()))", zOrigin, zShift);
2200 }else{
2201 fossil_fatal("unknown check-in or invalid date: %s", zOrigin);
2202 }
2203
2204 if( zFilePattern ){
2205 if( zType==0 ){
2206 /* When zFilePattern is specified and type is not specified, only show
@@ -2195,21 +2213,21 @@
2213 * zFilePattern. */
2214 zFilePattern = 0;
2215 }
2216 }
2217
2218 if( mode==TIMELINE_MODE_NONE ) mode = TIMELINE_MODE_BEFORE;
2219 blob_zero(&sql);
2220 blob_append(&sql, timeline_query_for_tty(), -1);
2221 blob_append_sql(&sql, "\n AND event.mtime %s %s",
2222 ( mode==TIMELINE_MODE_BEFORE ||
2223 mode==TIMELINE_MODE_PARENTS ) ? "<=" : ">=", zDate /*safe-for-%s*/
2224 );
2225
2226 if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
2227 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
2228 if( mode==TIMELINE_MODE_CHILDREN ){
2229 compute_descendants(objid, n);
2230 }else{
2231 compute_ancestors(objid, n, 0);
2232 }
2233 blob_append_sql(&sql, "\n AND blob.rid IN ok");
2234
+14 -8
--- src/tkt.c
+++ src/tkt.c
@@ -216,20 +216,25 @@
216216
const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
217217
j = fieldId(zBaseName);
218218
if( j<0 ) continue;
219219
aUsed[j] = 1;
220220
if( aField[j].mUsed & USEDBY_TICKET ){
221
- if( zName[0]=='+' ){
222
- zName++;
221
+ const char *zUsedByName = zName;
222
+ if( zUsedByName[0]=='+' ){
223
+ zUsedByName++;
223224
blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
224
- zName, zName, p->aField[i].zValue);
225
+ zUsedByName, zUsedByName, p->aField[i].zValue);
225226
}else{
226
- blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue);
227
+ blob_append_sql(&sql1,", \"%w\"=%Q", zUsedByName, p->aField[i].zValue);
227228
}
228229
}
229230
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230
- blob_append_sql(&sql2, ",\"%w\"", zName);
231
+ const char *zUsedByName = zName;
232
+ if( zUsedByName[0]=='+' ){
233
+ zUsedByName++;
234
+ }
235
+ blob_append_sql(&sql2, ",\"%w\"", zUsedByName);
231236
blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
232237
}
233238
if( rid>0 ){
234239
wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
235240
}
@@ -546,11 +551,13 @@
546551
Blob *pTicket, /* The text of the ticket change record */
547552
const char *zTktId, /* The ticket to which this change is applied */
548553
int needMod /* True if moderation is needed */
549554
){
550555
int result;
551
- int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
556
+ int rid;
557
+ manifest_crosslink_begin();
558
+ rid = content_put_ex(pTicket, 0, 0, 0, needMod);
552559
if( rid==0 ){
553560
fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
554561
}
555562
if( needMod ){
556563
moderation_table_create();
@@ -560,11 +567,10 @@
560567
);
561568
}else{
562569
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
563570
db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
564571
}
565
- manifest_crosslink_begin();
566572
result = (manifest_crosslink(rid, pTicket, MC_NONE)==0);
567573
assert( blob_is_reset(pTicket) );
568574
if( !result ){
569575
result = manifest_crosslink_end(MC_PERMIT_HOOKS);
570576
}else{
@@ -1386,11 +1392,11 @@
13861392
blob_appendf(&tktchng, "K %s\n", zTktUuid);
13871393
blob_appendf(&tktchng, "U %F\n", zUser);
13881394
md5sum_blob(&tktchng, &cksum);
13891395
blob_appendf(&tktchng, "Z %b\n", &cksum);
13901396
if( ticket_put(&tktchng, zTktUuid, ticket_need_moderation(1)) ){
1391
- fossil_fatal("%s\n", g.zErrMsg);
1397
+ fossil_fatal("%s", g.zErrMsg);
13921398
}else{
13931399
fossil_print("ticket %s succeeded for %s\n",
13941400
(eCmd==set?"set":"add"),zTktUuid);
13951401
}
13961402
}
13971403
--- src/tkt.c
+++ src/tkt.c
@@ -216,20 +216,25 @@
216 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
217 j = fieldId(zBaseName);
218 if( j<0 ) continue;
219 aUsed[j] = 1;
220 if( aField[j].mUsed & USEDBY_TICKET ){
221 if( zName[0]=='+' ){
222 zName++;
 
223 blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
224 zName, zName, p->aField[i].zValue);
225 }else{
226 blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue);
227 }
228 }
229 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230 blob_append_sql(&sql2, ",\"%w\"", zName);
 
 
 
 
231 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
232 }
233 if( rid>0 ){
234 wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
235 }
@@ -546,11 +551,13 @@
546 Blob *pTicket, /* The text of the ticket change record */
547 const char *zTktId, /* The ticket to which this change is applied */
548 int needMod /* True if moderation is needed */
549 ){
550 int result;
551 int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
 
 
552 if( rid==0 ){
553 fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
554 }
555 if( needMod ){
556 moderation_table_create();
@@ -560,11 +567,10 @@
560 );
561 }else{
562 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
563 db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
564 }
565 manifest_crosslink_begin();
566 result = (manifest_crosslink(rid, pTicket, MC_NONE)==0);
567 assert( blob_is_reset(pTicket) );
568 if( !result ){
569 result = manifest_crosslink_end(MC_PERMIT_HOOKS);
570 }else{
@@ -1386,11 +1392,11 @@
1386 blob_appendf(&tktchng, "K %s\n", zTktUuid);
1387 blob_appendf(&tktchng, "U %F\n", zUser);
1388 md5sum_blob(&tktchng, &cksum);
1389 blob_appendf(&tktchng, "Z %b\n", &cksum);
1390 if( ticket_put(&tktchng, zTktUuid, ticket_need_moderation(1)) ){
1391 fossil_fatal("%s\n", g.zErrMsg);
1392 }else{
1393 fossil_print("ticket %s succeeded for %s\n",
1394 (eCmd==set?"set":"add"),zTktUuid);
1395 }
1396 }
1397
--- src/tkt.c
+++ src/tkt.c
@@ -216,20 +216,25 @@
216 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
217 j = fieldId(zBaseName);
218 if( j<0 ) continue;
219 aUsed[j] = 1;
220 if( aField[j].mUsed & USEDBY_TICKET ){
221 const char *zUsedByName = zName;
222 if( zUsedByName[0]=='+' ){
223 zUsedByName++;
224 blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
225 zUsedByName, zUsedByName, p->aField[i].zValue);
226 }else{
227 blob_append_sql(&sql1,", \"%w\"=%Q", zUsedByName, p->aField[i].zValue);
228 }
229 }
230 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
231 const char *zUsedByName = zName;
232 if( zUsedByName[0]=='+' ){
233 zUsedByName++;
234 }
235 blob_append_sql(&sql2, ",\"%w\"", zUsedByName);
236 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
237 }
238 if( rid>0 ){
239 wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
240 }
@@ -546,11 +551,13 @@
551 Blob *pTicket, /* The text of the ticket change record */
552 const char *zTktId, /* The ticket to which this change is applied */
553 int needMod /* True if moderation is needed */
554 ){
555 int result;
556 int rid;
557 manifest_crosslink_begin();
558 rid = content_put_ex(pTicket, 0, 0, 0, needMod);
559 if( rid==0 ){
560 fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
561 }
562 if( needMod ){
563 moderation_table_create();
@@ -560,11 +567,10 @@
567 );
568 }else{
569 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
570 db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
571 }
 
572 result = (manifest_crosslink(rid, pTicket, MC_NONE)==0);
573 assert( blob_is_reset(pTicket) );
574 if( !result ){
575 result = manifest_crosslink_end(MC_PERMIT_HOOKS);
576 }else{
@@ -1386,11 +1392,11 @@
1392 blob_appendf(&tktchng, "K %s\n", zTktUuid);
1393 blob_appendf(&tktchng, "U %F\n", zUser);
1394 md5sum_blob(&tktchng, &cksum);
1395 blob_appendf(&tktchng, "Z %b\n", &cksum);
1396 if( ticket_put(&tktchng, zTktUuid, ticket_need_moderation(1)) ){
1397 fossil_fatal("%s", g.zErrMsg);
1398 }else{
1399 fossil_print("ticket %s succeeded for %s\n",
1400 (eCmd==set?"set":"add"),zTktUuid);
1401 }
1402 }
1403
+3 -2
--- src/undo.c
+++ src/undo.c
@@ -477,14 +477,15 @@
477477
if( undo_available==0 ){
478478
fossil_print("No undo or redo is available\n");
479479
}else{
480480
Stmt q;
481481
int nChng = 0;
482
+ const char *zArticle = undo_available==1 ? "An" : "A";
482483
zCmd = undo_available==1 ? "undo" : "redo";
483
- fossil_print("A %s is available for the following command:\n\n"
484
+ fossil_print("%s %s is available for the following command:\n\n"
484485
" %s %s\n\n",
485
- zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
486
+ zArticle, zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
486487
db_prepare(&q,
487488
"SELECT existsflag, pathname FROM undo ORDER BY pathname"
488489
);
489490
while( db_step(&q)==SQLITE_ROW ){
490491
if( nChng==0 ){
491492
--- src/undo.c
+++ src/undo.c
@@ -477,14 +477,15 @@
477 if( undo_available==0 ){
478 fossil_print("No undo or redo is available\n");
479 }else{
480 Stmt q;
481 int nChng = 0;
 
482 zCmd = undo_available==1 ? "undo" : "redo";
483 fossil_print("A %s is available for the following command:\n\n"
484 " %s %s\n\n",
485 zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
486 db_prepare(&q,
487 "SELECT existsflag, pathname FROM undo ORDER BY pathname"
488 );
489 while( db_step(&q)==SQLITE_ROW ){
490 if( nChng==0 ){
491
--- src/undo.c
+++ src/undo.c
@@ -477,14 +477,15 @@
477 if( undo_available==0 ){
478 fossil_print("No undo or redo is available\n");
479 }else{
480 Stmt q;
481 int nChng = 0;
482 const char *zArticle = undo_available==1 ? "An" : "A";
483 zCmd = undo_available==1 ? "undo" : "redo";
484 fossil_print("%s %s is available for the following command:\n\n"
485 " %s %s\n\n",
486 zArticle, zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
487 db_prepare(&q,
488 "SELECT existsflag, pathname FROM undo ORDER BY pathname"
489 );
490 while( db_step(&q)==SQLITE_ROW ){
491 if( nChng==0 ){
492
+37 -12
--- src/unversioned.c
+++ src/unversioned.c
@@ -190,13 +190,26 @@
190190
}
191191
return syncFlags;
192192
}
193193
194194
/*
195
+** Return true if the zName contains any whitespace
196
+*/
197
+static int contains_whitespace(const char *zName){
198
+ while( zName[0] ){
199
+ if( fossil_isspace(zName[0]) ) return 1;
200
+ zName++;
201
+ }
202
+ return 0;
203
+}
204
+
205
+/*
206
+** COMMAND: uv*
195207
** COMMAND: unversioned
196208
**
197209
** Usage: %fossil unversioned SUBCOMMAND ARGS...
210
+** or: %fossil uv SUBCOMMAND ARGS..
198211
**
199212
** Unversioned files (UV-files) are artifacts that are synced and are available
200213
** for download but which do not preserve history. Only the most recent version
201214
** of each UV-file is retained. Changes to an UV-file are permanent and cannot
202215
** be undone, so use appropriate caution with this command.
@@ -214,35 +227,40 @@
214227
**
215228
** edit FILE Bring up FILE in a text editor for modification.
216229
**
217230
** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
218231
**
219
-** list | ls Show all unversioned files held in the local repository.
232
+** list | ls Show all unversioned files held in the local
233
+** repository.
220234
**
221
-** revert ?URL? Restore the state of all unversioned files in the local
222
-** repository to match the remote repository URL.
235
+** revert ?URL? Restore the state of all unversioned files in the
236
+** local repository to match the remote repository
237
+** URL.
238
+**
223239
** Options:
224240
** -v|--verbose Extra diagnostic output
225241
** -n|--dryrun Show what would have happened
226242
**
227
-** rm FILE ... Remove an unversioned files from the local repository.
243
+** remove | rm FILE ... Remove unversioned files from the local repository.
228244
** Changes are not pushed to other repositories until
229
-** the next sync.
245
+** the next sync.
230246
**
231247
** sync ?URL? Synchronize the state of all unversioned files with
232
-** the remote repository URL. The most recent version of
233
-** each file is propagate to all repositories and all
234
-** prior versions are permanently forgotten.
248
+** the remote repository URL. The most recent version
249
+** of each file is propagate to all repositories and
250
+** all prior versions are permanently forgotten.
251
+**
235252
** Options:
236253
** -v|--verbose Extra diagnostic output
237254
** -n|--dryrun Show what would have happened
238255
**
239256
** touch FILE ... Update the TIMESTAMP on all of the listed files
240257
**
241258
** Options:
242259
**
243
-** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for "add" and "rm".
260
+** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for the "add",
261
+** "edit", "remove", and "touch" subcommands.
244262
*/
245263
void unversioned_cmd(void){
246264
const char *zCmd;
247265
int nCmd;
248266
const char *zMtime = find_option("mtime", 0, 1);
@@ -271,10 +289,13 @@
271289
for(i=3; i<g.argc; i++){
272290
zIn = zAs ? zAs : g.argv[i];
273291
if( zIn[0]==0 || zIn[0]=='/' || !file_is_simple_pathname(zIn,1) ){
274292
fossil_fatal("'%Q' is not an acceptable filename", zIn);
275293
}
294
+ if( contains_whitespace(zIn) ){
295
+ fossil_fatal("names of unversioned files may not contain whitespace");
296
+ }
276297
blob_init(&file,0,0);
277298
blob_read_from_file(&file, g.argv[i]);
278299
unversioned_write(zIn, &file, mtime);
279300
blob_reset(&file);
280301
}
@@ -389,11 +410,11 @@
389410
}else if( memcmp(zCmd, "revert", nCmd)==0 ){
390411
unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
391412
g.argv[1] = "sync";
392413
g.argv[2] = "--uv-noop";
393414
sync_unversioned(syncFlags);
394
- }else if( memcmp(zCmd, "rm", nCmd)==0 ){
415
+ }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 ){
395416
int i;
396417
verify_all_options();
397418
db_begin_transaction();
398419
for(i=3; i<g.argc; i++){
399420
db_multi_exec(
@@ -420,11 +441,11 @@
420441
);
421442
}
422443
db_unset("uv-hash", 0);
423444
db_end_transaction(0);
424445
}else{
425
- usage("add|cat|edit|export|ls|revert|rm|sync|touch");
446
+ usage("add|cat|edit|export|list|revert|remove|sync|touch");
426447
}
427448
}
428449
429450
/*
430451
** WEBPAGE: uvlist
@@ -431,18 +452,20 @@
431452
**
432453
** Display a list of all unversioned files in the repository.
433454
** Query parameters:
434455
**
435456
** byage=1 Order the initial display be decreasing age
457
+** showdel=0 Show deleted files
436458
*/
437459
void uvstat_page(void){
438460
Stmt q;
439461
sqlite3_int64 iNow;
440462
sqlite3_int64 iTotalSz = 0;
441463
int cnt = 0;
442464
int n = 0;
443465
const char *zOrderBy = "name";
466
+ int showDel = 0;
444467
char zSzName[100];
445468
446469
login_check_credentials();
447470
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
448471
style_header("Unversioned Files");
@@ -450,20 +473,22 @@
450473
@ No unversioned files on this server
451474
style_footer();
452475
return;
453476
}
454477
if( PB("byage") ) zOrderBy = "mtime DESC";
478
+ if( PB("showdel") ) showDel = 1;
455479
db_prepare(&q,
456480
"SELECT"
457481
" name,"
458482
" mtime,"
459483
" hash,"
460484
" sz,"
461485
" (SELECT login FROM rcvfrom, user"
462486
" WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid),"
463487
" rcvid"
464
- " FROM unversioned ORDER BY %s",
488
+ " FROM unversioned %s ORDER BY %s",
489
+ showDel ? "" : "WHERE hash IS NOT NULL" /*safe-for-%s*/,
465490
zOrderBy/*safe-for-%s*/
466491
);
467492
iNow = db_int64(0, "SELECT strftime('%%s','now');");
468493
while( db_step(&q)==SQLITE_ROW ){
469494
const char *zName = db_column_text(&q, 0);
470495
--- src/unversioned.c
+++ src/unversioned.c
@@ -190,13 +190,26 @@
190 }
191 return syncFlags;
192 }
193
194 /*
 
 
 
 
 
 
 
 
 
 
 
 
195 ** COMMAND: unversioned
196 **
197 ** Usage: %fossil unversioned SUBCOMMAND ARGS...
 
198 **
199 ** Unversioned files (UV-files) are artifacts that are synced and are available
200 ** for download but which do not preserve history. Only the most recent version
201 ** of each UV-file is retained. Changes to an UV-file are permanent and cannot
202 ** be undone, so use appropriate caution with this command.
@@ -214,35 +227,40 @@
214 **
215 ** edit FILE Bring up FILE in a text editor for modification.
216 **
217 ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
218 **
219 ** list | ls Show all unversioned files held in the local repository.
 
220 **
221 ** revert ?URL? Restore the state of all unversioned files in the local
222 ** repository to match the remote repository URL.
 
 
223 ** Options:
224 ** -v|--verbose Extra diagnostic output
225 ** -n|--dryrun Show what would have happened
226 **
227 ** rm FILE ... Remove an unversioned files from the local repository.
228 ** Changes are not pushed to other repositories until
229 ** the next sync.
230 **
231 ** sync ?URL? Synchronize the state of all unversioned files with
232 ** the remote repository URL. The most recent version of
233 ** each file is propagate to all repositories and all
234 ** prior versions are permanently forgotten.
 
235 ** Options:
236 ** -v|--verbose Extra diagnostic output
237 ** -n|--dryrun Show what would have happened
238 **
239 ** touch FILE ... Update the TIMESTAMP on all of the listed files
240 **
241 ** Options:
242 **
243 ** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for "add" and "rm".
 
244 */
245 void unversioned_cmd(void){
246 const char *zCmd;
247 int nCmd;
248 const char *zMtime = find_option("mtime", 0, 1);
@@ -271,10 +289,13 @@
271 for(i=3; i<g.argc; i++){
272 zIn = zAs ? zAs : g.argv[i];
273 if( zIn[0]==0 || zIn[0]=='/' || !file_is_simple_pathname(zIn,1) ){
274 fossil_fatal("'%Q' is not an acceptable filename", zIn);
275 }
 
 
 
276 blob_init(&file,0,0);
277 blob_read_from_file(&file, g.argv[i]);
278 unversioned_write(zIn, &file, mtime);
279 blob_reset(&file);
280 }
@@ -389,11 +410,11 @@
389 }else if( memcmp(zCmd, "revert", nCmd)==0 ){
390 unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
391 g.argv[1] = "sync";
392 g.argv[2] = "--uv-noop";
393 sync_unversioned(syncFlags);
394 }else if( memcmp(zCmd, "rm", nCmd)==0 ){
395 int i;
396 verify_all_options();
397 db_begin_transaction();
398 for(i=3; i<g.argc; i++){
399 db_multi_exec(
@@ -420,11 +441,11 @@
420 );
421 }
422 db_unset("uv-hash", 0);
423 db_end_transaction(0);
424 }else{
425 usage("add|cat|edit|export|ls|revert|rm|sync|touch");
426 }
427 }
428
429 /*
430 ** WEBPAGE: uvlist
@@ -431,18 +452,20 @@
431 **
432 ** Display a list of all unversioned files in the repository.
433 ** Query parameters:
434 **
435 ** byage=1 Order the initial display be decreasing age
 
436 */
437 void uvstat_page(void){
438 Stmt q;
439 sqlite3_int64 iNow;
440 sqlite3_int64 iTotalSz = 0;
441 int cnt = 0;
442 int n = 0;
443 const char *zOrderBy = "name";
 
444 char zSzName[100];
445
446 login_check_credentials();
447 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
448 style_header("Unversioned Files");
@@ -450,20 +473,22 @@
450 @ No unversioned files on this server
451 style_footer();
452 return;
453 }
454 if( PB("byage") ) zOrderBy = "mtime DESC";
 
455 db_prepare(&q,
456 "SELECT"
457 " name,"
458 " mtime,"
459 " hash,"
460 " sz,"
461 " (SELECT login FROM rcvfrom, user"
462 " WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid),"
463 " rcvid"
464 " FROM unversioned ORDER BY %s",
 
465 zOrderBy/*safe-for-%s*/
466 );
467 iNow = db_int64(0, "SELECT strftime('%%s','now');");
468 while( db_step(&q)==SQLITE_ROW ){
469 const char *zName = db_column_text(&q, 0);
470
--- src/unversioned.c
+++ src/unversioned.c
@@ -190,13 +190,26 @@
190 }
191 return syncFlags;
192 }
193
194 /*
195 ** Return true if the zName contains any whitespace
196 */
197 static int contains_whitespace(const char *zName){
198 while( zName[0] ){
199 if( fossil_isspace(zName[0]) ) return 1;
200 zName++;
201 }
202 return 0;
203 }
204
205 /*
206 ** COMMAND: uv*
207 ** COMMAND: unversioned
208 **
209 ** Usage: %fossil unversioned SUBCOMMAND ARGS...
210 ** or: %fossil uv SUBCOMMAND ARGS..
211 **
212 ** Unversioned files (UV-files) are artifacts that are synced and are available
213 ** for download but which do not preserve history. Only the most recent version
214 ** of each UV-file is retained. Changes to an UV-file are permanent and cannot
215 ** be undone, so use appropriate caution with this command.
@@ -214,35 +227,40 @@
227 **
228 ** edit FILE Bring up FILE in a text editor for modification.
229 **
230 ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
231 **
232 ** list | ls Show all unversioned files held in the local
233 ** repository.
234 **
235 ** revert ?URL? Restore the state of all unversioned files in the
236 ** local repository to match the remote repository
237 ** URL.
238 **
239 ** Options:
240 ** -v|--verbose Extra diagnostic output
241 ** -n|--dryrun Show what would have happened
242 **
243 ** remove | rm FILE ... Remove unversioned files from the local repository.
244 ** Changes are not pushed to other repositories until
245 ** the next sync.
246 **
247 ** sync ?URL? Synchronize the state of all unversioned files with
248 ** the remote repository URL. The most recent version
249 ** of each file is propagate to all repositories and
250 ** all prior versions are permanently forgotten.
251 **
252 ** Options:
253 ** -v|--verbose Extra diagnostic output
254 ** -n|--dryrun Show what would have happened
255 **
256 ** touch FILE ... Update the TIMESTAMP on all of the listed files
257 **
258 ** Options:
259 **
260 ** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for the "add",
261 ** "edit", "remove", and "touch" subcommands.
262 */
263 void unversioned_cmd(void){
264 const char *zCmd;
265 int nCmd;
266 const char *zMtime = find_option("mtime", 0, 1);
@@ -271,10 +289,13 @@
289 for(i=3; i<g.argc; i++){
290 zIn = zAs ? zAs : g.argv[i];
291 if( zIn[0]==0 || zIn[0]=='/' || !file_is_simple_pathname(zIn,1) ){
292 fossil_fatal("'%Q' is not an acceptable filename", zIn);
293 }
294 if( contains_whitespace(zIn) ){
295 fossil_fatal("names of unversioned files may not contain whitespace");
296 }
297 blob_init(&file,0,0);
298 blob_read_from_file(&file, g.argv[i]);
299 unversioned_write(zIn, &file, mtime);
300 blob_reset(&file);
301 }
@@ -389,11 +410,11 @@
410 }else if( memcmp(zCmd, "revert", nCmd)==0 ){
411 unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
412 g.argv[1] = "sync";
413 g.argv[2] = "--uv-noop";
414 sync_unversioned(syncFlags);
415 }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 ){
416 int i;
417 verify_all_options();
418 db_begin_transaction();
419 for(i=3; i<g.argc; i++){
420 db_multi_exec(
@@ -420,11 +441,11 @@
441 );
442 }
443 db_unset("uv-hash", 0);
444 db_end_transaction(0);
445 }else{
446 usage("add|cat|edit|export|list|revert|remove|sync|touch");
447 }
448 }
449
450 /*
451 ** WEBPAGE: uvlist
@@ -431,18 +452,20 @@
452 **
453 ** Display a list of all unversioned files in the repository.
454 ** Query parameters:
455 **
456 ** byage=1 Order the initial display be decreasing age
457 ** showdel=0 Show deleted files
458 */
459 void uvstat_page(void){
460 Stmt q;
461 sqlite3_int64 iNow;
462 sqlite3_int64 iTotalSz = 0;
463 int cnt = 0;
464 int n = 0;
465 const char *zOrderBy = "name";
466 int showDel = 0;
467 char zSzName[100];
468
469 login_check_credentials();
470 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
471 style_header("Unversioned Files");
@@ -450,20 +473,22 @@
473 @ No unversioned files on this server
474 style_footer();
475 return;
476 }
477 if( PB("byage") ) zOrderBy = "mtime DESC";
478 if( PB("showdel") ) showDel = 1;
479 db_prepare(&q,
480 "SELECT"
481 " name,"
482 " mtime,"
483 " hash,"
484 " sz,"
485 " (SELECT login FROM rcvfrom, user"
486 " WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid),"
487 " rcvid"
488 " FROM unversioned %s ORDER BY %s",
489 showDel ? "" : "WHERE hash IS NOT NULL" /*safe-for-%s*/,
490 zOrderBy/*safe-for-%s*/
491 );
492 iNow = db_int64(0, "SELECT strftime('%%s','now');");
493 while( db_step(&q)==SQLITE_ROW ){
494 const char *zName = db_column_text(&q, 0);
495
+48 -16
--- src/user.c
+++ src/user.c
@@ -19,14 +19,10 @@
1919
** querying information about users.
2020
*/
2121
#include "config.h"
2222
#include "user.h"
2323
24
-#if defined(_WIN32)
25
-#include <conio.h>
26
-#endif
27
-
2824
/*
2925
** Strip leading and trailing space from a string and add the string
3026
** onto the end of a blob.
3127
*/
3228
static void strip_string(Blob *pBlob, char *z){
@@ -43,53 +39,74 @@
4339
}
4440
blob_append(pBlob, z, -1);
4541
}
4642
4743
#if defined(_WIN32) || defined(__BIONIC__)
48
-#ifdef __MINGW32__
44
+#ifdef _WIN32
4945
#include <conio.h>
5046
#endif
47
+
5148
/*
52
-** getpass for Windows and Android
49
+** getpass() for Windows and Android.
5350
*/
51
+static char *zPwdBuffer = 0;
52
+static size_t nPwdBuffer = 0;
53
+
5454
static char *getpass(const char *prompt){
55
- static char pwd[64];
55
+ char *zPwd;
56
+ size_t nPwd;
5657
size_t i;
5758
59
+ if( zPwdBuffer==0 ){
60
+ zPwdBuffer = fossil_secure_alloc_page(&nPwdBuffer);
61
+ assert( zPwdBuffer );
62
+ }else{
63
+ fossil_secure_zero(zPwdBuffer, nPwdBuffer);
64
+ }
65
+ zPwd = zPwdBuffer;
66
+ nPwd = nPwdBuffer;
5867
fputs(prompt,stderr);
5968
fflush(stderr);
60
- for(i=0; i<sizeof(pwd)-1; ++i){
69
+ assert( zPwd!=0 );
70
+ assert( nPwd>0 );
71
+ for(i=0; i<nPwd-1; ++i){
6172
#if defined(_WIN32)
62
- pwd[i] = _getch();
73
+ zPwd[i] = _getch();
6374
#else
64
- pwd[i] = getc(stdin);
75
+ zPwd[i] = getc(stdin);
6576
#endif
66
- if(pwd[i]=='\r' || pwd[i]=='\n'){
77
+ if(zPwd[i]=='\r' || zPwd[i]=='\n'){
6778
break;
6879
}
6980
/* BS or DEL */
70
- else if(i>0 && (pwd[i]==8 || pwd[i]==127)){
81
+ else if(i>0 && (zPwd[i]==8 || zPwd[i]==127)){
7182
i -= 2;
7283
continue;
7384
}
7485
/* CTRL-C */
75
- else if(pwd[i]==3) {
86
+ else if(zPwd[i]==3) {
7687
i=0;
7788
break;
7889
}
7990
/* ESC */
80
- else if(pwd[i]==27){
91
+ else if(zPwd[i]==27){
8192
i=0;
8293
break;
8394
}
8495
else{
8596
fputc('*',stderr);
8697
}
8798
}
88
- pwd[i]='\0';
99
+ zPwd[i]='\0';
89100
fputs("\n", stderr);
90
- return pwd;
101
+ assert( zPwd==zPwdBuffer );
102
+ return zPwd;
103
+}
104
+void freepass(){
105
+ if( !zPwdBuffer ) return;
106
+ assert( nPwdBuffer>0 );
107
+ fossil_secure_free_page(zPwdBuffer, nPwdBuffer);
91108
}
92109
#endif
93110
94111
#if defined(_WIN32) || defined(WIN32)
95112
# include <io.h>
@@ -553,10 +570,25 @@
553570
db_multi_exec(
554571
"UPDATE user SET pw=shared_secret(pw,login), mtime=now()"
555572
" WHERE length(pw)>0 AND length(pw)!=40"
556573
);
557574
}
575
+
576
+/*
577
+** COMMAND: test-prompt-user
578
+**
579
+** Usage: %fossil test-prompt-user PROMPT
580
+**
581
+** Prompts the user for input and then prints it verbatim (i.e. without
582
+** a trailing line terminator).
583
+*/
584
+void test_prompt_user_cmd(void){
585
+ Blob answer;
586
+ if( g.argc!=3 ) usage("PROMPT");
587
+ prompt_user(g.argv[2], &answer);
588
+ fossil_print("%s", blob_str(&answer));
589
+}
558590
559591
/*
560592
** WEBPAGE: access_log
561593
**
562594
** Show login attempts, including timestamp and IP address.
563595
--- src/user.c
+++ src/user.c
@@ -19,14 +19,10 @@
19 ** querying information about users.
20 */
21 #include "config.h"
22 #include "user.h"
23
24 #if defined(_WIN32)
25 #include <conio.h>
26 #endif
27
28 /*
29 ** Strip leading and trailing space from a string and add the string
30 ** onto the end of a blob.
31 */
32 static void strip_string(Blob *pBlob, char *z){
@@ -43,53 +39,74 @@
43 }
44 blob_append(pBlob, z, -1);
45 }
46
47 #if defined(_WIN32) || defined(__BIONIC__)
48 #ifdef __MINGW32__
49 #include <conio.h>
50 #endif
 
51 /*
52 ** getpass for Windows and Android
53 */
 
 
 
54 static char *getpass(const char *prompt){
55 static char pwd[64];
 
56 size_t i;
57
 
 
 
 
 
 
 
 
58 fputs(prompt,stderr);
59 fflush(stderr);
60 for(i=0; i<sizeof(pwd)-1; ++i){
 
 
61 #if defined(_WIN32)
62 pwd[i] = _getch();
63 #else
64 pwd[i] = getc(stdin);
65 #endif
66 if(pwd[i]=='\r' || pwd[i]=='\n'){
67 break;
68 }
69 /* BS or DEL */
70 else if(i>0 && (pwd[i]==8 || pwd[i]==127)){
71 i -= 2;
72 continue;
73 }
74 /* CTRL-C */
75 else if(pwd[i]==3) {
76 i=0;
77 break;
78 }
79 /* ESC */
80 else if(pwd[i]==27){
81 i=0;
82 break;
83 }
84 else{
85 fputc('*',stderr);
86 }
87 }
88 pwd[i]='\0';
89 fputs("\n", stderr);
90 return pwd;
 
 
 
 
 
 
91 }
92 #endif
93
94 #if defined(_WIN32) || defined(WIN32)
95 # include <io.h>
@@ -553,10 +570,25 @@
553 db_multi_exec(
554 "UPDATE user SET pw=shared_secret(pw,login), mtime=now()"
555 " WHERE length(pw)>0 AND length(pw)!=40"
556 );
557 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
559 /*
560 ** WEBPAGE: access_log
561 **
562 ** Show login attempts, including timestamp and IP address.
563
--- src/user.c
+++ src/user.c
@@ -19,14 +19,10 @@
19 ** querying information about users.
20 */
21 #include "config.h"
22 #include "user.h"
23
 
 
 
 
24 /*
25 ** Strip leading and trailing space from a string and add the string
26 ** onto the end of a blob.
27 */
28 static void strip_string(Blob *pBlob, char *z){
@@ -43,53 +39,74 @@
39 }
40 blob_append(pBlob, z, -1);
41 }
42
43 #if defined(_WIN32) || defined(__BIONIC__)
44 #ifdef _WIN32
45 #include <conio.h>
46 #endif
47
48 /*
49 ** getpass() for Windows and Android.
50 */
51 static char *zPwdBuffer = 0;
52 static size_t nPwdBuffer = 0;
53
54 static char *getpass(const char *prompt){
55 char *zPwd;
56 size_t nPwd;
57 size_t i;
58
59 if( zPwdBuffer==0 ){
60 zPwdBuffer = fossil_secure_alloc_page(&nPwdBuffer);
61 assert( zPwdBuffer );
62 }else{
63 fossil_secure_zero(zPwdBuffer, nPwdBuffer);
64 }
65 zPwd = zPwdBuffer;
66 nPwd = nPwdBuffer;
67 fputs(prompt,stderr);
68 fflush(stderr);
69 assert( zPwd!=0 );
70 assert( nPwd>0 );
71 for(i=0; i<nPwd-1; ++i){
72 #if defined(_WIN32)
73 zPwd[i] = _getch();
74 #else
75 zPwd[i] = getc(stdin);
76 #endif
77 if(zPwd[i]=='\r' || zPwd[i]=='\n'){
78 break;
79 }
80 /* BS or DEL */
81 else if(i>0 && (zPwd[i]==8 || zPwd[i]==127)){
82 i -= 2;
83 continue;
84 }
85 /* CTRL-C */
86 else if(zPwd[i]==3) {
87 i=0;
88 break;
89 }
90 /* ESC */
91 else if(zPwd[i]==27){
92 i=0;
93 break;
94 }
95 else{
96 fputc('*',stderr);
97 }
98 }
99 zPwd[i]='\0';
100 fputs("\n", stderr);
101 assert( zPwd==zPwdBuffer );
102 return zPwd;
103 }
104 void freepass(){
105 if( !zPwdBuffer ) return;
106 assert( nPwdBuffer>0 );
107 fossil_secure_free_page(zPwdBuffer, nPwdBuffer);
108 }
109 #endif
110
111 #if defined(_WIN32) || defined(WIN32)
112 # include <io.h>
@@ -553,10 +570,25 @@
570 db_multi_exec(
571 "UPDATE user SET pw=shared_secret(pw,login), mtime=now()"
572 " WHERE length(pw)>0 AND length(pw)!=40"
573 );
574 }
575
576 /*
577 ** COMMAND: test-prompt-user
578 **
579 ** Usage: %fossil test-prompt-user PROMPT
580 **
581 ** Prompts the user for input and then prints it verbatim (i.e. without
582 ** a trailing line terminator).
583 */
584 void test_prompt_user_cmd(void){
585 Blob answer;
586 if( g.argc!=3 ) usage("PROMPT");
587 prompt_user(g.argv[2], &answer);
588 fossil_print("%s", blob_str(&answer));
589 }
590
591 /*
592 ** WEBPAGE: access_log
593 **
594 ** Show login attempts, including timestamp and IP address.
595
+1 -1
--- src/utf8.c
+++ src/utf8.c
@@ -317,11 +317,11 @@
317317
wchar_t *zUnicode; /* Unicode version of zUtf8 */
318318
DWORD dummy;
319319
Blob blob;
320320
321321
static int istty[2] = { -1, -1 };
322
- if( istty[toStdErr] == -1 ){
322
+ if( istty[toStdErr]==-1 ){
323323
istty[toStdErr] = _isatty(toStdErr + 1) != 0;
324324
}
325325
if( !istty[toStdErr] ){
326326
/* stdout/stderr is not a console. */
327327
return -1;
328328
--- src/utf8.c
+++ src/utf8.c
@@ -317,11 +317,11 @@
317 wchar_t *zUnicode; /* Unicode version of zUtf8 */
318 DWORD dummy;
319 Blob blob;
320
321 static int istty[2] = { -1, -1 };
322 if( istty[toStdErr] == -1 ){
323 istty[toStdErr] = _isatty(toStdErr + 1) != 0;
324 }
325 if( !istty[toStdErr] ){
326 /* stdout/stderr is not a console. */
327 return -1;
328
--- src/utf8.c
+++ src/utf8.c
@@ -317,11 +317,11 @@
317 wchar_t *zUnicode; /* Unicode version of zUtf8 */
318 DWORD dummy;
319 Blob blob;
320
321 static int istty[2] = { -1, -1 };
322 if( istty[toStdErr]==-1 ){
323 istty[toStdErr] = _isatty(toStdErr + 1) != 0;
324 }
325 if( !istty[toStdErr] ){
326 /* stdout/stderr is not a console. */
327 return -1;
328
+57
--- src/util.c
+++ src/util.c
@@ -55,10 +55,67 @@
5555
}
5656
void *fossil_realloc(void *p, size_t n){
5757
p = realloc(p, n);
5858
if( p==0 ) fossil_panic("out of memory");
5959
return p;
60
+}
61
+void fossil_secure_zero(void *p, size_t n){
62
+ volatile unsigned char *vp = (volatile unsigned char *)p;
63
+ size_t i;
64
+
65
+ if( p==0 ) return;
66
+ assert( n>0 );
67
+ if( n==0 ) return;
68
+ for(i=0; i<n; i++){ vp[i] ^= 0xFF; }
69
+ for(i=0; i<n; i++){ vp[i] ^= vp[i]; }
70
+}
71
+void fossil_get_page_size(size_t *piPageSize){
72
+#if defined(_WIN32)
73
+ SYSTEM_INFO sysInfo;
74
+ memset(&sysInfo, 0, sizeof(SYSTEM_INFO));
75
+ GetSystemInfo(&sysInfo);
76
+ *piPageSize = (size_t)sysInfo.dwPageSize;
77
+#else
78
+ *piPageSize = 4096; /* FIXME: What for POSIX? */
79
+#endif
80
+}
81
+void *fossil_secure_alloc_page(size_t *pN){
82
+ void *p;
83
+ size_t pageSize;
84
+
85
+ fossil_get_page_size(&pageSize);
86
+ assert( pageSize>0 );
87
+ assert( pageSize%2==0 );
88
+#if defined(_WIN32)
89
+ p = VirtualAlloc(NULL, pageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
90
+ if( p==NULL ){
91
+ fossil_fatal("VirtualAlloc failed: %lu\n", GetLastError());
92
+ }
93
+ if( !VirtualLock(p, pageSize) ){
94
+ fossil_fatal("VirtualLock failed: %lu\n", GetLastError());
95
+ }
96
+#else
97
+ p = fossil_malloc(pageSize);
98
+#endif
99
+ fossil_secure_zero(p, pageSize);
100
+ if( pN ) *pN = pageSize;
101
+ return p;
102
+}
103
+void fossil_secure_free_page(void *p, size_t n){
104
+ if( !p ) return;
105
+ assert( n>0 );
106
+ fossil_secure_zero(p, n);
107
+#if defined(_WIN32)
108
+ if( !VirtualUnlock(p, n) ){
109
+ fossil_fatal("VirtualUnlock failed: %lu\n", GetLastError());
110
+ }
111
+ if( !VirtualFree(p, 0, MEM_RELEASE) ){
112
+ fossil_fatal("VirtualFree failed: %lu\n", GetLastError());
113
+ }
114
+#else
115
+ fossil_free(p);
116
+#endif
60117
}
61118
62119
/*
63120
** This function implements a cross-platform "system()" interface.
64121
*/
65122
--- src/util.c
+++ src/util.c
@@ -55,10 +55,67 @@
55 }
56 void *fossil_realloc(void *p, size_t n){
57 p = realloc(p, n);
58 if( p==0 ) fossil_panic("out of memory");
59 return p;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60 }
61
62 /*
63 ** This function implements a cross-platform "system()" interface.
64 */
65
--- src/util.c
+++ src/util.c
@@ -55,10 +55,67 @@
55 }
56 void *fossil_realloc(void *p, size_t n){
57 p = realloc(p, n);
58 if( p==0 ) fossil_panic("out of memory");
59 return p;
60 }
61 void fossil_secure_zero(void *p, size_t n){
62 volatile unsigned char *vp = (volatile unsigned char *)p;
63 size_t i;
64
65 if( p==0 ) return;
66 assert( n>0 );
67 if( n==0 ) return;
68 for(i=0; i<n; i++){ vp[i] ^= 0xFF; }
69 for(i=0; i<n; i++){ vp[i] ^= vp[i]; }
70 }
71 void fossil_get_page_size(size_t *piPageSize){
72 #if defined(_WIN32)
73 SYSTEM_INFO sysInfo;
74 memset(&sysInfo, 0, sizeof(SYSTEM_INFO));
75 GetSystemInfo(&sysInfo);
76 *piPageSize = (size_t)sysInfo.dwPageSize;
77 #else
78 *piPageSize = 4096; /* FIXME: What for POSIX? */
79 #endif
80 }
81 void *fossil_secure_alloc_page(size_t *pN){
82 void *p;
83 size_t pageSize;
84
85 fossil_get_page_size(&pageSize);
86 assert( pageSize>0 );
87 assert( pageSize%2==0 );
88 #if defined(_WIN32)
89 p = VirtualAlloc(NULL, pageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
90 if( p==NULL ){
91 fossil_fatal("VirtualAlloc failed: %lu\n", GetLastError());
92 }
93 if( !VirtualLock(p, pageSize) ){
94 fossil_fatal("VirtualLock failed: %lu\n", GetLastError());
95 }
96 #else
97 p = fossil_malloc(pageSize);
98 #endif
99 fossil_secure_zero(p, pageSize);
100 if( pN ) *pN = pageSize;
101 return p;
102 }
103 void fossil_secure_free_page(void *p, size_t n){
104 if( !p ) return;
105 assert( n>0 );
106 fossil_secure_zero(p, n);
107 #if defined(_WIN32)
108 if( !VirtualUnlock(p, n) ){
109 fossil_fatal("VirtualUnlock failed: %lu\n", GetLastError());
110 }
111 if( !VirtualFree(p, 0, MEM_RELEASE) ){
112 fossil_fatal("VirtualFree failed: %lu\n", GetLastError());
113 }
114 #else
115 fossil_free(p);
116 #endif
117 }
118
119 /*
120 ** This function implements a cross-platform "system()" interface.
121 */
122
+8 -8
--- src/vfile.c
+++ src/vfile.c
@@ -264,19 +264,19 @@
264264
}
265265
}
266266
}
267267
#ifndef _WIN32
268268
if( chnged==0 || chnged==6 || chnged==7 || chnged==8 || chnged==9 ){
269
- if( origPerm == currentPerm ){
269
+ if( origPerm==currentPerm ){
270270
chnged = 0;
271
- }else if( currentPerm == PERM_EXE ){
271
+ }else if( currentPerm==PERM_EXE ){
272272
chnged = 6;
273
- }else if( currentPerm == PERM_LNK ){
273
+ }else if( currentPerm==PERM_LNK ){
274274
chnged = 7;
275
- }else if( origPerm == PERM_EXE ){
275
+ }else if( origPerm==PERM_EXE ){
276276
chnged = 8;
277
- }else if( origPerm == PERM_LNK ){
277
+ }else if( origPerm==PERM_LNK ){
278278
chnged = 9;
279279
}
280280
}
281281
#endif
282282
if( currentMtime!=oldMtime || chnged!=oldChnged ){
@@ -348,13 +348,13 @@
348348
blob_reset(&content);
349349
continue;
350350
}
351351
}
352352
if( verbose ) fossil_print("%s\n", &zName[nRepos]);
353
- if( file_wd_isdir(zName) == 1 ){
353
+ if( file_wd_isdir(zName)==1 ){
354354
/*TODO(dchest): remove directories? */
355
- fossil_fatal("%s is directory, cannot overwrite\n", zName);
355
+ fossil_fatal("%s is directory, cannot overwrite", zName);
356356
}
357357
if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(0)) ){
358358
file_delete(zName);
359359
}
360360
if( isLink ){
@@ -918,11 +918,11 @@
918918
blob_zero(pManOut);
919919
}
920920
db_must_be_within_tree();
921921
pManifest = manifest_get(vid, CFTYPE_MANIFEST, &err);
922922
if( pManifest==0 ){
923
- fossil_fatal("manifest file (%d) is malformed:\n%s\n",
923
+ fossil_fatal("manifest file (%d) is malformed:\n%s",
924924
vid, blob_str(&err));
925925
}
926926
manifest_file_rewind(pManifest);
927927
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
928928
if( pFile->zUuid==0 ) continue;
929929
--- src/vfile.c
+++ src/vfile.c
@@ -264,19 +264,19 @@
264 }
265 }
266 }
267 #ifndef _WIN32
268 if( chnged==0 || chnged==6 || chnged==7 || chnged==8 || chnged==9 ){
269 if( origPerm == currentPerm ){
270 chnged = 0;
271 }else if( currentPerm == PERM_EXE ){
272 chnged = 6;
273 }else if( currentPerm == PERM_LNK ){
274 chnged = 7;
275 }else if( origPerm == PERM_EXE ){
276 chnged = 8;
277 }else if( origPerm == PERM_LNK ){
278 chnged = 9;
279 }
280 }
281 #endif
282 if( currentMtime!=oldMtime || chnged!=oldChnged ){
@@ -348,13 +348,13 @@
348 blob_reset(&content);
349 continue;
350 }
351 }
352 if( verbose ) fossil_print("%s\n", &zName[nRepos]);
353 if( file_wd_isdir(zName) == 1 ){
354 /*TODO(dchest): remove directories? */
355 fossil_fatal("%s is directory, cannot overwrite\n", zName);
356 }
357 if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(0)) ){
358 file_delete(zName);
359 }
360 if( isLink ){
@@ -918,11 +918,11 @@
918 blob_zero(pManOut);
919 }
920 db_must_be_within_tree();
921 pManifest = manifest_get(vid, CFTYPE_MANIFEST, &err);
922 if( pManifest==0 ){
923 fossil_fatal("manifest file (%d) is malformed:\n%s\n",
924 vid, blob_str(&err));
925 }
926 manifest_file_rewind(pManifest);
927 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
928 if( pFile->zUuid==0 ) continue;
929
--- src/vfile.c
+++ src/vfile.c
@@ -264,19 +264,19 @@
264 }
265 }
266 }
267 #ifndef _WIN32
268 if( chnged==0 || chnged==6 || chnged==7 || chnged==8 || chnged==9 ){
269 if( origPerm==currentPerm ){
270 chnged = 0;
271 }else if( currentPerm==PERM_EXE ){
272 chnged = 6;
273 }else if( currentPerm==PERM_LNK ){
274 chnged = 7;
275 }else if( origPerm==PERM_EXE ){
276 chnged = 8;
277 }else if( origPerm==PERM_LNK ){
278 chnged = 9;
279 }
280 }
281 #endif
282 if( currentMtime!=oldMtime || chnged!=oldChnged ){
@@ -348,13 +348,13 @@
348 blob_reset(&content);
349 continue;
350 }
351 }
352 if( verbose ) fossil_print("%s\n", &zName[nRepos]);
353 if( file_wd_isdir(zName)==1 ){
354 /*TODO(dchest): remove directories? */
355 fossil_fatal("%s is directory, cannot overwrite", zName);
356 }
357 if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(0)) ){
358 file_delete(zName);
359 }
360 if( isLink ){
@@ -918,11 +918,11 @@
918 blob_zero(pManOut);
919 }
920 db_must_be_within_tree();
921 pManifest = manifest_get(vid, CFTYPE_MANIFEST, &err);
922 if( pManifest==0 ){
923 fossil_fatal("manifest file (%d) is malformed:\n%s",
924 vid, blob_str(&err));
925 }
926 manifest_file_rewind(pManifest);
927 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
928 if( pFile->zUuid==0 ) continue;
929
+105 -17
--- src/winhttp.c
+++ src/winhttp.c
@@ -24,10 +24,24 @@
2424
/* This code is for win32 only */
2525
#include <windows.h>
2626
#include <process.h>
2727
#include "winhttp.h"
2828
29
+/*
30
+** The HttpServer structure holds information about an instance of
31
+** the HTTP server itself.
32
+*/
33
+typedef struct HttpServer HttpServer;
34
+struct HttpServer {
35
+ HANDLE hStoppedEvent; /* Event to signal when server is stopped,
36
+ ** must be closed by callee. */
37
+ char *zStopper; /* The stopper file name, must be freed by
38
+ ** callee. */
39
+ SOCKET listener; /* Socket on which the server is listening,
40
+ ** may be closed by callee. */
41
+};
42
+
2943
/*
3044
** The HttpRequest structure holds information about each incoming
3145
** HTTP request.
3246
*/
3347
typedef struct HttpRequest HttpRequest;
@@ -70,10 +84,51 @@
7084
const char *zService,
7185
const char *zErr
7286
){
7387
fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
7488
}
89
+
90
+/*
91
+** Make sure the server stops as soon as possible after the stopper file
92
+** is found. If there is no stopper file name, do nothing.
93
+*/
94
+static void win32_server_stopper(void *pAppData){
95
+ HttpServer *p = (HttpServer*)pAppData;
96
+ if( p!=0 ){
97
+ HANDLE hStoppedEvent = p->hStoppedEvent;
98
+ const char *zStopper = p->zStopper;
99
+ SOCKET listener = p->listener;
100
+ if( hStoppedEvent!=NULL && zStopper!=0 && listener!=INVALID_SOCKET ){
101
+ while( 1 ){
102
+ DWORD dwResult = WaitForMultipleObjectsEx(1, &hStoppedEvent, FALSE,
103
+ 1000, TRUE);
104
+ if( dwResult!=WAIT_IO_COMPLETION && dwResult!=WAIT_TIMEOUT ){
105
+ /* The event is either invalid, signaled, or abandoned. Bail
106
+ ** out now because those conditions should indicate the parent
107
+ ** thread is dead or dying. */
108
+ break;
109
+ }
110
+ if( file_size(zStopper)>=0 ){
111
+ /* The stopper file has been found. Attempt to close the server
112
+ ** listener socket now and then exit. */
113
+ closesocket(listener);
114
+ p->listener = INVALID_SOCKET;
115
+ break;
116
+ }
117
+ }
118
+ }
119
+ if( hStoppedEvent!=NULL ){
120
+ CloseHandle(hStoppedEvent);
121
+ p->hStoppedEvent = NULL;
122
+ }
123
+ if( zStopper!=0 ){
124
+ fossil_free(p->zStopper);
125
+ p->zStopper = 0;
126
+ }
127
+ fossil_free(p);
128
+ }
129
+}
75130
76131
/*
77132
** Process a single incoming HTTP request.
78133
*/
79134
static void win32_http_request(void *pAppData){
@@ -163,11 +218,11 @@
163218
if( in ) fclose(in);
164219
closesocket(p->s);
165220
file_delete(zRequestFName);
166221
file_delete(zReplyFName);
167222
file_delete(zCmdFName);
168
- free(p);
223
+ fossil_free(p);
169224
}
170225
171226
/*
172227
** Process a single incoming SCGI request.
173228
*/
@@ -225,11 +280,11 @@
225280
if( out ) fclose(out);
226281
if( in ) fclose(in);
227282
closesocket(p->s);
228283
file_delete(zRequestFName);
229284
file_delete(zReplyFName);
230
- free(p);
285
+ fossil_free(p);
231286
}
232287
233288
234289
/*
235290
** Start a listening socket and process incoming HTTP requests on
@@ -243,19 +298,23 @@
243298
const char *zNotFound, /* The --notfound option, or NULL */
244299
const char *zFileGlob, /* The --fileglob option, or NULL */
245300
const char *zIpAddr, /* Bind to this IP address, if not NULL */
246301
int flags /* One or more HTTP_SERVER_ flags */
247302
){
303
+ HANDLE hStoppedEvent;
248304
WSADATA wd;
249305
SOCKET s = INVALID_SOCKET;
250306
SOCKADDR_IN addr;
251307
int idCnt = 0;
252308
int iPort = mnPort;
253309
Blob options;
254310
wchar_t zTmpPath[MAX_PATH];
311
+#if USE_SEE
312
+ const char *zSavedKey = 0;
313
+ size_t savedKeySize = 0;
314
+#endif
255315
256
- if( zStopper ) file_delete(zStopper);
257316
blob_zero(&options);
258317
if( zBaseUrl ){
259318
blob_appendf(&options, " --baseurl %s", zBaseUrl);
260319
}
261320
if( zNotFound ){
@@ -271,10 +330,18 @@
271330
blob_appendf(&options, " --th-trace");
272331
}
273332
if( flags & HTTP_SERVER_REPOLIST ){
274333
blob_appendf(&options, " --repolist");
275334
}
335
+#if USE_SEE
336
+ zSavedKey = db_get_saved_encryption_key();
337
+ savedKeySize = db_get_saved_encryption_key_size();
338
+ if( zSavedKey!=0 && savedKeySize>0 ){
339
+ blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
340
+ zSavedKey, savedKeySize);
341
+ }
342
+#endif
276343
if( WSAStartup(MAKEWORD(1,1), &wd) ){
277344
fossil_fatal("unable to initialize winsock");
278345
}
279346
while( iPort<=mxPort ){
280347
s = socket(AF_INET, SOCK_STREAM, 0);
@@ -324,17 +391,35 @@
324391
zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
325392
fossil_print("Launch webbrowser: %s\n", zBrowser);
326393
fossil_system(zBrowser);
327394
}
328395
fossil_print("Type Ctrl-C to stop the HTTP server\n");
396
+ /* Create an event used to signal when this server is exiting. */
397
+ hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
398
+ assert( hStoppedEvent!=NULL );
399
+ /* If there is a stopper file name, start the dedicated thread now.
400
+ ** It will attempt to close the listener socket within 1 second of
401
+ ** the stopper file being created. */
402
+ if( zStopper ){
403
+ HttpServer *pServer = fossil_malloc(sizeof(HttpServer));
404
+ memset(pServer, 0, sizeof(HttpServer));
405
+ DuplicateHandle(GetCurrentProcess(), hStoppedEvent,
406
+ GetCurrentProcess(), &pServer->hStoppedEvent,
407
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
408
+ assert( pServer->hStoppedEvent!=NULL );
409
+ pServer->zStopper = fossil_strdup(zStopper);
410
+ pServer->listener = s;
411
+ file_delete(zStopper);
412
+ _beginthread(win32_server_stopper, 0, (void*)pServer);
413
+ }
329414
/* Set the service status to running and pass the listener socket to the
330415
** service handling procedures. */
331416
win32_http_service_running(s);
332417
for(;;){
333418
SOCKET client;
334419
SOCKADDR_IN client_addr;
335
- HttpRequest *p;
420
+ HttpRequest *pRequest;
336421
int len = sizeof(client_addr);
337422
int wsaError;
338423
339424
client = accept(s, (struct sockaddr*)&client_addr, &len);
340425
if( client==INVALID_SOCKET ){
@@ -347,27 +432,27 @@
347432
}else{
348433
closesocket(s);
349434
WSACleanup();
350435
fossil_fatal("error from accept()");
351436
}
352
- }else if( zStopper && file_size(zStopper)>=0 ){
353
- break;
354
- }
355
- p = fossil_malloc( sizeof(*p) );
356
- p->id = ++idCnt;
357
- p->s = client;
358
- p->addr = client_addr;
359
- p->flags = flags;
360
- p->zOptions = blob_str(&options);
437
+ }
438
+ pRequest = fossil_malloc(sizeof(HttpRequest));
439
+ pRequest->id = ++idCnt;
440
+ pRequest->s = client;
441
+ pRequest->addr = client_addr;
442
+ pRequest->flags = flags;
443
+ pRequest->zOptions = blob_str(&options);
361444
if( flags & HTTP_SERVER_SCGI ){
362
- _beginthread(win32_scgi_request, 0, (void*)p);
445
+ _beginthread(win32_scgi_request, 0, (void*)pRequest);
363446
}else{
364
- _beginthread(win32_http_request, 0, (void*)p);
447
+ _beginthread(win32_http_request, 0, (void*)pRequest);
365448
}
366449
}
367450
closesocket(s);
368451
WSACleanup();
452
+ SetEvent(hStoppedEvent);
453
+ CloseHandle(hStoppedEvent);
369454
}
370455
371456
/*
372457
** The HttpService structure is used to pass information to the service main
373458
** function and to the service control handler function.
@@ -581,11 +666,13 @@
581666
}
582667
}
583668
return 0;
584669
}
585670
586
-/* dupe ifdef needed for mkindex
671
+/* Dupliate #ifdef needed for mkindex */
672
+#ifdef _WIN32
673
+/*
587674
** COMMAND: winsrv*
588675
**
589676
** Usage: %fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS?
590677
**
591678
** Where METHOD is one of: create delete show start stop.
@@ -1030,6 +1117,7 @@
10301117
fossil_fatal("METHOD should be one of:"
10311118
" create delete show start stop");
10321119
}
10331120
return;
10341121
}
1035
-#endif /* _WIN32 -- This code is for win32 only */
1122
+#endif /* _WIN32 -- dupe needed for mkindex */
1123
+#endif /* _WIN32 -- This code is for win32 only */
10361124
--- src/winhttp.c
+++ src/winhttp.c
@@ -24,10 +24,24 @@
24 /* This code is for win32 only */
25 #include <windows.h>
26 #include <process.h>
27 #include "winhttp.h"
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29 /*
30 ** The HttpRequest structure holds information about each incoming
31 ** HTTP request.
32 */
33 typedef struct HttpRequest HttpRequest;
@@ -70,10 +84,51 @@
70 const char *zService,
71 const char *zErr
72 ){
73 fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
74 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
76 /*
77 ** Process a single incoming HTTP request.
78 */
79 static void win32_http_request(void *pAppData){
@@ -163,11 +218,11 @@
163 if( in ) fclose(in);
164 closesocket(p->s);
165 file_delete(zRequestFName);
166 file_delete(zReplyFName);
167 file_delete(zCmdFName);
168 free(p);
169 }
170
171 /*
172 ** Process a single incoming SCGI request.
173 */
@@ -225,11 +280,11 @@
225 if( out ) fclose(out);
226 if( in ) fclose(in);
227 closesocket(p->s);
228 file_delete(zRequestFName);
229 file_delete(zReplyFName);
230 free(p);
231 }
232
233
234 /*
235 ** Start a listening socket and process incoming HTTP requests on
@@ -243,19 +298,23 @@
243 const char *zNotFound, /* The --notfound option, or NULL */
244 const char *zFileGlob, /* The --fileglob option, or NULL */
245 const char *zIpAddr, /* Bind to this IP address, if not NULL */
246 int flags /* One or more HTTP_SERVER_ flags */
247 ){
 
248 WSADATA wd;
249 SOCKET s = INVALID_SOCKET;
250 SOCKADDR_IN addr;
251 int idCnt = 0;
252 int iPort = mnPort;
253 Blob options;
254 wchar_t zTmpPath[MAX_PATH];
 
 
 
 
255
256 if( zStopper ) file_delete(zStopper);
257 blob_zero(&options);
258 if( zBaseUrl ){
259 blob_appendf(&options, " --baseurl %s", zBaseUrl);
260 }
261 if( zNotFound ){
@@ -271,10 +330,18 @@
271 blob_appendf(&options, " --th-trace");
272 }
273 if( flags & HTTP_SERVER_REPOLIST ){
274 blob_appendf(&options, " --repolist");
275 }
 
 
 
 
 
 
 
 
276 if( WSAStartup(MAKEWORD(1,1), &wd) ){
277 fossil_fatal("unable to initialize winsock");
278 }
279 while( iPort<=mxPort ){
280 s = socket(AF_INET, SOCK_STREAM, 0);
@@ -324,17 +391,35 @@
324 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
325 fossil_print("Launch webbrowser: %s\n", zBrowser);
326 fossil_system(zBrowser);
327 }
328 fossil_print("Type Ctrl-C to stop the HTTP server\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329 /* Set the service status to running and pass the listener socket to the
330 ** service handling procedures. */
331 win32_http_service_running(s);
332 for(;;){
333 SOCKET client;
334 SOCKADDR_IN client_addr;
335 HttpRequest *p;
336 int len = sizeof(client_addr);
337 int wsaError;
338
339 client = accept(s, (struct sockaddr*)&client_addr, &len);
340 if( client==INVALID_SOCKET ){
@@ -347,27 +432,27 @@
347 }else{
348 closesocket(s);
349 WSACleanup();
350 fossil_fatal("error from accept()");
351 }
352 }else if( zStopper && file_size(zStopper)>=0 ){
353 break;
354 }
355 p = fossil_malloc( sizeof(*p) );
356 p->id = ++idCnt;
357 p->s = client;
358 p->addr = client_addr;
359 p->flags = flags;
360 p->zOptions = blob_str(&options);
361 if( flags & HTTP_SERVER_SCGI ){
362 _beginthread(win32_scgi_request, 0, (void*)p);
363 }else{
364 _beginthread(win32_http_request, 0, (void*)p);
365 }
366 }
367 closesocket(s);
368 WSACleanup();
 
 
369 }
370
371 /*
372 ** The HttpService structure is used to pass information to the service main
373 ** function and to the service control handler function.
@@ -581,11 +666,13 @@
581 }
582 }
583 return 0;
584 }
585
586 /* dupe ifdef needed for mkindex
 
 
587 ** COMMAND: winsrv*
588 **
589 ** Usage: %fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS?
590 **
591 ** Where METHOD is one of: create delete show start stop.
@@ -1030,6 +1117,7 @@
1030 fossil_fatal("METHOD should be one of:"
1031 " create delete show start stop");
1032 }
1033 return;
1034 }
1035 #endif /* _WIN32 -- This code is for win32 only */
 
1036
--- src/winhttp.c
+++ src/winhttp.c
@@ -24,10 +24,24 @@
24 /* This code is for win32 only */
25 #include <windows.h>
26 #include <process.h>
27 #include "winhttp.h"
28
29 /*
30 ** The HttpServer structure holds information about an instance of
31 ** the HTTP server itself.
32 */
33 typedef struct HttpServer HttpServer;
34 struct HttpServer {
35 HANDLE hStoppedEvent; /* Event to signal when server is stopped,
36 ** must be closed by callee. */
37 char *zStopper; /* The stopper file name, must be freed by
38 ** callee. */
39 SOCKET listener; /* Socket on which the server is listening,
40 ** may be closed by callee. */
41 };
42
43 /*
44 ** The HttpRequest structure holds information about each incoming
45 ** HTTP request.
46 */
47 typedef struct HttpRequest HttpRequest;
@@ -70,10 +84,51 @@
84 const char *zService,
85 const char *zErr
86 ){
87 fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
88 }
89
90 /*
91 ** Make sure the server stops as soon as possible after the stopper file
92 ** is found. If there is no stopper file name, do nothing.
93 */
94 static void win32_server_stopper(void *pAppData){
95 HttpServer *p = (HttpServer*)pAppData;
96 if( p!=0 ){
97 HANDLE hStoppedEvent = p->hStoppedEvent;
98 const char *zStopper = p->zStopper;
99 SOCKET listener = p->listener;
100 if( hStoppedEvent!=NULL && zStopper!=0 && listener!=INVALID_SOCKET ){
101 while( 1 ){
102 DWORD dwResult = WaitForMultipleObjectsEx(1, &hStoppedEvent, FALSE,
103 1000, TRUE);
104 if( dwResult!=WAIT_IO_COMPLETION && dwResult!=WAIT_TIMEOUT ){
105 /* The event is either invalid, signaled, or abandoned. Bail
106 ** out now because those conditions should indicate the parent
107 ** thread is dead or dying. */
108 break;
109 }
110 if( file_size(zStopper)>=0 ){
111 /* The stopper file has been found. Attempt to close the server
112 ** listener socket now and then exit. */
113 closesocket(listener);
114 p->listener = INVALID_SOCKET;
115 break;
116 }
117 }
118 }
119 if( hStoppedEvent!=NULL ){
120 CloseHandle(hStoppedEvent);
121 p->hStoppedEvent = NULL;
122 }
123 if( zStopper!=0 ){
124 fossil_free(p->zStopper);
125 p->zStopper = 0;
126 }
127 fossil_free(p);
128 }
129 }
130
131 /*
132 ** Process a single incoming HTTP request.
133 */
134 static void win32_http_request(void *pAppData){
@@ -163,11 +218,11 @@
218 if( in ) fclose(in);
219 closesocket(p->s);
220 file_delete(zRequestFName);
221 file_delete(zReplyFName);
222 file_delete(zCmdFName);
223 fossil_free(p);
224 }
225
226 /*
227 ** Process a single incoming SCGI request.
228 */
@@ -225,11 +280,11 @@
280 if( out ) fclose(out);
281 if( in ) fclose(in);
282 closesocket(p->s);
283 file_delete(zRequestFName);
284 file_delete(zReplyFName);
285 fossil_free(p);
286 }
287
288
289 /*
290 ** Start a listening socket and process incoming HTTP requests on
@@ -243,19 +298,23 @@
298 const char *zNotFound, /* The --notfound option, or NULL */
299 const char *zFileGlob, /* The --fileglob option, or NULL */
300 const char *zIpAddr, /* Bind to this IP address, if not NULL */
301 int flags /* One or more HTTP_SERVER_ flags */
302 ){
303 HANDLE hStoppedEvent;
304 WSADATA wd;
305 SOCKET s = INVALID_SOCKET;
306 SOCKADDR_IN addr;
307 int idCnt = 0;
308 int iPort = mnPort;
309 Blob options;
310 wchar_t zTmpPath[MAX_PATH];
311 #if USE_SEE
312 const char *zSavedKey = 0;
313 size_t savedKeySize = 0;
314 #endif
315
 
316 blob_zero(&options);
317 if( zBaseUrl ){
318 blob_appendf(&options, " --baseurl %s", zBaseUrl);
319 }
320 if( zNotFound ){
@@ -271,10 +330,18 @@
330 blob_appendf(&options, " --th-trace");
331 }
332 if( flags & HTTP_SERVER_REPOLIST ){
333 blob_appendf(&options, " --repolist");
334 }
335 #if USE_SEE
336 zSavedKey = db_get_saved_encryption_key();
337 savedKeySize = db_get_saved_encryption_key_size();
338 if( zSavedKey!=0 && savedKeySize>0 ){
339 blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
340 zSavedKey, savedKeySize);
341 }
342 #endif
343 if( WSAStartup(MAKEWORD(1,1), &wd) ){
344 fossil_fatal("unable to initialize winsock");
345 }
346 while( iPort<=mxPort ){
347 s = socket(AF_INET, SOCK_STREAM, 0);
@@ -324,17 +391,35 @@
391 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
392 fossil_print("Launch webbrowser: %s\n", zBrowser);
393 fossil_system(zBrowser);
394 }
395 fossil_print("Type Ctrl-C to stop the HTTP server\n");
396 /* Create an event used to signal when this server is exiting. */
397 hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
398 assert( hStoppedEvent!=NULL );
399 /* If there is a stopper file name, start the dedicated thread now.
400 ** It will attempt to close the listener socket within 1 second of
401 ** the stopper file being created. */
402 if( zStopper ){
403 HttpServer *pServer = fossil_malloc(sizeof(HttpServer));
404 memset(pServer, 0, sizeof(HttpServer));
405 DuplicateHandle(GetCurrentProcess(), hStoppedEvent,
406 GetCurrentProcess(), &pServer->hStoppedEvent,
407 0, FALSE, DUPLICATE_SAME_ACCESS);
408 assert( pServer->hStoppedEvent!=NULL );
409 pServer->zStopper = fossil_strdup(zStopper);
410 pServer->listener = s;
411 file_delete(zStopper);
412 _beginthread(win32_server_stopper, 0, (void*)pServer);
413 }
414 /* Set the service status to running and pass the listener socket to the
415 ** service handling procedures. */
416 win32_http_service_running(s);
417 for(;;){
418 SOCKET client;
419 SOCKADDR_IN client_addr;
420 HttpRequest *pRequest;
421 int len = sizeof(client_addr);
422 int wsaError;
423
424 client = accept(s, (struct sockaddr*)&client_addr, &len);
425 if( client==INVALID_SOCKET ){
@@ -347,27 +432,27 @@
432 }else{
433 closesocket(s);
434 WSACleanup();
435 fossil_fatal("error from accept()");
436 }
437 }
438 pRequest = fossil_malloc(sizeof(HttpRequest));
439 pRequest->id = ++idCnt;
440 pRequest->s = client;
441 pRequest->addr = client_addr;
442 pRequest->flags = flags;
443 pRequest->zOptions = blob_str(&options);
 
 
444 if( flags & HTTP_SERVER_SCGI ){
445 _beginthread(win32_scgi_request, 0, (void*)pRequest);
446 }else{
447 _beginthread(win32_http_request, 0, (void*)pRequest);
448 }
449 }
450 closesocket(s);
451 WSACleanup();
452 SetEvent(hStoppedEvent);
453 CloseHandle(hStoppedEvent);
454 }
455
456 /*
457 ** The HttpService structure is used to pass information to the service main
458 ** function and to the service control handler function.
@@ -581,11 +666,13 @@
666 }
667 }
668 return 0;
669 }
670
671 /* Dupliate #ifdef needed for mkindex */
672 #ifdef _WIN32
673 /*
674 ** COMMAND: winsrv*
675 **
676 ** Usage: %fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS?
677 **
678 ** Where METHOD is one of: create delete show start stop.
@@ -1030,6 +1117,7 @@
1117 fossil_fatal("METHOD should be one of:"
1118 " create delete show start stop");
1119 }
1120 return;
1121 }
1122 #endif /* _WIN32 -- dupe needed for mkindex */
1123 #endif /* _WIN32 -- This code is for win32 only */
1124
+1 -1
--- src/xfer.c
+++ src/xfer.c
@@ -2140,11 +2140,11 @@
21402140
}
21412141
if( syncFlags & (SYNC_UV_TRACE|SYNC_UV_DRYRUN) ){
21422142
const char *zMsg = 0;
21432143
switch( iStatus ){
21442144
case 0:
2145
- case 1: zMsg = "UV-PULL"; break;
2145
+ case 1: zMsg = "UV-PULL"; break;
21462146
case 2: zMsg = "UV-PULL-MTIME-ONLY"; break;
21472147
case 4: zMsg = "UV-PUSH-MTIME-ONLY"; break;
21482148
case 5: zMsg = "UV-PUSH"; break;
21492149
}
21502150
if( zMsg ) fossil_print("\r%s: %s\n", zMsg, zName);
21512151
--- src/xfer.c
+++ src/xfer.c
@@ -2140,11 +2140,11 @@
2140 }
2141 if( syncFlags & (SYNC_UV_TRACE|SYNC_UV_DRYRUN) ){
2142 const char *zMsg = 0;
2143 switch( iStatus ){
2144 case 0:
2145 case 1: zMsg = "UV-PULL"; break;
2146 case 2: zMsg = "UV-PULL-MTIME-ONLY"; break;
2147 case 4: zMsg = "UV-PUSH-MTIME-ONLY"; break;
2148 case 5: zMsg = "UV-PUSH"; break;
2149 }
2150 if( zMsg ) fossil_print("\r%s: %s\n", zMsg, zName);
2151
--- src/xfer.c
+++ src/xfer.c
@@ -2140,11 +2140,11 @@
2140 }
2141 if( syncFlags & (SYNC_UV_TRACE|SYNC_UV_DRYRUN) ){
2142 const char *zMsg = 0;
2143 switch( iStatus ){
2144 case 0:
2145 case 1: zMsg = "UV-PULL"; break;
2146 case 2: zMsg = "UV-PULL-MTIME-ONLY"; break;
2147 case 4: zMsg = "UV-PUSH-MTIME-ONLY"; break;
2148 case 5: zMsg = "UV-PUSH"; break;
2149 }
2150 if( zMsg ) fossil_print("\r%s: %s\n", zMsg, zName);
2151
+55 -17
--- src/zip.c
+++ src/zip.c
@@ -350,29 +350,67 @@
350350
}
351351
nPrefix = blob_size(&filename);
352352
353353
pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
354354
if( pManifest ){
355
- char *zName;
355
+ int flg, eflg = 0;
356
+ char *zName = 0;
356357
zip_set_timedate(pManifest->rDate);
357
- if( (pInclude==0 || glob_match(pInclude, "manifest"))
358
- && !glob_match(pExclude, "manifest")
359
- && db_get_boolean("manifest", 0)
360
- ){
361
- blob_append(&filename, "manifest", -1);
362
- zName = blob_str(&filename);
363
- zip_add_folders(zName);
364
- sha1sum_blob(&mfile, &hash);
365
- sterilize_manifest(&mfile);
366
- zip_add_file(zName, &mfile, 0);
358
+ flg = db_get_manifest_setting();
359
+ if( flg ){
360
+ /* eflg is the effective flags, taking include/exclude into account */
361
+ if( (pInclude==0 || glob_match(pInclude, "manifest"))
362
+ && !glob_match(pExclude, "manifest")
363
+ && (flg & MFESTFLG_RAW) ){
364
+ eflg |= MFESTFLG_RAW;
365
+ }
366
+ if( (pInclude==0 || glob_match(pInclude, "manifest.uuid"))
367
+ && !glob_match(pExclude, "manifest.uuid")
368
+ && (flg & MFESTFLG_UUID) ){
369
+ eflg |= MFESTFLG_UUID;
370
+ }
371
+ if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
372
+ && !glob_match(pExclude, "manifest.tags")
373
+ && (flg & MFESTFLG_TAGS) ){
374
+ eflg |= MFESTFLG_TAGS;
375
+ }
376
+
377
+ if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
378
+ if( eflg & MFESTFLG_RAW ){
379
+ blob_append(&filename, "manifest", -1);
380
+ zName = blob_str(&filename);
381
+ zip_add_folders(zName);
382
+ }
383
+ if( eflg & MFESTFLG_UUID ){
384
+ sha1sum_blob(&mfile, &hash);
385
+ }
386
+ if( eflg & MFESTFLG_RAW ){
387
+ sterilize_manifest(&mfile);
388
+ zip_add_file(zName, &mfile, 0);
389
+ }
390
+ }
367391
blob_reset(&mfile);
368
- blob_append(&hash, "\n", 1);
369
- blob_resize(&filename, nPrefix);
370
- blob_append(&filename, "manifest.uuid", -1);
371
- zName = blob_str(&filename);
372
- zip_add_file(zName, &hash, 0);
373
- blob_reset(&hash);
392
+ if( eflg & MFESTFLG_UUID ){
393
+ blob_append(&hash, "\n", 1);
394
+ blob_resize(&filename, nPrefix);
395
+ blob_append(&filename, "manifest.uuid", -1);
396
+ zName = blob_str(&filename);
397
+ zip_add_folders(zName);
398
+ zip_add_file(zName, &hash, 0);
399
+ blob_reset(&hash);
400
+ }
401
+ if( eflg & MFESTFLG_TAGS ){
402
+ Blob tagslist;
403
+ blob_zero(&tagslist);
404
+ get_checkin_taglist(rid, &tagslist);
405
+ blob_resize(&filename, nPrefix);
406
+ blob_append(&filename, "manifest.tags", -1);
407
+ zName = blob_str(&filename);
408
+ zip_add_folders(zName);
409
+ zip_add_file(zName, &tagslist, 0);
410
+ blob_reset(&tagslist);
411
+ }
374412
}
375413
manifest_file_rewind(pManifest);
376414
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
377415
int fid;
378416
if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
379417
--- src/zip.c
+++ src/zip.c
@@ -350,29 +350,67 @@
350 }
351 nPrefix = blob_size(&filename);
352
353 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
354 if( pManifest ){
355 char *zName;
 
356 zip_set_timedate(pManifest->rDate);
357 if( (pInclude==0 || glob_match(pInclude, "manifest"))
358 && !glob_match(pExclude, "manifest")
359 && db_get_boolean("manifest", 0)
360 ){
361 blob_append(&filename, "manifest", -1);
362 zName = blob_str(&filename);
363 zip_add_folders(zName);
364 sha1sum_blob(&mfile, &hash);
365 sterilize_manifest(&mfile);
366 zip_add_file(zName, &mfile, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367 blob_reset(&mfile);
368 blob_append(&hash, "\n", 1);
369 blob_resize(&filename, nPrefix);
370 blob_append(&filename, "manifest.uuid", -1);
371 zName = blob_str(&filename);
372 zip_add_file(zName, &hash, 0);
373 blob_reset(&hash);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374 }
375 manifest_file_rewind(pManifest);
376 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
377 int fid;
378 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
379
--- src/zip.c
+++ src/zip.c
@@ -350,29 +350,67 @@
350 }
351 nPrefix = blob_size(&filename);
352
353 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
354 if( pManifest ){
355 int flg, eflg = 0;
356 char *zName = 0;
357 zip_set_timedate(pManifest->rDate);
358 flg = db_get_manifest_setting();
359 if( flg ){
360 /* eflg is the effective flags, taking include/exclude into account */
361 if( (pInclude==0 || glob_match(pInclude, "manifest"))
362 && !glob_match(pExclude, "manifest")
363 && (flg & MFESTFLG_RAW) ){
364 eflg |= MFESTFLG_RAW;
365 }
366 if( (pInclude==0 || glob_match(pInclude, "manifest.uuid"))
367 && !glob_match(pExclude, "manifest.uuid")
368 && (flg & MFESTFLG_UUID) ){
369 eflg |= MFESTFLG_UUID;
370 }
371 if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
372 && !glob_match(pExclude, "manifest.tags")
373 && (flg & MFESTFLG_TAGS) ){
374 eflg |= MFESTFLG_TAGS;
375 }
376
377 if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
378 if( eflg & MFESTFLG_RAW ){
379 blob_append(&filename, "manifest", -1);
380 zName = blob_str(&filename);
381 zip_add_folders(zName);
382 }
383 if( eflg & MFESTFLG_UUID ){
384 sha1sum_blob(&mfile, &hash);
385 }
386 if( eflg & MFESTFLG_RAW ){
387 sterilize_manifest(&mfile);
388 zip_add_file(zName, &mfile, 0);
389 }
390 }
391 blob_reset(&mfile);
392 if( eflg & MFESTFLG_UUID ){
393 blob_append(&hash, "\n", 1);
394 blob_resize(&filename, nPrefix);
395 blob_append(&filename, "manifest.uuid", -1);
396 zName = blob_str(&filename);
397 zip_add_folders(zName);
398 zip_add_file(zName, &hash, 0);
399 blob_reset(&hash);
400 }
401 if( eflg & MFESTFLG_TAGS ){
402 Blob tagslist;
403 blob_zero(&tagslist);
404 get_checkin_taglist(rid, &tagslist);
405 blob_resize(&filename, nPrefix);
406 blob_append(&filename, "manifest.tags", -1);
407 zName = blob_str(&filename);
408 zip_add_folders(zName);
409 zip_add_file(zName, &tagslist, 0);
410 blob_reset(&tagslist);
411 }
412 }
413 manifest_file_rewind(pManifest);
414 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
415 int fid;
416 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
417
+12 -3
--- test/delta1.test
+++ test/delta1.test
@@ -34,18 +34,27 @@
3434
set f1 [read_file $f]
3535
write_file t1 $f1
3636
for {set i 0} {$i<100} {incr i} {
3737
write_file t2 [random_changes $f1 1 1 0 0.1]
3838
fossil test-delta t1 t2
39
- test delta-$base-$i-1 {$RESULT=="ok"}
39
+ test delta-$base-$i-1 {[normalize_result]=="ok"}
4040
write_file t2 [random_changes $f1 1 1 0 0.2]
4141
fossil test-delta t1 t2
42
- test delta-$base-$i-2 {$RESULT=="ok"}
42
+ test delta-$base-$i-2 {[normalize_result]=="ok"}
4343
write_file t2 [random_changes $f1 1 1 0 0.4]
4444
fossil test-delta t1 t2
45
- test delta-$base-$i-3 {$RESULT=="ok"}
45
+ test delta-$base-$i-3 {[normalize_result]=="ok"}
4646
}
4747
}
4848
49
+set empties { "" "" "" a a "" }
50
+set i 0
51
+foreach {f1 f2} $empties {
52
+ incr i
53
+ write_file t1 $f1
54
+ write_file t2 $f2
55
+ fossil test-delta t1 t2
56
+ test delta-empty-$i {[normalize_result]=="ok"}
57
+}
4958
###############################################################################
5059
5160
test_cleanup
5261
5362
ADDED test/diff.test
5463
ADDED test/fake-editor.tcl
--- test/delta1.test
+++ test/delta1.test
@@ -34,18 +34,27 @@
34 set f1 [read_file $f]
35 write_file t1 $f1
36 for {set i 0} {$i<100} {incr i} {
37 write_file t2 [random_changes $f1 1 1 0 0.1]
38 fossil test-delta t1 t2
39 test delta-$base-$i-1 {$RESULT=="ok"}
40 write_file t2 [random_changes $f1 1 1 0 0.2]
41 fossil test-delta t1 t2
42 test delta-$base-$i-2 {$RESULT=="ok"}
43 write_file t2 [random_changes $f1 1 1 0 0.4]
44 fossil test-delta t1 t2
45 test delta-$base-$i-3 {$RESULT=="ok"}
46 }
47 }
48
 
 
 
 
 
 
 
 
 
49 ###############################################################################
50
51 test_cleanup
52
53 DDED test/diff.test
54 DDED test/fake-editor.tcl
--- test/delta1.test
+++ test/delta1.test
@@ -34,18 +34,27 @@
34 set f1 [read_file $f]
35 write_file t1 $f1
36 for {set i 0} {$i<100} {incr i} {
37 write_file t2 [random_changes $f1 1 1 0 0.1]
38 fossil test-delta t1 t2
39 test delta-$base-$i-1 {[normalize_result]=="ok"}
40 write_file t2 [random_changes $f1 1 1 0 0.2]
41 fossil test-delta t1 t2
42 test delta-$base-$i-2 {[normalize_result]=="ok"}
43 write_file t2 [random_changes $f1 1 1 0 0.4]
44 fossil test-delta t1 t2
45 test delta-$base-$i-3 {[normalize_result]=="ok"}
46 }
47 }
48
49 set empties { "" "" "" a a "" }
50 set i 0
51 foreach {f1 f2} $empties {
52 incr i
53 write_file t1 $f1
54 write_file t2 $f2
55 fossil test-delta t1 t2
56 test delta-empty-$i {[normalize_result]=="ok"}
57 }
58 ###############################################################################
59
60 test_cleanup
61
62 DDED test/diff.test
63 DDED test/fake-editor.tcl
--- a/test/diff.test
+++ b/test/diff.test
@@ -0,0 +1,31 @@
1
+16384]"
2
+write_file file4_file file4.dat "test file 4 (l16384]\ntwo"
3
+write_file f163842016 D. Richard Hipp
4
+#
5
+# This program is free software; you can redistribute it and/or
6
+# modify it under the terms of the Simplified BSD License (also
7
+# known as the "2-Clause License" or "FreeBSD License".)
8
+#
9
+# This program is distributed in the hope that it will be useful,
10
+# but without any warranty; without even the implied warranty of
11
+# merchantability or fitness for a particular purpose.
12
+#
13
+# Author contact information:
14
+# [email protected]
15
+# http://www.hwaci.com/drh/
16
+#
17
+############################################################################
18
+#
19
+# Tests for the diff command.
20
+#
21
+
22
+require_no_open_checkout
23
+
24
+test_setup; set rootDir [file normalize [pwd]]
25
+
26
+###################################
27
+# Tests of binary file det#
28
+# Coite_file file1.dat z 32768]
29
+fossil diff file1.dat
30
+
31
+test diff-file1-1 {[normalize_restest_cleanup
--- a/test/diff.test
+++ b/test/diff.test
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/diff.test
+++ b/test/diff.test
@@ -0,0 +1,31 @@
1 16384]"
2 write_file file4_file file4.dat "test file 4 (l16384]\ntwo"
3 write_file f163842016 D. Richard Hipp
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the Simplified BSD License (also
7 # known as the "2-Clause License" or "FreeBSD License".)
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but without any warranty; without even the implied warranty of
11 # merchantability or fitness for a particular purpose.
12 #
13 # Author contact information:
14 # [email protected]
15 # http://www.hwaci.com/drh/
16 #
17 ############################################################################
18 #
19 # Tests for the diff command.
20 #
21
22 require_no_open_checkout
23
24 test_setup; set rootDir [file normalize [pwd]]
25
26 ###################################
27 # Tests of binary file det#
28 # Coite_file file1.dat z 32768]
29 fossil diff file1.dat
30
31 test diff-file1-1 {[normalize_restest_cleanup
--- a/test/fake-editor.tcl
+++ b/test/fake-editor.tcl
@@ -0,0 +1,2 @@
1
+#
2
+# Copyright (
--- a/test/fake-editor.tcl
+++ b/test/fake-editor.tcl
@@ -0,0 +1,2 @@
 
 
--- a/test/fake-editor.tcl
+++ b/test/fake-editor.tcl
@@ -0,0 +1,2 @@
1 #
2 # Copyright (
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -66,10 +66,13 @@
6666
* <a href="../../../timeline?c=20015206bc"
6767
target="testwindow">
6868
This timeline has a hidden commit.</a> Click Unhide to reveal.
6969
* <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
7070
target="testwindow">Isolated check-ins.</a>
71
+ * <a href="../../../timeline?b=0fa60142&n=50"
72
+ target="testwindow">Single branch raiser from bottom of page
73
+ up to checkins 057e4b and d3cc6d</a>
7174
7275
External:
7376
7477
* <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
7578
target="testwindow">Timewarp due to a mis-configured system clock.</a>
7679
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -66,10 +66,13 @@
66 * <a href="../../../timeline?c=20015206bc"
67 target="testwindow">
68 This timeline has a hidden commit.</a> Click Unhide to reveal.
69 * <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
70 target="testwindow">Isolated check-ins.</a>
 
 
 
71
72 External:
73
74 * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
75 target="testwindow">Timewarp due to a mis-configured system clock.</a>
76
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -66,10 +66,13 @@
66 * <a href="../../../timeline?c=20015206bc"
67 target="testwindow">
68 This timeline has a hidden commit.</a> Click Unhide to reveal.
69 * <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
70 target="testwindow">Isolated check-ins.</a>
71 * <a href="../../../timeline?b=0fa60142&n=50"
72 target="testwindow">Single branch raiser from bottom of page
73 up to checkins 057e4b and d3cc6d</a>
74
75 External:
76
77 * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
78 target="testwindow">Timewarp due to a mis-configured system clock.</a>
79
+1 -1
--- test/json.test
+++ test/json.test
@@ -23,11 +23,11 @@
2323
# practice of eliminating all trace of the fossil json command when
2424
# not configured. If that changes, these conditions might not prevent
2525
# the rest of this file from running.
2626
fossil test-th-eval "hasfeature json"
2727
28
-if {$::RESULT ne "1"} then {
28
+if {[normalize_result] ne "1"} then {
2929
puts "Fossil was not compiled with JSON support."
3030
test_cleanup_then_return
3131
}
3232
3333
# We need a JSON parser to effectively test the JSON produced by
3434
--- test/json.test
+++ test/json.test
@@ -23,11 +23,11 @@
23 # practice of eliminating all trace of the fossil json command when
24 # not configured. If that changes, these conditions might not prevent
25 # the rest of this file from running.
26 fossil test-th-eval "hasfeature json"
27
28 if {$::RESULT ne "1"} then {
29 puts "Fossil was not compiled with JSON support."
30 test_cleanup_then_return
31 }
32
33 # We need a JSON parser to effectively test the JSON produced by
34
--- test/json.test
+++ test/json.test
@@ -23,11 +23,11 @@
23 # practice of eliminating all trace of the fossil json command when
24 # not configured. If that changes, these conditions might not prevent
25 # the rest of this file from running.
26 fossil test-th-eval "hasfeature json"
27
28 if {[normalize_result] ne "1"} then {
29 puts "Fossil was not compiled with JSON support."
30 test_cleanup_then_return
31 }
32
33 # We need a JSON parser to effectively test the JSON produced by
34
--- test/merge2.test
+++ test/merge2.test
@@ -35,10 +35,11 @@
3535
expr {srand($i*2+1)}
3636
write_file t23 [random_changes $f2 2 4 2 0.1]
3737
expr {srand($i*2)}
3838
write_file t32 [random_changes $f3 2 4 0 0.1]
3939
fossil 3-way-merge t1 t2 t3 a23
40
+ if {[regexp {<<<<< BEGIN MERGE CONFLICT:} [read_file a23]]} continue
4041
test merge-$base-$i-23 {[same_file a23 t23]}
4142
fossil 3-way-merge t1 t3 t2 a32
4243
test merge-$base-$i-32 {[same_file a32 t32]}
4344
}
4445
}
4546
--- test/merge2.test
+++ test/merge2.test
@@ -35,10 +35,11 @@
35 expr {srand($i*2+1)}
36 write_file t23 [random_changes $f2 2 4 2 0.1]
37 expr {srand($i*2)}
38 write_file t32 [random_changes $f3 2 4 0 0.1]
39 fossil 3-way-merge t1 t2 t3 a23
 
40 test merge-$base-$i-23 {[same_file a23 t23]}
41 fossil 3-way-merge t1 t3 t2 a32
42 test merge-$base-$i-32 {[same_file a32 t32]}
43 }
44 }
45
--- test/merge2.test
+++ test/merge2.test
@@ -35,10 +35,11 @@
35 expr {srand($i*2+1)}
36 write_file t23 [random_changes $f2 2 4 2 0.1]
37 expr {srand($i*2)}
38 write_file t32 [random_changes $f3 2 4 0 0.1]
39 fossil 3-way-merge t1 t2 t3 a23
40 if {[regexp {<<<<< BEGIN MERGE CONFLICT:} [read_file a23]]} continue
41 test merge-$base-$i-23 {[same_file a23 t23]}
42 fossil 3-way-merge t1 t3 t2 a32
43 test merge-$base-$i-32 {[same_file a32 t32]}
44 }
45 }
46
--- test/mv-rm.test
+++ test/mv-rm.test
@@ -15,10 +15,12 @@
1515
#
1616
############################################################################
1717
#
1818
# MV / RM Commands
1919
#
20
+
21
+set path [file dirname [info script]]
2022
2123
require_no_open_checkout
2224
2325
########################################
2426
# Setup: Add Files and Commit #
2527
2628
ADDED test/set-manifest.test
--- test/mv-rm.test
+++ test/mv-rm.test
@@ -15,10 +15,12 @@
15 #
16 ############################################################################
17 #
18 # MV / RM Commands
19 #
 
 
20
21 require_no_open_checkout
22
23 ########################################
24 # Setup: Add Files and Commit #
25
26 DDED test/set-manifest.test
--- test/mv-rm.test
+++ test/mv-rm.test
@@ -15,10 +15,12 @@
15 #
16 ############################################################################
17 #
18 # MV / RM Commands
19 #
20
21 set path [file dirname [info script]]
22
23 require_no_open_checkout
24
25 ########################################
26 # Setup: Add Files and Commit #
27
28 DDED test/set-manifest.test
--- a/test/set-manifest.test
+++ b/test/set-manifest.test
@@ -0,0 +1,113 @@
1
+#
2
+# Copyright (c) 2016 D. Richard Hipp
3
+#
4
+# This program is free software; you can redistribute it and/or
5
+# modify it under the terms of the Simplified BSD License (also
6
+# known as the "2-Clause License" or "FreeBSD License".)
7
+#
8
+# This program is distributed in the hope that it will be useful,
9
+# but without any warranty; without even the implied warranty of
10
+# merchantability or fitness for a particular purpose.
11
+#
12
+# Author contact information:
13
+# [email protected]
14
+# http://www.hwaci.com/drh/
15
+#
16
+############################################################################
17
+#
18
+# Test manifest setting
19
+#
20
+
21
+t (c) 2016 D. Richard Hipp
22
+#
23
+# This program is free software; you can redistribute it and/or
24
+# modify it under the terms of the Simplified BSD License (also
25
+# known as the "2-Clause License" or "FreeBSD License".)
26
+#
27
+# T#
28
+# Copyright (c) 20
29
+
30
+proc file_contains {fname match} {
31
+ set fp [open $fname r]
32
+ set contents [read $fp]
33
+ close $fp
34
+ set lines [split $contents "\n"]
35
+ foreach line $lines {
36
+ if {[regexp $match $line]} {
37
+ return 1
38
+ }
39
+ }
40
+ return 0
41
+}
42
+
43
+# We need SHA1 to effectively test the manifest files produced by
44
+# fossil. It looks like the one from tcllib is exactly what we need.
45
+# On ActiveTcl, add it with teacup. On other platforms, YMMV.
46
+# teacup install sha1
47
+if {[catch {package require sha1}] != 0} then {
48
+ puts "The \"sha1\" package is not available."
49
+ test_cleanup_then_return
50
+}
51
+
52
+# We need a respository, so let it have one.
53
+test_setup
54
+
55
+#### Verify classic behavior of the manifest setting
56
+
57
+# Setting is off by default, and there are no extra files.
58
+fossil settings manifest
59
+test "set-manifest-1" {[regexp {^manifest *$} $RESULT]}
60
+set filelist [$v" {$RESULT eq ""}
61
+ fossi D. Richard Hipp
62
+#
63
+# This program is free software; you can redistribute it and/or
64
+# modify it under the terms of the Simplified BSD License (also
65
+# known as the "2-Clause License" or "FreeBSD License".)
66
+#
67
+# This program is distributed in the hope that it will be useful,
68
+# buithout any warranty; without even the implied warranty of
69
+# mer#
70
+# Copyright manifes$ckid eq $uuid} foreach f $filelist {
71
+ test "set-manifest-2-$v-f-$f" {[file isfile $f]}
72
+ }
73
+}
74
+
75
+# ... and manifest.uuid is the checkout's hash
76
+fossil info
77
+regexp {(?m)^checkout:\s+([0-9a-f]{40,64})\s.*$} $RESULT ckoutline ckid
78
+set uuid [string trim [read_file "manifest.uuid"]]
79
+test "set-manifest-2-uuid" {[same_uuid $ckid $uuid]}
80
+
81
+
82
+# ... which is also the SHA1 of the file "manifest" before it was
83
+#License" or "FreeBSD License0
84
+
85
+proc file_contains {fname match}e "manifest"] "" ma2-manifest" {$muuid eq $uuidequire sha1}] != 0} then close $fp
86
+ set lines [split $contents "\n"]
87
+ foreach line $lines {
88
+ if {[regexp $match $line]} {
89
+ return 1
90
+ }
91
+ }
92
+ return 0
93
+}
94
+
95
+# We need SHA1 to effectively test the manifest files produced by
96
+# fossil. It looks like the one from tcllib is exactly what we need.
97
+# On ActiveTcl, add it with teacup. On other platforms, YMMV.
98
+# teacup install sha1
99
+if {[catch {package require sha1}] != 0} then {
100
+ puts "The \"sha1\" package is not available."
101
+ test_cleanup_then_return
102
+}
103
+
104
+# We need a respository, so let it have one.
105
+test_setup
106
+
107
+#### Verify classic behavior of the manifest setting
108
+
109
+# Setting is off by default, and there are no extra files.
110
+fossil settings manifest
111
+test "set-manifest-1" {[regexp {^manifest *$} $RESULT]}
112
+set filelist [$v" {$RESULT eq ""}
113
+ fossi D. R
--- a/test/set-manifest.test
+++ b/test/set-manifest.test
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/set-manifest.test
+++ b/test/set-manifest.test
@@ -0,0 +1,113 @@
1 #
2 # Copyright (c) 2016 D. Richard Hipp
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the Simplified BSD License (also
6 # known as the "2-Clause License" or "FreeBSD License".)
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but without any warranty; without even the implied warranty of
10 # merchantability or fitness for a particular purpose.
11 #
12 # Author contact information:
13 # [email protected]
14 # http://www.hwaci.com/drh/
15 #
16 ############################################################################
17 #
18 # Test manifest setting
19 #
20
21 t (c) 2016 D. Richard Hipp
22 #
23 # This program is free software; you can redistribute it and/or
24 # modify it under the terms of the Simplified BSD License (also
25 # known as the "2-Clause License" or "FreeBSD License".)
26 #
27 # T#
28 # Copyright (c) 20
29
30 proc file_contains {fname match} {
31 set fp [open $fname r]
32 set contents [read $fp]
33 close $fp
34 set lines [split $contents "\n"]
35 foreach line $lines {
36 if {[regexp $match $line]} {
37 return 1
38 }
39 }
40 return 0
41 }
42
43 # We need SHA1 to effectively test the manifest files produced by
44 # fossil. It looks like the one from tcllib is exactly what we need.
45 # On ActiveTcl, add it with teacup. On other platforms, YMMV.
46 # teacup install sha1
47 if {[catch {package require sha1}] != 0} then {
48 puts "The \"sha1\" package is not available."
49 test_cleanup_then_return
50 }
51
52 # We need a respository, so let it have one.
53 test_setup
54
55 #### Verify classic behavior of the manifest setting
56
57 # Setting is off by default, and there are no extra files.
58 fossil settings manifest
59 test "set-manifest-1" {[regexp {^manifest *$} $RESULT]}
60 set filelist [$v" {$RESULT eq ""}
61 fossi D. Richard Hipp
62 #
63 # This program is free software; you can redistribute it and/or
64 # modify it under the terms of the Simplified BSD License (also
65 # known as the "2-Clause License" or "FreeBSD License".)
66 #
67 # This program is distributed in the hope that it will be useful,
68 # buithout any warranty; without even the implied warranty of
69 # mer#
70 # Copyright manifes$ckid eq $uuid} foreach f $filelist {
71 test "set-manifest-2-$v-f-$f" {[file isfile $f]}
72 }
73 }
74
75 # ... and manifest.uuid is the checkout's hash
76 fossil info
77 regexp {(?m)^checkout:\s+([0-9a-f]{40,64})\s.*$} $RESULT ckoutline ckid
78 set uuid [string trim [read_file "manifest.uuid"]]
79 test "set-manifest-2-uuid" {[same_uuid $ckid $uuid]}
80
81
82 # ... which is also the SHA1 of the file "manifest" before it was
83 #License" or "FreeBSD License0
84
85 proc file_contains {fname match}e "manifest"] "" ma2-manifest" {$muuid eq $uuidequire sha1}] != 0} then close $fp
86 set lines [split $contents "\n"]
87 foreach line $lines {
88 if {[regexp $match $line]} {
89 return 1
90 }
91 }
92 return 0
93 }
94
95 # We need SHA1 to effectively test the manifest files produced by
96 # fossil. It looks like the one from tcllib is exactly what we need.
97 # On ActiveTcl, add it with teacup. On other platforms, YMMV.
98 # teacup install sha1
99 if {[catch {package require sha1}] != 0} then {
100 puts "The \"sha1\" package is not available."
101 test_cleanup_then_return
102 }
103
104 # We need a respository, so let it have one.
105 test_setup
106
107 #### Verify classic behavior of the manifest setting
108
109 # Setting is off by default, and there are no extra files.
110 fossil settings manifest
111 test "set-manifest-1" {[regexp {^manifest *$} $RESULT]}
112 set filelist [$v" {$RESULT eq ""}
113 fossi D. R
--- test/settings-repo.test
+++ test/settings-repo.test
@@ -16,12 +16,15 @@
1616
############################################################################
1717
#
1818
# The "settings" and "unset" commands that may modify the repository.
1919
#
2020
21
+set path [file dirname [info script]]
22
+
2123
require_no_open_checkout
22
-set dir [file dirname [info script]]; test_setup
24
+
25
+test_setup
2326
2427
###############################################################################
2528
#
2629
# Complete syntax as tested:
2730
#
2831
--- test/settings-repo.test
+++ test/settings-repo.test
@@ -16,12 +16,15 @@
16 ############################################################################
17 #
18 # The "settings" and "unset" commands that may modify the repository.
19 #
20
 
 
21 require_no_open_checkout
22 set dir [file dirname [info script]]; test_setup
 
23
24 ###############################################################################
25 #
26 # Complete syntax as tested:
27 #
28
--- test/settings-repo.test
+++ test/settings-repo.test
@@ -16,12 +16,15 @@
16 ############################################################################
17 #
18 # The "settings" and "unset" commands that may modify the repository.
19 #
20
21 set path [file dirname [info script]]
22
23 require_no_open_checkout
24
25 test_setup
26
27 ###############################################################################
28 #
29 # Complete syntax as tested:
30 #
31
--- test/settings.test
+++ test/settings.test
@@ -16,11 +16,11 @@
1616
############################################################################
1717
#
1818
# The "settings" and "unset" commands.
1919
#
2020
21
-set dir [file dirname [info script]]; test_setup
21
+set path [file dirname [info script]]; test_setup
2222
2323
###############################################################################
2424
#
2525
# Complete syntax as tested:
2626
#
2727
--- test/settings.test
+++ test/settings.test
@@ -16,11 +16,11 @@
16 ############################################################################
17 #
18 # The "settings" and "unset" commands.
19 #
20
21 set dir [file dirname [info script]]; test_setup
22
23 ###############################################################################
24 #
25 # Complete syntax as tested:
26 #
27
--- test/settings.test
+++ test/settings.test
@@ -16,11 +16,11 @@
16 ############################################################################
17 #
18 # The "settings" and "unset" commands.
19 #
20
21 set path [file dirname [info script]]; test_setup
22
23 ###############################################################################
24 #
25 # Complete syntax as tested:
26 #
27
+2 -6
--- test/stash.test
+++ test/stash.test
@@ -185,15 +185,13 @@
185185
ADDED f0
186186
} -changes {
187187
ADDED f0
188188
MISSING f1
189189
EDITED f2
190
- MISSING f3
190
+ RENAMED f3n
191191
} -addremove {
192
- ADDED f3n
193192
DELETED f1
194
- DELETED f3
195193
} -exists {f0 f2 f3n} -notexists {f1 f3}
196194
197195
# Confirm there is no longer a stash saved
198196
fossil stash list
199197
test stash-2-list {[first_data_line] eq "empty stash"}
@@ -311,13 +309,11 @@
311309
UPDATE f1
312310
UPDATE f2n
313311
} -changes {
314312
RENAMED f2n
315313
} -addremove {
316
- ADDED f2n
317
- DELETED f2
318
-} -exists {f1 f2n} -notexists {f2} -knownbugs {-changes}
314
+} -exists {f1 f2n} -notexists {f2}
319315
320316
321317
322318
########
323319
# fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
324320
325321
ADDED test/symlinks.test
--- test/stash.test
+++ test/stash.test
@@ -185,15 +185,13 @@
185 ADDED f0
186 } -changes {
187 ADDED f0
188 MISSING f1
189 EDITED f2
190 MISSING f3
191 } -addremove {
192 ADDED f3n
193 DELETED f1
194 DELETED f3
195 } -exists {f0 f2 f3n} -notexists {f1 f3}
196
197 # Confirm there is no longer a stash saved
198 fossil stash list
199 test stash-2-list {[first_data_line] eq "empty stash"}
@@ -311,13 +309,11 @@
311 UPDATE f1
312 UPDATE f2n
313 } -changes {
314 RENAMED f2n
315 } -addremove {
316 ADDED f2n
317 DELETED f2
318 } -exists {f1 f2n} -notexists {f2} -knownbugs {-changes}
319
320
321
322 ########
323 # fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
324
325 DDED test/symlinks.test
--- test/stash.test
+++ test/stash.test
@@ -185,15 +185,13 @@
185 ADDED f0
186 } -changes {
187 ADDED f0
188 MISSING f1
189 EDITED f2
190 RENAMED f3n
191 } -addremove {
 
192 DELETED f1
 
193 } -exists {f0 f2 f3n} -notexists {f1 f3}
194
195 # Confirm there is no longer a stash saved
196 fossil stash list
197 test stash-2-list {[first_data_line] eq "empty stash"}
@@ -311,13 +309,11 @@
309 UPDATE f1
310 UPDATE f2n
311 } -changes {
312 RENAMED f2n
313 } -addremove {
314 } -exists {f1 f2n} -notexists {f2}
 
 
315
316
317
318 ########
319 # fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
320
321 DDED test/symlinks.test
--- a/test/symlinks.test
+++ b/test/symlinks.test
@@ -0,0 +1,68 @@
1
+#
2
+# Copyright (c) 2016 D. Richard Hipp
3
+#
4
+# This program is free software; you can redistribute it and/or
5
+# modify it under the terms of the Simplified BSD License (also
6
+# known as the "2-Clause License" or "FreeBSD License".)
7
+#
8
+# This program is distributed in the hope that it will be useful,
9
+# but without any warranty; without even the implied warranty of
10
+# merchantability or fitness for a particular purpose.
11
+#
12
+# Author contact information:
13
+# [email protected]
14
+# http://www.hwaci.com/drh/
15
+#
16
+############################################################################
17
+#
18
+# Symbolic link tests.
19
+#
20
+
21
+set path [file dirname [info script]]
22
+
23
+if {$tcl_platform(platform) eq "windows"allow
24
+puts $RESULTmlinks are not supported on Windows."
25
+ test_cleanup_then_returnon
26
+
27
+fossil test-th-eval --open-con"setting allow-symlinks"
28
+
29
+itory [normalize_result]
30
+
31
+if {[string length $repository] == 0} {
32
+ puts "Detection of the open repository file failed."
33
+ test_cleanup_then_return
34
+}
35
+
36
+#######################################
37
+# Use symbolic link to a directory... #
38
+##############fossil commit -m "c1"_then_returnon
39
+
40
+fossil test-th-eval --open-con"setting allow-symlinks"
41
+
42
+itory [normalize_rght (c) 2016 D. Rich#
43
+# Copyright up_then_returnon
44
+
45
+fossil test-th-eval --open-con"setting allow-symlinks"
46
+
47
+itory [normalize_result]
48
+
49
+if {[string length $repository] == 0} {
50
+ puts "Detection of the open repository file failed."
51
+ test_cleanup_then_return
52
+}
53
+
54
+#######################################
55
+# Use symbolic link to a directory... #
56
+#######################################
57
+
58
+file mkdir [file join $rootDir subdirA]
59
+exec ln -s [file join $rootDir subdirA] symdirA
60
+
61
+###############################################################################
62
+
63
+write_file [file join $rootDir subdirA f1.txt] "f1"
64
+write_file [file join $rootDir subdirA f2.txt] "f2"
65
+
66
+test symlinks-dir-1 {[file exists [file join $rootDir subdirA f1.txt]] eq 1}
67
+test symlinks-dir-2 {[file exists [file join $rootDir symdirA f1.txt]] eq 1}
68
+test symlinks-di
--- a/test/symlinks.test
+++ b/test/symlinks.test
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/symlinks.test
+++ b/test/symlinks.test
@@ -0,0 +1,68 @@
1 #
2 # Copyright (c) 2016 D. Richard Hipp
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the Simplified BSD License (also
6 # known as the "2-Clause License" or "FreeBSD License".)
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but without any warranty; without even the implied warranty of
10 # merchantability or fitness for a particular purpose.
11 #
12 # Author contact information:
13 # [email protected]
14 # http://www.hwaci.com/drh/
15 #
16 ############################################################################
17 #
18 # Symbolic link tests.
19 #
20
21 set path [file dirname [info script]]
22
23 if {$tcl_platform(platform) eq "windows"allow
24 puts $RESULTmlinks are not supported on Windows."
25 test_cleanup_then_returnon
26
27 fossil test-th-eval --open-con"setting allow-symlinks"
28
29 itory [normalize_result]
30
31 if {[string length $repository] == 0} {
32 puts "Detection of the open repository file failed."
33 test_cleanup_then_return
34 }
35
36 #######################################
37 # Use symbolic link to a directory... #
38 ##############fossil commit -m "c1"_then_returnon
39
40 fossil test-th-eval --open-con"setting allow-symlinks"
41
42 itory [normalize_rght (c) 2016 D. Rich#
43 # Copyright up_then_returnon
44
45 fossil test-th-eval --open-con"setting allow-symlinks"
46
47 itory [normalize_result]
48
49 if {[string length $repository] == 0} {
50 puts "Detection of the open repository file failed."
51 test_cleanup_then_return
52 }
53
54 #######################################
55 # Use symbolic link to a directory... #
56 #######################################
57
58 file mkdir [file join $rootDir subdirA]
59 exec ln -s [file join $rootDir subdirA] symdirA
60
61 ###############################################################################
62
63 write_file [file join $rootDir subdirA f1.txt] "f1"
64 write_file [file join $rootDir subdirA f2.txt] "f2"
65
66 test symlinks-dir-1 {[file exists [file join $rootDir subdirA f1.txt]] eq 1}
67 test symlinks-dir-2 {[file exists [file join $rootDir symdirA f1.txt]] eq 1}
68 test symlinks-di
+126 -18
--- test/tester.tcl
+++ test/tester.tcl
@@ -136,13 +136,20 @@
136136
#
137137
proc fossil_maybe_answer {answer args} {
138138
global fossilexe
139139
set cmd $fossilexe
140140
set expectError 0
141
- if {[lindex $args end] eq "-expectError"} {
141
+ set index [lsearch -exact $args -expectError]
142
+ if {$index != -1} {
142143
set expectError 1
143
- set args [lrange $args 0 end-1]
144
+ set args [lreplace $args $index $index]
145
+ }
146
+ set keepNewline 0
147
+ set index [lsearch -exact $args -keepNewline]
148
+ if {$index != -1} {
149
+ set keepNewline 1
150
+ set args [lreplace $args $index $index]
144151
}
145152
foreach a $args {
146153
lappend cmd $a
147154
}
148155
protOut $cmd
@@ -150,14 +157,22 @@
150157
flush stdout
151158
if {[string length $answer] > 0} {
152159
protOut $answer
153160
set prompt_file [file join $::tempPath fossil_prompt_answer]
154161
write_file $prompt_file $answer\n
155
- set rc [catch {eval exec $cmd <$prompt_file} result]
162
+ if {$keepNewline} {
163
+ set rc [catch {eval exec -keepnewline $cmd <$prompt_file} result]
164
+ } else {
165
+ set rc [catch {eval exec $cmd <$prompt_file} result]
166
+ }
156167
file delete $prompt_file
157168
} else {
158
- set rc [catch {eval exec $cmd} result]
169
+ if {$keepNewline} {
170
+ set rc [catch {eval exec -keepnewline $cmd} result]
171
+ } else {
172
+ set rc [catch {eval exec $cmd} result]
173
+ }
159174
}
160175
global RESULT CODE
161176
set CODE $rc
162177
if {($rc && !$expectError) || (!$rc && $expectError)} {
163178
protOut "ERROR: $result" 1
@@ -210,11 +225,11 @@
210225
th1-setup \
211226
th1-uri-regexp]
212227
213228
fossil test-th-eval "hasfeature tcl"
214229
215
- if {$::RESULT eq "1"} {
230
+ if {[normalize_result] eq "1"} {
216231
lappend result tcl-setup
217232
}
218233
219234
return [lsort -dictionary $result]
220235
}
@@ -270,33 +285,34 @@
270285
ssh-command \
271286
ssl-ca-location \
272287
ssl-identity \
273288
th1-setup \
274289
th1-uri-regexp \
290
+ uv-sync \
275291
web-browser]
276292
277293
fossil test-th-eval "hasfeature legacyMvRm"
278294
279
- if {$::RESULT eq "1"} {
295
+ if {[normalize_result] eq "1"} {
280296
lappend result mv-rm-files
281297
}
282298
283299
fossil test-th-eval "hasfeature tcl"
284300
285
- if {$::RESULT eq "1"} {
301
+ if {[normalize_result] eq "1"} {
286302
lappend result tcl tcl-setup
287303
}
288304
289305
fossil test-th-eval "hasfeature th1Docs"
290306
291
- if {$::RESULT eq "1"} {
307
+ if {[normalize_result] eq "1"} {
292308
lappend result th1-docs
293309
}
294310
295311
fossil test-th-eval "hasfeature th1Hooks"
296312
297
- if {$::RESULT eq "1"} {
313
+ if {[normalize_result] eq "1"} {
298314
lappend result th1-hooks
299315
}
300316
301317
return [lsort -dictionary $result]
302318
}
@@ -439,27 +455,27 @@
439455
440456
# This procedure only returns non-zero if the Tcl integration feature was
441457
# enabled at compile-time and is now enabled at runtime.
442458
proc is_tcl_usable_by_fossil {} {
443459
fossil test-th-eval "hasfeature tcl"
444
- if {$::RESULT ne "1"} {return 0}
460
+ if {[normalize_result] ne "1"} {return 0}
445461
fossil test-th-eval "setting tcl"
446
- if {$::RESULT eq "1"} {return 1}
462
+ if {[normalize_result] eq "1"} {return 1}
447463
fossil test-th-eval --open-config "setting tcl"
448
- if {$::RESULT eq "1"} {return 1}
464
+ if {[normalize_result] eq "1"} {return 1}
449465
return [info exists ::env(TH1_ENABLE_TCL)]
450466
}
451467
452468
# This procedure only returns non-zero if the TH1 hooks feature was enabled
453469
# at compile-time and is now enabled at runtime.
454470
proc are_th1_hooks_usable_by_fossil {} {
455471
fossil test-th-eval "hasfeature th1Hooks"
456
- if {$::RESULT ne "1"} {return 0}
472
+ if {[normalize_result] ne "1"} {return 0}
457473
fossil test-th-eval "setting th1-hooks"
458
- if {$::RESULT eq "1"} {return 1}
474
+ if {[normalize_result] eq "1"} {return 1}
459475
fossil test-th-eval --open-config "setting th1-hooks"
460
- if {$::RESULT eq "1"} {return 1}
476
+ if {[normalize_result] eq "1"} {return 1}
461477
return [info exists ::env(TH1_ENABLE_HOOKS)]
462478
}
463479
464480
# This (rarely used) procedure is designed to run a test within the Fossil
465481
# source checkout (e.g. one that does NOT modify any state), while saving
@@ -559,14 +575,14 @@
559575
# NOTE: Check if we can use any of the environment variables.
560576
#
561577
foreach name $names {
562578
set value [getEnvironmentVariable $name]
563579
564
- if {[string length $value] > 0} then {
580
+ if {[string length $value] > 0} {
565581
set value [file normalize $value]
566582
567
- if {[file exists $value] && [file isdirectory $value]} then {
583
+ if {[file exists $value] && [file isdirectory $value]} {
568584
return $value
569585
}
570586
}
571587
}
572588
@@ -574,11 +590,11 @@
574590
# NOTE: On non-Windows systems, fallback to /tmp if it is usable.
575591
#
576592
if {$::tcl_platform(platform) ne "windows"} {
577593
set value /tmp
578594
579
- if {[file exists $value] && [file isdirectory $value]} then {
595
+ if {[file exists $value] && [file isdirectory $value]} {
580596
return $value
581597
}
582598
}
583599
584600
#
@@ -731,10 +747,102 @@
731747
}
732748
append out \n$line
733749
}
734750
return [string range $out 1 end]
735751
}
752
+
753
+# This procedure executes the "fossil server" command. The return value
754
+# is a list comprised of the new process identifier and the port on which
755
+# the server started. The varName argument refers to a variable
756
+# where the "stop argument" is to be stored. This value must eventually be
757
+# passed to the [test_stop_server] procedure.
758
+proc test_start_server { repository {varName ""} } {
759
+ global fossilexe tempPath
760
+ set command [list exec $fossilexe server --localhost]
761
+ if {[string length $varName] > 0} {
762
+ upvar 1 $varName stopArg
763
+ }
764
+ if {$::tcl_platform(platform) eq "windows"} {
765
+ set stopArg [file join [getTemporaryPath] [appendArgs \
766
+ [string trim [clock seconds] -] _ [getSeqNo] .stopper]]
767
+ lappend command --stopper $stopArg
768
+ }
769
+ set outFileName [file join $tempPath [appendArgs \
770
+ fossil_server_ [string trim [clock seconds] -] _ \
771
+ [getSeqNo]]].out
772
+ lappend command $repository >&$outFileName &
773
+ set pid [eval $command]
774
+ if {$::tcl_platform(platform) ne "windows"} {
775
+ set stopArg $pid
776
+ }
777
+ after 1000; # output might not be there yet
778
+ set output [read_file $outFileName]
779
+ if {![regexp {Listening.*TCP port (\d+)} $output dummy port]} {
780
+ puts stdout "Could not detect Fossil server port, using default..."
781
+ set port 8080; # return the default port just in case
782
+ }
783
+ return [list $pid $port $outFileName]
784
+}
785
+
786
+# This procedure stops a Fossil server instance that was previously started
787
+# by the [test_start_server] procedure. The value of the "stop argument"
788
+# will vary by platform as will the exact method used to stop the server.
789
+# The fileName argument is the name of a temporary output file to delete.
790
+proc test_stop_server { stopArg pid fileName } {
791
+ if {$::tcl_platform(platform) eq "windows"} {
792
+ #
793
+ # NOTE: On Windows, the "stop argument" must be the name of a file
794
+ # that does NOT already exist.
795
+ #
796
+ if {[string length $stopArg] > 0 && \
797
+ ![file exists $stopArg] && \
798
+ [catch {write_file $stopArg [clock seconds]}] == 0} {
799
+ while {1} {
800
+ if {[catch {
801
+ #
802
+ # NOTE: Using the TaskList utility requires Windows XP or
803
+ # later.
804
+ #
805
+ exec tasklist.exe /FI "PID eq $pid"
806
+ } result] != 0 || ![regexp -- " $pid " $result]} {
807
+ break
808
+ }
809
+ after 1000; # wait a bit...
810
+ }
811
+ file delete $stopArg
812
+ if {[string length $fileName] > 0} {
813
+ file delete $fileName
814
+ }
815
+ return true
816
+ }
817
+ } else {
818
+ #
819
+ # NOTE: On Unix, the "stop argument" must be an integer identifier
820
+ # that refers to an existing process.
821
+ #
822
+ if {[regexp {^(?:-)?\d+$} $stopArg] && \
823
+ [catch {exec kill -TERM $stopArg}] == 0} {
824
+ while {1} {
825
+ if {[catch {
826
+ #
827
+ # TODO: Is this portable to all the supported variants of
828
+ # Unix? It should be, it's POSIX.
829
+ #
830
+ exec ps -p $pid
831
+ } result] != 0 || ![regexp -- "(?:^$pid| $pid) " $result]} {
832
+ break
833
+ }
834
+ after 1000; # wait a bit...
835
+ }
836
+ if {[string length $fileName] > 0} {
837
+ file delete $fileName
838
+ }
839
+ return true
840
+ }
841
+ }
842
+ return false
843
+}
736844
737845
# Executes the "fossil http" command. The entire content of the HTTP request
738846
# is read from the data file name, with [subst] being performed on it prior to
739847
# submission. Temporary input and output files are created and deleted. The
740848
# result will be the contents of the temoprary output file.
741849
--- test/tester.tcl
+++ test/tester.tcl
@@ -136,13 +136,20 @@
136 #
137 proc fossil_maybe_answer {answer args} {
138 global fossilexe
139 set cmd $fossilexe
140 set expectError 0
141 if {[lindex $args end] eq "-expectError"} {
 
142 set expectError 1
143 set args [lrange $args 0 end-1]
 
 
 
 
 
 
144 }
145 foreach a $args {
146 lappend cmd $a
147 }
148 protOut $cmd
@@ -150,14 +157,22 @@
150 flush stdout
151 if {[string length $answer] > 0} {
152 protOut $answer
153 set prompt_file [file join $::tempPath fossil_prompt_answer]
154 write_file $prompt_file $answer\n
155 set rc [catch {eval exec $cmd <$prompt_file} result]
 
 
 
 
156 file delete $prompt_file
157 } else {
158 set rc [catch {eval exec $cmd} result]
 
 
 
 
159 }
160 global RESULT CODE
161 set CODE $rc
162 if {($rc && !$expectError) || (!$rc && $expectError)} {
163 protOut "ERROR: $result" 1
@@ -210,11 +225,11 @@
210 th1-setup \
211 th1-uri-regexp]
212
213 fossil test-th-eval "hasfeature tcl"
214
215 if {$::RESULT eq "1"} {
216 lappend result tcl-setup
217 }
218
219 return [lsort -dictionary $result]
220 }
@@ -270,33 +285,34 @@
270 ssh-command \
271 ssl-ca-location \
272 ssl-identity \
273 th1-setup \
274 th1-uri-regexp \
 
275 web-browser]
276
277 fossil test-th-eval "hasfeature legacyMvRm"
278
279 if {$::RESULT eq "1"} {
280 lappend result mv-rm-files
281 }
282
283 fossil test-th-eval "hasfeature tcl"
284
285 if {$::RESULT eq "1"} {
286 lappend result tcl tcl-setup
287 }
288
289 fossil test-th-eval "hasfeature th1Docs"
290
291 if {$::RESULT eq "1"} {
292 lappend result th1-docs
293 }
294
295 fossil test-th-eval "hasfeature th1Hooks"
296
297 if {$::RESULT eq "1"} {
298 lappend result th1-hooks
299 }
300
301 return [lsort -dictionary $result]
302 }
@@ -439,27 +455,27 @@
439
440 # This procedure only returns non-zero if the Tcl integration feature was
441 # enabled at compile-time and is now enabled at runtime.
442 proc is_tcl_usable_by_fossil {} {
443 fossil test-th-eval "hasfeature tcl"
444 if {$::RESULT ne "1"} {return 0}
445 fossil test-th-eval "setting tcl"
446 if {$::RESULT eq "1"} {return 1}
447 fossil test-th-eval --open-config "setting tcl"
448 if {$::RESULT eq "1"} {return 1}
449 return [info exists ::env(TH1_ENABLE_TCL)]
450 }
451
452 # This procedure only returns non-zero if the TH1 hooks feature was enabled
453 # at compile-time and is now enabled at runtime.
454 proc are_th1_hooks_usable_by_fossil {} {
455 fossil test-th-eval "hasfeature th1Hooks"
456 if {$::RESULT ne "1"} {return 0}
457 fossil test-th-eval "setting th1-hooks"
458 if {$::RESULT eq "1"} {return 1}
459 fossil test-th-eval --open-config "setting th1-hooks"
460 if {$::RESULT eq "1"} {return 1}
461 return [info exists ::env(TH1_ENABLE_HOOKS)]
462 }
463
464 # This (rarely used) procedure is designed to run a test within the Fossil
465 # source checkout (e.g. one that does NOT modify any state), while saving
@@ -559,14 +575,14 @@
559 # NOTE: Check if we can use any of the environment variables.
560 #
561 foreach name $names {
562 set value [getEnvironmentVariable $name]
563
564 if {[string length $value] > 0} then {
565 set value [file normalize $value]
566
567 if {[file exists $value] && [file isdirectory $value]} then {
568 return $value
569 }
570 }
571 }
572
@@ -574,11 +590,11 @@
574 # NOTE: On non-Windows systems, fallback to /tmp if it is usable.
575 #
576 if {$::tcl_platform(platform) ne "windows"} {
577 set value /tmp
578
579 if {[file exists $value] && [file isdirectory $value]} then {
580 return $value
581 }
582 }
583
584 #
@@ -731,10 +747,102 @@
731 }
732 append out \n$line
733 }
734 return [string range $out 1 end]
735 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
736
737 # Executes the "fossil http" command. The entire content of the HTTP request
738 # is read from the data file name, with [subst] being performed on it prior to
739 # submission. Temporary input and output files are created and deleted. The
740 # result will be the contents of the temoprary output file.
741
--- test/tester.tcl
+++ test/tester.tcl
@@ -136,13 +136,20 @@
136 #
137 proc fossil_maybe_answer {answer args} {
138 global fossilexe
139 set cmd $fossilexe
140 set expectError 0
141 set index [lsearch -exact $args -expectError]
142 if {$index != -1} {
143 set expectError 1
144 set args [lreplace $args $index $index]
145 }
146 set keepNewline 0
147 set index [lsearch -exact $args -keepNewline]
148 if {$index != -1} {
149 set keepNewline 1
150 set args [lreplace $args $index $index]
151 }
152 foreach a $args {
153 lappend cmd $a
154 }
155 protOut $cmd
@@ -150,14 +157,22 @@
157 flush stdout
158 if {[string length $answer] > 0} {
159 protOut $answer
160 set prompt_file [file join $::tempPath fossil_prompt_answer]
161 write_file $prompt_file $answer\n
162 if {$keepNewline} {
163 set rc [catch {eval exec -keepnewline $cmd <$prompt_file} result]
164 } else {
165 set rc [catch {eval exec $cmd <$prompt_file} result]
166 }
167 file delete $prompt_file
168 } else {
169 if {$keepNewline} {
170 set rc [catch {eval exec -keepnewline $cmd} result]
171 } else {
172 set rc [catch {eval exec $cmd} result]
173 }
174 }
175 global RESULT CODE
176 set CODE $rc
177 if {($rc && !$expectError) || (!$rc && $expectError)} {
178 protOut "ERROR: $result" 1
@@ -210,11 +225,11 @@
225 th1-setup \
226 th1-uri-regexp]
227
228 fossil test-th-eval "hasfeature tcl"
229
230 if {[normalize_result] eq "1"} {
231 lappend result tcl-setup
232 }
233
234 return [lsort -dictionary $result]
235 }
@@ -270,33 +285,34 @@
285 ssh-command \
286 ssl-ca-location \
287 ssl-identity \
288 th1-setup \
289 th1-uri-regexp \
290 uv-sync \
291 web-browser]
292
293 fossil test-th-eval "hasfeature legacyMvRm"
294
295 if {[normalize_result] eq "1"} {
296 lappend result mv-rm-files
297 }
298
299 fossil test-th-eval "hasfeature tcl"
300
301 if {[normalize_result] eq "1"} {
302 lappend result tcl tcl-setup
303 }
304
305 fossil test-th-eval "hasfeature th1Docs"
306
307 if {[normalize_result] eq "1"} {
308 lappend result th1-docs
309 }
310
311 fossil test-th-eval "hasfeature th1Hooks"
312
313 if {[normalize_result] eq "1"} {
314 lappend result th1-hooks
315 }
316
317 return [lsort -dictionary $result]
318 }
@@ -439,27 +455,27 @@
455
456 # This procedure only returns non-zero if the Tcl integration feature was
457 # enabled at compile-time and is now enabled at runtime.
458 proc is_tcl_usable_by_fossil {} {
459 fossil test-th-eval "hasfeature tcl"
460 if {[normalize_result] ne "1"} {return 0}
461 fossil test-th-eval "setting tcl"
462 if {[normalize_result] eq "1"} {return 1}
463 fossil test-th-eval --open-config "setting tcl"
464 if {[normalize_result] eq "1"} {return 1}
465 return [info exists ::env(TH1_ENABLE_TCL)]
466 }
467
468 # This procedure only returns non-zero if the TH1 hooks feature was enabled
469 # at compile-time and is now enabled at runtime.
470 proc are_th1_hooks_usable_by_fossil {} {
471 fossil test-th-eval "hasfeature th1Hooks"
472 if {[normalize_result] ne "1"} {return 0}
473 fossil test-th-eval "setting th1-hooks"
474 if {[normalize_result] eq "1"} {return 1}
475 fossil test-th-eval --open-config "setting th1-hooks"
476 if {[normalize_result] eq "1"} {return 1}
477 return [info exists ::env(TH1_ENABLE_HOOKS)]
478 }
479
480 # This (rarely used) procedure is designed to run a test within the Fossil
481 # source checkout (e.g. one that does NOT modify any state), while saving
@@ -559,14 +575,14 @@
575 # NOTE: Check if we can use any of the environment variables.
576 #
577 foreach name $names {
578 set value [getEnvironmentVariable $name]
579
580 if {[string length $value] > 0} {
581 set value [file normalize $value]
582
583 if {[file exists $value] && [file isdirectory $value]} {
584 return $value
585 }
586 }
587 }
588
@@ -574,11 +590,11 @@
590 # NOTE: On non-Windows systems, fallback to /tmp if it is usable.
591 #
592 if {$::tcl_platform(platform) ne "windows"} {
593 set value /tmp
594
595 if {[file exists $value] && [file isdirectory $value]} {
596 return $value
597 }
598 }
599
600 #
@@ -731,10 +747,102 @@
747 }
748 append out \n$line
749 }
750 return [string range $out 1 end]
751 }
752
753 # This procedure executes the "fossil server" command. The return value
754 # is a list comprised of the new process identifier and the port on which
755 # the server started. The varName argument refers to a variable
756 # where the "stop argument" is to be stored. This value must eventually be
757 # passed to the [test_stop_server] procedure.
758 proc test_start_server { repository {varName ""} } {
759 global fossilexe tempPath
760 set command [list exec $fossilexe server --localhost]
761 if {[string length $varName] > 0} {
762 upvar 1 $varName stopArg
763 }
764 if {$::tcl_platform(platform) eq "windows"} {
765 set stopArg [file join [getTemporaryPath] [appendArgs \
766 [string trim [clock seconds] -] _ [getSeqNo] .stopper]]
767 lappend command --stopper $stopArg
768 }
769 set outFileName [file join $tempPath [appendArgs \
770 fossil_server_ [string trim [clock seconds] -] _ \
771 [getSeqNo]]].out
772 lappend command $repository >&$outFileName &
773 set pid [eval $command]
774 if {$::tcl_platform(platform) ne "windows"} {
775 set stopArg $pid
776 }
777 after 1000; # output might not be there yet
778 set output [read_file $outFileName]
779 if {![regexp {Listening.*TCP port (\d+)} $output dummy port]} {
780 puts stdout "Could not detect Fossil server port, using default..."
781 set port 8080; # return the default port just in case
782 }
783 return [list $pid $port $outFileName]
784 }
785
786 # This procedure stops a Fossil server instance that was previously started
787 # by the [test_start_server] procedure. The value of the "stop argument"
788 # will vary by platform as will the exact method used to stop the server.
789 # The fileName argument is the name of a temporary output file to delete.
790 proc test_stop_server { stopArg pid fileName } {
791 if {$::tcl_platform(platform) eq "windows"} {
792 #
793 # NOTE: On Windows, the "stop argument" must be the name of a file
794 # that does NOT already exist.
795 #
796 if {[string length $stopArg] > 0 && \
797 ![file exists $stopArg] && \
798 [catch {write_file $stopArg [clock seconds]}] == 0} {
799 while {1} {
800 if {[catch {
801 #
802 # NOTE: Using the TaskList utility requires Windows XP or
803 # later.
804 #
805 exec tasklist.exe /FI "PID eq $pid"
806 } result] != 0 || ![regexp -- " $pid " $result]} {
807 break
808 }
809 after 1000; # wait a bit...
810 }
811 file delete $stopArg
812 if {[string length $fileName] > 0} {
813 file delete $fileName
814 }
815 return true
816 }
817 } else {
818 #
819 # NOTE: On Unix, the "stop argument" must be an integer identifier
820 # that refers to an existing process.
821 #
822 if {[regexp {^(?:-)?\d+$} $stopArg] && \
823 [catch {exec kill -TERM $stopArg}] == 0} {
824 while {1} {
825 if {[catch {
826 #
827 # TODO: Is this portable to all the supported variants of
828 # Unix? It should be, it's POSIX.
829 #
830 exec ps -p $pid
831 } result] != 0 || ![regexp -- "(?:^$pid| $pid) " $result]} {
832 break
833 }
834 after 1000; # wait a bit...
835 }
836 if {[string length $fileName] > 0} {
837 file delete $fileName
838 }
839 return true
840 }
841 }
842 return false
843 }
844
845 # Executes the "fossil http" command. The entire content of the HTTP request
846 # is read from the data file name, with [subst] being performed on it prior to
847 # submission. Temporary input and output files are created and deleted. The
848 # result will be the contents of the temoprary output file.
849
--- test/th1-docs.test
+++ test/th1-docs.test
@@ -18,18 +18,18 @@
1818
# TH1 Docs
1919
#
2020
2121
fossil test-th-eval "hasfeature th1Docs"
2222
23
-if {$::RESULT ne "1"} {
23
+if {[normalize_result] ne "1"} {
2424
puts "Fossil was not compiled with TH1 docs support."
2525
test_cleanup_then_return
2626
}
2727
2828
fossil test-th-eval "hasfeature tcl"
2929
30
-if {$::RESULT ne "1"} {
30
+if {[normalize_result] ne "1"} {
3131
puts "Fossil was not compiled with Tcl support."
3232
test_cleanup_then_return
3333
}
3434
3535
###############################################################################
3636
--- test/th1-docs.test
+++ test/th1-docs.test
@@ -18,18 +18,18 @@
18 # TH1 Docs
19 #
20
21 fossil test-th-eval "hasfeature th1Docs"
22
23 if {$::RESULT ne "1"} {
24 puts "Fossil was not compiled with TH1 docs support."
25 test_cleanup_then_return
26 }
27
28 fossil test-th-eval "hasfeature tcl"
29
30 if {$::RESULT ne "1"} {
31 puts "Fossil was not compiled with Tcl support."
32 test_cleanup_then_return
33 }
34
35 ###############################################################################
36
--- test/th1-docs.test
+++ test/th1-docs.test
@@ -18,18 +18,18 @@
18 # TH1 Docs
19 #
20
21 fossil test-th-eval "hasfeature th1Docs"
22
23 if {[normalize_result] ne "1"} {
24 puts "Fossil was not compiled with TH1 docs support."
25 test_cleanup_then_return
26 }
27
28 fossil test-th-eval "hasfeature tcl"
29
30 if {[normalize_result] ne "1"} {
31 puts "Fossil was not compiled with Tcl support."
32 test_cleanup_then_return
33 }
34
35 ###############################################################################
36
--- test/th1-hooks.test
+++ test/th1-hooks.test
@@ -18,11 +18,11 @@
1818
# TH1 Hooks
1919
#
2020
2121
fossil test-th-eval "hasfeature th1Hooks"
2222
23
-if {$::RESULT ne "1"} {
23
+if {[normalize_result] ne "1"} {
2424
puts "Fossil was not compiled with TH1 hooks support."
2525
test_cleanup_then_return
2626
}
2727
2828
###############################################################################
@@ -75,12 +75,17 @@
7575
return -code 2 "TH_RETURN return code"
7676
} elseif {$::cmd_name eq "timeline"} {
7777
set length [llength $::cmd_args]
7878
set length [expr {$length - 1}]
7979
if {[lindex $::cmd_args $length] eq "custom"} {
80
+ append_hook_log "CUSTOM TIMELINE"
8081
emit_hook_log
8182
return "custom timeline"
83
+ } elseif {[lindex $::cmd_args $length] eq "custom2"} {
84
+ emit_hook_log
85
+ puts "+++ some stuff here +++"
86
+ continue "custom2 timeline"
8287
} elseif {[lindex $::cmd_args $length] eq "now"} {
8388
emit_hook_log
8489
return "now timeline"
8590
} else {
8691
emit_hook_log
@@ -122,15 +127,21 @@
122127
123128
saveTh1SetupFile; writeTh1SetupFile $testTh1Setup
124129
125130
###############################################################################
126131
127
-fossil timeline custom; # NOTE: Bad "WHEN" argument.
132
+fossil timeline custom -expectError; # NOTE: Bad "WHEN" argument.
128133
test th1-cmd-hooks-1a {[normalize_result] eq \
134
+{<h1><b>command_hook timeline CUSTOM TIMELINE</b></h1>
135
+unknown check-in or invalid date: custom}}
136
+
137
+###############################################################################
138
+
139
+fossil timeline custom2; # NOTE: Bad "WHEN" argument.
140
+test th1-cmd-hooks-1b {[normalize_result] eq \
129141
{<h1><b>command_hook timeline</b></h1>
130
-+++ no more data (0) +++
131
-
++++ some stuff here +++
132142
<h1><b>command_hook timeline command_notify timeline</b></h1>}}
133143
134144
###############################################################################
135145
136146
fossil timeline
137147
--- test/th1-hooks.test
+++ test/th1-hooks.test
@@ -18,11 +18,11 @@
18 # TH1 Hooks
19 #
20
21 fossil test-th-eval "hasfeature th1Hooks"
22
23 if {$::RESULT ne "1"} {
24 puts "Fossil was not compiled with TH1 hooks support."
25 test_cleanup_then_return
26 }
27
28 ###############################################################################
@@ -75,12 +75,17 @@
75 return -code 2 "TH_RETURN return code"
76 } elseif {$::cmd_name eq "timeline"} {
77 set length [llength $::cmd_args]
78 set length [expr {$length - 1}]
79 if {[lindex $::cmd_args $length] eq "custom"} {
 
80 emit_hook_log
81 return "custom timeline"
 
 
 
 
82 } elseif {[lindex $::cmd_args $length] eq "now"} {
83 emit_hook_log
84 return "now timeline"
85 } else {
86 emit_hook_log
@@ -122,15 +127,21 @@
122
123 saveTh1SetupFile; writeTh1SetupFile $testTh1Setup
124
125 ###############################################################################
126
127 fossil timeline custom; # NOTE: Bad "WHEN" argument.
128 test th1-cmd-hooks-1a {[normalize_result] eq \
 
 
 
 
 
 
 
129 {<h1><b>command_hook timeline</b></h1>
130 +++ no more data (0) +++
131
++++ some stuff here +++
132 <h1><b>command_hook timeline command_notify timeline</b></h1>}}
133
134 ###############################################################################
135
136 fossil timeline
137
--- test/th1-hooks.test
+++ test/th1-hooks.test
@@ -18,11 +18,11 @@
18 # TH1 Hooks
19 #
20
21 fossil test-th-eval "hasfeature th1Hooks"
22
23 if {[normalize_result] ne "1"} {
24 puts "Fossil was not compiled with TH1 hooks support."
25 test_cleanup_then_return
26 }
27
28 ###############################################################################
@@ -75,12 +75,17 @@
75 return -code 2 "TH_RETURN return code"
76 } elseif {$::cmd_name eq "timeline"} {
77 set length [llength $::cmd_args]
78 set length [expr {$length - 1}]
79 if {[lindex $::cmd_args $length] eq "custom"} {
80 append_hook_log "CUSTOM TIMELINE"
81 emit_hook_log
82 return "custom timeline"
83 } elseif {[lindex $::cmd_args $length] eq "custom2"} {
84 emit_hook_log
85 puts "+++ some stuff here +++"
86 continue "custom2 timeline"
87 } elseif {[lindex $::cmd_args $length] eq "now"} {
88 emit_hook_log
89 return "now timeline"
90 } else {
91 emit_hook_log
@@ -122,15 +127,21 @@
127
128 saveTh1SetupFile; writeTh1SetupFile $testTh1Setup
129
130 ###############################################################################
131
132 fossil timeline custom -expectError; # NOTE: Bad "WHEN" argument.
133 test th1-cmd-hooks-1a {[normalize_result] eq \
134 {<h1><b>command_hook timeline CUSTOM TIMELINE</b></h1>
135 unknown check-in or invalid date: custom}}
136
137 ###############################################################################
138
139 fossil timeline custom2; # NOTE: Bad "WHEN" argument.
140 test th1-cmd-hooks-1b {[normalize_result] eq \
141 {<h1><b>command_hook timeline</b></h1>
 
 
++++ some stuff here +++
142 <h1><b>command_hook timeline command_notify timeline</b></h1>}}
143
144 ###############################################################################
145
146 fossil timeline
147
--- test/th1-repo.test
+++ test/th1-repo.test
@@ -19,10 +19,12 @@
1919
############################################################################
2020
#
2121
# TH1 tests that may modify the repository
2222
#
2323
24
+set path [file dirname [info script]]
25
+
2426
require_no_open_checkout
2527
2628
########################################
2729
# Setup: Add Files and Commit #
2830
########################################
@@ -51,12 +53,10 @@
5153
set files_md [list subdirB/f5.md subdirB/f6.md subdirB/f8.md subdirC/f10.md]
5254
5355
fossil add $rootDir
5456
fossil commit -m "c1"
5557
56
-set dir [file dirname [info script]]
57
-
5858
###############################################################################
5959
6060
fossil test-th-eval --open-config "dir trunk subdir*/*.md"
6161
test th1-dir-1 {[llength $RESULT] eq [llength $files_md]}
6262
6363
--- test/th1-repo.test
+++ test/th1-repo.test
@@ -19,10 +19,12 @@
19 ############################################################################
20 #
21 # TH1 tests that may modify the repository
22 #
23
 
 
24 require_no_open_checkout
25
26 ########################################
27 # Setup: Add Files and Commit #
28 ########################################
@@ -51,12 +53,10 @@
51 set files_md [list subdirB/f5.md subdirB/f6.md subdirB/f8.md subdirC/f10.md]
52
53 fossil add $rootDir
54 fossil commit -m "c1"
55
56 set dir [file dirname [info script]]
57
58 ###############################################################################
59
60 fossil test-th-eval --open-config "dir trunk subdir*/*.md"
61 test th1-dir-1 {[llength $RESULT] eq [llength $files_md]}
62
63
--- test/th1-repo.test
+++ test/th1-repo.test
@@ -19,10 +19,12 @@
19 ############################################################################
20 #
21 # TH1 tests that may modify the repository
22 #
23
24 set path [file dirname [info script]]
25
26 require_no_open_checkout
27
28 ########################################
29 # Setup: Add Files and Commit #
30 ########################################
@@ -51,12 +53,10 @@
53 set files_md [list subdirB/f5.md subdirB/f6.md subdirB/f8.md subdirC/f10.md]
54
55 fossil add $rootDir
56 fossil commit -m "c1"
57
 
 
58 ###############################################################################
59
60 fossil test-th-eval --open-config "dir trunk subdir*/*.md"
61 test th1-dir-1 {[llength $RESULT] eq [llength $files_md]}
62
63
+12 -12
--- test/th1-tcl.test
+++ test/th1-tcl.test
@@ -16,17 +16,17 @@
1616
############################################################################
1717
#
1818
# TH1/Tcl integration
1919
#
2020
21
-set dir [file dirname [info script]]
21
+set path [file dirname [info script]]
2222
2323
###############################################################################
2424
2525
fossil test-th-eval "hasfeature tcl"
2626
27
-if {$::RESULT ne "1"} {
27
+if {[normalize_result] ne "1"} {
2828
puts "Fossil was not compiled with Tcl support."
2929
test_cleanup_then_return
3030
}
3131
3232
###############################################################################
@@ -38,11 +38,11 @@
3838
set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.
3939
4040
###############################################################################
4141
4242
fossil test-th-render --open-config \
43
- [file nativename [file join $dir th1-tcl1.txt]]
43
+ [file nativename [file join $path th1-tcl1.txt]]
4444
4545
test th1-tcl-1 {[regexp -- {^tclReady\(before\) = 0
4646
tclReady\(after\) = 1
4747
\d+
4848
\d+
@@ -65,62 +65,62 @@
6565
6666
###############################################################################
6767
6868
if {[catch {package require sqlite3}] == 0} {
6969
fossil test-th-render --open-config \
70
- [file nativename [file join $dir th1-tcl2.txt]]
70
+ [file nativename [file join $path th1-tcl2.txt]]
7171
7272
test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
7373
} else {
7474
puts stderr "Skipping 'th1-tcl-2', SQLite package for Tcl not available"
7575
}
7676
7777
###############################################################################
7878
7979
fossil test-th-render --open-config \
80
- [file nativename [file join $dir th1-tcl3.txt]]
80
+ [file nativename [file join $path th1-tcl3.txt]]
8181
8282
test th1-tcl-3 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
8383
invalid command name &quot;bad_command&quot;</p>}}
8484
8585
###############################################################################
8686
8787
fossil test-th-render --open-config \
88
- [file nativename [file join $dir th1-tcl4.txt]]
88
+ [file nativename [file join $path th1-tcl4.txt]]
8989
9090
test th1-tcl-4 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
9191
divide by zero</p>}}
9292
9393
###############################################################################
9494
9595
fossil test-th-render --open-config \
96
- [file nativename [file join $dir th1-tcl5.txt]]
96
+ [file nativename [file join $path th1-tcl5.txt]]
9797
9898
test th1-tcl-5 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
9999
Tcl command not found: bad_command</p>} || $RESULT eq {<hr /><p\
100100
class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}
101101
102102
###############################################################################
103103
104104
fossil test-th-render --open-config \
105
- [file nativename [file join $dir th1-tcl6.txt]]
105
+ [file nativename [file join $path th1-tcl6.txt]]
106106
107107
test th1-tcl-6 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
108108
no such command: bad_command</p>}}
109109
110110
###############################################################################
111111
112112
fossil test-th-render --open-config \
113
- [file nativename [file join $dir th1-tcl7.txt]]
113
+ [file nativename [file join $path th1-tcl7.txt]]
114114
115115
test th1-tcl-7 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
116116
syntax error in expression: &quot;2**0&quot;</p>}}
117117
118118
###############################################################################
119119
120120
fossil test-th-render --open-config \
121
- [file nativename [file join $dir th1-tcl8.txt]]
121
+ [file nativename [file join $path th1-tcl8.txt]]
122122
123123
test th1-tcl-8 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
124124
cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr /><p\
125125
class="thmainError">ERROR: tailcall can only be called from a proc or\
126126
lambda</p>} || $RESULT eq {<hr /><p class="thmainError">ERROR: This test\
@@ -127,14 +127,14 @@
127127
requires Tcl 8.6 or higher.</p>}}
128128
129129
###############################################################################
130130
131131
fossil test-th-render --open-config \
132
- [file nativename [file join $dir th1-tcl9.txt]]
132
+ [file nativename [file join $path th1-tcl9.txt]]
133133
134134
test th1-tcl-9 {[string trim $RESULT] eq [list [file tail $fossilexe] 3 \
135
-[list test-th-render --open-config [file nativename [file join $dir \
135
+[list test-th-render --open-config [file nativename [file join $path \
136136
th1-tcl9.txt]]]]}
137137
138138
###############################################################################
139139
140140
fossil test-th-eval "tclMakeSafe a"
141141
--- test/th1-tcl.test
+++ test/th1-tcl.test
@@ -16,17 +16,17 @@
16 ############################################################################
17 #
18 # TH1/Tcl integration
19 #
20
21 set dir [file dirname [info script]]
22
23 ###############################################################################
24
25 fossil test-th-eval "hasfeature tcl"
26
27 if {$::RESULT ne "1"} {
28 puts "Fossil was not compiled with Tcl support."
29 test_cleanup_then_return
30 }
31
32 ###############################################################################
@@ -38,11 +38,11 @@
38 set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.
39
40 ###############################################################################
41
42 fossil test-th-render --open-config \
43 [file nativename [file join $dir th1-tcl1.txt]]
44
45 test th1-tcl-1 {[regexp -- {^tclReady\(before\) = 0
46 tclReady\(after\) = 1
47 \d+
48 \d+
@@ -65,62 +65,62 @@
65
66 ###############################################################################
67
68 if {[catch {package require sqlite3}] == 0} {
69 fossil test-th-render --open-config \
70 [file nativename [file join $dir th1-tcl2.txt]]
71
72 test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
73 } else {
74 puts stderr "Skipping 'th1-tcl-2', SQLite package for Tcl not available"
75 }
76
77 ###############################################################################
78
79 fossil test-th-render --open-config \
80 [file nativename [file join $dir th1-tcl3.txt]]
81
82 test th1-tcl-3 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
83 invalid command name &quot;bad_command&quot;</p>}}
84
85 ###############################################################################
86
87 fossil test-th-render --open-config \
88 [file nativename [file join $dir th1-tcl4.txt]]
89
90 test th1-tcl-4 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
91 divide by zero</p>}}
92
93 ###############################################################################
94
95 fossil test-th-render --open-config \
96 [file nativename [file join $dir th1-tcl5.txt]]
97
98 test th1-tcl-5 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
99 Tcl command not found: bad_command</p>} || $RESULT eq {<hr /><p\
100 class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}
101
102 ###############################################################################
103
104 fossil test-th-render --open-config \
105 [file nativename [file join $dir th1-tcl6.txt]]
106
107 test th1-tcl-6 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
108 no such command: bad_command</p>}}
109
110 ###############################################################################
111
112 fossil test-th-render --open-config \
113 [file nativename [file join $dir th1-tcl7.txt]]
114
115 test th1-tcl-7 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
116 syntax error in expression: &quot;2**0&quot;</p>}}
117
118 ###############################################################################
119
120 fossil test-th-render --open-config \
121 [file nativename [file join $dir th1-tcl8.txt]]
122
123 test th1-tcl-8 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
124 cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr /><p\
125 class="thmainError">ERROR: tailcall can only be called from a proc or\
126 lambda</p>} || $RESULT eq {<hr /><p class="thmainError">ERROR: This test\
@@ -127,14 +127,14 @@
127 requires Tcl 8.6 or higher.</p>}}
128
129 ###############################################################################
130
131 fossil test-th-render --open-config \
132 [file nativename [file join $dir th1-tcl9.txt]]
133
134 test th1-tcl-9 {[string trim $RESULT] eq [list [file tail $fossilexe] 3 \
135 [list test-th-render --open-config [file nativename [file join $dir \
136 th1-tcl9.txt]]]]}
137
138 ###############################################################################
139
140 fossil test-th-eval "tclMakeSafe a"
141
--- test/th1-tcl.test
+++ test/th1-tcl.test
@@ -16,17 +16,17 @@
16 ############################################################################
17 #
18 # TH1/Tcl integration
19 #
20
21 set path [file dirname [info script]]
22
23 ###############################################################################
24
25 fossil test-th-eval "hasfeature tcl"
26
27 if {[normalize_result] ne "1"} {
28 puts "Fossil was not compiled with Tcl support."
29 test_cleanup_then_return
30 }
31
32 ###############################################################################
@@ -38,11 +38,11 @@
38 set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.
39
40 ###############################################################################
41
42 fossil test-th-render --open-config \
43 [file nativename [file join $path th1-tcl1.txt]]
44
45 test th1-tcl-1 {[regexp -- {^tclReady\(before\) = 0
46 tclReady\(after\) = 1
47 \d+
48 \d+
@@ -65,62 +65,62 @@
65
66 ###############################################################################
67
68 if {[catch {package require sqlite3}] == 0} {
69 fossil test-th-render --open-config \
70 [file nativename [file join $path th1-tcl2.txt]]
71
72 test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
73 } else {
74 puts stderr "Skipping 'th1-tcl-2', SQLite package for Tcl not available"
75 }
76
77 ###############################################################################
78
79 fossil test-th-render --open-config \
80 [file nativename [file join $path th1-tcl3.txt]]
81
82 test th1-tcl-3 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
83 invalid command name &quot;bad_command&quot;</p>}}
84
85 ###############################################################################
86
87 fossil test-th-render --open-config \
88 [file nativename [file join $path th1-tcl4.txt]]
89
90 test th1-tcl-4 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
91 divide by zero</p>}}
92
93 ###############################################################################
94
95 fossil test-th-render --open-config \
96 [file nativename [file join $path th1-tcl5.txt]]
97
98 test th1-tcl-5 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
99 Tcl command not found: bad_command</p>} || $RESULT eq {<hr /><p\
100 class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}
101
102 ###############################################################################
103
104 fossil test-th-render --open-config \
105 [file nativename [file join $path th1-tcl6.txt]]
106
107 test th1-tcl-6 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
108 no such command: bad_command</p>}}
109
110 ###############################################################################
111
112 fossil test-th-render --open-config \
113 [file nativename [file join $path th1-tcl7.txt]]
114
115 test th1-tcl-7 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
116 syntax error in expression: &quot;2**0&quot;</p>}}
117
118 ###############################################################################
119
120 fossil test-th-render --open-config \
121 [file nativename [file join $path th1-tcl8.txt]]
122
123 test th1-tcl-8 {$RESULT eq {<hr /><p class="thmainError">ERROR:\
124 cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr /><p\
125 class="thmainError">ERROR: tailcall can only be called from a proc or\
126 lambda</p>} || $RESULT eq {<hr /><p class="thmainError">ERROR: This test\
@@ -127,14 +127,14 @@
127 requires Tcl 8.6 or higher.</p>}}
128
129 ###############################################################################
130
131 fossil test-th-render --open-config \
132 [file nativename [file join $path th1-tcl9.txt]]
133
134 test th1-tcl-9 {[string trim $RESULT] eq [list [file tail $fossilexe] 3 \
135 [list test-th-render --open-config [file nativename [file join $path \
136 th1-tcl9.txt]]]]}
137
138 ###############################################################################
139
140 fossil test-th-eval "tclMakeSafe a"
141
+39 -3
--- test/th1.test
+++ test/th1.test
@@ -16,11 +16,11 @@
1616
############################################################################
1717
#
1818
# TH1 Commands
1919
#
2020
21
-set dir [file dirname [info script]]; test_setup
21
+set path [file dirname [info script]]; test_setup
2222
2323
###############################################################################
2424
2525
set th1Tcl [is_tcl_usable_by_fossil]
2626
set th1Hooks [are_th1_hooks_usable_by_fossil]
@@ -1038,11 +1038,11 @@
10381038
error expr for getParameter glob_match globalState hascap hasfeature\
10391039
html htmlize http httpize if info insertCsrf lindex linecount list\
10401040
llength lsearch markdown proc puts query randhex redirect regexp\
10411041
reinitialize rename render repository return searchable set\
10421042
setParameter setting stime string styleFooter styleHeader tclReady\
1043
- trace unset uplevel upvar utime verifyCsrf wiki}
1043
+ trace unset unversioned uplevel upvar utime verifyCsrf wiki}
10441044
set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe}
10451045
if {$th1Tcl} {
10461046
test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]}
10471047
} else {
10481048
test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]}
@@ -1468,11 +1468,11 @@
14681468
</div>
14691469
}}}
14701470
14711471
###############################################################################
14721472
1473
-set markdown [read_file [file join $dir markdown-test1.md]]
1473
+set markdown [read_file [file join $path markdown-test1.md]]
14741474
fossil test-th-eval [string map \
14751475
[list %markdown% $markdown] {markdown {%markdown%}}]
14761476
test th1-markdown-5 {[normalize_result] eq \
14771477
{{Markdown Formatter Test Document} {<div class="markdown">
14781478
@@ -1562,9 +1562,45 @@
15621562
}
15631563
15641564
fossil test-th-source $th1FileName
15651565
test th1-source-1 {$RESULT eq {TH_RETURN: 0 1 2 3 4 5 6 7 8 9}}
15661566
file delete $th1FileName
1567
+
1568
+###############################################################################
1569
+
1570
+#
1571
+# TODO: Modify the result of this test if the list of unversioned files
1572
+# changes.
1573
+#
1574
+run_in_checkout {
1575
+ fossil test-th-eval --open-config "unversioned list"
1576
+}
1577
+
1578
+test th1-unversioned-1 {[normalize_result] eq \
1579
+{build-icons/linux.gif build-icons/linux64.gif build-icons/mac.gif\
1580
+build-icons/openbsd.gif build-icons/src.gif build-icons/win32.gif\
1581
+download.html download/fossil-linux-x86-1.32.zip\
1582
+download/fossil-linux-x86-1.33.zip download/fossil-linux-x86-1.34.zip\
1583
+download/fossil-linux-x86-1.35.zip download/fossil-macosx-x86-1.32.zip\
1584
+download/fossil-macosx-x86-1.33.zip download/fossil-macosx-x86-1.34.zip\
1585
+download/fossil-macosx-x86-1.35.zip download/fossil-openbsd-x86-1.32.zip\
1586
+download/fossil-openbsd-x86-1.33.zip download/fossil-openbsd-x86-1.34.tar.gz\
1587
+download/fossil-openbsd-x86-1.35.tar.gz download/fossil-src-1.32.tar.gz\
1588
+download/fossil-src-1.33.tar.gz download/fossil-src-1.34.tar.gz\
1589
+download/fossil-src-1.35.tar.gz download/fossil-w32-1.32.zip\
1590
+download/fossil-w32-1.33.zip download/fossil-w32-1.34.zip\
1591
+download/fossil-w32-1.35.zip download/releasenotes-1.32.html\
1592
+download/releasenotes-1.33.html download/releasenotes-1.34.html\
1593
+download/releasenotes-1.35.html index.wiki}}
1594
+
1595
+###############################################################################
1596
+
1597
+run_in_checkout {
1598
+ fossil test-th-eval --open-config \
1599
+ {string length [unversioned content build-icons/src.gif]}
1600
+}
1601
+
1602
+test th1-unversioned-2 {$RESULT eq {4592}}
15671603
15681604
###############################################################################
15691605
15701606
test_cleanup
15711607
15721608
ADDED test/unversioned.test
--- test/th1.test
+++ test/th1.test
@@ -16,11 +16,11 @@
16 ############################################################################
17 #
18 # TH1 Commands
19 #
20
21 set dir [file dirname [info script]]; test_setup
22
23 ###############################################################################
24
25 set th1Tcl [is_tcl_usable_by_fossil]
26 set th1Hooks [are_th1_hooks_usable_by_fossil]
@@ -1038,11 +1038,11 @@
1038 error expr for getParameter glob_match globalState hascap hasfeature\
1039 html htmlize http httpize if info insertCsrf lindex linecount list\
1040 llength lsearch markdown proc puts query randhex redirect regexp\
1041 reinitialize rename render repository return searchable set\
1042 setParameter setting stime string styleFooter styleHeader tclReady\
1043 trace unset uplevel upvar utime verifyCsrf wiki}
1044 set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe}
1045 if {$th1Tcl} {
1046 test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]}
1047 } else {
1048 test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]}
@@ -1468,11 +1468,11 @@
1468 </div>
1469 }}}
1470
1471 ###############################################################################
1472
1473 set markdown [read_file [file join $dir markdown-test1.md]]
1474 fossil test-th-eval [string map \
1475 [list %markdown% $markdown] {markdown {%markdown%}}]
1476 test th1-markdown-5 {[normalize_result] eq \
1477 {{Markdown Formatter Test Document} {<div class="markdown">
1478
@@ -1562,9 +1562,45 @@
1562 }
1563
1564 fossil test-th-source $th1FileName
1565 test th1-source-1 {$RESULT eq {TH_RETURN: 0 1 2 3 4 5 6 7 8 9}}
1566 file delete $th1FileName
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1567
1568 ###############################################################################
1569
1570 test_cleanup
1571
1572 DDED test/unversioned.test
--- test/th1.test
+++ test/th1.test
@@ -16,11 +16,11 @@
16 ############################################################################
17 #
18 # TH1 Commands
19 #
20
21 set path [file dirname [info script]]; test_setup
22
23 ###############################################################################
24
25 set th1Tcl [is_tcl_usable_by_fossil]
26 set th1Hooks [are_th1_hooks_usable_by_fossil]
@@ -1038,11 +1038,11 @@
1038 error expr for getParameter glob_match globalState hascap hasfeature\
1039 html htmlize http httpize if info insertCsrf lindex linecount list\
1040 llength lsearch markdown proc puts query randhex redirect regexp\
1041 reinitialize rename render repository return searchable set\
1042 setParameter setting stime string styleFooter styleHeader tclReady\
1043 trace unset unversioned uplevel upvar utime verifyCsrf wiki}
1044 set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe}
1045 if {$th1Tcl} {
1046 test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]}
1047 } else {
1048 test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]}
@@ -1468,11 +1468,11 @@
1468 </div>
1469 }}}
1470
1471 ###############################################################################
1472
1473 set markdown [read_file [file join $path markdown-test1.md]]
1474 fossil test-th-eval [string map \
1475 [list %markdown% $markdown] {markdown {%markdown%}}]
1476 test th1-markdown-5 {[normalize_result] eq \
1477 {{Markdown Formatter Test Document} {<div class="markdown">
1478
@@ -1562,9 +1562,45 @@
1562 }
1563
1564 fossil test-th-source $th1FileName
1565 test th1-source-1 {$RESULT eq {TH_RETURN: 0 1 2 3 4 5 6 7 8 9}}
1566 file delete $th1FileName
1567
1568 ###############################################################################
1569
1570 #
1571 # TODO: Modify the result of this test if the list of unversioned files
1572 # changes.
1573 #
1574 run_in_checkout {
1575 fossil test-th-eval --open-config "unversioned list"
1576 }
1577
1578 test th1-unversioned-1 {[normalize_result] eq \
1579 {build-icons/linux.gif build-icons/linux64.gif build-icons/mac.gif\
1580 build-icons/openbsd.gif build-icons/src.gif build-icons/win32.gif\
1581 download.html download/fossil-linux-x86-1.32.zip\
1582 download/fossil-linux-x86-1.33.zip download/fossil-linux-x86-1.34.zip\
1583 download/fossil-linux-x86-1.35.zip download/fossil-macosx-x86-1.32.zip\
1584 download/fossil-macosx-x86-1.33.zip download/fossil-macosx-x86-1.34.zip\
1585 download/fossil-macosx-x86-1.35.zip download/fossil-openbsd-x86-1.32.zip\
1586 download/fossil-openbsd-x86-1.33.zip download/fossil-openbsd-x86-1.34.tar.gz\
1587 download/fossil-openbsd-x86-1.35.tar.gz download/fossil-src-1.32.tar.gz\
1588 download/fossil-src-1.33.tar.gz download/fossil-src-1.34.tar.gz\
1589 download/fossil-src-1.35.tar.gz download/fossil-w32-1.32.zip\
1590 download/fossil-w32-1.33.zip download/fossil-w32-1.34.zip\
1591 download/fossil-w32-1.35.zip download/releasenotes-1.32.html\
1592 download/releasenotes-1.33.html download/releasenotes-1.34.html\
1593 download/releasenotes-1.35.html index.wiki}}
1594
1595 ###############################################################################
1596
1597 run_in_checkout {
1598 fossil test-th-eval --open-config \
1599 {string length [unversioned content build-icons/src.gif]}
1600 }
1601
1602 test th1-unversioned-2 {$RESULT eq {4592}}
1603
1604 ###############################################################################
1605
1606 test_cleanup
1607
1608 DDED test/unversioned.test
--- a/test/unversioned.test
+++ b/test/unversioned.test
@@ -0,0 +1 @@
1
+nam
--- a/test/unversioned.test
+++ b/test/unversioned.test
@@ -0,0 +1 @@
 
--- a/test/unversioned.test
+++ b/test/unversioned.test
@@ -0,0 +1 @@
1 nam
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -83,11 +83,11 @@
8383
8484
# define the SQLite files, which need special flags on compile
8585
SQLITESRC=sqlite3.c
8686
ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
8787
SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
88
-SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_WIN32_NO_ANSI
88
+SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_WIN32_NO_ANSI
8989
9090
# define the SQLite shell files, which need special flags on compile
9191
SQLITESHELLSRC=shell.c
9292
ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
9393
SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
9494
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -83,11 +83,11 @@
83
84 # define the SQLite files, which need special flags on compile
85 SQLITESRC=sqlite3.c
86 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
87 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
88 SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_WIN32_NO_ANSI
89
90 # define the SQLite shell files, which need special flags on compile
91 SQLITESHELLSRC=shell.c
92 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
93 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
94
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -83,11 +83,11 @@
83
84 # define the SQLite files, which need special flags on compile
85 SQLITESRC=sqlite3.c
86 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
87 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
88 SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_WIN32_NO_ANSI
89
90 # define the SQLite shell files, which need special flags on compile
91 SQLITESHELLSRC=shell.c
92 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
93 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
94
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -24,11 +24,11 @@
2424
CFLAGS = -o
2525
BCC = $(DMDIR)\bin\dmc $(CFLAGS)
2626
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2727
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
2828
29
-SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
29
+SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
3030
3131
SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
3232
3333
SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
3434
3535
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -24,11 +24,11 @@
24 CFLAGS = -o
25 BCC = $(DMDIR)\bin\dmc $(CFLAGS)
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
30
31 SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -24,11 +24,11 @@
24 CFLAGS = -o
25 BCC = $(DMDIR)\bin\dmc $(CFLAGS)
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
30
31 SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2174,10 +2174,12 @@
21742174
-DSQLITE_OMIT_DECLTYPE \
21752175
-DSQLITE_OMIT_DEPRECATED \
21762176
-DSQLITE_OMIT_PROGRESS_CALLBACK \
21772177
-DSQLITE_OMIT_SHARED_CACHE \
21782178
-DSQLITE_OMIT_LOAD_EXTENSION \
2179
+ -DSQLITE_MAX_EXPR_DEPTH=0 \
2180
+ -DSQLITE_USE_ALLOCA \
21792181
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
21802182
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
21812183
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
21822184
-DSQLITE_ENABLE_FTS4 \
21832185
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
21842186
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
 
 
2179 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2180 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2181 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2182 -DSQLITE_ENABLE_FTS4 \
2183 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2184
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
2179 -DSQLITE_MAX_EXPR_DEPTH=0 \
2180 -DSQLITE_USE_ALLOCA \
2181 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2182 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2183 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2184 -DSQLITE_ENABLE_FTS4 \
2185 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2186
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2174,10 +2174,12 @@
21742174
-DSQLITE_OMIT_DECLTYPE \
21752175
-DSQLITE_OMIT_DEPRECATED \
21762176
-DSQLITE_OMIT_PROGRESS_CALLBACK \
21772177
-DSQLITE_OMIT_SHARED_CACHE \
21782178
-DSQLITE_OMIT_LOAD_EXTENSION \
2179
+ -DSQLITE_MAX_EXPR_DEPTH=0 \
2180
+ -DSQLITE_USE_ALLOCA \
21792181
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
21802182
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
21812183
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
21822184
-DSQLITE_ENABLE_FTS4 \
21832185
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
21842186
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
 
 
2179 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2180 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2181 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2182 -DSQLITE_ENABLE_FTS4 \
2183 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2184
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
2179 -DSQLITE_MAX_EXPR_DEPTH=0 \
2180 -DSQLITE_USE_ALLOCA \
2181 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2182 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2183 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2184 -DSQLITE_ENABLE_FTS4 \
2185 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2186
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -2174,10 +2174,12 @@
21742174
-DSQLITE_OMIT_DECLTYPE \
21752175
-DSQLITE_OMIT_DEPRECATED \
21762176
-DSQLITE_OMIT_PROGRESS_CALLBACK \
21772177
-DSQLITE_OMIT_SHARED_CACHE \
21782178
-DSQLITE_OMIT_LOAD_EXTENSION \
2179
+ -DSQLITE_MAX_EXPR_DEPTH=0 \
2180
+ -DSQLITE_USE_ALLOCA \
21792181
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
21802182
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
21812183
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
21822184
-DSQLITE_ENABLE_FTS4 \
21832185
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
21842186
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
 
 
2179 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2180 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2181 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2182 -DSQLITE_ENABLE_FTS4 \
2183 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2184
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
2179 -DSQLITE_MAX_EXPR_DEPTH=0 \
2180 -DSQLITE_USE_ALLOCA \
2181 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2182 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2183 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2184 -DSQLITE_ENABLE_FTS4 \
2185 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2186
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -2174,10 +2174,12 @@
21742174
-DSQLITE_OMIT_DECLTYPE \
21752175
-DSQLITE_OMIT_DEPRECATED \
21762176
-DSQLITE_OMIT_PROGRESS_CALLBACK \
21772177
-DSQLITE_OMIT_SHARED_CACHE \
21782178
-DSQLITE_OMIT_LOAD_EXTENSION \
2179
+ -DSQLITE_MAX_EXPR_DEPTH=0 \
2180
+ -DSQLITE_USE_ALLOCA \
21792181
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
21802182
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
21812183
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
21822184
-DSQLITE_ENABLE_FTS4 \
21832185
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
21842186
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
 
 
2179 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2180 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2181 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2182 -DSQLITE_ENABLE_FTS4 \
2183 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2184
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -2174,10 +2174,12 @@
2174 -DSQLITE_OMIT_DECLTYPE \
2175 -DSQLITE_OMIT_DEPRECATED \
2176 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2177 -DSQLITE_OMIT_SHARED_CACHE \
2178 -DSQLITE_OMIT_LOAD_EXTENSION \
2179 -DSQLITE_MAX_EXPR_DEPTH=0 \
2180 -DSQLITE_USE_ALLOCA \
2181 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2182 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2183 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2184 -DSQLITE_ENABLE_FTS4 \
2185 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2186
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -321,10 +321,12 @@
321321
/DSQLITE_OMIT_DECLTYPE \
322322
/DSQLITE_OMIT_DEPRECATED \
323323
/DSQLITE_OMIT_PROGRESS_CALLBACK \
324324
/DSQLITE_OMIT_SHARED_CACHE \
325325
/DSQLITE_OMIT_LOAD_EXTENSION \
326
+ /DSQLITE_MAX_EXPR_DEPTH=0 \
327
+ /DSQLITE_USE_ALLOCA \
326328
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
327329
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
328330
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
329331
/DSQLITE_ENABLE_FTS4 \
330332
/DSQLITE_ENABLE_FTS3_PARENTHESIS \
331333
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -321,10 +321,12 @@
321 /DSQLITE_OMIT_DECLTYPE \
322 /DSQLITE_OMIT_DEPRECATED \
323 /DSQLITE_OMIT_PROGRESS_CALLBACK \
324 /DSQLITE_OMIT_SHARED_CACHE \
325 /DSQLITE_OMIT_LOAD_EXTENSION \
 
 
326 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
327 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
328 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
329 /DSQLITE_ENABLE_FTS4 \
330 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
331
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -321,10 +321,12 @@
321 /DSQLITE_OMIT_DECLTYPE \
322 /DSQLITE_OMIT_DEPRECATED \
323 /DSQLITE_OMIT_PROGRESS_CALLBACK \
324 /DSQLITE_OMIT_SHARED_CACHE \
325 /DSQLITE_OMIT_LOAD_EXTENSION \
326 /DSQLITE_MAX_EXPR_DEPTH=0 \
327 /DSQLITE_USE_ALLOCA \
328 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
329 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
330 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
331 /DSQLITE_ENABLE_FTS4 \
332 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
333
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -321,10 +321,12 @@
321321
/DSQLITE_OMIT_DECLTYPE \
322322
/DSQLITE_OMIT_DEPRECATED \
323323
/DSQLITE_OMIT_PROGRESS_CALLBACK \
324324
/DSQLITE_OMIT_SHARED_CACHE \
325325
/DSQLITE_OMIT_LOAD_EXTENSION \
326
+ /DSQLITE_MAX_EXPR_DEPTH=0 \
327
+ /DSQLITE_USE_ALLOCA \
326328
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
327329
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
328330
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
329331
/DSQLITE_ENABLE_FTS4 \
330332
/DSQLITE_ENABLE_FTS3_PARENTHESIS \
331333
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -321,10 +321,12 @@
321 /DSQLITE_OMIT_DECLTYPE \
322 /DSQLITE_OMIT_DEPRECATED \
323 /DSQLITE_OMIT_PROGRESS_CALLBACK \
324 /DSQLITE_OMIT_SHARED_CACHE \
325 /DSQLITE_OMIT_LOAD_EXTENSION \
 
 
326 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
327 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
328 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
329 /DSQLITE_ENABLE_FTS4 \
330 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
331
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -321,10 +321,12 @@
321 /DSQLITE_OMIT_DECLTYPE \
322 /DSQLITE_OMIT_DEPRECATED \
323 /DSQLITE_OMIT_PROGRESS_CALLBACK \
324 /DSQLITE_OMIT_SHARED_CACHE \
325 /DSQLITE_OMIT_LOAD_EXTENSION \
326 /DSQLITE_MAX_EXPR_DEPTH=0 \
327 /DSQLITE_USE_ALLOCA \
328 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
329 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
330 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
331 /DSQLITE_ENABLE_FTS4 \
332 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
333
+11 -11
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -66,11 +66,11 @@
6666
<p>
6767
In addition to setting various CGI environment variables, if the HTTP
6868
request contains POST content, then the web server relays the POST content
6969
to standard input of the CGI script.
7070
<p>
71
-In summary, the task of the
71
+In summary, the task of the
7272
CGI script is to read the various CGI environment variables and
7373
the POST content on standard input (if any), figure out an appropriate
7474
reply, then write that reply on standard output.
7575
The web server will read the output from the CGI script, reformat it
7676
into an appropriate HTTP reply, and relay the result back to the
@@ -89,31 +89,31 @@
8989
like the following:
9090
<blockquote><pre>
9191
#!/usr/bin/fossil
9292
repository: /home/www/repos/project.fossil
9393
</pre></blockquote>
94
-The first line of the script is a
94
+The first line of the script is a
9595
"[https://en.wikipedia.org/wiki/Shebang_%28Unix%29|shebang]"
9696
that tells the operating system what program to use as the interpreter
9797
for this script. On unix, when you execute a script that starts with
9898
a shebang, the operating system runs the program identified by the
99
-shebang with a single argument that is the full pathname of the script
99
+shebang with a single argument that is the full pathname of the script
100100
itself.
101101
In our example, the interpreter is Fossil, and the argument might
102102
be something like "/var/www/cgi-bin/one/two" (depending on how your
103103
particular web server is configured).
104104
<p>
105105
The Fossil program that is run as the script interpreter
106106
is the same Fossil that runs when
107107
you type ordinary Fossil commands like "fossil sync" or "fossil commit".
108108
But in this case, as soon as it launches, the Fossil program
109
-recognizes that the GATEWAY_INTERFACE environment variable is
109
+recognizes that the GATEWAY_INTERFACE environment variable is
110110
set to "CGI/1.0" and it therefore knows that it is being used as
111111
CGI rather than as an ordinary command-line tool, and behaves accordingly.
112112
<p>
113113
When Fossil recognizes that it is being run as CGI, it opens and reads
114
-the file identified by its sole argument (the file named by
114
+the file identified by its sole argument (the file named by
115115
<code>argv&#91;1&#93;</code>). In our example, the second line of that file
116116
tells Fossil the location of the repository it will be serving.
117117
Fossil then starts looking at the CGI environment variables to figure
118118
out what web page is being requested, generates that one web page,
119119
then exits.
@@ -130,12 +130,12 @@
130130
<ol type='A'>
131131
<li> [https://www.fossil-scm.org/fossil/info/c14ecc43]
132132
<li> [https://www.fossil-scm.org/fossil/info?name=c14ecc43]
133133
</ol>
134134
In both cases, the CGI script is called "/fossil". For case (A),
135
-the PATH_INFO variable will be "info/c14ecc43" and so the
136
-"[/help?cmd=/info]" webpage will be generated and the suffix of
135
+the PATH_INFO variable will be "info/c14ecc43" and so the
136
+"[/help?cmd=/info|/info]" webpage will be generated and the suffix of
137137
PATH_INFO will be converted into the "name" query parameter, which
138138
identifies the artifact about which information is requested.
139139
In case (B), the PATH_INFO is just "info", but the same "name"
140140
query parameter is set explicitly by the URL itself.
141141
</blockquote>
@@ -164,11 +164,11 @@
164164
<blockquote>
165165
<b>http://example.com/cgis/example2/subdir/three/timeline</b>
166166
</blockquote>
167167
Here is what happens:
168168
<ol>
169
-<li> The input URI on the HTTP request is
169
+<li> The input URI on the HTTP request is
170170
<b>/cgis/example2/subdir/three/timeline</b>
171171
<li> The web server searches prefixes of the input URI until it finds
172172
the "cgis/example2" script. The web server then sets
173173
PATH_INFO to the "subdir/three/timeline" suffix and invokes the
174174
"cgis/example2" script.
@@ -175,11 +175,11 @@
175175
<li> Fossil runs and sees the "directory:" line pointing to
176176
"/home/www/repos". Fossil then starts pulling terms off the
177177
front of the PATH_INFO looking for a repository. It first looks
178178
at "/home/www/resps/subdir.fossil" but there is no such repository.
179179
So then it looks at "/home/www/repos/subdir/three.fossil" and finds
180
- a repository. The PATH_INFO is shortened by removing
180
+ a repository. The PATH_INFO is shortened by removing
181181
"subdir/three/" leaving it at just "timeline".
182182
<li> Fossil looks at the rest of PATH_INFO to see that the webpage
183183
requested is "timeline".
184184
</ol>
185185
</blockquote>
@@ -201,14 +201,14 @@
201201
and has a value.
202202
<li><p>
203203
The "[/help?cmd=ui|fossil ui]" and "[/help?cmd=server|fossil server]" commands
204204
are implemented using a simple built-in web server that accepts incoming HTTP
205205
requests, translates each request into a CGI invocation, then creates a
206
-separate child Fossil process to handle each request. In other words, CGI
206
+separate child Fossil process to handle each request. In other words, CGI
207207
is used internally to implement "fossil ui/server".
208208
<p>
209209
SCGI is processed using the same built-in web server, just modified
210210
to parse SCGI requests instead of HTTP requests. Each SCGI request is
211
-converted into CGI, then Fossil creates a separate child Fossil
211
+converted into CGI, then Fossil creates a separate child Fossil
212212
process to handle each CGI request.
213213
</ol>
214214
</blockquote>
215215
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -66,11 +66,11 @@
66 <p>
67 In addition to setting various CGI environment variables, if the HTTP
68 request contains POST content, then the web server relays the POST content
69 to standard input of the CGI script.
70 <p>
71 In summary, the task of the
72 CGI script is to read the various CGI environment variables and
73 the POST content on standard input (if any), figure out an appropriate
74 reply, then write that reply on standard output.
75 The web server will read the output from the CGI script, reformat it
76 into an appropriate HTTP reply, and relay the result back to the
@@ -89,31 +89,31 @@
89 like the following:
90 <blockquote><pre>
91 #!/usr/bin/fossil
92 repository: /home/www/repos/project.fossil
93 </pre></blockquote>
94 The first line of the script is a
95 "[https://en.wikipedia.org/wiki/Shebang_%28Unix%29|shebang]"
96 that tells the operating system what program to use as the interpreter
97 for this script. On unix, when you execute a script that starts with
98 a shebang, the operating system runs the program identified by the
99 shebang with a single argument that is the full pathname of the script
100 itself.
101 In our example, the interpreter is Fossil, and the argument might
102 be something like "/var/www/cgi-bin/one/two" (depending on how your
103 particular web server is configured).
104 <p>
105 The Fossil program that is run as the script interpreter
106 is the same Fossil that runs when
107 you type ordinary Fossil commands like "fossil sync" or "fossil commit".
108 But in this case, as soon as it launches, the Fossil program
109 recognizes that the GATEWAY_INTERFACE environment variable is
110 set to "CGI/1.0" and it therefore knows that it is being used as
111 CGI rather than as an ordinary command-line tool, and behaves accordingly.
112 <p>
113 When Fossil recognizes that it is being run as CGI, it opens and reads
114 the file identified by its sole argument (the file named by
115 <code>argv&#91;1&#93;</code>). In our example, the second line of that file
116 tells Fossil the location of the repository it will be serving.
117 Fossil then starts looking at the CGI environment variables to figure
118 out what web page is being requested, generates that one web page,
119 then exits.
@@ -130,12 +130,12 @@
130 <ol type='A'>
131 <li> [https://www.fossil-scm.org/fossil/info/c14ecc43]
132 <li> [https://www.fossil-scm.org/fossil/info?name=c14ecc43]
133 </ol>
134 In both cases, the CGI script is called "/fossil". For case (A),
135 the PATH_INFO variable will be "info/c14ecc43" and so the
136 "[/help?cmd=/info]" webpage will be generated and the suffix of
137 PATH_INFO will be converted into the "name" query parameter, which
138 identifies the artifact about which information is requested.
139 In case (B), the PATH_INFO is just "info", but the same "name"
140 query parameter is set explicitly by the URL itself.
141 </blockquote>
@@ -164,11 +164,11 @@
164 <blockquote>
165 <b>http://example.com/cgis/example2/subdir/three/timeline</b>
166 </blockquote>
167 Here is what happens:
168 <ol>
169 <li> The input URI on the HTTP request is
170 <b>/cgis/example2/subdir/three/timeline</b>
171 <li> The web server searches prefixes of the input URI until it finds
172 the "cgis/example2" script. The web server then sets
173 PATH_INFO to the "subdir/three/timeline" suffix and invokes the
174 "cgis/example2" script.
@@ -175,11 +175,11 @@
175 <li> Fossil runs and sees the "directory:" line pointing to
176 "/home/www/repos". Fossil then starts pulling terms off the
177 front of the PATH_INFO looking for a repository. It first looks
178 at "/home/www/resps/subdir.fossil" but there is no such repository.
179 So then it looks at "/home/www/repos/subdir/three.fossil" and finds
180 a repository. The PATH_INFO is shortened by removing
181 "subdir/three/" leaving it at just "timeline".
182 <li> Fossil looks at the rest of PATH_INFO to see that the webpage
183 requested is "timeline".
184 </ol>
185 </blockquote>
@@ -201,14 +201,14 @@
201 and has a value.
202 <li><p>
203 The "[/help?cmd=ui|fossil ui]" and "[/help?cmd=server|fossil server]" commands
204 are implemented using a simple built-in web server that accepts incoming HTTP
205 requests, translates each request into a CGI invocation, then creates a
206 separate child Fossil process to handle each request. In other words, CGI
207 is used internally to implement "fossil ui/server".
208 <p>
209 SCGI is processed using the same built-in web server, just modified
210 to parse SCGI requests instead of HTTP requests. Each SCGI request is
211 converted into CGI, then Fossil creates a separate child Fossil
212 process to handle each CGI request.
213 </ol>
214 </blockquote>
215
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -66,11 +66,11 @@
66 <p>
67 In addition to setting various CGI environment variables, if the HTTP
68 request contains POST content, then the web server relays the POST content
69 to standard input of the CGI script.
70 <p>
71 In summary, the task of the
72 CGI script is to read the various CGI environment variables and
73 the POST content on standard input (if any), figure out an appropriate
74 reply, then write that reply on standard output.
75 The web server will read the output from the CGI script, reformat it
76 into an appropriate HTTP reply, and relay the result back to the
@@ -89,31 +89,31 @@
89 like the following:
90 <blockquote><pre>
91 #!/usr/bin/fossil
92 repository: /home/www/repos/project.fossil
93 </pre></blockquote>
94 The first line of the script is a
95 "[https://en.wikipedia.org/wiki/Shebang_%28Unix%29|shebang]"
96 that tells the operating system what program to use as the interpreter
97 for this script. On unix, when you execute a script that starts with
98 a shebang, the operating system runs the program identified by the
99 shebang with a single argument that is the full pathname of the script
100 itself.
101 In our example, the interpreter is Fossil, and the argument might
102 be something like "/var/www/cgi-bin/one/two" (depending on how your
103 particular web server is configured).
104 <p>
105 The Fossil program that is run as the script interpreter
106 is the same Fossil that runs when
107 you type ordinary Fossil commands like "fossil sync" or "fossil commit".
108 But in this case, as soon as it launches, the Fossil program
109 recognizes that the GATEWAY_INTERFACE environment variable is
110 set to "CGI/1.0" and it therefore knows that it is being used as
111 CGI rather than as an ordinary command-line tool, and behaves accordingly.
112 <p>
113 When Fossil recognizes that it is being run as CGI, it opens and reads
114 the file identified by its sole argument (the file named by
115 <code>argv&#91;1&#93;</code>). In our example, the second line of that file
116 tells Fossil the location of the repository it will be serving.
117 Fossil then starts looking at the CGI environment variables to figure
118 out what web page is being requested, generates that one web page,
119 then exits.
@@ -130,12 +130,12 @@
130 <ol type='A'>
131 <li> [https://www.fossil-scm.org/fossil/info/c14ecc43]
132 <li> [https://www.fossil-scm.org/fossil/info?name=c14ecc43]
133 </ol>
134 In both cases, the CGI script is called "/fossil". For case (A),
135 the PATH_INFO variable will be "info/c14ecc43" and so the
136 "[/help?cmd=/info|/info]" webpage will be generated and the suffix of
137 PATH_INFO will be converted into the "name" query parameter, which
138 identifies the artifact about which information is requested.
139 In case (B), the PATH_INFO is just "info", but the same "name"
140 query parameter is set explicitly by the URL itself.
141 </blockquote>
@@ -164,11 +164,11 @@
164 <blockquote>
165 <b>http://example.com/cgis/example2/subdir/three/timeline</b>
166 </blockquote>
167 Here is what happens:
168 <ol>
169 <li> The input URI on the HTTP request is
170 <b>/cgis/example2/subdir/three/timeline</b>
171 <li> The web server searches prefixes of the input URI until it finds
172 the "cgis/example2" script. The web server then sets
173 PATH_INFO to the "subdir/three/timeline" suffix and invokes the
174 "cgis/example2" script.
@@ -175,11 +175,11 @@
175 <li> Fossil runs and sees the "directory:" line pointing to
176 "/home/www/repos". Fossil then starts pulling terms off the
177 front of the PATH_INFO looking for a repository. It first looks
178 at "/home/www/resps/subdir.fossil" but there is no such repository.
179 So then it looks at "/home/www/repos/subdir/three.fossil" and finds
180 a repository. The PATH_INFO is shortened by removing
181 "subdir/three/" leaving it at just "timeline".
182 <li> Fossil looks at the rest of PATH_INFO to see that the webpage
183 requested is "timeline".
184 </ol>
185 </blockquote>
@@ -201,14 +201,14 @@
201 and has a value.
202 <li><p>
203 The "[/help?cmd=ui|fossil ui]" and "[/help?cmd=server|fossil server]" commands
204 are implemented using a simple built-in web server that accepts incoming HTTP
205 requests, translates each request into a CGI invocation, then creates a
206 separate child Fossil process to handle each request. In other words, CGI
207 is used internally to implement "fossil ui/server".
208 <p>
209 SCGI is processed using the same built-in web server, just modified
210 to parse SCGI requests instead of HTTP requests. Each SCGI request is
211 converted into CGI, then Fossil creates a separate child Fossil
212 process to handle each CGI request.
213 </ol>
214 </blockquote>
215
--- www/adding_code.wiki
+++ www/adding_code.wiki
@@ -22,11 +22,11 @@
2222
2323
2. The <b>makeheaders</b> preprocessor generates all the ".h" files
2424
automatically. Fossil programmers write ".c" files only and let the
2525
makeheaders preprocessor create the ".h" files.
2626
27
- 3. The <b>translate</b> preprocessor converts source code lines that
27
+ 3. The <b>translate</b> preprocessor converts source code lines that
2828
begin with "@" into string literals, or into print statements that
2929
generate web page output, depending on context.
3030
3131
The [./makefile.wiki|Makefile] for Fossil takes care of running these
3232
preprocessors with all the right arguments and in the right order. So it is
@@ -39,13 +39,13 @@
3939
<h2>3.0 Adding New Source Code Files</h2>
4040
4141
New source code files are added in the "src/" subdirectory of the Fossil
4242
source tree. Suppose one wants to add a new source code file named
4343
"xyzzy.c". The first step is to add this file to the various makefiles.
44
-Do so by editing the file src/makemake.tcl and adding "xyzzy" (without
44
+Do so by editing the file src/makemake.tcl and adding "xyzzy" (without
4545
the final ".c") to the list of source modules at the top of that script.
46
-Save the result and then run the makemake.tcl script using a TCL
46
+Save the result and then run the makemake.tcl script using a TCL
4747
interpreter. The command to run the makemake.tcl script is:
4848
4949
<b>tclsh makemake.tcl</b>
5050
5151
The working directory must be src/ when the command above is run.
@@ -60,11 +60,11 @@
6060
6161
<blockquote><verbatim>
6262
/*
6363
** Copyright boilerplate goes here.
6464
*****************************************************
65
-** High-level description of what this module goes
65
+** High-level description of what this module goes
6666
** here.
6767
*/
6868
#include "config.h"
6969
#include "xyzzy.h"
7070
@@ -83,11 +83,11 @@
8383
exceptions to this rule. Don't worry about those exceptions. The
8484
files you write will require this #include line.)
8585
8686
The "#if INTERFACE ... #endif" section is optional and is only needed
8787
if there are structure definitions or typedefs or macros that need to
88
-be used by other source code files. The makeheaders preprocessor
88
+be used by other source code files. The makeheaders preprocessor
8989
uses definitions in the INTERFACE section to help it generate header
9090
files. See [../src/makeheaders.html | makeheaders.html] for additional
9191
information.
9292
9393
After creating a template file such as shown above, and after updating
9494
--- www/adding_code.wiki
+++ www/adding_code.wiki
@@ -22,11 +22,11 @@
22
23 2. The <b>makeheaders</b> preprocessor generates all the ".h" files
24 automatically. Fossil programmers write ".c" files only and let the
25 makeheaders preprocessor create the ".h" files.
26
27 3. The <b>translate</b> preprocessor converts source code lines that
28 begin with "@" into string literals, or into print statements that
29 generate web page output, depending on context.
30
31 The [./makefile.wiki|Makefile] for Fossil takes care of running these
32 preprocessors with all the right arguments and in the right order. So it is
@@ -39,13 +39,13 @@
39 <h2>3.0 Adding New Source Code Files</h2>
40
41 New source code files are added in the "src/" subdirectory of the Fossil
42 source tree. Suppose one wants to add a new source code file named
43 "xyzzy.c". The first step is to add this file to the various makefiles.
44 Do so by editing the file src/makemake.tcl and adding "xyzzy" (without
45 the final ".c") to the list of source modules at the top of that script.
46 Save the result and then run the makemake.tcl script using a TCL
47 interpreter. The command to run the makemake.tcl script is:
48
49 <b>tclsh makemake.tcl</b>
50
51 The working directory must be src/ when the command above is run.
@@ -60,11 +60,11 @@
60
61 <blockquote><verbatim>
62 /*
63 ** Copyright boilerplate goes here.
64 *****************************************************
65 ** High-level description of what this module goes
66 ** here.
67 */
68 #include "config.h"
69 #include "xyzzy.h"
70
@@ -83,11 +83,11 @@
83 exceptions to this rule. Don't worry about those exceptions. The
84 files you write will require this #include line.)
85
86 The "#if INTERFACE ... #endif" section is optional and is only needed
87 if there are structure definitions or typedefs or macros that need to
88 be used by other source code files. The makeheaders preprocessor
89 uses definitions in the INTERFACE section to help it generate header
90 files. See [../src/makeheaders.html | makeheaders.html] for additional
91 information.
92
93 After creating a template file such as shown above, and after updating
94
--- www/adding_code.wiki
+++ www/adding_code.wiki
@@ -22,11 +22,11 @@
22
23 2. The <b>makeheaders</b> preprocessor generates all the ".h" files
24 automatically. Fossil programmers write ".c" files only and let the
25 makeheaders preprocessor create the ".h" files.
26
27 3. The <b>translate</b> preprocessor converts source code lines that
28 begin with "@" into string literals, or into print statements that
29 generate web page output, depending on context.
30
31 The [./makefile.wiki|Makefile] for Fossil takes care of running these
32 preprocessors with all the right arguments and in the right order. So it is
@@ -39,13 +39,13 @@
39 <h2>3.0 Adding New Source Code Files</h2>
40
41 New source code files are added in the "src/" subdirectory of the Fossil
42 source tree. Suppose one wants to add a new source code file named
43 "xyzzy.c". The first step is to add this file to the various makefiles.
44 Do so by editing the file src/makemake.tcl and adding "xyzzy" (without
45 the final ".c") to the list of source modules at the top of that script.
46 Save the result and then run the makemake.tcl script using a TCL
47 interpreter. The command to run the makemake.tcl script is:
48
49 <b>tclsh makemake.tcl</b>
50
51 The working directory must be src/ when the command above is run.
@@ -60,11 +60,11 @@
60
61 <blockquote><verbatim>
62 /*
63 ** Copyright boilerplate goes here.
64 *****************************************************
65 ** High-level description of what this module goes
66 ** here.
67 */
68 #include "config.h"
69 #include "xyzzy.h"
70
@@ -83,11 +83,11 @@
83 exceptions to this rule. Don't worry about those exceptions. The
84 files you write will require this #include line.)
85
86 The "#if INTERFACE ... #endif" section is optional and is only needed
87 if there are structure definitions or typedefs or macros that need to
88 be used by other source code files. The makeheaders preprocessor
89 uses definitions in the INTERFACE section to help it generate header
90 files. See [../src/makeheaders.html | makeheaders.html] for additional
91 information.
92
93 After creating a template file such as shown above, and after updating
94
+11 -11
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,27 +1,27 @@
11
<title>Defense Against Spiders</title>
22
33
The website presented by a Fossil server has many hyperlinks.
44
Even a modest project can have millions of pages in its
5
-tree, and many of those pages (for example diffs and annotations
5
+tree, and many of those pages (for example diffs and annotations
66
and ZIP archive of older check-ins) can be expensive to compute.
77
If a spider or bot tries to walk a website implemented by
88
Fossil, it can present a crippling bandwidth and CPU load.
99
1010
The website presented by a Fossil server is intended to be used
11
-interactively by humans, not walked by spiders. This article
11
+interactively by humans, not walked by spiders. This article
1212
describes the techniques used by Fossil to try to welcome human
1313
users while keeping out spiders.
1414
1515
<h2>The "hyperlink" user capability</h2>
1616
1717
Every Fossil web session has a "user". For random passers-by on the internet
1818
(and for spiders) that user is "nobody". The "anonymous" user is also
1919
available for humans who do not wish to identify themselves. The difference
2020
is that "anonymous" requires a login (using a password supplied via
21
-a CAPTCHA) whereas "nobody" does not require a login.
22
-The site administrator can also create logins with
21
+a CAPTCHA) whereas "nobody" does not require a login.
22
+The site administrator can also create logins with
2323
passwords for specific individuals.
2424
2525
The "h" or "hyperlink" capability is a permission that can be granted
2626
to users that enables the display of hyperlinks. Most of the hyperlinks
2727
generated by Fossil are suppressed if this capability is missing. So
@@ -37,11 +37,11 @@
3737
page inviting the user to log in as anonymous in order to activate hyperlinks.
3838
3939
Removing the "h" capability from user "nobody" is an effective means
4040
of preventing spiders from walking a Fossil-generated website. But
4141
it can also be annoying to humans, since it requires them to log in.
42
-Hence, Fossil provides other techniques for blocking spiders which
42
+Hence, Fossil provides other techniques for blocking spiders which
4343
are less cumbersome to humans.
4444
4545
<h2>Automatic hyperlinks based on UserAgent</h2>
4646
4747
Fossil has the ability to selectively enable hyperlinks for users
@@ -94,25 +94,25 @@
9494
web browsers implement javascript, so hyperlinks will appears
9595
normally for human users.
9696
9797
<h2>Further defenses</h2>
9898
99
-Recently (as of this writing, in the spring of 2013) the Fossil server
99
+Recently (as of this writing, in the spring of 2013) the Fossil server
100100
on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
101
-by Chinese spiders that use forged UserAgent strings to make them look
101
+by Chinese spiders that use forged UserAgent strings to make them look
102102
like normal web browsers and which interpret javascript. We do not
103103
believe these attacks to be nefarious since SQLite is public domain
104104
and the attackers could obtain all information they ever wanted to
105
-know about SQLite simply by cloning the repository. Instead, we
105
+know about SQLite simply by cloning the repository. Instead, we
106106
believe these "attacks" are coming from "script kiddies". But regardless
107107
of whether or not malice is involved, these attacks do present
108108
an unnecessary load on the server which reduces the responsiveness of
109109
the SQLite website for well-behaved and socially responsible users.
110110
For this reason, additional defenses against
111111
spiders have been put in place.
112112
113
-On the Admin/Access page of Fossil, just below the
113
+On the Admin/Access page of Fossil, just below the
114114
"<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
115115
setting, there are now two additional subsettings that can be optionally
116116
enabled to control hyperlinks.
117117
118118
The first subsetting waits to run the
@@ -137,11 +137,11 @@
137137
Fossil currently does a very good job of providing easy access to humans
138138
while keeping out troublesome robots and spiders. However, spiders and
139139
bots continue to grow more sophisticated, requiring ever more advanced
140140
defenses. This "arms race" is unlikely to ever end. The developers of
141141
Fossil will continue to try improve the spider defenses of Fossil so
142
-check back from time to time for the latest releases and updates.
142
+check back from time to time for the latest releases and updates.
143143
144144
Readers of this page who have suggestions on how to improve the spider
145145
defenses in Fossil are invited to submit your ideas to the Fossil Users
146
-mailing list:
146
+mailing list:
147147
[mailto:[email protected] | [email protected]].
148148
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,27 +1,27 @@
1 <title>Defense Against Spiders</title>
2
3 The website presented by a Fossil server has many hyperlinks.
4 Even a modest project can have millions of pages in its
5 tree, and many of those pages (for example diffs and annotations
6 and ZIP archive of older check-ins) can be expensive to compute.
7 If a spider or bot tries to walk a website implemented by
8 Fossil, it can present a crippling bandwidth and CPU load.
9
10 The website presented by a Fossil server is intended to be used
11 interactively by humans, not walked by spiders. This article
12 describes the techniques used by Fossil to try to welcome human
13 users while keeping out spiders.
14
15 <h2>The "hyperlink" user capability</h2>
16
17 Every Fossil web session has a "user". For random passers-by on the internet
18 (and for spiders) that user is "nobody". The "anonymous" user is also
19 available for humans who do not wish to identify themselves. The difference
20 is that "anonymous" requires a login (using a password supplied via
21 a CAPTCHA) whereas "nobody" does not require a login.
22 The site administrator can also create logins with
23 passwords for specific individuals.
24
25 The "h" or "hyperlink" capability is a permission that can be granted
26 to users that enables the display of hyperlinks. Most of the hyperlinks
27 generated by Fossil are suppressed if this capability is missing. So
@@ -37,11 +37,11 @@
37 page inviting the user to log in as anonymous in order to activate hyperlinks.
38
39 Removing the "h" capability from user "nobody" is an effective means
40 of preventing spiders from walking a Fossil-generated website. But
41 it can also be annoying to humans, since it requires them to log in.
42 Hence, Fossil provides other techniques for blocking spiders which
43 are less cumbersome to humans.
44
45 <h2>Automatic hyperlinks based on UserAgent</h2>
46
47 Fossil has the ability to selectively enable hyperlinks for users
@@ -94,25 +94,25 @@
94 web browsers implement javascript, so hyperlinks will appears
95 normally for human users.
96
97 <h2>Further defenses</h2>
98
99 Recently (as of this writing, in the spring of 2013) the Fossil server
100 on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
101 by Chinese spiders that use forged UserAgent strings to make them look
102 like normal web browsers and which interpret javascript. We do not
103 believe these attacks to be nefarious since SQLite is public domain
104 and the attackers could obtain all information they ever wanted to
105 know about SQLite simply by cloning the repository. Instead, we
106 believe these "attacks" are coming from "script kiddies". But regardless
107 of whether or not malice is involved, these attacks do present
108 an unnecessary load on the server which reduces the responsiveness of
109 the SQLite website for well-behaved and socially responsible users.
110 For this reason, additional defenses against
111 spiders have been put in place.
112
113 On the Admin/Access page of Fossil, just below the
114 "<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
115 setting, there are now two additional subsettings that can be optionally
116 enabled to control hyperlinks.
117
118 The first subsetting waits to run the
@@ -137,11 +137,11 @@
137 Fossil currently does a very good job of providing easy access to humans
138 while keeping out troublesome robots and spiders. However, spiders and
139 bots continue to grow more sophisticated, requiring ever more advanced
140 defenses. This "arms race" is unlikely to ever end. The developers of
141 Fossil will continue to try improve the spider defenses of Fossil so
142 check back from time to time for the latest releases and updates.
143
144 Readers of this page who have suggestions on how to improve the spider
145 defenses in Fossil are invited to submit your ideas to the Fossil Users
146 mailing list:
147 [mailto:[email protected] | [email protected]].
148
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,27 +1,27 @@
1 <title>Defense Against Spiders</title>
2
3 The website presented by a Fossil server has many hyperlinks.
4 Even a modest project can have millions of pages in its
5 tree, and many of those pages (for example diffs and annotations
6 and ZIP archive of older check-ins) can be expensive to compute.
7 If a spider or bot tries to walk a website implemented by
8 Fossil, it can present a crippling bandwidth and CPU load.
9
10 The website presented by a Fossil server is intended to be used
11 interactively by humans, not walked by spiders. This article
12 describes the techniques used by Fossil to try to welcome human
13 users while keeping out spiders.
14
15 <h2>The "hyperlink" user capability</h2>
16
17 Every Fossil web session has a "user". For random passers-by on the internet
18 (and for spiders) that user is "nobody". The "anonymous" user is also
19 available for humans who do not wish to identify themselves. The difference
20 is that "anonymous" requires a login (using a password supplied via
21 a CAPTCHA) whereas "nobody" does not require a login.
22 The site administrator can also create logins with
23 passwords for specific individuals.
24
25 The "h" or "hyperlink" capability is a permission that can be granted
26 to users that enables the display of hyperlinks. Most of the hyperlinks
27 generated by Fossil are suppressed if this capability is missing. So
@@ -37,11 +37,11 @@
37 page inviting the user to log in as anonymous in order to activate hyperlinks.
38
39 Removing the "h" capability from user "nobody" is an effective means
40 of preventing spiders from walking a Fossil-generated website. But
41 it can also be annoying to humans, since it requires them to log in.
42 Hence, Fossil provides other techniques for blocking spiders which
43 are less cumbersome to humans.
44
45 <h2>Automatic hyperlinks based on UserAgent</h2>
46
47 Fossil has the ability to selectively enable hyperlinks for users
@@ -94,25 +94,25 @@
94 web browsers implement javascript, so hyperlinks will appears
95 normally for human users.
96
97 <h2>Further defenses</h2>
98
99 Recently (as of this writing, in the spring of 2013) the Fossil server
100 on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
101 by Chinese spiders that use forged UserAgent strings to make them look
102 like normal web browsers and which interpret javascript. We do not
103 believe these attacks to be nefarious since SQLite is public domain
104 and the attackers could obtain all information they ever wanted to
105 know about SQLite simply by cloning the repository. Instead, we
106 believe these "attacks" are coming from "script kiddies". But regardless
107 of whether or not malice is involved, these attacks do present
108 an unnecessary load on the server which reduces the responsiveness of
109 the SQLite website for well-behaved and socially responsible users.
110 For this reason, additional defenses against
111 spiders have been put in place.
112
113 On the Admin/Access page of Fossil, just below the
114 "<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
115 setting, there are now two additional subsettings that can be optionally
116 enabled to control hyperlinks.
117
118 The first subsetting waits to run the
@@ -137,11 +137,11 @@
137 Fossil currently does a very good job of providing easy access to humans
138 while keeping out troublesome robots and spiders. However, spiders and
139 bots continue to grow more sophisticated, requiring ever more advanced
140 defenses. This "arms race" is unlikely to ever end. The developers of
141 Fossil will continue to try improve the spider defenses of Fossil so
142 check back from time to time for the latest releases and updates.
143
144 Readers of this page who have suggestions on how to improve the spider
145 defenses in Fossil are invited to submit your ideas to the Fossil Users
146 mailing list:
147 [mailto:[email protected] | [email protected]].
148
+4 -4
--- www/blame.wiki
+++ www/blame.wiki
@@ -18,16 +18,16 @@
1818
<li>Locate the check-in that contains the file that is to be
1919
annotated. Call this check-in C0.
2020
<li>Find all direct ancestors of C0. A direct ancestor is the closure
2121
of the primary parent of C0. Merged in branches are not part of
2222
the direct ancestors of C0.
23
-<li>Prune the list of ancestors of C0 so that it contains only
23
+<li>Prune the list of ancestors of C0 so that it contains only
2424
check-in in which the file to be annotated was modified.
2525
<li>Load the complete text of the file to be annotated from check-in C0.
2626
Call this version of the file F0.
2727
<li>Parse F0 into lines. Mark each line as "unchanged".
28
-<li>For each ancestor of C0 on the pruned list (call the ancestor CX),
28
+<li>For each ancestor of C0 on the pruned list (call the ancestor CX),
2929
beginning with the most
3030
recent ancestor and moving toward the oldest ancestor, do the
3131
following steps:
3232
<ol type='a'>
3333
<li>Load the text for the file to be annotated as it existed in check-in CX.
@@ -44,19 +44,19 @@
4444
<h2>3.0 Discussion and Notes</h2>
4545
4646
The time-consuming part of this algorithm is step 6b - computing the
4747
diff from all historical versions of the file to the version of the file
4848
under analysis. For a large file that has many historical changes, this
49
-can take several seconds. For this reason, the default
49
+can take several seconds. For this reason, the default
5050
[/help?cmd=/annotate|/annotate] webpage only shows those lines that where
5151
changed by the 20 most recent modifications to the file. This allows
5252
the loop on step 6 to terminate after only 19 diffs instead of the hundreds
5353
or thousands of diffs that might be required for a frequently modified file.
5454
5555
As currently implemented (as of 2015-12-12) the annotate algorithm does not
56
-follow files across name changes. File name change information is
56
+follow files across name changes. File name change information is
5757
available in the database, and so the algorithm could be enhanced to follow
5858
files across name changes by modifications to step 3.
5959
6060
Step 2 is interesting in that it is
6161
[/artifact/6cb824a0417?ln=196-201 | implemented] using a
6262
[https://www.sqlite.org/lang_with.html#recursivecte|recursive common table expression].
6363
--- www/blame.wiki
+++ www/blame.wiki
@@ -18,16 +18,16 @@
18 <li>Locate the check-in that contains the file that is to be
19 annotated. Call this check-in C0.
20 <li>Find all direct ancestors of C0. A direct ancestor is the closure
21 of the primary parent of C0. Merged in branches are not part of
22 the direct ancestors of C0.
23 <li>Prune the list of ancestors of C0 so that it contains only
24 check-in in which the file to be annotated was modified.
25 <li>Load the complete text of the file to be annotated from check-in C0.
26 Call this version of the file F0.
27 <li>Parse F0 into lines. Mark each line as "unchanged".
28 <li>For each ancestor of C0 on the pruned list (call the ancestor CX),
29 beginning with the most
30 recent ancestor and moving toward the oldest ancestor, do the
31 following steps:
32 <ol type='a'>
33 <li>Load the text for the file to be annotated as it existed in check-in CX.
@@ -44,19 +44,19 @@
44 <h2>3.0 Discussion and Notes</h2>
45
46 The time-consuming part of this algorithm is step 6b - computing the
47 diff from all historical versions of the file to the version of the file
48 under analysis. For a large file that has many historical changes, this
49 can take several seconds. For this reason, the default
50 [/help?cmd=/annotate|/annotate] webpage only shows those lines that where
51 changed by the 20 most recent modifications to the file. This allows
52 the loop on step 6 to terminate after only 19 diffs instead of the hundreds
53 or thousands of diffs that might be required for a frequently modified file.
54
55 As currently implemented (as of 2015-12-12) the annotate algorithm does not
56 follow files across name changes. File name change information is
57 available in the database, and so the algorithm could be enhanced to follow
58 files across name changes by modifications to step 3.
59
60 Step 2 is interesting in that it is
61 [/artifact/6cb824a0417?ln=196-201 | implemented] using a
62 [https://www.sqlite.org/lang_with.html#recursivecte|recursive common table expression].
63
--- www/blame.wiki
+++ www/blame.wiki
@@ -18,16 +18,16 @@
18 <li>Locate the check-in that contains the file that is to be
19 annotated. Call this check-in C0.
20 <li>Find all direct ancestors of C0. A direct ancestor is the closure
21 of the primary parent of C0. Merged in branches are not part of
22 the direct ancestors of C0.
23 <li>Prune the list of ancestors of C0 so that it contains only
24 check-in in which the file to be annotated was modified.
25 <li>Load the complete text of the file to be annotated from check-in C0.
26 Call this version of the file F0.
27 <li>Parse F0 into lines. Mark each line as "unchanged".
28 <li>For each ancestor of C0 on the pruned list (call the ancestor CX),
29 beginning with the most
30 recent ancestor and moving toward the oldest ancestor, do the
31 following steps:
32 <ol type='a'>
33 <li>Load the text for the file to be annotated as it existed in check-in CX.
@@ -44,19 +44,19 @@
44 <h2>3.0 Discussion and Notes</h2>
45
46 The time-consuming part of this algorithm is step 6b - computing the
47 diff from all historical versions of the file to the version of the file
48 under analysis. For a large file that has many historical changes, this
49 can take several seconds. For this reason, the default
50 [/help?cmd=/annotate|/annotate] webpage only shows those lines that where
51 changed by the 20 most recent modifications to the file. This allows
52 the loop on step 6 to terminate after only 19 diffs instead of the hundreds
53 or thousands of diffs that might be required for a frequently modified file.
54
55 As currently implemented (as of 2015-12-12) the annotate algorithm does not
56 follow files across name changes. File name change information is
57 available in the database, and so the algorithm could be enhanced to follow
58 files across name changes by modifications to step 3.
59
60 Step 2 is interesting in that it is
61 [/artifact/6cb824a0417?ln=196-201 | implemented] using a
62 [https://www.sqlite.org/lang_with.html#recursivecte|recursive common table expression].
63
--- www/bugtheory.wiki
+++ www/bugtheory.wiki
@@ -27,11 +27,11 @@
2727
Recall that a fossil repository consists of an
2828
unordered collection of <i>artifacts</i>. (See the
2929
<a href="fileformat.wiki">file format document</a> for details.)
3030
Some artifacts have a special format, and among those are
3131
<a href="fileformat.wiki#tktchng">Ticket Change Artifacts</a>.
32
-One or more ticket change artifacts are associated with each
32
+One or more ticket change artifacts are associated with each
3333
ticket. A ticket is created by a ticket change artifact.
3434
Each subsequent modification of the ticket is a separate artifact.
3535
3636
The "push", "pull", and "sync" algorithms share ticket change artifacts
3737
between repositories in the same way as every other artifact. In fact,
3838
--- www/bugtheory.wiki
+++ www/bugtheory.wiki
@@ -27,11 +27,11 @@
27 Recall that a fossil repository consists of an
28 unordered collection of <i>artifacts</i>. (See the
29 <a href="fileformat.wiki">file format document</a> for details.)
30 Some artifacts have a special format, and among those are
31 <a href="fileformat.wiki#tktchng">Ticket Change Artifacts</a>.
32 One or more ticket change artifacts are associated with each
33 ticket. A ticket is created by a ticket change artifact.
34 Each subsequent modification of the ticket is a separate artifact.
35
36 The "push", "pull", and "sync" algorithms share ticket change artifacts
37 between repositories in the same way as every other artifact. In fact,
38
--- www/bugtheory.wiki
+++ www/bugtheory.wiki
@@ -27,11 +27,11 @@
27 Recall that a fossil repository consists of an
28 unordered collection of <i>artifacts</i>. (See the
29 <a href="fileformat.wiki">file format document</a> for details.)
30 Some artifacts have a special format, and among those are
31 <a href="fileformat.wiki#tktchng">Ticket Change Artifacts</a>.
32 One or more ticket change artifacts are associated with each
33 ticket. A ticket is created by a ticket change artifact.
34 Each subsequent modification of the ticket is a separate artifact.
35
36 The "push", "pull", and "sync" algorithms share ticket change artifacts
37 between repositories in the same way as every other artifact. In fact,
38
+31 -2
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,20 +1,42 @@
11
<title>Change Log</title>
22
3
-<h2>Changes for Version 1.36 (2016-00-00)</h2>
3
+<a name='v1_37'></a>
4
+<h2>Changes for Version 1.37 (2017-XX-YY)</h2>
5
+
6
+ * Fix a C99-ism that prevents the 1.36 release from building with MSVC.
7
+ * Fix [/help?cmd=ticket|ticket set] when using the "+" prefix with fields
8
+ from the "ticketchng" table.
9
+ * Enhance the "brlist" page to make use of branch colors.
10
+ * Remove the "fusefs" command from builds that do not have the underlying
11
+ support enabled.
12
+ * Fixes for incremental git import/export.
13
+ * Minor security enhancements to
14
+ [./encryptedrepos.wiki|encrypted repositories].
15
+ * TH1 enhancements:
16
+ <ul><li>Add <nowiki>[unversioned content]</nowiki> command.</li>
17
+ <li>Add <nowiki>[unversioned list]</nowiki> command.</li>
18
+ <li>Add project_description variable.</li>
19
+ </ul>
20
+
21
+<a name='v1_36'></a>
22
+<h2>Changes for Version 1.36 (2016-10-24)</h2>
423
524
* Add support for [./unvers.wiki|unversioned content],
625
the [/help?cmd=unversioned|fossil unversioned] command and the
726
[/help?cmd=/uv|/uv] and [/uvlist] web pages.
827
* The [/uv/download.html|download page] is moved into
928
[./unvers.wiki|unversioned content] so that the self-hosting Fossil
1029
websites no longer uses any external content.
1130
* Added the "Search" button to the graphical diff generated by
1231
the --tk option on the [/help?cmd=diff|diff] command.
32
+ * Added the "--checkin VERSION" option to the
33
+ [/help?cmd=diff|diff] command.
34
+ * Various performance enhancements to the [/help?cmd=diff|diff] command.
1335
* Update internal Unicode character tables, used in regular expression
1436
handling, from version 8.0 to 9.0.
15
- * Update the built-in SQLite to version 3.15 (beta). Fossil now requires
37
+ * Update the built-in SQLite to version 3.15. Fossil now requires
1638
the SQLITE_DBCONFIG_MAINDBNAME interface of SQLite which is only available
1739
in SQLite version 3.15 and later and so Fossil will not work with
1840
earlier SQLite versions.
1941
* Fix [https://www.mail-archive.com/[email protected]/msg23618.html|multi-line timeline bug]
2042
* Enhance the [/help?cmd=purge|fossil purge] command.
@@ -25,10 +47,11 @@
2547
able to pull from their parent but not push.
2648
* Added the -nocomplain option to the TH1 "query" command.
2749
* Added support for the chng=GLOBLIST query parameter on the
2850
[/help?cmd=/timeline|/timeline] webpage.
2951
52
+<a name='v1_35'></a>
3053
<h2>Changes for Version 1.35 (2016-06-14)</h2>
3154
3255
* Enable symlinks by default on all non-Windows platforms.
3356
* Enhance the [/md_rules|Markdown formatting] so that hyperlinks that begin
3457
with "/" are relative to the root of the Fossil repository.
@@ -68,10 +91,11 @@
6891
names in place of getpass() to read passwords and passphrases
6992
* Option --baseurl now works on Windows.
7093
* Numerious documentation improvements.
7194
* Update the built-in SQLite to version 3.13.0.
7295
96
+<a name='v1_34'></a>
7397
<h2>Changes for Version 1.34 (2015-11-02)</h2>
7498
7599
* Make the [/help?cmd=clean|fossil clean] command undoable for files less
76100
than 10MiB.
77101
* Update internal Unicode character tables, used in regular expression
@@ -103,10 +127,11 @@
103127
* Change the mimetype for ".n" and ".man" files to text/plain.
104128
* Display improvements in the [/help?cmd=bisect|fossil bisect chart] command.
105129
* Updated the built-in SQLite to version 3.9.1 and activated JSON1 and FTS5
106130
support (both currently unused within Fossil).
107131
132
+<a name='v1_33'></a>
108133
<h2>Changes for Version 1.33 (2015-05-23)</h2>
109134
* Improved fork detection on [/help?cmd=update|fossil update],
110135
[/help?cmd=status|fossil status] and related commands.
111136
* Change the default skin to what used to be called "San Francisco Modern".
112137
* Add the [/repo-tabsize] web page
@@ -152,10 +177,11 @@
152177
field for direct entry of the user name to each applicable report.
153178
* Create parent directories of [/help?cmd=settings|empty-dirs] if they don't
154179
already exist.
155180
* Inhibit timeline links to wiki pages that have been deleted.
156181
182
+<a name='v1_33'></a>
157183
<h2>Changes for Version 1.32 (2015-03-14)</h2>
158184
* When creating a new repository using [/help?cmd=init|fossil init], ensure
159185
that the new repository is fully compatible with historical versions of
160186
Fossil by having a valid manifest as RID 1.
161187
* Anti-aliased rendering of arrowheads on timeline graphs.
@@ -168,10 +194,11 @@
168194
* Enhance the "ln=" query parameter on artifact displays to accept multiple
169195
ranges, separate by spaces (or "+" when URL-encoded).
170196
* Added [/help?cmd=forget|fossil forget] as an alias for
171197
[/help?cmd=rm|fossil rm].
172198
199
+<a name='v1_31'></a>
173200
<h2>Changes For Version 1.31 (2015-02-23)</h2>
174201
* Change the auxiliary schema by adding columns MLINK.ISAUX and MLINK.PMID
175202
columns to the schema, to support better drawing of file change graphs.
176203
A [/help?cmd=rebuild|fossil rebuild] is recommended but is not required.
177204
so that the new graph drawing logic can work effectively.
@@ -219,10 +246,11 @@
219246
* Allow the user of Common Table Expressions in the SQL that defaults
220247
ticket reports.
221248
* Break out the components (css, footer, and header) for the
222249
various built-in skins into separate files in the source tree.
223250
251
+<a name='v1_30'></a>
224252
<h2>Changes For Version 1.30 (2015-01-19)</h2>
225253
* Added the [/help?cmd=bundle|fossil bundle] command.
226254
* Added the [/help?cmd=purge|fossil purge] command.
227255
* Added the [/help?cmd=publish|fossil publish] command.
228256
* Added the [/help?cmd=unpublished|fossil unpublished] command.
@@ -289,10 +317,11 @@
289317
the correctness of printf-style formatting strings.
290318
* Fix CVE-2014-3566, also known as the POODLE SSL 3.0 vulnerability.
291319
* Numerous documentation fixes and improvements.
292320
* Other obscure and minor bug fixes - see the timeline for details.
293321
322
+<a name='v1_29'></a>
294323
<h2>Changes For Version 1.29 (2014-06-12)</h2>
295324
* Add the ability to display content, diffs and annotations for UTF16
296325
text files in the web interface.
297326
* Add the "SaveAs..." and "Invert" buttons
298327
to the graphical diff display that results
299328
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,20 +1,42 @@
1 <title>Change Log</title>
2
3 <h2>Changes for Version 1.36 (2016-00-00)</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
5 * Add support for [./unvers.wiki|unversioned content],
6 the [/help?cmd=unversioned|fossil unversioned] command and the
7 [/help?cmd=/uv|/uv] and [/uvlist] web pages.
8 * The [/uv/download.html|download page] is moved into
9 [./unvers.wiki|unversioned content] so that the self-hosting Fossil
10 websites no longer uses any external content.
11 * Added the "Search" button to the graphical diff generated by
12 the --tk option on the [/help?cmd=diff|diff] command.
 
 
 
13 * Update internal Unicode character tables, used in regular expression
14 handling, from version 8.0 to 9.0.
15 * Update the built-in SQLite to version 3.15 (beta). Fossil now requires
16 the SQLITE_DBCONFIG_MAINDBNAME interface of SQLite which is only available
17 in SQLite version 3.15 and later and so Fossil will not work with
18 earlier SQLite versions.
19 * Fix [https://www.mail-archive.com/[email protected]/msg23618.html|multi-line timeline bug]
20 * Enhance the [/help?cmd=purge|fossil purge] command.
@@ -25,10 +47,11 @@
25 able to pull from their parent but not push.
26 * Added the -nocomplain option to the TH1 "query" command.
27 * Added support for the chng=GLOBLIST query parameter on the
28 [/help?cmd=/timeline|/timeline] webpage.
29
 
30 <h2>Changes for Version 1.35 (2016-06-14)</h2>
31
32 * Enable symlinks by default on all non-Windows platforms.
33 * Enhance the [/md_rules|Markdown formatting] so that hyperlinks that begin
34 with "/" are relative to the root of the Fossil repository.
@@ -68,10 +91,11 @@
68 names in place of getpass() to read passwords and passphrases
69 * Option --baseurl now works on Windows.
70 * Numerious documentation improvements.
71 * Update the built-in SQLite to version 3.13.0.
72
 
73 <h2>Changes for Version 1.34 (2015-11-02)</h2>
74
75 * Make the [/help?cmd=clean|fossil clean] command undoable for files less
76 than 10MiB.
77 * Update internal Unicode character tables, used in regular expression
@@ -103,10 +127,11 @@
103 * Change the mimetype for ".n" and ".man" files to text/plain.
104 * Display improvements in the [/help?cmd=bisect|fossil bisect chart] command.
105 * Updated the built-in SQLite to version 3.9.1 and activated JSON1 and FTS5
106 support (both currently unused within Fossil).
107
 
108 <h2>Changes for Version 1.33 (2015-05-23)</h2>
109 * Improved fork detection on [/help?cmd=update|fossil update],
110 [/help?cmd=status|fossil status] and related commands.
111 * Change the default skin to what used to be called "San Francisco Modern".
112 * Add the [/repo-tabsize] web page
@@ -152,10 +177,11 @@
152 field for direct entry of the user name to each applicable report.
153 * Create parent directories of [/help?cmd=settings|empty-dirs] if they don't
154 already exist.
155 * Inhibit timeline links to wiki pages that have been deleted.
156
 
157 <h2>Changes for Version 1.32 (2015-03-14)</h2>
158 * When creating a new repository using [/help?cmd=init|fossil init], ensure
159 that the new repository is fully compatible with historical versions of
160 Fossil by having a valid manifest as RID 1.
161 * Anti-aliased rendering of arrowheads on timeline graphs.
@@ -168,10 +194,11 @@
168 * Enhance the "ln=" query parameter on artifact displays to accept multiple
169 ranges, separate by spaces (or "+" when URL-encoded).
170 * Added [/help?cmd=forget|fossil forget] as an alias for
171 [/help?cmd=rm|fossil rm].
172
 
173 <h2>Changes For Version 1.31 (2015-02-23)</h2>
174 * Change the auxiliary schema by adding columns MLINK.ISAUX and MLINK.PMID
175 columns to the schema, to support better drawing of file change graphs.
176 A [/help?cmd=rebuild|fossil rebuild] is recommended but is not required.
177 so that the new graph drawing logic can work effectively.
@@ -219,10 +246,11 @@
219 * Allow the user of Common Table Expressions in the SQL that defaults
220 ticket reports.
221 * Break out the components (css, footer, and header) for the
222 various built-in skins into separate files in the source tree.
223
 
224 <h2>Changes For Version 1.30 (2015-01-19)</h2>
225 * Added the [/help?cmd=bundle|fossil bundle] command.
226 * Added the [/help?cmd=purge|fossil purge] command.
227 * Added the [/help?cmd=publish|fossil publish] command.
228 * Added the [/help?cmd=unpublished|fossil unpublished] command.
@@ -289,10 +317,11 @@
289 the correctness of printf-style formatting strings.
290 * Fix CVE-2014-3566, also known as the POODLE SSL 3.0 vulnerability.
291 * Numerous documentation fixes and improvements.
292 * Other obscure and minor bug fixes - see the timeline for details.
293
 
294 <h2>Changes For Version 1.29 (2014-06-12)</h2>
295 * Add the ability to display content, diffs and annotations for UTF16
296 text files in the web interface.
297 * Add the "SaveAs..." and "Invert" buttons
298 to the graphical diff display that results
299
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,20 +1,42 @@
1 <title>Change Log</title>
2
3 <a name='v1_37'></a>
4 <h2>Changes for Version 1.37 (2017-XX-YY)</h2>
5
6 * Fix a C99-ism that prevents the 1.36 release from building with MSVC.
7 * Fix [/help?cmd=ticket|ticket set] when using the "+" prefix with fields
8 from the "ticketchng" table.
9 * Enhance the "brlist" page to make use of branch colors.
10 * Remove the "fusefs" command from builds that do not have the underlying
11 support enabled.
12 * Fixes for incremental git import/export.
13 * Minor security enhancements to
14 [./encryptedrepos.wiki|encrypted repositories].
15 * TH1 enhancements:
16 <ul><li>Add <nowiki>[unversioned content]</nowiki> command.</li>
17 <li>Add <nowiki>[unversioned list]</nowiki> command.</li>
18 <li>Add project_description variable.</li>
19 </ul>
20
21 <a name='v1_36'></a>
22 <h2>Changes for Version 1.36 (2016-10-24)</h2>
23
24 * Add support for [./unvers.wiki|unversioned content],
25 the [/help?cmd=unversioned|fossil unversioned] command and the
26 [/help?cmd=/uv|/uv] and [/uvlist] web pages.
27 * The [/uv/download.html|download page] is moved into
28 [./unvers.wiki|unversioned content] so that the self-hosting Fossil
29 websites no longer uses any external content.
30 * Added the "Search" button to the graphical diff generated by
31 the --tk option on the [/help?cmd=diff|diff] command.
32 * Added the "--checkin VERSION" option to the
33 [/help?cmd=diff|diff] command.
34 * Various performance enhancements to the [/help?cmd=diff|diff] command.
35 * Update internal Unicode character tables, used in regular expression
36 handling, from version 8.0 to 9.0.
37 * Update the built-in SQLite to version 3.15. Fossil now requires
38 the SQLITE_DBCONFIG_MAINDBNAME interface of SQLite which is only available
39 in SQLite version 3.15 and later and so Fossil will not work with
40 earlier SQLite versions.
41 * Fix [https://www.mail-archive.com/[email protected]/msg23618.html|multi-line timeline bug]
42 * Enhance the [/help?cmd=purge|fossil purge] command.
@@ -25,10 +47,11 @@
47 able to pull from their parent but not push.
48 * Added the -nocomplain option to the TH1 "query" command.
49 * Added support for the chng=GLOBLIST query parameter on the
50 [/help?cmd=/timeline|/timeline] webpage.
51
52 <a name='v1_35'></a>
53 <h2>Changes for Version 1.35 (2016-06-14)</h2>
54
55 * Enable symlinks by default on all non-Windows platforms.
56 * Enhance the [/md_rules|Markdown formatting] so that hyperlinks that begin
57 with "/" are relative to the root of the Fossil repository.
@@ -68,10 +91,11 @@
91 names in place of getpass() to read passwords and passphrases
92 * Option --baseurl now works on Windows.
93 * Numerious documentation improvements.
94 * Update the built-in SQLite to version 3.13.0.
95
96 <a name='v1_34'></a>
97 <h2>Changes for Version 1.34 (2015-11-02)</h2>
98
99 * Make the [/help?cmd=clean|fossil clean] command undoable for files less
100 than 10MiB.
101 * Update internal Unicode character tables, used in regular expression
@@ -103,10 +127,11 @@
127 * Change the mimetype for ".n" and ".man" files to text/plain.
128 * Display improvements in the [/help?cmd=bisect|fossil bisect chart] command.
129 * Updated the built-in SQLite to version 3.9.1 and activated JSON1 and FTS5
130 support (both currently unused within Fossil).
131
132 <a name='v1_33'></a>
133 <h2>Changes for Version 1.33 (2015-05-23)</h2>
134 * Improved fork detection on [/help?cmd=update|fossil update],
135 [/help?cmd=status|fossil status] and related commands.
136 * Change the default skin to what used to be called "San Francisco Modern".
137 * Add the [/repo-tabsize] web page
@@ -152,10 +177,11 @@
177 field for direct entry of the user name to each applicable report.
178 * Create parent directories of [/help?cmd=settings|empty-dirs] if they don't
179 already exist.
180 * Inhibit timeline links to wiki pages that have been deleted.
181
182 <a name='v1_33'></a>
183 <h2>Changes for Version 1.32 (2015-03-14)</h2>
184 * When creating a new repository using [/help?cmd=init|fossil init], ensure
185 that the new repository is fully compatible with historical versions of
186 Fossil by having a valid manifest as RID 1.
187 * Anti-aliased rendering of arrowheads on timeline graphs.
@@ -168,10 +194,11 @@
194 * Enhance the "ln=" query parameter on artifact displays to accept multiple
195 ranges, separate by spaces (or "+" when URL-encoded).
196 * Added [/help?cmd=forget|fossil forget] as an alias for
197 [/help?cmd=rm|fossil rm].
198
199 <a name='v1_31'></a>
200 <h2>Changes For Version 1.31 (2015-02-23)</h2>
201 * Change the auxiliary schema by adding columns MLINK.ISAUX and MLINK.PMID
202 columns to the schema, to support better drawing of file change graphs.
203 A [/help?cmd=rebuild|fossil rebuild] is recommended but is not required.
204 so that the new graph drawing logic can work effectively.
@@ -219,10 +246,11 @@
246 * Allow the user of Common Table Expressions in the SQL that defaults
247 ticket reports.
248 * Break out the components (css, footer, and header) for the
249 various built-in skins into separate files in the source tree.
250
251 <a name='v1_30'></a>
252 <h2>Changes For Version 1.30 (2015-01-19)</h2>
253 * Added the [/help?cmd=bundle|fossil bundle] command.
254 * Added the [/help?cmd=purge|fossil purge] command.
255 * Added the [/help?cmd=publish|fossil publish] command.
256 * Added the [/help?cmd=unpublished|fossil unpublished] command.
@@ -289,10 +317,11 @@
317 the correctness of printf-style formatting strings.
318 * Fix CVE-2014-3566, also known as the POODLE SSL 3.0 vulnerability.
319 * Numerous documentation fixes and improvements.
320 * Other obscure and minor bug fixes - see the timeline for details.
321
322 <a name='v1_29'></a>
323 <h2>Changes For Version 1.29 (2014-06-12)</h2>
324 * Add the ability to display content, diffs and annotations for UTF16
325 text files in the web interface.
326 * Add the "SaveAs..." and "Invert" buttons
327 to the graphical diff display that results
328
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -55,20 +55,20 @@
5555
</pre></blockquote>
5656
5757
The full 40-character SHA1 hash is unwieldy to remember and type, though,
5858
so Fossil also accepts a unique prefix of the hash, using any combination
5959
of upper and lower case letters, as long as the prefix is at least 4
60
-characters long. Hence the following commands all
60
+characters long. Hence the following commands all
6161
accomplish the same thing as the above:
6262
6363
<blockquote><pre>
6464
fossil info e5a734a19a9
6565
fossil info E5a734A
6666
fossil info e5a7
6767
</blockquote>
6868
69
-Many web-interface screens identify check-ins by 10- or 16-character
69
+Many web-interface screens identify check-ins by 10- or 16-character
7070
prefix of canonical name.
7171
7272
<h2>Tags And Branch Names</h2>
7373
7474
Using a tag or branch name where a check-in name is expected causes
@@ -112,11 +112,11 @@
112112
113113
<blockquote><tt>
114114
fossil info tag:deed2
115115
</tt></blockquote>
116116
117
-The "tag:deed2" name will refer to the most recent check-in
117
+The "tag:deed2" name will refer to the most recent check-in
118118
tagged with "deed2" not to the
119119
check-in whose canonical name begins with "deed2".
120120
121121
<h2>Whole Branches</h2>
122122
@@ -147,11 +147,11 @@
147147
* <i>YYYY-MM-DD</i>
148148
* <i>YYYY-MM-DD HH:MM</i>
149149
* <i>YYYY-MM-DD HH:MM:SS</i>
150150
* <i>YYYY-MM-DD HH:MM:SS.SSS</i>
151151
152
-The space between the day and the year can optionally be
152
+The space between the day and the year can optionally be
153153
replaced by an uppercase <b>T</b> and the entire timestamp can
154154
optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth
155155
form with fractional seconds, any number of digits may follow the
156156
decimal point, though due to precision limits only the first three
157157
digits will be significant.
@@ -158,17 +158,17 @@
158158
159159
In its default configuration, Fossil interprets and displays all dates
160160
in Universal Coordinated Time (UTC). This tends to work the best for
161161
distributed projects where participants are scattered around the globe.
162162
But there is an option on the Admin/Timeline page of the web-interface to
163
-switch to local time. The "<b>Z</b>" suffix on an timestamp check-in
163
+switch to local time. The "<b>Z</b>" suffix on a timestamp check-in
164164
name is meaningless if Fossil is in the default mode of using UTC for
165165
everything, but if Fossil has been switched to local time mode, then the
166
-"<b>Z</b>" suffix means to interpret that particular timestamp using
166
+"<b>Z</b>" suffix means to interpret that particular timestamp using
167167
UTC instead of local time.
168168
169
-For an example of how timestamps are useful,
169
+For an example of how timestamps are useful,
170170
consider the homepage for the Fossil website itself:
171171
172172
<blockquote>
173173
http://www.fossil-scm.org/fossil/doc/<b>trunk</b>/www/index.wiki
174174
</blockquote>
@@ -191,11 +191,11 @@
191191
<blockquote>
192192
fossil update trunk:2010-07-01T14:30
193193
</blockquote>
194194
195195
Would cause Fossil to update the working check-out to be the most recent
196
-check-in on the trunk that is not more recent that 14:30 (UTC) on
196
+check-in on the trunk that is not more recent that 14:30 (UTC) on
197197
July 1, 2010.
198198
199199
<h2>Root Of A Branch</h2>
200200
201201
A branch name that begins with the "<tt>root:</tt>" prefix refers to the
@@ -220,11 +220,11 @@
220220
current check-out. And the "previous" or "prev" tag means the primary
221221
(non-merge) parent of the current check-out.
222222
223223
For embedded documentation, the tag "ckout" means the version as present in
224224
the local source tree on disk, provided that the web server is started using
225
-"fossil ui" or "fossil server" from within the source tree. This tag can be
225
+"fossil ui" or "fossil server" from within the source tree. This tag can be
226226
used to preview local changes to documentation before committing them. It does
227227
not apply to CLI commands.
228228
229229
<h2>Additional Examples</h2>
230230
231231
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -55,20 +55,20 @@
55 </pre></blockquote>
56
57 The full 40-character SHA1 hash is unwieldy to remember and type, though,
58 so Fossil also accepts a unique prefix of the hash, using any combination
59 of upper and lower case letters, as long as the prefix is at least 4
60 characters long. Hence the following commands all
61 accomplish the same thing as the above:
62
63 <blockquote><pre>
64 fossil info e5a734a19a9
65 fossil info E5a734A
66 fossil info e5a7
67 </blockquote>
68
69 Many web-interface screens identify check-ins by 10- or 16-character
70 prefix of canonical name.
71
72 <h2>Tags And Branch Names</h2>
73
74 Using a tag or branch name where a check-in name is expected causes
@@ -112,11 +112,11 @@
112
113 <blockquote><tt>
114 fossil info tag:deed2
115 </tt></blockquote>
116
117 The "tag:deed2" name will refer to the most recent check-in
118 tagged with "deed2" not to the
119 check-in whose canonical name begins with "deed2".
120
121 <h2>Whole Branches</h2>
122
@@ -147,11 +147,11 @@
147 * <i>YYYY-MM-DD</i>
148 * <i>YYYY-MM-DD HH:MM</i>
149 * <i>YYYY-MM-DD HH:MM:SS</i>
150 * <i>YYYY-MM-DD HH:MM:SS.SSS</i>
151
152 The space between the day and the year can optionally be
153 replaced by an uppercase <b>T</b> and the entire timestamp can
154 optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth
155 form with fractional seconds, any number of digits may follow the
156 decimal point, though due to precision limits only the first three
157 digits will be significant.
@@ -158,17 +158,17 @@
158
159 In its default configuration, Fossil interprets and displays all dates
160 in Universal Coordinated Time (UTC). This tends to work the best for
161 distributed projects where participants are scattered around the globe.
162 But there is an option on the Admin/Timeline page of the web-interface to
163 switch to local time. The "<b>Z</b>" suffix on an timestamp check-in
164 name is meaningless if Fossil is in the default mode of using UTC for
165 everything, but if Fossil has been switched to local time mode, then the
166 "<b>Z</b>" suffix means to interpret that particular timestamp using
167 UTC instead of local time.
168
169 For an example of how timestamps are useful,
170 consider the homepage for the Fossil website itself:
171
172 <blockquote>
173 http://www.fossil-scm.org/fossil/doc/<b>trunk</b>/www/index.wiki
174 </blockquote>
@@ -191,11 +191,11 @@
191 <blockquote>
192 fossil update trunk:2010-07-01T14:30
193 </blockquote>
194
195 Would cause Fossil to update the working check-out to be the most recent
196 check-in on the trunk that is not more recent that 14:30 (UTC) on
197 July 1, 2010.
198
199 <h2>Root Of A Branch</h2>
200
201 A branch name that begins with the "<tt>root:</tt>" prefix refers to the
@@ -220,11 +220,11 @@
220 current check-out. And the "previous" or "prev" tag means the primary
221 (non-merge) parent of the current check-out.
222
223 For embedded documentation, the tag "ckout" means the version as present in
224 the local source tree on disk, provided that the web server is started using
225 "fossil ui" or "fossil server" from within the source tree. This tag can be
226 used to preview local changes to documentation before committing them. It does
227 not apply to CLI commands.
228
229 <h2>Additional Examples</h2>
230
231
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -55,20 +55,20 @@
55 </pre></blockquote>
56
57 The full 40-character SHA1 hash is unwieldy to remember and type, though,
58 so Fossil also accepts a unique prefix of the hash, using any combination
59 of upper and lower case letters, as long as the prefix is at least 4
60 characters long. Hence the following commands all
61 accomplish the same thing as the above:
62
63 <blockquote><pre>
64 fossil info e5a734a19a9
65 fossil info E5a734A
66 fossil info e5a7
67 </blockquote>
68
69 Many web-interface screens identify check-ins by 10- or 16-character
70 prefix of canonical name.
71
72 <h2>Tags And Branch Names</h2>
73
74 Using a tag or branch name where a check-in name is expected causes
@@ -112,11 +112,11 @@
112
113 <blockquote><tt>
114 fossil info tag:deed2
115 </tt></blockquote>
116
117 The "tag:deed2" name will refer to the most recent check-in
118 tagged with "deed2" not to the
119 check-in whose canonical name begins with "deed2".
120
121 <h2>Whole Branches</h2>
122
@@ -147,11 +147,11 @@
147 * <i>YYYY-MM-DD</i>
148 * <i>YYYY-MM-DD HH:MM</i>
149 * <i>YYYY-MM-DD HH:MM:SS</i>
150 * <i>YYYY-MM-DD HH:MM:SS.SSS</i>
151
152 The space between the day and the year can optionally be
153 replaced by an uppercase <b>T</b> and the entire timestamp can
154 optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth
155 form with fractional seconds, any number of digits may follow the
156 decimal point, though due to precision limits only the first three
157 digits will be significant.
@@ -158,17 +158,17 @@
158
159 In its default configuration, Fossil interprets and displays all dates
160 in Universal Coordinated Time (UTC). This tends to work the best for
161 distributed projects where participants are scattered around the globe.
162 But there is an option on the Admin/Timeline page of the web-interface to
163 switch to local time. The "<b>Z</b>" suffix on a timestamp check-in
164 name is meaningless if Fossil is in the default mode of using UTC for
165 everything, but if Fossil has been switched to local time mode, then the
166 "<b>Z</b>" suffix means to interpret that particular timestamp using
167 UTC instead of local time.
168
169 For an example of how timestamps are useful,
170 consider the homepage for the Fossil website itself:
171
172 <blockquote>
173 http://www.fossil-scm.org/fossil/doc/<b>trunk</b>/www/index.wiki
174 </blockquote>
@@ -191,11 +191,11 @@
191 <blockquote>
192 fossil update trunk:2010-07-01T14:30
193 </blockquote>
194
195 Would cause Fossil to update the working check-out to be the most recent
196 check-in on the trunk that is not more recent that 14:30 (UTC) on
197 July 1, 2010.
198
199 <h2>Root Of A Branch</h2>
200
201 A branch name that begins with the "<tt>root:</tt>" prefix refers to the
@@ -220,11 +220,11 @@
220 current check-out. And the "previous" or "prev" tag means the primary
221 (non-merge) parent of the current check-out.
222
223 For embedded documentation, the tag "ckout" means the version as present in
224 the local source tree on disk, provided that the web server is started using
225 "fossil ui" or "fossil server" from within the source tree. This tag can be
226 used to preview local changes to documentation before committing them. It does
227 not apply to CLI commands.
228
229 <h2>Additional Examples</h2>
230
231
--- www/childprojects.wiki
+++ www/childprojects.wiki
@@ -37,21 +37,21 @@
3737
VALUES('project-code',lower(hex(randomblob(20))));
3838
INSERT INTO config(name,value)
3939
VALUES('project-name','CHILD-PROJECT-NAME');
4040
</verbatim></blockquote>
4141
42
-Modify the CHILD-PROJECT-NAME in the last statement to be the name of
42
+Modify the CHILD-PROJECT-NAME in the last statement to be the name of
4343
the child project, of course.
4444
4545
The repository is now a separate project, independent from its parent.
4646
Clone the new project to the developers as needed.
4747
4848
The child project and the parent project will not normally be able to sync
4949
with one another, since they are now separate projects with distinct
5050
project codes. However, if the
51
-"--from-parent-project" command-line option is provided to the
52
-"[/help?cmd=pull|fossil pull]" command in the child, and the URL of
51
+"--from-parent-project" command-line option is provided to the
52
+"[/help?cmd=pull|fossil pull]" command in the child, and the URL of
5353
parent repository is also provided on the command-line, then updates to
5454
the parent project that occurred after the child was created will be added
5555
to the child repository. Thus, by periodically doing a
5656
pull --from-parent-project, the child project is able to stay up to date
5757
with all the latest changes in the parent.
5858
--- www/childprojects.wiki
+++ www/childprojects.wiki
@@ -37,21 +37,21 @@
37 VALUES('project-code',lower(hex(randomblob(20))));
38 INSERT INTO config(name,value)
39 VALUES('project-name','CHILD-PROJECT-NAME');
40 </verbatim></blockquote>
41
42 Modify the CHILD-PROJECT-NAME in the last statement to be the name of
43 the child project, of course.
44
45 The repository is now a separate project, independent from its parent.
46 Clone the new project to the developers as needed.
47
48 The child project and the parent project will not normally be able to sync
49 with one another, since they are now separate projects with distinct
50 project codes. However, if the
51 "--from-parent-project" command-line option is provided to the
52 "[/help?cmd=pull|fossil pull]" command in the child, and the URL of
53 parent repository is also provided on the command-line, then updates to
54 the parent project that occurred after the child was created will be added
55 to the child repository. Thus, by periodically doing a
56 pull --from-parent-project, the child project is able to stay up to date
57 with all the latest changes in the parent.
58
--- www/childprojects.wiki
+++ www/childprojects.wiki
@@ -37,21 +37,21 @@
37 VALUES('project-code',lower(hex(randomblob(20))));
38 INSERT INTO config(name,value)
39 VALUES('project-name','CHILD-PROJECT-NAME');
40 </verbatim></blockquote>
41
42 Modify the CHILD-PROJECT-NAME in the last statement to be the name of
43 the child project, of course.
44
45 The repository is now a separate project, independent from its parent.
46 Clone the new project to the developers as needed.
47
48 The child project and the parent project will not normally be able to sync
49 with one another, since they are now separate projects with distinct
50 project codes. However, if the
51 "--from-parent-project" command-line option is provided to the
52 "[/help?cmd=pull|fossil pull]" command in the child, and the URL of
53 parent repository is also provided on the command-line, then updates to
54 the parent project that occurred after the child was created will be added
55 to the child repository. Thus, by periodically doing a
56 pull --from-parent-project, the child project is able to stay up to date
57 with all the latest changes in the parent.
58
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -13,10 +13,15 @@
1313
to setup and operate.
1414
1515
This document is intended as a quick introduction to the concepts
1616
behind Fossil.
1717
18
+See also:
19
+
20
+ * [./whyusefossil.wiki#definitions|Definitions]
21
+ * [./quickstart.wiki|Quick start guide]
22
+
1823
<h2>2.0 Composition Of A Project</h2>
1924
<img src="concept1.gif" align="right" hspace="10">
2025
2126
A software project normally consists of a "source tree".
2227
A source tree is a hierarchy of files that are used to generate
@@ -126,11 +131,11 @@
126131
<h3>2.2 Manifests</h3>
127132
128133
Associated with every check-in is a special file called the
129134
[./fileformat.wiki#manifest| "manifest"]. The manifest is a
130135
listing of all other files in
131
-that source tree. The manifest contains the (complete) artifact ID
136
+that source tree. The manifest contains the (complete) artifact ID
132137
of the file and the name of the file as it appears on disk,
133138
and thus serves as a mapping from artifact ID to disk name. The artifact ID
134139
of the manifest is the identifier for the entire check-in. When
135140
you look at a "timeline" of changes in Fossil, the ID associated
136141
with each check-in or commit is really just the artifact ID of the
@@ -142,11 +147,11 @@
142147
manifest file to be materialized to disk, if desired. Both Fossil
143148
itself, and SQLite cause the manifest file to be materialized to disk
144149
so that the makefiles for these project can read the manifest and
145150
embed version information in generated binaries.
146151
147
-<p>Fossil automatically generates a manifest whenever you "commit"
152
+<p>Fossil automatically generates a manifest whenever you "commit"
148153
a new check-in. So this is not something that you, the developer,
149154
need to worry with. The format of a manifest is intentionally
150155
designed to be simple to parse, so that if
151156
you want to read and interpret a manifest, either by hand or
152157
with a script, that is easy to do. But you will probably never
@@ -195,11 +200,11 @@
195200
Fossil effectively. You will want to have some kind of text editor
196201
for entering check-in comments. Fossil will use whatever text editor
197202
is identified by your VISUAL environment variable. Fossil will also
198203
use GPG to clearsign your manifests if you happen to have it installed,
199204
but Fossil will skip that step if GPG missing from your system.
200
-You can optionally set up Fossil to use external "diff" programs,
205
+You can optionally set up Fossil to use external "diff" programs,
201206
though Fossil has an excellent built-in "diff" algorithm that works
202207
fine for most people. If you happen to have Tcl/Tk installed on your
203208
system, Fossil will use it to generate a graphical "diff" display when
204209
you use the --tk option to the "diff" command, but this too is entirely
205210
optional.
@@ -206,11 +211,11 @@
206211
207212
208213
To uninstall Fossil, simply delete the executable.
209214
210215
To upgrade an older version of Fossil to a newer version, just
211
-replace the old executable with the new one. You might need to
216
+replace the old executable with the new one. You might need to
212217
run "<b>fossil all rebuild</b>" to restructure your repositories after
213218
an upgrade. Running "all rebuild" never hurts, so when upgrading it
214219
is a good policy to run it even if it is not strictly necessary.
215220
216221
To use Fossil, simply type the name of the executable in your
@@ -261,11 +266,11 @@
261266
262267
<ol>
263268
<li>
264269
Establish a local repository using either the <b>new</b> command
265270
to start a new project, or the <b>clone</b> command to make a clone
266
-of a repository for an existing project.
271
+of a repository for an existing project.
267272
</li>
268273
269274
<li>
270275
Establish one or more source trees using
271276
the <b>open</b> command with the name of the repository file as its
@@ -274,11 +279,11 @@
274279
275280
<li>
276281
The <b>open</b> command in the previous step populates your local source
277282
tree with a copy of the latest check-in. Usually this is what you want.
278283
In the rare cases where it is not, use the <b>update</b> command to
279
-switch to a different check-in.
284
+switch to a different check-in.
280285
Use the <b>timeline</b> or <b>leaves</b> commands
281286
to identify alternative check-ins to switch to.
282287
</li>
283288
284289
<li>
@@ -297,17 +302,17 @@
297302
you cloned from or whatever server you most recently synced with.
298303
</li>
299304
300305
<li>
301306
When your coworkers make their own changes, you can merge those changes
302
-into your local local source tree using the <b>update</b> command.
307
+into your local local source tree using the <b>update</b> command.
303308
In autosync mode, <b>update</b> will first go back to the server you
304309
cloned from or with which you most recently synced, and pull down all
305310
recent changes into your local repository. Then it will merge recent
306311
changes into your local source tree. If you do an <b>update</b> and
307312
find that it messes something up in your source tree (perhaps a co-worker
308
-checked in incompatible changes) you can use the <b>undo</b> command
313
+checked in incompatible changes) you can use the <b>undo</b> command
309314
to back out the changes.
310315
</li>
311316
312317
<li>
313318
Repeat all of the above until you have generated great software.
314319
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -13,10 +13,15 @@
13 to setup and operate.
14
15 This document is intended as a quick introduction to the concepts
16 behind Fossil.
17
 
 
 
 
 
18 <h2>2.0 Composition Of A Project</h2>
19 <img src="concept1.gif" align="right" hspace="10">
20
21 A software project normally consists of a "source tree".
22 A source tree is a hierarchy of files that are used to generate
@@ -126,11 +131,11 @@
126 <h3>2.2 Manifests</h3>
127
128 Associated with every check-in is a special file called the
129 [./fileformat.wiki#manifest| "manifest"]. The manifest is a
130 listing of all other files in
131 that source tree. The manifest contains the (complete) artifact ID
132 of the file and the name of the file as it appears on disk,
133 and thus serves as a mapping from artifact ID to disk name. The artifact ID
134 of the manifest is the identifier for the entire check-in. When
135 you look at a "timeline" of changes in Fossil, the ID associated
136 with each check-in or commit is really just the artifact ID of the
@@ -142,11 +147,11 @@
142 manifest file to be materialized to disk, if desired. Both Fossil
143 itself, and SQLite cause the manifest file to be materialized to disk
144 so that the makefiles for these project can read the manifest and
145 embed version information in generated binaries.
146
147 <p>Fossil automatically generates a manifest whenever you "commit"
148 a new check-in. So this is not something that you, the developer,
149 need to worry with. The format of a manifest is intentionally
150 designed to be simple to parse, so that if
151 you want to read and interpret a manifest, either by hand or
152 with a script, that is easy to do. But you will probably never
@@ -195,11 +200,11 @@
195 Fossil effectively. You will want to have some kind of text editor
196 for entering check-in comments. Fossil will use whatever text editor
197 is identified by your VISUAL environment variable. Fossil will also
198 use GPG to clearsign your manifests if you happen to have it installed,
199 but Fossil will skip that step if GPG missing from your system.
200 You can optionally set up Fossil to use external "diff" programs,
201 though Fossil has an excellent built-in "diff" algorithm that works
202 fine for most people. If you happen to have Tcl/Tk installed on your
203 system, Fossil will use it to generate a graphical "diff" display when
204 you use the --tk option to the "diff" command, but this too is entirely
205 optional.
@@ -206,11 +211,11 @@
206
207
208 To uninstall Fossil, simply delete the executable.
209
210 To upgrade an older version of Fossil to a newer version, just
211 replace the old executable with the new one. You might need to
212 run "<b>fossil all rebuild</b>" to restructure your repositories after
213 an upgrade. Running "all rebuild" never hurts, so when upgrading it
214 is a good policy to run it even if it is not strictly necessary.
215
216 To use Fossil, simply type the name of the executable in your
@@ -261,11 +266,11 @@
261
262 <ol>
263 <li>
264 Establish a local repository using either the <b>new</b> command
265 to start a new project, or the <b>clone</b> command to make a clone
266 of a repository for an existing project.
267 </li>
268
269 <li>
270 Establish one or more source trees using
271 the <b>open</b> command with the name of the repository file as its
@@ -274,11 +279,11 @@
274
275 <li>
276 The <b>open</b> command in the previous step populates your local source
277 tree with a copy of the latest check-in. Usually this is what you want.
278 In the rare cases where it is not, use the <b>update</b> command to
279 switch to a different check-in.
280 Use the <b>timeline</b> or <b>leaves</b> commands
281 to identify alternative check-ins to switch to.
282 </li>
283
284 <li>
@@ -297,17 +302,17 @@
297 you cloned from or whatever server you most recently synced with.
298 </li>
299
300 <li>
301 When your coworkers make their own changes, you can merge those changes
302 into your local local source tree using the <b>update</b> command.
303 In autosync mode, <b>update</b> will first go back to the server you
304 cloned from or with which you most recently synced, and pull down all
305 recent changes into your local repository. Then it will merge recent
306 changes into your local source tree. If you do an <b>update</b> and
307 find that it messes something up in your source tree (perhaps a co-worker
308 checked in incompatible changes) you can use the <b>undo</b> command
309 to back out the changes.
310 </li>
311
312 <li>
313 Repeat all of the above until you have generated great software.
314
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -13,10 +13,15 @@
13 to setup and operate.
14
15 This document is intended as a quick introduction to the concepts
16 behind Fossil.
17
18 See also:
19
20 * [./whyusefossil.wiki#definitions|Definitions]
21 * [./quickstart.wiki|Quick start guide]
22
23 <h2>2.0 Composition Of A Project</h2>
24 <img src="concept1.gif" align="right" hspace="10">
25
26 A software project normally consists of a "source tree".
27 A source tree is a hierarchy of files that are used to generate
@@ -126,11 +131,11 @@
131 <h3>2.2 Manifests</h3>
132
133 Associated with every check-in is a special file called the
134 [./fileformat.wiki#manifest| "manifest"]. The manifest is a
135 listing of all other files in
136 that source tree. The manifest contains the (complete) artifact ID
137 of the file and the name of the file as it appears on disk,
138 and thus serves as a mapping from artifact ID to disk name. The artifact ID
139 of the manifest is the identifier for the entire check-in. When
140 you look at a "timeline" of changes in Fossil, the ID associated
141 with each check-in or commit is really just the artifact ID of the
@@ -142,11 +147,11 @@
147 manifest file to be materialized to disk, if desired. Both Fossil
148 itself, and SQLite cause the manifest file to be materialized to disk
149 so that the makefiles for these project can read the manifest and
150 embed version information in generated binaries.
151
152 <p>Fossil automatically generates a manifest whenever you "commit"
153 a new check-in. So this is not something that you, the developer,
154 need to worry with. The format of a manifest is intentionally
155 designed to be simple to parse, so that if
156 you want to read and interpret a manifest, either by hand or
157 with a script, that is easy to do. But you will probably never
@@ -195,11 +200,11 @@
200 Fossil effectively. You will want to have some kind of text editor
201 for entering check-in comments. Fossil will use whatever text editor
202 is identified by your VISUAL environment variable. Fossil will also
203 use GPG to clearsign your manifests if you happen to have it installed,
204 but Fossil will skip that step if GPG missing from your system.
205 You can optionally set up Fossil to use external "diff" programs,
206 though Fossil has an excellent built-in "diff" algorithm that works
207 fine for most people. If you happen to have Tcl/Tk installed on your
208 system, Fossil will use it to generate a graphical "diff" display when
209 you use the --tk option to the "diff" command, but this too is entirely
210 optional.
@@ -206,11 +211,11 @@
211
212
213 To uninstall Fossil, simply delete the executable.
214
215 To upgrade an older version of Fossil to a newer version, just
216 replace the old executable with the new one. You might need to
217 run "<b>fossil all rebuild</b>" to restructure your repositories after
218 an upgrade. Running "all rebuild" never hurts, so when upgrading it
219 is a good policy to run it even if it is not strictly necessary.
220
221 To use Fossil, simply type the name of the executable in your
@@ -261,11 +266,11 @@
266
267 <ol>
268 <li>
269 Establish a local repository using either the <b>new</b> command
270 to start a new project, or the <b>clone</b> command to make a clone
271 of a repository for an existing project.
272 </li>
273
274 <li>
275 Establish one or more source trees using
276 the <b>open</b> command with the name of the repository file as its
@@ -274,11 +279,11 @@
279
280 <li>
281 The <b>open</b> command in the previous step populates your local source
282 tree with a copy of the latest check-in. Usually this is what you want.
283 In the rare cases where it is not, use the <b>update</b> command to
284 switch to a different check-in.
285 Use the <b>timeline</b> or <b>leaves</b> commands
286 to identify alternative check-ins to switch to.
287 </li>
288
289 <li>
@@ -297,17 +302,17 @@
302 you cloned from or whatever server you most recently synced with.
303 </li>
304
305 <li>
306 When your coworkers make their own changes, you can merge those changes
307 into your local local source tree using the <b>update</b> command.
308 In autosync mode, <b>update</b> will first go back to the server you
309 cloned from or with which you most recently synced, and pull down all
310 recent changes into your local repository. Then it will merge recent
311 changes into your local source tree. If you do an <b>update</b> and
312 find that it messes something up in your source tree (perhaps a co-worker
313 checked in incompatible changes) you can use the <b>undo</b> command
314 to back out the changes.
315 </li>
316
317 <li>
318 Repeat all of the above until you have generated great software.
319
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -10,11 +10,11 @@
1010
[./copyright-release.pdf | Contributor Agreement (PDF)]
1111
(or [./copyright-release.html | as HTML]) on file for you. We require
1212
this in order to maintain clear title to the Fossil code and prevent
1313
the introduction of code with incompatible licenses or other entanglements
1414
that might cause legal problems for Fossil users. Many larger companies
15
-and other lawyer-rich organizations require this as a precondition to using
15
+and other lawyer-rich organizations require this as a precondition to using
1616
Fossil.
1717
1818
If you do not wish to submit a Contributor Agreement, we would still
1919
welcome your suggestions and example code, but we will not use your code
2020
directly - we will be forced to re-implement your changes from scratch which
@@ -21,14 +21,14 @@
2121
might take longer.
2222
2323
<h2>2.0 Submitting Patches</h2>
2424
2525
Suggested changes or bug fixes can be submitted by creating a patch
26
-against the current source tree. Email patches to
27
-<a href="mailto:[email protected]">[email protected]</a>. Be sure to
26
+against the current source tree. Email patches to
27
+<a href="mailto:[email protected]">[email protected]</a>. Be sure to
2828
describe in detail what the patch does and which version of Fossil
29
-it is written against.
29
+it is written against.
3030
3131
A contributor agreement is not strictly necessary to submit a patch.
3232
However, without a contributor agreement on file, your patch will be
3333
used for reference only - it will not be applied to the code. This
3434
may delay acceptance of your patch.
@@ -53,23 +53,23 @@
5353
Fossil Architect (Richard Hipp) will merge changes onto the trunk.</p>
5454
5555
Contributors are required to following the
5656
[./checkin.wiki | pre-checkin checklist] prior to every check-in to
5757
the Fossil self-hosting repository. This checklist is short and succinct
58
-and should only require a few seconds to follow. Contributors
58
+and should only require a few seconds to follow. Contributors
5959
should print out a copy of the pre-checkin checklist and keep
6060
it on a notecard beside their workstations, for quick reference.
6161
6262
Contributors should review the
6363
[./style.wiki | Coding Style Guidelines] and mimic the coding style
6464
used through the rest of the Fossil source code. Your code should
6565
blend in. A third-party reader should be unable to distinguish your
66
-code from any other code in the source corpus.
66
+code from any other code in the source corpus.
6767
6868
<h2>4.0 Testing</h2>
6969
70
-Fossil has the beginnings of a
70
+Fossil has the beginnings of a
7171
[../test/release-checklist.wiki | release checklist] but this is an
7272
area that needs further work. (Your contributions here are welcomed!)
7373
Contributors with check-in privileges are expected to run the release
7474
checklist on any major changes they contribute, and if appropriate expand
7575
the checklist and/or the automated test scripts to cover their additions.
7676
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -10,11 +10,11 @@
10 [./copyright-release.pdf | Contributor Agreement (PDF)]
11 (or [./copyright-release.html | as HTML]) on file for you. We require
12 this in order to maintain clear title to the Fossil code and prevent
13 the introduction of code with incompatible licenses or other entanglements
14 that might cause legal problems for Fossil users. Many larger companies
15 and other lawyer-rich organizations require this as a precondition to using
16 Fossil.
17
18 If you do not wish to submit a Contributor Agreement, we would still
19 welcome your suggestions and example code, but we will not use your code
20 directly - we will be forced to re-implement your changes from scratch which
@@ -21,14 +21,14 @@
21 might take longer.
22
23 <h2>2.0 Submitting Patches</h2>
24
25 Suggested changes or bug fixes can be submitted by creating a patch
26 against the current source tree. Email patches to
27 <a href="mailto:[email protected]">[email protected]</a>. Be sure to
28 describe in detail what the patch does and which version of Fossil
29 it is written against.
30
31 A contributor agreement is not strictly necessary to submit a patch.
32 However, without a contributor agreement on file, your patch will be
33 used for reference only - it will not be applied to the code. This
34 may delay acceptance of your patch.
@@ -53,23 +53,23 @@
53 Fossil Architect (Richard Hipp) will merge changes onto the trunk.</p>
54
55 Contributors are required to following the
56 [./checkin.wiki | pre-checkin checklist] prior to every check-in to
57 the Fossil self-hosting repository. This checklist is short and succinct
58 and should only require a few seconds to follow. Contributors
59 should print out a copy of the pre-checkin checklist and keep
60 it on a notecard beside their workstations, for quick reference.
61
62 Contributors should review the
63 [./style.wiki | Coding Style Guidelines] and mimic the coding style
64 used through the rest of the Fossil source code. Your code should
65 blend in. A third-party reader should be unable to distinguish your
66 code from any other code in the source corpus.
67
68 <h2>4.0 Testing</h2>
69
70 Fossil has the beginnings of a
71 [../test/release-checklist.wiki | release checklist] but this is an
72 area that needs further work. (Your contributions here are welcomed!)
73 Contributors with check-in privileges are expected to run the release
74 checklist on any major changes they contribute, and if appropriate expand
75 the checklist and/or the automated test scripts to cover their additions.
76
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -10,11 +10,11 @@
10 [./copyright-release.pdf | Contributor Agreement (PDF)]
11 (or [./copyright-release.html | as HTML]) on file for you. We require
12 this in order to maintain clear title to the Fossil code and prevent
13 the introduction of code with incompatible licenses or other entanglements
14 that might cause legal problems for Fossil users. Many larger companies
15 and other lawyer-rich organizations require this as a precondition to using
16 Fossil.
17
18 If you do not wish to submit a Contributor Agreement, we would still
19 welcome your suggestions and example code, but we will not use your code
20 directly - we will be forced to re-implement your changes from scratch which
@@ -21,14 +21,14 @@
21 might take longer.
22
23 <h2>2.0 Submitting Patches</h2>
24
25 Suggested changes or bug fixes can be submitted by creating a patch
26 against the current source tree. Email patches to
27 <a href="mailto:[email protected]">[email protected]</a>. Be sure to
28 describe in detail what the patch does and which version of Fossil
29 it is written against.
30
31 A contributor agreement is not strictly necessary to submit a patch.
32 However, without a contributor agreement on file, your patch will be
33 used for reference only - it will not be applied to the code. This
34 may delay acceptance of your patch.
@@ -53,23 +53,23 @@
53 Fossil Architect (Richard Hipp) will merge changes onto the trunk.</p>
54
55 Contributors are required to following the
56 [./checkin.wiki | pre-checkin checklist] prior to every check-in to
57 the Fossil self-hosting repository. This checklist is short and succinct
58 and should only require a few seconds to follow. Contributors
59 should print out a copy of the pre-checkin checklist and keep
60 it on a notecard beside their workstations, for quick reference.
61
62 Contributors should review the
63 [./style.wiki | Coding Style Guidelines] and mimic the coding style
64 used through the rest of the Fossil source code. Your code should
65 blend in. A third-party reader should be unable to distinguish your
66 code from any other code in the source corpus.
67
68 <h2>4.0 Testing</h2>
69
70 Fossil has the beginnings of a
71 [../test/release-checklist.wiki | release checklist] but this is an
72 area that needs further work. (Your contributions here are welcomed!)
73 Contributors with check-in privileges are expected to run the release
74 checklist on any major changes they contribute, and if appropriate expand
75 the checklist and/or the automated test scripts to cover their additions.
76
--- www/custom_ticket.wiki
+++ www/custom_ticket.wiki
@@ -65,11 +65,11 @@
6565
&lt;/tr>
6666
&lt;th1>enable_output 1&lt;/th1>
6767
</pre>
6868
This bit of code will get rid of the "email" field entry for logged-in users.
6969
Since we know the user's information, we don't have to ask for it. NOTE: it
70
-might be good to automatically scoop up the user's email and put it here.
70
+might be good to automatically scoop up the user's email and put it here.
7171
</p>
7272
</blockquote>
7373
7474
<h2>Modify the 'view ticket' page</h2><blockquote>
7575
<p>
@@ -83,11 +83,11 @@
8383
&lt;td align="right">Opened by:&lt;/td>&lt;td bgcolor="#d0d0d0">
8484
$&lt;opened_by>
8585
&lt;/td>
8686
</pre>
8787
This will add a row which displays these two fields, in the event the user has
88
-"edit" capability.
88
+"edit" capability.
8989
</p>
9090
</blockquote>
9191
9292
<h2>Modify the 'edit ticket' page</h2><blockquote>
9393
<p>
9494
--- www/custom_ticket.wiki
+++ www/custom_ticket.wiki
@@ -65,11 +65,11 @@
65 &lt;/tr>
66 &lt;th1>enable_output 1&lt;/th1>
67 </pre>
68 This bit of code will get rid of the "email" field entry for logged-in users.
69 Since we know the user's information, we don't have to ask for it. NOTE: it
70 might be good to automatically scoop up the user's email and put it here.
71 </p>
72 </blockquote>
73
74 <h2>Modify the 'view ticket' page</h2><blockquote>
75 <p>
@@ -83,11 +83,11 @@
83 &lt;td align="right">Opened by:&lt;/td>&lt;td bgcolor="#d0d0d0">
84 $&lt;opened_by>
85 &lt;/td>
86 </pre>
87 This will add a row which displays these two fields, in the event the user has
88 "edit" capability.
89 </p>
90 </blockquote>
91
92 <h2>Modify the 'edit ticket' page</h2><blockquote>
93 <p>
94
--- www/custom_ticket.wiki
+++ www/custom_ticket.wiki
@@ -65,11 +65,11 @@
65 &lt;/tr>
66 &lt;th1>enable_output 1&lt;/th1>
67 </pre>
68 This bit of code will get rid of the "email" field entry for logged-in users.
69 Since we know the user's information, we don't have to ask for it. NOTE: it
70 might be good to automatically scoop up the user's email and put it here.
71 </p>
72 </blockquote>
73
74 <h2>Modify the 'view ticket' page</h2><blockquote>
75 <p>
@@ -83,11 +83,11 @@
83 &lt;td align="right">Opened by:&lt;/td>&lt;td bgcolor="#d0d0d0">
84 $&lt;opened_by>
85 &lt;/td>
86 </pre>
87 This will add a row which displays these two fields, in the event the user has
88 "edit" capability.
89 </p>
90 </blockquote>
91
92 <h2>Modify the 'edit ticket' page</h2><blockquote>
93 <p>
94
--- www/customskin.md
+++ www/customskin.md
@@ -144,10 +144,14 @@
144144
respository settings and the specific page being generated.
145145
146146
* **project_name** - The project_name variable is filled with the
147147
name of the project as configured under the Admin/Configuration
148148
menu.
149
+
150
+ * **project_description** - The project_description variable is
151
+ filled with the description of the project as configured under
152
+ the Admin/Configuration menu.
149153
150154
* **title** - The title variable holds the title of the page being
151155
generated.
152156
153157
The title variable is special in that it is deleted after
154158
--- www/customskin.md
+++ www/customskin.md
@@ -144,10 +144,14 @@
144 respository settings and the specific page being generated.
145
146 * **project_name** - The project_name variable is filled with the
147 name of the project as configured under the Admin/Configuration
148 menu.
 
 
 
 
149
150 * **title** - The title variable holds the title of the page being
151 generated.
152
153 The title variable is special in that it is deleted after
154
--- www/customskin.md
+++ www/customskin.md
@@ -144,10 +144,14 @@
144 respository settings and the specific page being generated.
145
146 * **project_name** - The project_name variable is filled with the
147 name of the project as configured under the Admin/Configuration
148 menu.
149
150 * **project_description** - The project_description variable is
151 filled with the description of the project as configured under
152 the Admin/Configuration menu.
153
154 * **title** - The title variable holds the title of the page being
155 generated.
156
157 The title variable is special in that it is deleted after
158
--- www/delta_encoder_algorithm.wiki
+++ www/delta_encoder_algorithm.wiki
@@ -153,11 +153,11 @@
153153
byte forward. The "base" is left unchanged in that case.</p>
154154
155155
<p>The processing loop stops at one of two conditions:
156156
<ol>
157157
<li>The encoder decided to move the window forward, but the end of the
158
-window reached the end of the "target".
158
+window reached the end of the "target".
159159
</li>
160160
<li>After the emission of instructions the new "base" location is
161161
within NHASH bytes of end of the "target", i.e. there are no more than
162162
at most NHASH bytes left.
163163
</li>
164164
--- www/delta_encoder_algorithm.wiki
+++ www/delta_encoder_algorithm.wiki
@@ -153,11 +153,11 @@
153 byte forward. The "base" is left unchanged in that case.</p>
154
155 <p>The processing loop stops at one of two conditions:
156 <ol>
157 <li>The encoder decided to move the window forward, but the end of the
158 window reached the end of the "target".
159 </li>
160 <li>After the emission of instructions the new "base" location is
161 within NHASH bytes of end of the "target", i.e. there are no more than
162 at most NHASH bytes left.
163 </li>
164
--- www/delta_encoder_algorithm.wiki
+++ www/delta_encoder_algorithm.wiki
@@ -153,11 +153,11 @@
153 byte forward. The "base" is left unchanged in that case.</p>
154
155 <p>The processing loop stops at one of two conditions:
156 <ol>
157 <li>The encoder decided to move the window forward, but the end of the
158 window reached the end of the "target".
159 </li>
160 <li>After the emission of instructions the new "base" location is
161 within NHASH bytes of end of the "target", i.e. there are no more than
162 at most NHASH bytes left.
163 </li>
164
--- www/delta_format.wiki
+++ www/delta_format.wiki
@@ -161,49 +161,49 @@
161161
</table>
162162
163163
<p>The unified diff behind the above delta is</p>
164164
165165
<table border=1><tr><td><pre>
166
-bluepeak:(761) ~/Projects/Tcl/Fossil/Devel/devel > diff -u ../DELTA/old ../DELTA/new
166
+bluepeak:(761) ~/Projects/Tcl/Fossil/Devel/devel > diff -u ../DELTA/old ../DELTA/new
167167
--- ../DELTA/old 2007-08-23 21:14:40.000000000 -0700
168168
+++ ../DELTA/new 2007-08-23 21:14:33.000000000 -0700
169169
@@ -5,7 +5,7 @@
170
-
170
+
171171
* If the server does not have write permission on the database
172
- file, or on the directory containing the database file (and
172
+ file, or on the directory containing the database file (and
173173
- it is thus unable to update database because it cannot create
174174
+ it is thus unable to update the database because it cannot create
175175
a rollback journal) then it currently fails silently on a push.
176176
It needs to return a helpful error.
177
-
177
+
178178
@@ -27,8 +27,8 @@
179179
* Additional information displayed for the "vinfo" page:
180
-
180
+
181181
+ All leaves of this version that are not included in the
182182
- descendant list. With date, user, comment, and hyperlink.
183183
- Leaves in the descendant table should be marked as such.
184184
+ descendant list. With date, user, comment, and hyperlink.
185185
+ Leaves in the descendant table should be marked as such.
186186
See the compute_leaves() function to see how to find all
187187
leaves.
188188
+ Add file diff links to the file change list.
189189
@@ -37,7 +37,7 @@
190
-
190
+
191191
* The /xfer handler (for push, pull, and clone) does not do
192192
delta compression. This results in excess bandwidth usage.
193193
- There are some code in xfer.c that are sketches of ideas on
194194
+ There are some pieces in xfer.c that are sketches of ideas on
195195
how to do delta compression, but nothing has been implemented.
196
-
196
+
197197
* Enhancements to the diff and tkdiff commands in the cli.
198198
@@ -45,7 +45,7 @@
199199
single file. Allow diffs against any two arbitrary versions,
200
- not just diffs against the current check-out. Allow
200
+ not just diffs against the current check-out. Allow
201201
configuration options to replace tkdiff with some other
202202
- visual differ of the users choice.
203203
+ visual differ of the users choice. Example: eskil.
204
-
204
+
205205
* Ticketing interface (expand this bullet)
206206
207207
</pre></td></tr></table>
208208
209209
210210
--- www/delta_format.wiki
+++ www/delta_format.wiki
@@ -161,49 +161,49 @@
161 </table>
162
163 <p>The unified diff behind the above delta is</p>
164
165 <table border=1><tr><td><pre>
166 bluepeak:(761) ~/Projects/Tcl/Fossil/Devel/devel > diff -u ../DELTA/old ../DELTA/new
167 --- ../DELTA/old 2007-08-23 21:14:40.000000000 -0700
168 +++ ../DELTA/new 2007-08-23 21:14:33.000000000 -0700
169 @@ -5,7 +5,7 @@
170
171 * If the server does not have write permission on the database
172 file, or on the directory containing the database file (and
173 - it is thus unable to update database because it cannot create
174 + it is thus unable to update the database because it cannot create
175 a rollback journal) then it currently fails silently on a push.
176 It needs to return a helpful error.
177
178 @@ -27,8 +27,8 @@
179 * Additional information displayed for the "vinfo" page:
180
181 + All leaves of this version that are not included in the
182 - descendant list. With date, user, comment, and hyperlink.
183 - Leaves in the descendant table should be marked as such.
184 + descendant list. With date, user, comment, and hyperlink.
185 + Leaves in the descendant table should be marked as such.
186 See the compute_leaves() function to see how to find all
187 leaves.
188 + Add file diff links to the file change list.
189 @@ -37,7 +37,7 @@
190
191 * The /xfer handler (for push, pull, and clone) does not do
192 delta compression. This results in excess bandwidth usage.
193 - There are some code in xfer.c that are sketches of ideas on
194 + There are some pieces in xfer.c that are sketches of ideas on
195 how to do delta compression, but nothing has been implemented.
196
197 * Enhancements to the diff and tkdiff commands in the cli.
198 @@ -45,7 +45,7 @@
199 single file. Allow diffs against any two arbitrary versions,
200 not just diffs against the current check-out. Allow
201 configuration options to replace tkdiff with some other
202 - visual differ of the users choice.
203 + visual differ of the users choice. Example: eskil.
204
205 * Ticketing interface (expand this bullet)
206
207 </pre></td></tr></table>
208
209
210
--- www/delta_format.wiki
+++ www/delta_format.wiki
@@ -161,49 +161,49 @@
161 </table>
162
163 <p>The unified diff behind the above delta is</p>
164
165 <table border=1><tr><td><pre>
166 bluepeak:(761) ~/Projects/Tcl/Fossil/Devel/devel > diff -u ../DELTA/old ../DELTA/new
167 --- ../DELTA/old 2007-08-23 21:14:40.000000000 -0700
168 +++ ../DELTA/new 2007-08-23 21:14:33.000000000 -0700
169 @@ -5,7 +5,7 @@
170
171 * If the server does not have write permission on the database
172 file, or on the directory containing the database file (and
173 - it is thus unable to update database because it cannot create
174 + it is thus unable to update the database because it cannot create
175 a rollback journal) then it currently fails silently on a push.
176 It needs to return a helpful error.
177
178 @@ -27,8 +27,8 @@
179 * Additional information displayed for the "vinfo" page:
180
181 + All leaves of this version that are not included in the
182 - descendant list. With date, user, comment, and hyperlink.
183 - Leaves in the descendant table should be marked as such.
184 + descendant list. With date, user, comment, and hyperlink.
185 + Leaves in the descendant table should be marked as such.
186 See the compute_leaves() function to see how to find all
187 leaves.
188 + Add file diff links to the file change list.
189 @@ -37,7 +37,7 @@
190
191 * The /xfer handler (for push, pull, and clone) does not do
192 delta compression. This results in excess bandwidth usage.
193 - There are some code in xfer.c that are sketches of ideas on
194 + There are some pieces in xfer.c that are sketches of ideas on
195 how to do delta compression, but nothing has been implemented.
196
197 * Enhancements to the diff and tkdiff commands in the cli.
198 @@ -45,7 +45,7 @@
199 single file. Allow diffs against any two arbitrary versions,
200 not just diffs against the current check-out. Allow
201 configuration options to replace tkdiff with some other
202 - visual differ of the users choice.
203 + visual differ of the users choice. Example: eskil.
204
205 * Ticketing interface (expand this bullet)
206
207 </pre></td></tr></table>
208
209
210
--- www/embeddeddoc.wiki
+++ www/embeddeddoc.wiki
@@ -42,13 +42,13 @@
4242
<b>http://www.hwaci.com/cgi-bin/fossil</b>.
4343
If you launch the web server using the "<b>fossil server</b>" command line,
4444
then the <i>&lt;baseurl&gt;</i> is usually
4545
<b>http://localhost:8080/</b>.
4646
47
-The <i>&lt;version&gt;</i> is any unique prefix of the check-in ID for
47
+The <i>&lt;version&gt;</i> is any unique prefix of the check-in ID for
4848
the check-in containing the documentation you want to access.
49
-Or <i>&lt;version&gt;</i> can be the name of a
49
+Or <i>&lt;version&gt;</i> can be the name of a
5050
[./branching.wiki | branch] in order to show
5151
the documentation for the latest version of that branch.
5252
Or <i>&lt;version&gt;</i> can be one of the keywords "<b>tip</b>" or
5353
"<b>ckout</b>". The "<b>tip</b>" keyword means to use the most recent
5454
check-in. This is useful if you want to see the very latest
@@ -62,30 +62,30 @@
6262
6363
Finally, the <i>&lt;filename&gt;</i> element of the URL is the
6464
pathname of the documentation file relative to the root of the source
6565
tree.
6666
67
-The mimetype (and thus the rendering) of documentation files is
68
-determined by the file suffix. Fossil currently understands
67
+The mimetype (and thus the rendering) of documentation files is
68
+determined by the file suffix. Fossil currently understands
6969
[/mimetype_list|many different file suffixes],
7070
including all the popular ones such as ".css", ".gif", ".htm",
7171
".html", ".jpg", ".jpeg", ".png", and ".txt".
7272
73
-Documentation files whose names end in ".wiki" use the
73
+Documentation files whose names end in ".wiki" use the
7474
[/wiki_rules | fossil wiki markup] -
7575
a safe subset of HTML together with some wiki rules for paragraph
76
-breaks, lists, and hyperlinks.
76
+breaks, lists, and hyperlinks.
7777
Documentation files ending in ".md" or ".markdown" use the
7878
[/md_rules | Markdown markup langauge].
7979
Documentation files ending in ".txt" are plain text.
8080
Wiki, markdown, and plain text documentation files
8181
are rendered with the standard fossil header and footer added.
8282
Most other mimetypes are delivered directly to the requesting
8383
web browser without interpretation, additions, or changes.
8484
8585
Files with the mimetype "text/html" (the .html or .htm suffix) are
86
-usually rendered directly to the browser without interpretation.
86
+usually rendered directly to the browser without interpretation.
8787
However, if the file begins with a &lt;div&gt; element like this:
8888
8989
<b>&lt;div class='fossil-doc' data-title='<i>Title Text</i>'&gt;</b>
9090
9191
Then the standard Fossil header and footer are added to the document
@@ -117,11 +117,11 @@
117117
<blockquote><pre>
118118
#!/usr/bin/fossil
119119
repository: /fossil/fossil.fossil
120120
</pre></blockquote>
121121
122
-This is one of four ways to set up a
122
+This is one of four ways to set up a
123123
<a href="./server.wiki">fossil web server</a>.
124124
125125
The "<b>/trunk/</b>" part of the URL tells fossil to use
126126
the documentation files from the most recent trunk check-in.
127127
If you wanted to see an historical version of this document,
@@ -138,11 +138,11 @@
138138
<li> <i>YYYY-MM-DD</i>
139139
<li> <i>YYYY-MM-DD</i><b>T</b><i>HH:MM</i>
140140
<li> <i>YYYY-MM-DD</i><b>T</b><i>HH:MM:SS</i>
141141
</ul>
142142
143
-When the symbolic name is a date and time, fossil shows the version
143
+When the symbolic name is a date and time, fossil shows the version
144144
of the document that was most recently checked in as of the date
145145
and time specified. So, for example, to see what the fossil website
146146
looked like at the beginning of 2010, enter:
147147
148148
<blockquote>
149149
--- www/embeddeddoc.wiki
+++ www/embeddeddoc.wiki
@@ -42,13 +42,13 @@
42 <b>http://www.hwaci.com/cgi-bin/fossil</b>.
43 If you launch the web server using the "<b>fossil server</b>" command line,
44 then the <i>&lt;baseurl&gt;</i> is usually
45 <b>http://localhost:8080/</b>.
46
47 The <i>&lt;version&gt;</i> is any unique prefix of the check-in ID for
48 the check-in containing the documentation you want to access.
49 Or <i>&lt;version&gt;</i> can be the name of a
50 [./branching.wiki | branch] in order to show
51 the documentation for the latest version of that branch.
52 Or <i>&lt;version&gt;</i> can be one of the keywords "<b>tip</b>" or
53 "<b>ckout</b>". The "<b>tip</b>" keyword means to use the most recent
54 check-in. This is useful if you want to see the very latest
@@ -62,30 +62,30 @@
62
63 Finally, the <i>&lt;filename&gt;</i> element of the URL is the
64 pathname of the documentation file relative to the root of the source
65 tree.
66
67 The mimetype (and thus the rendering) of documentation files is
68 determined by the file suffix. Fossil currently understands
69 [/mimetype_list|many different file suffixes],
70 including all the popular ones such as ".css", ".gif", ".htm",
71 ".html", ".jpg", ".jpeg", ".png", and ".txt".
72
73 Documentation files whose names end in ".wiki" use the
74 [/wiki_rules | fossil wiki markup] -
75 a safe subset of HTML together with some wiki rules for paragraph
76 breaks, lists, and hyperlinks.
77 Documentation files ending in ".md" or ".markdown" use the
78 [/md_rules | Markdown markup langauge].
79 Documentation files ending in ".txt" are plain text.
80 Wiki, markdown, and plain text documentation files
81 are rendered with the standard fossil header and footer added.
82 Most other mimetypes are delivered directly to the requesting
83 web browser without interpretation, additions, or changes.
84
85 Files with the mimetype "text/html" (the .html or .htm suffix) are
86 usually rendered directly to the browser without interpretation.
87 However, if the file begins with a &lt;div&gt; element like this:
88
89 <b>&lt;div class='fossil-doc' data-title='<i>Title Text</i>'&gt;</b>
90
91 Then the standard Fossil header and footer are added to the document
@@ -117,11 +117,11 @@
117 <blockquote><pre>
118 #!/usr/bin/fossil
119 repository: /fossil/fossil.fossil
120 </pre></blockquote>
121
122 This is one of four ways to set up a
123 <a href="./server.wiki">fossil web server</a>.
124
125 The "<b>/trunk/</b>" part of the URL tells fossil to use
126 the documentation files from the most recent trunk check-in.
127 If you wanted to see an historical version of this document,
@@ -138,11 +138,11 @@
138 <li> <i>YYYY-MM-DD</i>
139 <li> <i>YYYY-MM-DD</i><b>T</b><i>HH:MM</i>
140 <li> <i>YYYY-MM-DD</i><b>T</b><i>HH:MM:SS</i>
141 </ul>
142
143 When the symbolic name is a date and time, fossil shows the version
144 of the document that was most recently checked in as of the date
145 and time specified. So, for example, to see what the fossil website
146 looked like at the beginning of 2010, enter:
147
148 <blockquote>
149
--- www/embeddeddoc.wiki
+++ www/embeddeddoc.wiki
@@ -42,13 +42,13 @@
42 <b>http://www.hwaci.com/cgi-bin/fossil</b>.
43 If you launch the web server using the "<b>fossil server</b>" command line,
44 then the <i>&lt;baseurl&gt;</i> is usually
45 <b>http://localhost:8080/</b>.
46
47 The <i>&lt;version&gt;</i> is any unique prefix of the check-in ID for
48 the check-in containing the documentation you want to access.
49 Or <i>&lt;version&gt;</i> can be the name of a
50 [./branching.wiki | branch] in order to show
51 the documentation for the latest version of that branch.
52 Or <i>&lt;version&gt;</i> can be one of the keywords "<b>tip</b>" or
53 "<b>ckout</b>". The "<b>tip</b>" keyword means to use the most recent
54 check-in. This is useful if you want to see the very latest
@@ -62,30 +62,30 @@
62
63 Finally, the <i>&lt;filename&gt;</i> element of the URL is the
64 pathname of the documentation file relative to the root of the source
65 tree.
66
67 The mimetype (and thus the rendering) of documentation files is
68 determined by the file suffix. Fossil currently understands
69 [/mimetype_list|many different file suffixes],
70 including all the popular ones such as ".css", ".gif", ".htm",
71 ".html", ".jpg", ".jpeg", ".png", and ".txt".
72
73 Documentation files whose names end in ".wiki" use the
74 [/wiki_rules | fossil wiki markup] -
75 a safe subset of HTML together with some wiki rules for paragraph
76 breaks, lists, and hyperlinks.
77 Documentation files ending in ".md" or ".markdown" use the
78 [/md_rules | Markdown markup langauge].
79 Documentation files ending in ".txt" are plain text.
80 Wiki, markdown, and plain text documentation files
81 are rendered with the standard fossil header and footer added.
82 Most other mimetypes are delivered directly to the requesting
83 web browser without interpretation, additions, or changes.
84
85 Files with the mimetype "text/html" (the .html or .htm suffix) are
86 usually rendered directly to the browser without interpretation.
87 However, if the file begins with a &lt;div&gt; element like this:
88
89 <b>&lt;div class='fossil-doc' data-title='<i>Title Text</i>'&gt;</b>
90
91 Then the standard Fossil header and footer are added to the document
@@ -117,11 +117,11 @@
117 <blockquote><pre>
118 #!/usr/bin/fossil
119 repository: /fossil/fossil.fossil
120 </pre></blockquote>
121
122 This is one of four ways to set up a
123 <a href="./server.wiki">fossil web server</a>.
124
125 The "<b>/trunk/</b>" part of the URL tells fossil to use
126 the documentation files from the most recent trunk check-in.
127 If you wanted to see an historical version of this document,
@@ -138,11 +138,11 @@
138 <li> <i>YYYY-MM-DD</i>
139 <li> <i>YYYY-MM-DD</i><b>T</b><i>HH:MM</i>
140 <li> <i>YYYY-MM-DD</i><b>T</b><i>HH:MM:SS</i>
141 </ul>
142
143 When the symbolic name is a date and time, fossil shows the version
144 of the document that was most recently checked in as of the date
145 and time specified. So, for example, to see what the fossil website
146 looked like at the beginning of 2010, enter:
147
148 <blockquote>
149
--- www/encryptedrepos.wiki
+++ www/encryptedrepos.wiki
@@ -3,11 +3,11 @@
33
Fossil can be compiled so that it works with encrypted repositories using
44
the [https://www.sqlite.org/see/doc/trunk/www/readme.wiki|SQLite Encryption Extension].
55
This technical note explains the process.
66
</blockquote>
77
<h2>Building An Encryption-Enabled Fossil</h2><blockquote>
8
-The SQLite Encryption Extension (SEE) is proprietary software and requires
8
+The SQLite Encryption Extension (SEE) is proprietary software and requires
99
[http://www.hwaci.com/cgi-bin/see-step1|purchasing a license].
1010
<p>
1111
Assuming you have an SEE license, the first step of compiling Fossil to
1212
use SEE is to create an SEE-enabled version of the SQLite database source code.
1313
This alternative SQLite database source file should be called "sqlite3-see.c"
1414
--- www/encryptedrepos.wiki
+++ www/encryptedrepos.wiki
@@ -3,11 +3,11 @@
3 Fossil can be compiled so that it works with encrypted repositories using
4 the [https://www.sqlite.org/see/doc/trunk/www/readme.wiki|SQLite Encryption Extension].
5 This technical note explains the process.
6 </blockquote>
7 <h2>Building An Encryption-Enabled Fossil</h2><blockquote>
8 The SQLite Encryption Extension (SEE) is proprietary software and requires
9 [http://www.hwaci.com/cgi-bin/see-step1|purchasing a license].
10 <p>
11 Assuming you have an SEE license, the first step of compiling Fossil to
12 use SEE is to create an SEE-enabled version of the SQLite database source code.
13 This alternative SQLite database source file should be called "sqlite3-see.c"
14
--- www/encryptedrepos.wiki
+++ www/encryptedrepos.wiki
@@ -3,11 +3,11 @@
3 Fossil can be compiled so that it works with encrypted repositories using
4 the [https://www.sqlite.org/see/doc/trunk/www/readme.wiki|SQLite Encryption Extension].
5 This technical note explains the process.
6 </blockquote>
7 <h2>Building An Encryption-Enabled Fossil</h2><blockquote>
8 The SQLite Encryption Extension (SEE) is proprietary software and requires
9 [http://www.hwaci.com/cgi-bin/see-step1|purchasing a license].
10 <p>
11 Assuming you have an SEE license, the first step of compiling Fossil to
12 use SEE is to create an SEE-enabled version of the SQLite database source code.
13 This alternative SQLite database source file should be called "sqlite3-see.c"
14
+5 -1
--- www/env-opts.md
+++ www/env-opts.md
@@ -88,11 +88,15 @@
8888
`--sqlstats`: (Sets `g.fSqlStats`.) Print a number of performance
8989
statistics about each SQLite database used when it is closed.
9090
9191
`--sshtrace`: (Sets `g.fSshTrace`.)
9292
93
-`--ssl-identity SSLIDENTITY`:
93
+`--ssl-identity`: The fully qualified name of the file containing the client
94
+certificate and private key to use, in PEM format. It can be created by
95
+concatenating the client certificate and private key files. This identity will
96
+be presented to SSL servers to authenticate the client, in addition to the
97
+normal password authentication.
9498
9599
`--systemtrace`: (Sets `g.fSystemTrace`.) Trace all commands launched
96100
as sub processes.
97101
98102
`--user LOGIN`: (Sets `g.zLogin`) Also `-U LOGIN`. Set the user name
99103
--- www/env-opts.md
+++ www/env-opts.md
@@ -88,11 +88,15 @@
88 `--sqlstats`: (Sets `g.fSqlStats`.) Print a number of performance
89 statistics about each SQLite database used when it is closed.
90
91 `--sshtrace`: (Sets `g.fSshTrace`.)
92
93 `--ssl-identity SSLIDENTITY`:
 
 
 
 
94
95 `--systemtrace`: (Sets `g.fSystemTrace`.) Trace all commands launched
96 as sub processes.
97
98 `--user LOGIN`: (Sets `g.zLogin`) Also `-U LOGIN`. Set the user name
99
--- www/env-opts.md
+++ www/env-opts.md
@@ -88,11 +88,15 @@
88 `--sqlstats`: (Sets `g.fSqlStats`.) Print a number of performance
89 statistics about each SQLite database used when it is closed.
90
91 `--sshtrace`: (Sets `g.fSshTrace`.)
92
93 `--ssl-identity`: The fully qualified name of the file containing the client
94 certificate and private key to use, in PEM format. It can be created by
95 concatenating the client certificate and private key files. This identity will
96 be presented to SSL servers to authenticate the client, in addition to the
97 normal password authentication.
98
99 `--systemtrace`: (Sets `g.fSystemTrace`.) Trace all commands launched
100 as sub processes.
101
102 `--user LOGIN`: (Sets `g.zLogin`) Also `-U LOGIN`. Set the user name
103
+3 -3
--- www/event.wiki
+++ www/event.wiki
@@ -23,11 +23,11 @@
2323
can be something simple like "Version 1.2.3" perhaps with a bright
2424
color background to draw attention to the entry and the wiki content
2525
can contain release notes, for example.
2626
2727
* <b>Blog Entries</b>. Blog entries from developers describing the current
28
- state of a project, or rational for various design decisions, or
28
+ state of a project, or rational for various design decisions, or
2929
roadmaps for future development, can be entered as technotes.
3030
3131
* <b>Process Checkpoints</b>. For projects that have a formal process,
3232
technotes can be used to record the completion or the initiation of
3333
various process steps. For example, a technote can be used to record
@@ -49,11 +49,11 @@
4949
stay better organized and provide a better historical record of the
5050
development progress.
5151
5252
<h2>Viewing Technotes</h2>
5353
54
-Because technotes are considered a special kind of wiki,
54
+Because technotes are considered a special kind of wiki,
5555
users must have permission to read wiki in order read technotes.
5656
Enable the "j" permission under the /Setup/Users menu in order
5757
to give specific users or user classes the ability to view wiki
5858
and technotes.
5959
@@ -64,12 +64,12 @@
6464
6565
There is a hyperlink under the /wikihelp menu that can be used to create
6666
new technotes. And there is a submenu hyperlink on technote displays for
6767
editing existing technotes.
6868
69
-Users must have check-in privileges (permission "i") in order to
69
+Users must have check-in privileges (permission "i") in order to
7070
create or edit technotes. In addition, users must have create-wiki
7171
privilege (permission "f") to create new technotes and edit-wiki
7272
privilege (permission "k") in order to edit existing technotes.
7373
7474
Technote content may be formatted as [/wiki_rules | Fossil wiki],
7575
[/md_rules | Markdown], or a plain text.
7676
--- www/event.wiki
+++ www/event.wiki
@@ -23,11 +23,11 @@
23 can be something simple like "Version 1.2.3" perhaps with a bright
24 color background to draw attention to the entry and the wiki content
25 can contain release notes, for example.
26
27 * <b>Blog Entries</b>. Blog entries from developers describing the current
28 state of a project, or rational for various design decisions, or
29 roadmaps for future development, can be entered as technotes.
30
31 * <b>Process Checkpoints</b>. For projects that have a formal process,
32 technotes can be used to record the completion or the initiation of
33 various process steps. For example, a technote can be used to record
@@ -49,11 +49,11 @@
49 stay better organized and provide a better historical record of the
50 development progress.
51
52 <h2>Viewing Technotes</h2>
53
54 Because technotes are considered a special kind of wiki,
55 users must have permission to read wiki in order read technotes.
56 Enable the "j" permission under the /Setup/Users menu in order
57 to give specific users or user classes the ability to view wiki
58 and technotes.
59
@@ -64,12 +64,12 @@
64
65 There is a hyperlink under the /wikihelp menu that can be used to create
66 new technotes. And there is a submenu hyperlink on technote displays for
67 editing existing technotes.
68
69 Users must have check-in privileges (permission "i") in order to
70 create or edit technotes. In addition, users must have create-wiki
71 privilege (permission "f") to create new technotes and edit-wiki
72 privilege (permission "k") in order to edit existing technotes.
73
74 Technote content may be formatted as [/wiki_rules | Fossil wiki],
75 [/md_rules | Markdown], or a plain text.
76
--- www/event.wiki
+++ www/event.wiki
@@ -23,11 +23,11 @@
23 can be something simple like "Version 1.2.3" perhaps with a bright
24 color background to draw attention to the entry and the wiki content
25 can contain release notes, for example.
26
27 * <b>Blog Entries</b>. Blog entries from developers describing the current
28 state of a project, or rational for various design decisions, or
29 roadmaps for future development, can be entered as technotes.
30
31 * <b>Process Checkpoints</b>. For projects that have a formal process,
32 technotes can be used to record the completion or the initiation of
33 various process steps. For example, a technote can be used to record
@@ -49,11 +49,11 @@
49 stay better organized and provide a better historical record of the
50 development progress.
51
52 <h2>Viewing Technotes</h2>
53
54 Because technotes are considered a special kind of wiki,
55 users must have permission to read wiki in order read technotes.
56 Enable the "j" permission under the /Setup/Users menu in order
57 to give specific users or user classes the ability to view wiki
58 and technotes.
59
@@ -64,12 +64,12 @@
64
65 There is a hyperlink under the /wikihelp menu that can be used to create
66 new technotes. And there is a submenu hyperlink on technote displays for
67 editing existing technotes.
68
69 Users must have check-in privileges (permission "i") in order to
70 create or edit technotes. In addition, users must have create-wiki
71 privilege (permission "f") to create new technotes and edit-wiki
72 privilege (permission "k") in order to edit existing technotes.
73
74 Technote content may be formatted as [/wiki_rules | Fossil wiki],
75 [/md_rules | Markdown], or a plain text.
76
+5 -5
--- www/faq.wiki
+++ www/faq.wiki
@@ -62,12 +62,12 @@
6262
If you already have a fork in your check-in tree and you want to convert
6363
that fork to a branch, you can do this from the web interface.
6464
First locate the check-in that you want to be
6565
the initial check-in of your branch on the timeline and click on its
6666
link so that you are on the <b>ci</b> page. Then find the "<b>edit</b>"
67
-link (near the "Commands:" label) and click on that. On the
68
-"Edit Check-in" page, check the box beside "Branching:" and fill in
67
+link (near the "Commands:" label) and click on that. On the
68
+"Edit Check-in" page, check the box beside "Branching:" and fill in
6969
the name of your new branch to the right and press the "Apply Changes"
7070
button.</blockquote></li>
7171
7272
<a name="q4"></a>
7373
<p><b>(4) How do I tag a check-in?</b></p>
@@ -89,11 +89,11 @@
8989
9090
The CHECK-IN in the previous line can be any
9191
[./checkin_names.wiki | valid check-in name format].
9292
9393
You can also add (and remove) tags from a check-in using the
94
-[./webui.wiki | web interface]. First locate the check-in that you
94
+[./webui.wiki | web interface]. First locate the check-in that you
9595
what to tag on the timeline, then click on the link to go the detailed
9696
information page for that check-in. Then find the "<b>edit</b>"
9797
link (near the "Commands:" label) and click on that. There are
9898
controls on the edit page that allow new tags to be added and existing
9999
tags to be removed.</blockquote></li>
@@ -100,13 +100,13 @@
100100
101101
<a name="q5"></a>
102102
<p><b>(5) How do I create a private branch that won't get pushed back to the
103103
main repository.</b></p>
104104
105
-<blockquote>Use the <b>--private</b> command-line option on the
105
+<blockquote>Use the <b>--private</b> command-line option on the
106106
<b>commit</b> command. The result will be a check-in which exists on
107
-your local repository only and is never pushed to other repositories.
107
+your local repository only and is never pushed to other repositories.
108108
All descendants of a private check-in are also private.
109109
110110
Unless you specify something different using the <b>--branch</b> and/or
111111
<b>--bgcolor</b> options, the new private check-in will be put on a branch
112112
named "private" with an orange background color.
113113
--- www/faq.wiki
+++ www/faq.wiki
@@ -62,12 +62,12 @@
62 If you already have a fork in your check-in tree and you want to convert
63 that fork to a branch, you can do this from the web interface.
64 First locate the check-in that you want to be
65 the initial check-in of your branch on the timeline and click on its
66 link so that you are on the <b>ci</b> page. Then find the "<b>edit</b>"
67 link (near the "Commands:" label) and click on that. On the
68 "Edit Check-in" page, check the box beside "Branching:" and fill in
69 the name of your new branch to the right and press the "Apply Changes"
70 button.</blockquote></li>
71
72 <a name="q4"></a>
73 <p><b>(4) How do I tag a check-in?</b></p>
@@ -89,11 +89,11 @@
89
90 The CHECK-IN in the previous line can be any
91 [./checkin_names.wiki | valid check-in name format].
92
93 You can also add (and remove) tags from a check-in using the
94 [./webui.wiki | web interface]. First locate the check-in that you
95 what to tag on the timeline, then click on the link to go the detailed
96 information page for that check-in. Then find the "<b>edit</b>"
97 link (near the "Commands:" label) and click on that. There are
98 controls on the edit page that allow new tags to be added and existing
99 tags to be removed.</blockquote></li>
@@ -100,13 +100,13 @@
100
101 <a name="q5"></a>
102 <p><b>(5) How do I create a private branch that won't get pushed back to the
103 main repository.</b></p>
104
105 <blockquote>Use the <b>--private</b> command-line option on the
106 <b>commit</b> command. The result will be a check-in which exists on
107 your local repository only and is never pushed to other repositories.
108 All descendants of a private check-in are also private.
109
110 Unless you specify something different using the <b>--branch</b> and/or
111 <b>--bgcolor</b> options, the new private check-in will be put on a branch
112 named "private" with an orange background color.
113
--- www/faq.wiki
+++ www/faq.wiki
@@ -62,12 +62,12 @@
62 If you already have a fork in your check-in tree and you want to convert
63 that fork to a branch, you can do this from the web interface.
64 First locate the check-in that you want to be
65 the initial check-in of your branch on the timeline and click on its
66 link so that you are on the <b>ci</b> page. Then find the "<b>edit</b>"
67 link (near the "Commands:" label) and click on that. On the
68 "Edit Check-in" page, check the box beside "Branching:" and fill in
69 the name of your new branch to the right and press the "Apply Changes"
70 button.</blockquote></li>
71
72 <a name="q4"></a>
73 <p><b>(4) How do I tag a check-in?</b></p>
@@ -89,11 +89,11 @@
89
90 The CHECK-IN in the previous line can be any
91 [./checkin_names.wiki | valid check-in name format].
92
93 You can also add (and remove) tags from a check-in using the
94 [./webui.wiki | web interface]. First locate the check-in that you
95 what to tag on the timeline, then click on the link to go the detailed
96 information page for that check-in. Then find the "<b>edit</b>"
97 link (near the "Commands:" label) and click on that. There are
98 controls on the edit page that allow new tags to be added and existing
99 tags to be removed.</blockquote></li>
@@ -100,13 +100,13 @@
100
101 <a name="q5"></a>
102 <p><b>(5) How do I create a private branch that won't get pushed back to the
103 main repository.</b></p>
104
105 <blockquote>Use the <b>--private</b> command-line option on the
106 <b>commit</b> command. The result will be a check-in which exists on
107 your local repository only and is never pushed to other repositories.
108 All descendants of a private check-in are also private.
109
110 Unless you specify something different using the <b>--branch</b> and/or
111 <b>--bgcolor</b> options, the new private check-in will be put on a branch
112 named "private" with an orange background color.
113
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -2,11 +2,11 @@
22
<h1 align="center">
33
Fossil File Formats
44
</h1>
55
66
The global state of a fossil repository is kept simple so that it can
7
-endure in useful form for decades or centuries.
7
+endure in useful form for decades or centuries.
88
A fossil repository is intended to be readable,
99
searchable, and extensible by people not yet born.
1010
1111
The global state of a fossil repository is an unordered
1212
set of <i>artifacts</i>.
@@ -14,11 +14,11 @@
1414
part of a trouble ticket, or one of several special control artifacts
1515
used to show the relationships between other artifacts within the
1616
project. Each artifact is normally represented on disk as a separate
1717
file. Artifacts can be text or binary.
1818
19
-In addition to the global state,
19
+In addition to the global state,
2020
each fossil repository also contains local state.
2121
The local state consists of web-page formatting
2222
preferences, authorized users, ticket display and reporting formats,
2323
and so forth. The global state is shared in common among all
2424
repositories for the same project, whereas the local state is often
@@ -30,11 +30,11 @@
3030
mentioned here in order to distinguish it from global state.
3131
3232
Each artifact in the repository is named by its SHA1 hash.
3333
No prefixes or meta information is added to an artifact before
3434
its hash is computed. The name of an artifact in the repository
35
-is exactly the same SHA1 hash that is computed by sha1sum
35
+is exactly the same SHA1 hash that is computed by sha1sum
3636
on the file as it exists in your source tree.</p>
3737
3838
Some artifacts have a particular format which gives them special
3939
meaning to fossil. Fossil recognizes:
4040
@@ -84,11 +84,11 @@
8484
Each card begins with a single
8585
character "card type". Zero or more arguments may follow
8686
the card type. All arguments are separated from each other
8787
and from the card-type character by a single space
8888
character. There is no surplus white space between arguments
89
-and no leading or trailing whitespace except for the newline
89
+and no leading or trailing whitespace except for the newline
9090
character that acts as the card separator.
9191
9292
All cards of the manifest occur in strict sorted lexicographical order.
9393
No card may be duplicated.
9494
The entire manifest may be PGP clear-signed, but otherwise it
@@ -114,18 +114,18 @@
114114
another manifest that serves as the "baseline" for this manifest. A
115115
manifest that has a B-card is called a delta-manifest and a manifest
116116
that omits the B-card is a baseline-manifest. The other manifest
117117
identified by the argument of the B-card must be a baseline-manifest.
118118
A baseline-manifest records the complete contents of a check-in.
119
-A delta-manifest records only changes from its baseline.
119
+A delta-manifest records only changes from its baseline.
120120
121121
A manifest must have exactly one C-card. The sole argument to
122122
the C-card is a check-in comment that describes the check-in that
123123
the manifest defines. The check-in comment is text. The following
124124
escape sequences are applied to the text:
125125
A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
126
-newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
126
+newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
127127
(ASCII 0x5C) is represented as two backslashes "\\". Apart from
128128
space and newline, no other whitespace characters are allowed in
129129
the check-in comment. Nor are any unprintable characters allowed
130130
in the comment.
131131
@@ -166,15 +166,15 @@
166166
text in the comment of the C-card. If the N-card is omitted, a default mimetype
167167
is used.
168168
169169
A manifest has zero or one P-cards. Most manifests have one P-card.
170170
The P-card has a varying number of arguments that
171
-defines other manifests from which the current manifest
172
-is derived. Each argument is an 40-character lowercase
173
-hexadecimal SHA1 of the predecessor manifest. All arguments
174
-to the P-card must be unique to that line.
175
-The first predecessor is the direct ancestor of the manifest.
171
+define other manifests from which the current manifest
172
+is derived. Each argument is a 40-character lowercase
173
+hexadecimal SHA1 of a predecessor manifest. All arguments
174
+to the P-card must be unique within that card.
175
+The first argument is the SHA1 of the direct ancestor of the manifest.
176176
Other arguments define manifests with which the first was
177177
merged to yield the current manifest. Most manifests have
178178
a P-card with a single argument. The first manifest in the
179179
project has no ancestors and thus has no P-card or (depending
180180
on the Fossil version) an empty P-card (no arguments).
@@ -184,28 +184,28 @@
184184
whereas a P-card defines the immediate ancestor or a merge
185185
ancestor, the Q-card is used to identify a single check-in or a small
186186
range of check-ins which were cherry-picked for inclusion in or
187187
exclusion from the current manifest. The first argument of
188188
the Q-card is the artifact ID of another manifest (the "target")
189
-which has had its changes included or excluded in the current manifest.
189
+which has had its changes included or excluded in the current manifest.
190190
The target is preceded by "+" or "-" to show inclusion or
191191
exclusion, respectively. The optional second argument to the
192192
Q-card is another manifest artifact ID which is the "baseline"
193193
for the cherry-pick. If omitted, the baseline is the primary
194194
parent of the target. The
195195
changes included or excluded consist of all changes moving from
196
-the baseline to the target.
196
+the baseline to the target.
197197
198
-The Q-card was added to the interface specification on 2011-02-26.
198
+The Q-card was added to the interface specification on 2011-02-26.
199199
Older versions of Fossil will reject manifests that contain Q-cards.
200200
201201
A manifest may optionally have a single R-card. The R-card has
202
-a single argument which is the MD5 checksum of all files in
202
+a single argument which is the MD5 checksum of all files in
203203
the check-in except the manifest itself. The checksum is expressed
204
-as 32-characters of lowercase hexadecimal. The checksum is
204
+as 32 characters of lowercase hexadecimal. The checksum is
205205
computed as follows: For each file in the check-in (except for
206
-the manifest itself) in strict sorted lexicographical order,
206
+the manifest itself) in strict sorted lexicographical order,
207207
take the pathname of the file relative to the root of the
208208
repository, append a single space (ASCII 0x20), the
209209
size of the file in ASCII decimal, a single newline
210210
character (ASCII 0x0A), and the complete text of the file.
211211
Compute the MD5 checksum of the result.
@@ -228,12 +228,12 @@
228228
is encoded using the same character escapes as is used for the
229229
check-in comment argument to the C-card.
230230
231231
A manifest must have a single Z-card as its last line. The argument
232232
to the Z-card is a 32-character lowercase hexadecimal MD5 hash
233
-of all prior lines of the manifest up to and including the newline
234
-character that immediately precedes the "Z". The Z-card is
233
+of all prior lines of the manifest up to and including the newline
234
+character that immediately precedes the "Z". The Z-card is
235235
a sanity check to prove that the manifest is well-formed and
236236
consistent.
237237
238238
A sample manifest from Fossil itself can be seen
239239
[/artifact/28987096ac | here].
@@ -240,27 +240,27 @@
240240
241241
<a name="cluster"></a>
242242
<h2>2.0 Clusters</h2>
243243
244244
A cluster is an artifact that declares the existence of other artifacts.
245
-Clusters are used during repository synchronization to help
245
+Clusters are used during repository synchronization to help
246246
reduce network traffic. As such, clusters are an optimization and
247247
may be removed from a repository without loss or damage to the
248248
underlying project code.
249249
250250
Clusters follow a syntax that is very similar to manifests.
251
-A Cluster is a line-oriented text file. Newline characters
251
+A cluster is a line-oriented text file. Newline characters
252252
(ASCII 0x0a) separate the artifact into cards. Each card begins with a single
253253
character "card type". Zero or more arguments may follow
254254
the card type. All arguments are separated from each other
255255
and from the card-type character by a single space
256256
character. There is no surplus white space between arguments
257
-and no leading or trailing whitespace except for the newline
257
+and no leading or trailing whitespace except for the newline
258258
character that acts as the card separator.
259259
All cards of a cluster occur in strict sorted lexicographical order.
260260
No card may be duplicated.
261
-The cluster may not contain additional text or data beyond
261
+The cluster may not contain additional text or data beyond
262262
what is described here.
263263
Unlike manifests, clusters are never PGP signed.
264264
265265
Allowed cards in the cluster are as follows:
266266
@@ -268,12 +268,12 @@
268268
<b>M</b> <i>artifact-id</i><br />
269269
<b>Z</b> <i>checksum</i>
270270
</blockquote>
271271
272272
A cluster contains one or more "M" cards followed by a single "Z"
273
-line. Each M card has a single argument which is the artifact ID of
274
-another artifact in the repository. The Z card work exactly like
273
+card. Each M card has a single argument which is the artifact ID of
274
+another artifact in the repository. The Z card works exactly like
275275
the Z card of a manifest. The argument to the Z card is the
276276
lower-case hexadecimal representation of the MD5 checksum of all
277277
prior cards in the cluster. The Z-card is required.
278278
279279
An example cluster from Fossil can be seen
@@ -315,11 +315,11 @@
315315
first value is the tag name. The first character of the tag
316316
is either "+", "-", or "*". The "+" means the tag should be added
317317
to the artifact. The "-" means the tag should be removed.
318318
The "*" character means the tag should be added to the artifact
319319
and all direct descendants (but not descendants through a merge) down
320
-to but not including the first descendant that contains a
320
+to but not including the first descendant that contains a
321321
more recent "-", "*", or "+" tag with the same name.
322322
The optional third argument is the value of the tag. A tag
323323
without a value is a Boolean.
324324
325325
When two or more tags with the same name are applied to the
@@ -331,11 +331,11 @@
331331
for display purposes. The "user" tag overrides the name of the
332332
check-in user. The "date" tag overrides the check-in date.
333333
The "branch" tag sets the name of the branch that at check-in
334334
belongs to. Symbolic tags begin with the "sym-" prefix.
335335
336
-The U card is the name of the user that created the control
336
+The U card is the name of the user that created the control
337337
artifact. The Z card is the usual required artifact checksum.
338338
339339
An example control artifacts can be seen [/info/9d302ccda8 | here].
340340
341341
@@ -360,11 +360,11 @@
360360
361361
The D card is the date and time when the wiki page was edited.
362362
The P card specifies the parent wiki pages, if any. The L card
363363
gives the name of the wiki page. The optional N card specifies
364364
the mimetype of the wiki text. If the N card is omitted, the
365
-mimetype is assumed to be text/x-fossil-wiki.
365
+mimetype is assumed to be text/x-fossil-wiki.
366366
The U card specifies the login
367367
of the user who made this edit to the wiki page. The Z card is
368368
the usual checksum over the entire artifact and is required.
369369
370370
The W card is used to specify the text of the wiki page. The
@@ -405,11 +405,11 @@
405405
If the <i>value</i> parameter of the J card is omitted, then the
406406
field is set to an empty string.
407407
Each fossil server has a ticket configuration which specifies the fields its
408408
understands. The ticket configuration is part of the local state for
409409
the repository and thus can vary from one repository to another.
410
-Hence a J card might specify a <i>field</i> that do not exist in the
410
+Hence a J card might specify a <i>field</i> that do not exist in the
411411
local ticket configuration. If a J card specifies a <i>field</i> that
412412
is not in the local configuration, then that J card
413413
is simply ignored.
414414
415415
The first argument of the J card is the field name. The second
@@ -424,11 +424,11 @@
424424
425425
<a name="attachment"></a>
426426
<h2>6.0 Attachments</h2>
427427
428428
An attachment artifact associates some other artifact that is the
429
-attachment (the source artifact) with a ticket or wiki page or
429
+attachment (the source artifact) with a ticket or wiki page or
430430
technical note to which
431431
the attachment is connected (the target artifact).
432432
The following cards are allowed on an attachment artifact:
433433
434434
<blockquote>
@@ -441,11 +441,11 @@
441441
</blockquote>
442442
443443
The A card specifies a filename for the attachment in its first argument.
444444
The second argument to the A card is the name of the wiki page or
445445
ticket or technical note to which the attachment is connected. The
446
-third argument is either missing or else it is the 40-character artifact
446
+third argument is either missing or else it is the 40-character artifact
447447
ID of the attachment itself. A missing third argument means that the
448448
attachment should be deleted.
449449
450450
The C card is an optional comment describing what the attachment is about.
451451
The C card is optional, but there can only be one.
@@ -487,11 +487,11 @@
487487
</blockquote>
488488
489489
The C card contains text that is displayed on the timeline for the
490490
technote. The C card is optional, but there can only be one.
491491
492
-A single D card is required to give the date and time when the
492
+A single D card is required to give the date and time when the
493493
technote artifact was created. This is different from the time at which
494494
the technote appears on the timeline.
495495
496496
A single E card gives the time of the technote (the point on the timeline
497497
where the technote is displayed) and a unique identifier for the technote.
@@ -525,11 +525,11 @@
525525
display color for timelines.
526526
527527
The optional U card gives name of the user who entered the technote.
528528
529529
A single W card provides wiki text for the document associated with the
530
-technote. The format of the W card is exactly the same as for a
530
+technote. The format of the W card is exactly the same as for a
531531
[#wikichng | wiki artifact].
532532
533533
The Z card is the required checksum over the rest of the artifact.
534534
535535
536536
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -2,11 +2,11 @@
2 <h1 align="center">
3 Fossil File Formats
4 </h1>
5
6 The global state of a fossil repository is kept simple so that it can
7 endure in useful form for decades or centuries.
8 A fossil repository is intended to be readable,
9 searchable, and extensible by people not yet born.
10
11 The global state of a fossil repository is an unordered
12 set of <i>artifacts</i>.
@@ -14,11 +14,11 @@
14 part of a trouble ticket, or one of several special control artifacts
15 used to show the relationships between other artifacts within the
16 project. Each artifact is normally represented on disk as a separate
17 file. Artifacts can be text or binary.
18
19 In addition to the global state,
20 each fossil repository also contains local state.
21 The local state consists of web-page formatting
22 preferences, authorized users, ticket display and reporting formats,
23 and so forth. The global state is shared in common among all
24 repositories for the same project, whereas the local state is often
@@ -30,11 +30,11 @@
30 mentioned here in order to distinguish it from global state.
31
32 Each artifact in the repository is named by its SHA1 hash.
33 No prefixes or meta information is added to an artifact before
34 its hash is computed. The name of an artifact in the repository
35 is exactly the same SHA1 hash that is computed by sha1sum
36 on the file as it exists in your source tree.</p>
37
38 Some artifacts have a particular format which gives them special
39 meaning to fossil. Fossil recognizes:
40
@@ -84,11 +84,11 @@
84 Each card begins with a single
85 character "card type". Zero or more arguments may follow
86 the card type. All arguments are separated from each other
87 and from the card-type character by a single space
88 character. There is no surplus white space between arguments
89 and no leading or trailing whitespace except for the newline
90 character that acts as the card separator.
91
92 All cards of the manifest occur in strict sorted lexicographical order.
93 No card may be duplicated.
94 The entire manifest may be PGP clear-signed, but otherwise it
@@ -114,18 +114,18 @@
114 another manifest that serves as the "baseline" for this manifest. A
115 manifest that has a B-card is called a delta-manifest and a manifest
116 that omits the B-card is a baseline-manifest. The other manifest
117 identified by the argument of the B-card must be a baseline-manifest.
118 A baseline-manifest records the complete contents of a check-in.
119 A delta-manifest records only changes from its baseline.
120
121 A manifest must have exactly one C-card. The sole argument to
122 the C-card is a check-in comment that describes the check-in that
123 the manifest defines. The check-in comment is text. The following
124 escape sequences are applied to the text:
125 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
126 newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
127 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
128 space and newline, no other whitespace characters are allowed in
129 the check-in comment. Nor are any unprintable characters allowed
130 in the comment.
131
@@ -166,15 +166,15 @@
166 text in the comment of the C-card. If the N-card is omitted, a default mimetype
167 is used.
168
169 A manifest has zero or one P-cards. Most manifests have one P-card.
170 The P-card has a varying number of arguments that
171 defines other manifests from which the current manifest
172 is derived. Each argument is an 40-character lowercase
173 hexadecimal SHA1 of the predecessor manifest. All arguments
174 to the P-card must be unique to that line.
175 The first predecessor is the direct ancestor of the manifest.
176 Other arguments define manifests with which the first was
177 merged to yield the current manifest. Most manifests have
178 a P-card with a single argument. The first manifest in the
179 project has no ancestors and thus has no P-card or (depending
180 on the Fossil version) an empty P-card (no arguments).
@@ -184,28 +184,28 @@
184 whereas a P-card defines the immediate ancestor or a merge
185 ancestor, the Q-card is used to identify a single check-in or a small
186 range of check-ins which were cherry-picked for inclusion in or
187 exclusion from the current manifest. The first argument of
188 the Q-card is the artifact ID of another manifest (the "target")
189 which has had its changes included or excluded in the current manifest.
190 The target is preceded by "+" or "-" to show inclusion or
191 exclusion, respectively. The optional second argument to the
192 Q-card is another manifest artifact ID which is the "baseline"
193 for the cherry-pick. If omitted, the baseline is the primary
194 parent of the target. The
195 changes included or excluded consist of all changes moving from
196 the baseline to the target.
197
198 The Q-card was added to the interface specification on 2011-02-26.
199 Older versions of Fossil will reject manifests that contain Q-cards.
200
201 A manifest may optionally have a single R-card. The R-card has
202 a single argument which is the MD5 checksum of all files in
203 the check-in except the manifest itself. The checksum is expressed
204 as 32-characters of lowercase hexadecimal. The checksum is
205 computed as follows: For each file in the check-in (except for
206 the manifest itself) in strict sorted lexicographical order,
207 take the pathname of the file relative to the root of the
208 repository, append a single space (ASCII 0x20), the
209 size of the file in ASCII decimal, a single newline
210 character (ASCII 0x0A), and the complete text of the file.
211 Compute the MD5 checksum of the result.
@@ -228,12 +228,12 @@
228 is encoded using the same character escapes as is used for the
229 check-in comment argument to the C-card.
230
231 A manifest must have a single Z-card as its last line. The argument
232 to the Z-card is a 32-character lowercase hexadecimal MD5 hash
233 of all prior lines of the manifest up to and including the newline
234 character that immediately precedes the "Z". The Z-card is
235 a sanity check to prove that the manifest is well-formed and
236 consistent.
237
238 A sample manifest from Fossil itself can be seen
239 [/artifact/28987096ac | here].
@@ -240,27 +240,27 @@
240
241 <a name="cluster"></a>
242 <h2>2.0 Clusters</h2>
243
244 A cluster is an artifact that declares the existence of other artifacts.
245 Clusters are used during repository synchronization to help
246 reduce network traffic. As such, clusters are an optimization and
247 may be removed from a repository without loss or damage to the
248 underlying project code.
249
250 Clusters follow a syntax that is very similar to manifests.
251 A Cluster is a line-oriented text file. Newline characters
252 (ASCII 0x0a) separate the artifact into cards. Each card begins with a single
253 character "card type". Zero or more arguments may follow
254 the card type. All arguments are separated from each other
255 and from the card-type character by a single space
256 character. There is no surplus white space between arguments
257 and no leading or trailing whitespace except for the newline
258 character that acts as the card separator.
259 All cards of a cluster occur in strict sorted lexicographical order.
260 No card may be duplicated.
261 The cluster may not contain additional text or data beyond
262 what is described here.
263 Unlike manifests, clusters are never PGP signed.
264
265 Allowed cards in the cluster are as follows:
266
@@ -268,12 +268,12 @@
268 <b>M</b> <i>artifact-id</i><br />
269 <b>Z</b> <i>checksum</i>
270 </blockquote>
271
272 A cluster contains one or more "M" cards followed by a single "Z"
273 line. Each M card has a single argument which is the artifact ID of
274 another artifact in the repository. The Z card work exactly like
275 the Z card of a manifest. The argument to the Z card is the
276 lower-case hexadecimal representation of the MD5 checksum of all
277 prior cards in the cluster. The Z-card is required.
278
279 An example cluster from Fossil can be seen
@@ -315,11 +315,11 @@
315 first value is the tag name. The first character of the tag
316 is either "+", "-", or "*". The "+" means the tag should be added
317 to the artifact. The "-" means the tag should be removed.
318 The "*" character means the tag should be added to the artifact
319 and all direct descendants (but not descendants through a merge) down
320 to but not including the first descendant that contains a
321 more recent "-", "*", or "+" tag with the same name.
322 The optional third argument is the value of the tag. A tag
323 without a value is a Boolean.
324
325 When two or more tags with the same name are applied to the
@@ -331,11 +331,11 @@
331 for display purposes. The "user" tag overrides the name of the
332 check-in user. The "date" tag overrides the check-in date.
333 The "branch" tag sets the name of the branch that at check-in
334 belongs to. Symbolic tags begin with the "sym-" prefix.
335
336 The U card is the name of the user that created the control
337 artifact. The Z card is the usual required artifact checksum.
338
339 An example control artifacts can be seen [/info/9d302ccda8 | here].
340
341
@@ -360,11 +360,11 @@
360
361 The D card is the date and time when the wiki page was edited.
362 The P card specifies the parent wiki pages, if any. The L card
363 gives the name of the wiki page. The optional N card specifies
364 the mimetype of the wiki text. If the N card is omitted, the
365 mimetype is assumed to be text/x-fossil-wiki.
366 The U card specifies the login
367 of the user who made this edit to the wiki page. The Z card is
368 the usual checksum over the entire artifact and is required.
369
370 The W card is used to specify the text of the wiki page. The
@@ -405,11 +405,11 @@
405 If the <i>value</i> parameter of the J card is omitted, then the
406 field is set to an empty string.
407 Each fossil server has a ticket configuration which specifies the fields its
408 understands. The ticket configuration is part of the local state for
409 the repository and thus can vary from one repository to another.
410 Hence a J card might specify a <i>field</i> that do not exist in the
411 local ticket configuration. If a J card specifies a <i>field</i> that
412 is not in the local configuration, then that J card
413 is simply ignored.
414
415 The first argument of the J card is the field name. The second
@@ -424,11 +424,11 @@
424
425 <a name="attachment"></a>
426 <h2>6.0 Attachments</h2>
427
428 An attachment artifact associates some other artifact that is the
429 attachment (the source artifact) with a ticket or wiki page or
430 technical note to which
431 the attachment is connected (the target artifact).
432 The following cards are allowed on an attachment artifact:
433
434 <blockquote>
@@ -441,11 +441,11 @@
441 </blockquote>
442
443 The A card specifies a filename for the attachment in its first argument.
444 The second argument to the A card is the name of the wiki page or
445 ticket or technical note to which the attachment is connected. The
446 third argument is either missing or else it is the 40-character artifact
447 ID of the attachment itself. A missing third argument means that the
448 attachment should be deleted.
449
450 The C card is an optional comment describing what the attachment is about.
451 The C card is optional, but there can only be one.
@@ -487,11 +487,11 @@
487 </blockquote>
488
489 The C card contains text that is displayed on the timeline for the
490 technote. The C card is optional, but there can only be one.
491
492 A single D card is required to give the date and time when the
493 technote artifact was created. This is different from the time at which
494 the technote appears on the timeline.
495
496 A single E card gives the time of the technote (the point on the timeline
497 where the technote is displayed) and a unique identifier for the technote.
@@ -525,11 +525,11 @@
525 display color for timelines.
526
527 The optional U card gives name of the user who entered the technote.
528
529 A single W card provides wiki text for the document associated with the
530 technote. The format of the W card is exactly the same as for a
531 [#wikichng | wiki artifact].
532
533 The Z card is the required checksum over the rest of the artifact.
534
535
536
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -2,11 +2,11 @@
2 <h1 align="center">
3 Fossil File Formats
4 </h1>
5
6 The global state of a fossil repository is kept simple so that it can
7 endure in useful form for decades or centuries.
8 A fossil repository is intended to be readable,
9 searchable, and extensible by people not yet born.
10
11 The global state of a fossil repository is an unordered
12 set of <i>artifacts</i>.
@@ -14,11 +14,11 @@
14 part of a trouble ticket, or one of several special control artifacts
15 used to show the relationships between other artifacts within the
16 project. Each artifact is normally represented on disk as a separate
17 file. Artifacts can be text or binary.
18
19 In addition to the global state,
20 each fossil repository also contains local state.
21 The local state consists of web-page formatting
22 preferences, authorized users, ticket display and reporting formats,
23 and so forth. The global state is shared in common among all
24 repositories for the same project, whereas the local state is often
@@ -30,11 +30,11 @@
30 mentioned here in order to distinguish it from global state.
31
32 Each artifact in the repository is named by its SHA1 hash.
33 No prefixes or meta information is added to an artifact before
34 its hash is computed. The name of an artifact in the repository
35 is exactly the same SHA1 hash that is computed by sha1sum
36 on the file as it exists in your source tree.</p>
37
38 Some artifacts have a particular format which gives them special
39 meaning to fossil. Fossil recognizes:
40
@@ -84,11 +84,11 @@
84 Each card begins with a single
85 character "card type". Zero or more arguments may follow
86 the card type. All arguments are separated from each other
87 and from the card-type character by a single space
88 character. There is no surplus white space between arguments
89 and no leading or trailing whitespace except for the newline
90 character that acts as the card separator.
91
92 All cards of the manifest occur in strict sorted lexicographical order.
93 No card may be duplicated.
94 The entire manifest may be PGP clear-signed, but otherwise it
@@ -114,18 +114,18 @@
114 another manifest that serves as the "baseline" for this manifest. A
115 manifest that has a B-card is called a delta-manifest and a manifest
116 that omits the B-card is a baseline-manifest. The other manifest
117 identified by the argument of the B-card must be a baseline-manifest.
118 A baseline-manifest records the complete contents of a check-in.
119 A delta-manifest records only changes from its baseline.
120
121 A manifest must have exactly one C-card. The sole argument to
122 the C-card is a check-in comment that describes the check-in that
123 the manifest defines. The check-in comment is text. The following
124 escape sequences are applied to the text:
125 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
126 newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
127 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
128 space and newline, no other whitespace characters are allowed in
129 the check-in comment. Nor are any unprintable characters allowed
130 in the comment.
131
@@ -166,15 +166,15 @@
166 text in the comment of the C-card. If the N-card is omitted, a default mimetype
167 is used.
168
169 A manifest has zero or one P-cards. Most manifests have one P-card.
170 The P-card has a varying number of arguments that
171 define other manifests from which the current manifest
172 is derived. Each argument is a 40-character lowercase
173 hexadecimal SHA1 of a predecessor manifest. All arguments
174 to the P-card must be unique within that card.
175 The first argument is the SHA1 of the direct ancestor of the manifest.
176 Other arguments define manifests with which the first was
177 merged to yield the current manifest. Most manifests have
178 a P-card with a single argument. The first manifest in the
179 project has no ancestors and thus has no P-card or (depending
180 on the Fossil version) an empty P-card (no arguments).
@@ -184,28 +184,28 @@
184 whereas a P-card defines the immediate ancestor or a merge
185 ancestor, the Q-card is used to identify a single check-in or a small
186 range of check-ins which were cherry-picked for inclusion in or
187 exclusion from the current manifest. The first argument of
188 the Q-card is the artifact ID of another manifest (the "target")
189 which has had its changes included or excluded in the current manifest.
190 The target is preceded by "+" or "-" to show inclusion or
191 exclusion, respectively. The optional second argument to the
192 Q-card is another manifest artifact ID which is the "baseline"
193 for the cherry-pick. If omitted, the baseline is the primary
194 parent of the target. The
195 changes included or excluded consist of all changes moving from
196 the baseline to the target.
197
198 The Q-card was added to the interface specification on 2011-02-26.
199 Older versions of Fossil will reject manifests that contain Q-cards.
200
201 A manifest may optionally have a single R-card. The R-card has
202 a single argument which is the MD5 checksum of all files in
203 the check-in except the manifest itself. The checksum is expressed
204 as 32 characters of lowercase hexadecimal. The checksum is
205 computed as follows: For each file in the check-in (except for
206 the manifest itself) in strict sorted lexicographical order,
207 take the pathname of the file relative to the root of the
208 repository, append a single space (ASCII 0x20), the
209 size of the file in ASCII decimal, a single newline
210 character (ASCII 0x0A), and the complete text of the file.
211 Compute the MD5 checksum of the result.
@@ -228,12 +228,12 @@
228 is encoded using the same character escapes as is used for the
229 check-in comment argument to the C-card.
230
231 A manifest must have a single Z-card as its last line. The argument
232 to the Z-card is a 32-character lowercase hexadecimal MD5 hash
233 of all prior lines of the manifest up to and including the newline
234 character that immediately precedes the "Z". The Z-card is
235 a sanity check to prove that the manifest is well-formed and
236 consistent.
237
238 A sample manifest from Fossil itself can be seen
239 [/artifact/28987096ac | here].
@@ -240,27 +240,27 @@
240
241 <a name="cluster"></a>
242 <h2>2.0 Clusters</h2>
243
244 A cluster is an artifact that declares the existence of other artifacts.
245 Clusters are used during repository synchronization to help
246 reduce network traffic. As such, clusters are an optimization and
247 may be removed from a repository without loss or damage to the
248 underlying project code.
249
250 Clusters follow a syntax that is very similar to manifests.
251 A cluster is a line-oriented text file. Newline characters
252 (ASCII 0x0a) separate the artifact into cards. Each card begins with a single
253 character "card type". Zero or more arguments may follow
254 the card type. All arguments are separated from each other
255 and from the card-type character by a single space
256 character. There is no surplus white space between arguments
257 and no leading or trailing whitespace except for the newline
258 character that acts as the card separator.
259 All cards of a cluster occur in strict sorted lexicographical order.
260 No card may be duplicated.
261 The cluster may not contain additional text or data beyond
262 what is described here.
263 Unlike manifests, clusters are never PGP signed.
264
265 Allowed cards in the cluster are as follows:
266
@@ -268,12 +268,12 @@
268 <b>M</b> <i>artifact-id</i><br />
269 <b>Z</b> <i>checksum</i>
270 </blockquote>
271
272 A cluster contains one or more "M" cards followed by a single "Z"
273 card. Each M card has a single argument which is the artifact ID of
274 another artifact in the repository. The Z card works exactly like
275 the Z card of a manifest. The argument to the Z card is the
276 lower-case hexadecimal representation of the MD5 checksum of all
277 prior cards in the cluster. The Z-card is required.
278
279 An example cluster from Fossil can be seen
@@ -315,11 +315,11 @@
315 first value is the tag name. The first character of the tag
316 is either "+", "-", or "*". The "+" means the tag should be added
317 to the artifact. The "-" means the tag should be removed.
318 The "*" character means the tag should be added to the artifact
319 and all direct descendants (but not descendants through a merge) down
320 to but not including the first descendant that contains a
321 more recent "-", "*", or "+" tag with the same name.
322 The optional third argument is the value of the tag. A tag
323 without a value is a Boolean.
324
325 When two or more tags with the same name are applied to the
@@ -331,11 +331,11 @@
331 for display purposes. The "user" tag overrides the name of the
332 check-in user. The "date" tag overrides the check-in date.
333 The "branch" tag sets the name of the branch that at check-in
334 belongs to. Symbolic tags begin with the "sym-" prefix.
335
336 The U card is the name of the user that created the control
337 artifact. The Z card is the usual required artifact checksum.
338
339 An example control artifacts can be seen [/info/9d302ccda8 | here].
340
341
@@ -360,11 +360,11 @@
360
361 The D card is the date and time when the wiki page was edited.
362 The P card specifies the parent wiki pages, if any. The L card
363 gives the name of the wiki page. The optional N card specifies
364 the mimetype of the wiki text. If the N card is omitted, the
365 mimetype is assumed to be text/x-fossil-wiki.
366 The U card specifies the login
367 of the user who made this edit to the wiki page. The Z card is
368 the usual checksum over the entire artifact and is required.
369
370 The W card is used to specify the text of the wiki page. The
@@ -405,11 +405,11 @@
405 If the <i>value</i> parameter of the J card is omitted, then the
406 field is set to an empty string.
407 Each fossil server has a ticket configuration which specifies the fields its
408 understands. The ticket configuration is part of the local state for
409 the repository and thus can vary from one repository to another.
410 Hence a J card might specify a <i>field</i> that do not exist in the
411 local ticket configuration. If a J card specifies a <i>field</i> that
412 is not in the local configuration, then that J card
413 is simply ignored.
414
415 The first argument of the J card is the field name. The second
@@ -424,11 +424,11 @@
424
425 <a name="attachment"></a>
426 <h2>6.0 Attachments</h2>
427
428 An attachment artifact associates some other artifact that is the
429 attachment (the source artifact) with a ticket or wiki page or
430 technical note to which
431 the attachment is connected (the target artifact).
432 The following cards are allowed on an attachment artifact:
433
434 <blockquote>
@@ -441,11 +441,11 @@
441 </blockquote>
442
443 The A card specifies a filename for the attachment in its first argument.
444 The second argument to the A card is the name of the wiki page or
445 ticket or technical note to which the attachment is connected. The
446 third argument is either missing or else it is the 40-character artifact
447 ID of the attachment itself. A missing third argument means that the
448 attachment should be deleted.
449
450 The C card is an optional comment describing what the attachment is about.
451 The C card is optional, but there can only be one.
@@ -487,11 +487,11 @@
487 </blockquote>
488
489 The C card contains text that is displayed on the timeline for the
490 technote. The C card is optional, but there can only be one.
491
492 A single D card is required to give the date and time when the
493 technote artifact was created. This is different from the time at which
494 the technote appears on the timeline.
495
496 A single E card gives the time of the technote (the point on the timeline
497 where the technote is displayed) and a unique identifier for the technote.
@@ -525,11 +525,11 @@
525 display color for timelines.
526
527 The optional U card gives name of the user who entered the technote.
528
529 A single W card provides wiki text for the document associated with the
530 technote. The format of the W card is exactly the same as for a
531 [#wikichng | wiki artifact].
532
533 The Z card is the required checksum over the rest of the artifact.
534
535
536
--- www/fiveminutes.wiki
+++ www/fiveminutes.wiki
@@ -4,65 +4,65 @@
44
The following document was contributed by Gilles Ganault on 2013-01-08.
55
</i></b>
66
</p><hr>
77
88
<h1>Up and running in 5 minutes as a single user</h1>
9
-<p>This short document explains the main basic Fossil commands for a single
10
-user, i.e. with no additional users, with no need to synchronize with some remote
9
+<p>This short document explains the main basic Fossil commands for a single
10
+user, i.e. with no additional users, with no need to synchronize with some remote
1111
repository, and no need for branching/forking.</p>
1212
1313
<h2>Create a new repository</h2>
1414
<p>fossil new c:\test.repo</p>
15
-<p>This will create the new SQLite binary file that holds the repository, i.e.
16
-files, tickets, wiki, etc. It can be located anywhere, although it's considered
17
-best practice to keep it outside the work directory where you will work on files
15
+<p>This will create the new SQLite binary file that holds the repository, i.e.
16
+files, tickets, wiki, etc. It can be located anywhere, although it's considered
17
+best practice to keep it outside the work directory where you will work on files
1818
after they've been checked out of the repository.</p>
1919
2020
<h2>Open the repository</h2>
2121
<p>cd c:\temp\test.fossil</p>
2222
<p>fossil open c:\test.repo</p>
23
-<p>This will check out the last revision of all the files in the repository,
24
-if any, into the current work directory. In addition, it will create a binary
23
+<p>This will check out the last revision of all the files in the repository,
24
+if any, into the current work directory. In addition, it will create a binary
2525
file _FOSSIL_ to keep track of changes (on non-Windows systems it is called
2626
<tt>.fslckout</tt>).</p>
2727
2828
<h2>Add new files</h2>
2929
<p>fossil add .</p>
30
-<p>To tell Fossil to add new files to the repository. The files aren't actually
31
-added until you run &quot;commit&quot;. When using &quot;.&quot;, it tells Fossil
32
-to add all the files in the current directory recursively, i.e. including all
30
+<p>To tell Fossil to add new files to the repository. The files aren't actually
31
+added until you run &quot;commit&quot;. When using &quot;.&quot;, it tells Fossil
32
+to add all the files in the current directory recursively, i.e. including all
3333
the files in all the subdirectories.</p>
3434
<p>Note: To tell Fossil to ignore some extensions:</p>
3535
<p>fossil settings ignore-glob &quot;*.o,*.obj,*.exe&quot; --global</p>
3636
3737
<h2>Remove files that haven't been committed yet</h2>
3838
<p>fossil delete myfile.c</p>
39
-<p>This will simply remove the item from the list of files that were previously
39
+<p>This will simply remove the item from the list of files that were previously
4040
added through &quot;fossil add&quot;.</p>
4141
4242
<h2>Check current status</h2>
4343
<p>fossil changes</p>
44
-<p>This shows the list of changes that have been done and will be committed the
45
-next time you run &quot;fossil commit&quot;. It's a useful command to run before
44
+<p>This shows the list of changes that have been done and will be committed the
45
+next time you run &quot;fossil commit&quot;. It's a useful command to run before
4646
running &quot;fossil commit&quot; just to check that things are OK before proceeding.</p>
4747
4848
<h2>Commit changes</h2>
49
-<p>To actually apply the pending changes to the repository, e.g. new files marked
50
-for addition, checked-out files that have been edited and must be checked-in,
49
+<p>To actually apply the pending changes to the repository, e.g. new files marked
50
+for addition, checked-out files that have been edited and must be checked-in,
5151
etc.</p>
5252
5353
<p>fossil commit -m "Added stuff"</p>
5454
5555
If no file names are provided on the command-line then all changes will be checked in,
5656
otherwise just the listed file(s) will be checked in.
5757
5858
<h2>Compare two revisions of a file</h2>
59
-<p>If you wish to compare the last revision of a file and its checked out version
59
+<p>If you wish to compare the last revision of a file and its checked out version
6060
in your work directory:</p>
6161
<p>fossil gdiff myfile.c</p>
6262
<p>If you wish to compare two different revisions of a file in the repository:</p>
63
-<p>fossil finfo myfile: Note the first hash, which is the UUID of the commit
63
+<p>fossil finfo myfile: Note the first hash, which is the UUID of the commit
6464
when the file was committed</p>
6565
<p>fossil gdiff --from UUID#1 --to UUID#2 myfile.c</p>
6666
<h2>Cancel changes and go back to previous revision</h2>
6767
<p>fossil revert myfile.c</p>
6868
<p>Fossil does not prompt when reverting a file. It simply reminds the user about the
@@ -69,8 +69,8 @@
6969
"undo" command, just in case the revert was a mistake.</p>
7070
7171
7272
<h2>Close the repository</h2>
7373
<p>fossil close</p>
74
-<p>This will simply remove the _FOSSIL_ at the root of the work directory but
75
-will not delete the files in the work directory. From then on, any use of &quot;fossil&quot;
74
+<p>This will simply remove the _FOSSIL_ at the root of the work directory but
75
+will not delete the files in the work directory. From then on, any use of &quot;fossil&quot;
7676
will trigger an error since there is no longer any connection.</p>
7777
--- www/fiveminutes.wiki
+++ www/fiveminutes.wiki
@@ -4,65 +4,65 @@
4 The following document was contributed by Gilles Ganault on 2013-01-08.
5 </i></b>
6 </p><hr>
7
8 <h1>Up and running in 5 minutes as a single user</h1>
9 <p>This short document explains the main basic Fossil commands for a single
10 user, i.e. with no additional users, with no need to synchronize with some remote
11 repository, and no need for branching/forking.</p>
12
13 <h2>Create a new repository</h2>
14 <p>fossil new c:\test.repo</p>
15 <p>This will create the new SQLite binary file that holds the repository, i.e.
16 files, tickets, wiki, etc. It can be located anywhere, although it's considered
17 best practice to keep it outside the work directory where you will work on files
18 after they've been checked out of the repository.</p>
19
20 <h2>Open the repository</h2>
21 <p>cd c:\temp\test.fossil</p>
22 <p>fossil open c:\test.repo</p>
23 <p>This will check out the last revision of all the files in the repository,
24 if any, into the current work directory. In addition, it will create a binary
25 file _FOSSIL_ to keep track of changes (on non-Windows systems it is called
26 <tt>.fslckout</tt>).</p>
27
28 <h2>Add new files</h2>
29 <p>fossil add .</p>
30 <p>To tell Fossil to add new files to the repository. The files aren't actually
31 added until you run &quot;commit&quot;. When using &quot;.&quot;, it tells Fossil
32 to add all the files in the current directory recursively, i.e. including all
33 the files in all the subdirectories.</p>
34 <p>Note: To tell Fossil to ignore some extensions:</p>
35 <p>fossil settings ignore-glob &quot;*.o,*.obj,*.exe&quot; --global</p>
36
37 <h2>Remove files that haven't been committed yet</h2>
38 <p>fossil delete myfile.c</p>
39 <p>This will simply remove the item from the list of files that were previously
40 added through &quot;fossil add&quot;.</p>
41
42 <h2>Check current status</h2>
43 <p>fossil changes</p>
44 <p>This shows the list of changes that have been done and will be committed the
45 next time you run &quot;fossil commit&quot;. It's a useful command to run before
46 running &quot;fossil commit&quot; just to check that things are OK before proceeding.</p>
47
48 <h2>Commit changes</h2>
49 <p>To actually apply the pending changes to the repository, e.g. new files marked
50 for addition, checked-out files that have been edited and must be checked-in,
51 etc.</p>
52
53 <p>fossil commit -m "Added stuff"</p>
54
55 If no file names are provided on the command-line then all changes will be checked in,
56 otherwise just the listed file(s) will be checked in.
57
58 <h2>Compare two revisions of a file</h2>
59 <p>If you wish to compare the last revision of a file and its checked out version
60 in your work directory:</p>
61 <p>fossil gdiff myfile.c</p>
62 <p>If you wish to compare two different revisions of a file in the repository:</p>
63 <p>fossil finfo myfile: Note the first hash, which is the UUID of the commit
64 when the file was committed</p>
65 <p>fossil gdiff --from UUID#1 --to UUID#2 myfile.c</p>
66 <h2>Cancel changes and go back to previous revision</h2>
67 <p>fossil revert myfile.c</p>
68 <p>Fossil does not prompt when reverting a file. It simply reminds the user about the
@@ -69,8 +69,8 @@
69 "undo" command, just in case the revert was a mistake.</p>
70
71
72 <h2>Close the repository</h2>
73 <p>fossil close</p>
74 <p>This will simply remove the _FOSSIL_ at the root of the work directory but
75 will not delete the files in the work directory. From then on, any use of &quot;fossil&quot;
76 will trigger an error since there is no longer any connection.</p>
77
--- www/fiveminutes.wiki
+++ www/fiveminutes.wiki
@@ -4,65 +4,65 @@
4 The following document was contributed by Gilles Ganault on 2013-01-08.
5 </i></b>
6 </p><hr>
7
8 <h1>Up and running in 5 minutes as a single user</h1>
9 <p>This short document explains the main basic Fossil commands for a single
10 user, i.e. with no additional users, with no need to synchronize with some remote
11 repository, and no need for branching/forking.</p>
12
13 <h2>Create a new repository</h2>
14 <p>fossil new c:\test.repo</p>
15 <p>This will create the new SQLite binary file that holds the repository, i.e.
16 files, tickets, wiki, etc. It can be located anywhere, although it's considered
17 best practice to keep it outside the work directory where you will work on files
18 after they've been checked out of the repository.</p>
19
20 <h2>Open the repository</h2>
21 <p>cd c:\temp\test.fossil</p>
22 <p>fossil open c:\test.repo</p>
23 <p>This will check out the last revision of all the files in the repository,
24 if any, into the current work directory. In addition, it will create a binary
25 file _FOSSIL_ to keep track of changes (on non-Windows systems it is called
26 <tt>.fslckout</tt>).</p>
27
28 <h2>Add new files</h2>
29 <p>fossil add .</p>
30 <p>To tell Fossil to add new files to the repository. The files aren't actually
31 added until you run &quot;commit&quot;. When using &quot;.&quot;, it tells Fossil
32 to add all the files in the current directory recursively, i.e. including all
33 the files in all the subdirectories.</p>
34 <p>Note: To tell Fossil to ignore some extensions:</p>
35 <p>fossil settings ignore-glob &quot;*.o,*.obj,*.exe&quot; --global</p>
36
37 <h2>Remove files that haven't been committed yet</h2>
38 <p>fossil delete myfile.c</p>
39 <p>This will simply remove the item from the list of files that were previously
40 added through &quot;fossil add&quot;.</p>
41
42 <h2>Check current status</h2>
43 <p>fossil changes</p>
44 <p>This shows the list of changes that have been done and will be committed the
45 next time you run &quot;fossil commit&quot;. It's a useful command to run before
46 running &quot;fossil commit&quot; just to check that things are OK before proceeding.</p>
47
48 <h2>Commit changes</h2>
49 <p>To actually apply the pending changes to the repository, e.g. new files marked
50 for addition, checked-out files that have been edited and must be checked-in,
51 etc.</p>
52
53 <p>fossil commit -m "Added stuff"</p>
54
55 If no file names are provided on the command-line then all changes will be checked in,
56 otherwise just the listed file(s) will be checked in.
57
58 <h2>Compare two revisions of a file</h2>
59 <p>If you wish to compare the last revision of a file and its checked out version
60 in your work directory:</p>
61 <p>fossil gdiff myfile.c</p>
62 <p>If you wish to compare two different revisions of a file in the repository:</p>
63 <p>fossil finfo myfile: Note the first hash, which is the UUID of the commit
64 when the file was committed</p>
65 <p>fossil gdiff --from UUID#1 --to UUID#2 myfile.c</p>
66 <h2>Cancel changes and go back to previous revision</h2>
67 <p>fossil revert myfile.c</p>
68 <p>Fossil does not prompt when reverting a file. It simply reminds the user about the
@@ -69,8 +69,8 @@
69 "undo" command, just in case the revert was a mistake.</p>
70
71
72 <h2>Close the repository</h2>
73 <p>fossil close</p>
74 <p>This will simply remove the _FOSSIL_ at the root of the work directory but
75 will not delete the files in the work directory. From then on, any use of &quot;fossil&quot;
76 will trigger an error since there is no longer any connection.</p>
77
--- www/foss-cklist.wiki
+++ www/foss-cklist.wiki
@@ -89,11 +89,11 @@
8989
9090
<li><p>The project has a website.
9191
9292
<li><p>Release version numbers are in the traditional X.Y or X.Y.Z format.
9393
94
-<li><p>Releases can be downloaded as tarball using
94
+<li><p>Releases can be downloaded as tarball using
9595
gzip or bzip2 compression.
9696
9797
<li><p>Releases unpack into a versioned top-level directory.
9898
(ex: "projectname-1.2.3/").
9999
@@ -102,12 +102,12 @@
102102
tarball.
103103
104104
<li><p>There are no incompatible licenses in the code.
105105
106106
<li><p>The project has not been blithely proclaimed "public domain" without
107
-having gone through the tedious and exacting legal steps to actually put it
107
+having gone through the tedious and exacting legal steps to actually put it
108108
in the public domain.
109109
110110
<li><p>There is an accurate change log in the code and on the website.
111111
112112
<li><p>There is documentation in the code and on the website.
113113
</ol>
114114
--- www/foss-cklist.wiki
+++ www/foss-cklist.wiki
@@ -89,11 +89,11 @@
89
90 <li><p>The project has a website.
91
92 <li><p>Release version numbers are in the traditional X.Y or X.Y.Z format.
93
94 <li><p>Releases can be downloaded as tarball using
95 gzip or bzip2 compression.
96
97 <li><p>Releases unpack into a versioned top-level directory.
98 (ex: "projectname-1.2.3/").
99
@@ -102,12 +102,12 @@
102 tarball.
103
104 <li><p>There are no incompatible licenses in the code.
105
106 <li><p>The project has not been blithely proclaimed "public domain" without
107 having gone through the tedious and exacting legal steps to actually put it
108 in the public domain.
109
110 <li><p>There is an accurate change log in the code and on the website.
111
112 <li><p>There is documentation in the code and on the website.
113 </ol>
114
--- www/foss-cklist.wiki
+++ www/foss-cklist.wiki
@@ -89,11 +89,11 @@
89
90 <li><p>The project has a website.
91
92 <li><p>Release version numbers are in the traditional X.Y or X.Y.Z format.
93
94 <li><p>Releases can be downloaded as tarball using
95 gzip or bzip2 compression.
96
97 <li><p>Releases unpack into a versioned top-level directory.
98 (ex: "projectname-1.2.3/").
99
@@ -102,12 +102,12 @@
102 tarball.
103
104 <li><p>There are no incompatible licenses in the code.
105
106 <li><p>The project has not been blithely proclaimed "public domain" without
107 having gone through the tedious and exacting legal steps to actually put it
108 in the public domain.
109
110 <li><p>There is an accurate change log in the code and on the website.
111
112 <li><p>There is documentation in the code and on the website.
113 </ol>
114
--- www/fossil-from-msvc.wiki
+++ www/fossil-from-msvc.wiki
@@ -11,41 +11,41 @@
1111
<li>Tools &gt; External Tools, where the items in this list map
1212
to "External Tool X" that we'll add to our own Fossil
1313
menu later: </li>
1414
<ol type="1">
1515
<li>Rename the default "&#91;New Tool 1&#93;" to eg.
16
- "Commit"&nbsp;&nbsp;&nbsp;2.
16
+ "Commit"&nbsp;&nbsp;&nbsp;2.
1717
</li>
1818
<li>Change Command to where Fossil is located eg.
1919
"c:\fossil.exe"</li>
2020
<li>Change Arguments to the required command, eg.
21
- "commit -m".
21
+ "commit -m".
2222
The user will be prompted to type the comment that Commit expects</li>
23
- <li>Set "Initial Directory" to point it to the work directory
23
+ <li>Set "Initial Directory" to point it to the work directory
2424
where the source files are currently checked out
2525
by Fossil (eg. c:\Workspace). It's also possible to use system
2626
variables such as "$(ProjectDir)" instead of hard-coding the path</li>
2727
<li>Check "Prompt for arguments", since Commit
2828
requires typing a comment. Useless for commands like Changes
2929
that don't require arguments</li>
30
- <li>Uncheck "Close on Exit", so we can see what Fossil says
31
- before closing the DOS box. Note that "Use Output Window"
32
- will display the output in a child window within the IDE instead of
30
+ <li>Uncheck "Close on Exit", so we can see what Fossil says
31
+ before closing the DOS box. Note that "Use Output Window"
32
+ will display the output in a child window within the IDE instead of
3333
opening a DOS box</li>
3434
<li>Click on OK</li>
3535
</ol>
3636
<li>Tools &gt; Customize &gt; Commands</li>
3737
<ol type="1">
38
- <li>With "Menu bar = Menu Bar" selected, click on "Add
38
+ <li>With "Menu bar = Menu Bar" selected, click on "Add
3939
New Menu". A new "Fossil" menu is displayed in the
4040
IDE's menu bar</li>
4141
<li>Click on "Modify Selection" to rename it
4242
"Fossil", and...</li>
4343
<li>Use the "Move Down" button to move it lower in
4444
the list</li>
4545
</ol>
46
- <li>Still in Customize dialog: In the "Menu bar" combo, select
47
- the new Fossil menu you just created, and Click on "Add Command...":
48
- From Categories, select Tools, and select "External Command 1".
49
- Click on Close. It's unfortunate that the IDE doesn't say which command
46
+ <li>Still in Customize dialog: In the "Menu bar" combo, select
47
+ the new Fossil menu you just created, and Click on "Add Command...":
48
+ From Categories, select Tools, and select "External Command 1".
49
+ Click on Close. It's unfortunate that the IDE doesn't say which command
5050
maps to "External Command X".</li>
5151
</ol>
5252
--- www/fossil-from-msvc.wiki
+++ www/fossil-from-msvc.wiki
@@ -11,41 +11,41 @@
11 <li>Tools &gt; External Tools, where the items in this list map
12 to "External Tool X" that we'll add to our own Fossil
13 menu later: </li>
14 <ol type="1">
15 <li>Rename the default "&#91;New Tool 1&#93;" to eg.
16 "Commit"&nbsp;&nbsp;&nbsp;2.
17 </li>
18 <li>Change Command to where Fossil is located eg.
19 "c:\fossil.exe"</li>
20 <li>Change Arguments to the required command, eg.
21 "commit -m".
22 The user will be prompted to type the comment that Commit expects</li>
23 <li>Set "Initial Directory" to point it to the work directory
24 where the source files are currently checked out
25 by Fossil (eg. c:\Workspace). It's also possible to use system
26 variables such as "$(ProjectDir)" instead of hard-coding the path</li>
27 <li>Check "Prompt for arguments", since Commit
28 requires typing a comment. Useless for commands like Changes
29 that don't require arguments</li>
30 <li>Uncheck "Close on Exit", so we can see what Fossil says
31 before closing the DOS box. Note that "Use Output Window"
32 will display the output in a child window within the IDE instead of
33 opening a DOS box</li>
34 <li>Click on OK</li>
35 </ol>
36 <li>Tools &gt; Customize &gt; Commands</li>
37 <ol type="1">
38 <li>With "Menu bar = Menu Bar" selected, click on "Add
39 New Menu". A new "Fossil" menu is displayed in the
40 IDE's menu bar</li>
41 <li>Click on "Modify Selection" to rename it
42 "Fossil", and...</li>
43 <li>Use the "Move Down" button to move it lower in
44 the list</li>
45 </ol>
46 <li>Still in Customize dialog: In the "Menu bar" combo, select
47 the new Fossil menu you just created, and Click on "Add Command...":
48 From Categories, select Tools, and select "External Command 1".
49 Click on Close. It's unfortunate that the IDE doesn't say which command
50 maps to "External Command X".</li>
51 </ol>
52
--- www/fossil-from-msvc.wiki
+++ www/fossil-from-msvc.wiki
@@ -11,41 +11,41 @@
11 <li>Tools &gt; External Tools, where the items in this list map
12 to "External Tool X" that we'll add to our own Fossil
13 menu later: </li>
14 <ol type="1">
15 <li>Rename the default "&#91;New Tool 1&#93;" to eg.
16 "Commit"&nbsp;&nbsp;&nbsp;2.
17 </li>
18 <li>Change Command to where Fossil is located eg.
19 "c:\fossil.exe"</li>
20 <li>Change Arguments to the required command, eg.
21 "commit -m".
22 The user will be prompted to type the comment that Commit expects</li>
23 <li>Set "Initial Directory" to point it to the work directory
24 where the source files are currently checked out
25 by Fossil (eg. c:\Workspace). It's also possible to use system
26 variables such as "$(ProjectDir)" instead of hard-coding the path</li>
27 <li>Check "Prompt for arguments", since Commit
28 requires typing a comment. Useless for commands like Changes
29 that don't require arguments</li>
30 <li>Uncheck "Close on Exit", so we can see what Fossil says
31 before closing the DOS box. Note that "Use Output Window"
32 will display the output in a child window within the IDE instead of
33 opening a DOS box</li>
34 <li>Click on OK</li>
35 </ol>
36 <li>Tools &gt; Customize &gt; Commands</li>
37 <ol type="1">
38 <li>With "Menu bar = Menu Bar" selected, click on "Add
39 New Menu". A new "Fossil" menu is displayed in the
40 IDE's menu bar</li>
41 <li>Click on "Modify Selection" to rename it
42 "Fossil", and...</li>
43 <li>Use the "Move Down" button to move it lower in
44 the list</li>
45 </ol>
46 <li>Still in Customize dialog: In the "Menu bar" combo, select
47 the new Fossil menu you just created, and Click on "Add Command...":
48 From Categories, select Tools, and select "External Command 1".
49 Click on Close. It's unfortunate that the IDE doesn't say which command
50 maps to "External Command X".</li>
51 </ol>
52
+2 -2
--- www/index.wiki
+++ www/index.wiki
@@ -2,11 +2,11 @@
22
33
<h3>What Is Fossil?</h3>
44
55
<div style='width:200px;float:right;border:2px solid #446979;padding:10px;margin:0px 10px;'>
66
<ul>
7
-<li> [http://www.fossil-scm.org/download.html | Download]
7
+<li> [/uv/download.html | Download]
88
<li> [./quickstart.wiki | Quick Start]
99
<li> [./build.wiki | Install]
1010
<li> [../COPYRIGHT-BSD2.txt | License]
1111
<li> [./faq.wiki | FAQ]
1212
<li> [./changes.wiki | Change Log]
@@ -38,11 +38,11 @@
3838
([./webpage-ex.md|examples]) designed to promote situational awareness.
3939
4040
This entire website is just a running instance of Fossil.
4141
The pages you see here are all [./wikitheory.wiki | wiki] or
4242
[./embeddeddoc.wiki | embedded documentation] or (in the case of
43
- the [/uv/download.html|download] page)
43
+ the [/uv/download.html|download] page)
4444
[./unvers.wiki | unversioned files].
4545
When you clone Fossil from one of its
4646
[./selfhost.wiki | self-hosting repositories],
4747
you get more than just source code - you get this entire website.
4848
4949
--- www/index.wiki
+++ www/index.wiki
@@ -2,11 +2,11 @@
2
3 <h3>What Is Fossil?</h3>
4
5 <div style='width:200px;float:right;border:2px solid #446979;padding:10px;margin:0px 10px;'>
6 <ul>
7 <li> [http://www.fossil-scm.org/download.html | Download]
8 <li> [./quickstart.wiki | Quick Start]
9 <li> [./build.wiki | Install]
10 <li> [../COPYRIGHT-BSD2.txt | License]
11 <li> [./faq.wiki | FAQ]
12 <li> [./changes.wiki | Change Log]
@@ -38,11 +38,11 @@
38 ([./webpage-ex.md|examples]) designed to promote situational awareness.
39
40 This entire website is just a running instance of Fossil.
41 The pages you see here are all [./wikitheory.wiki | wiki] or
42 [./embeddeddoc.wiki | embedded documentation] or (in the case of
43 the [/uv/download.html|download] page)
44 [./unvers.wiki | unversioned files].
45 When you clone Fossil from one of its
46 [./selfhost.wiki | self-hosting repositories],
47 you get more than just source code - you get this entire website.
48
49
--- www/index.wiki
+++ www/index.wiki
@@ -2,11 +2,11 @@
2
3 <h3>What Is Fossil?</h3>
4
5 <div style='width:200px;float:right;border:2px solid #446979;padding:10px;margin:0px 10px;'>
6 <ul>
7 <li> [/uv/download.html | Download]
8 <li> [./quickstart.wiki | Quick Start]
9 <li> [./build.wiki | Install]
10 <li> [../COPYRIGHT-BSD2.txt | License]
11 <li> [./faq.wiki | FAQ]
12 <li> [./changes.wiki | Change Log]
@@ -38,11 +38,11 @@
38 ([./webpage-ex.md|examples]) designed to promote situational awareness.
39
40 This entire website is just a running instance of Fossil.
41 The pages you see here are all [./wikitheory.wiki | wiki] or
42 [./embeddeddoc.wiki | embedded documentation] or (in the case of
43 the [/uv/download.html|download] page)
44 [./unvers.wiki | unversioned files].
45 When you clone Fossil from one of its
46 [./selfhost.wiki | self-hosting repositories],
47 you get more than just source code - you get this entire website.
48
49
+54 -15
--- www/inout.wiki
+++ www/inout.wiki
@@ -1,10 +1,10 @@
11
<title>Import And Export</title>
22
3
-Fossil has the ability to import and export repositories from and to
3
+Fossil has the ability to import and export repositories from and to
44
[http://git-scm.com/ | Git]. And since most other version control
5
-systems will also import/export from Git, that means that you can
5
+systems will also import/export from Git, that means that you can
66
import/export a Fossil repository to most version control systems using
77
Git as an intermediary.
88
99
<h2>Git → Fossil</h2>
1010
@@ -20,11 +20,11 @@
2020
command is the name of a new Fossil repository that is created to hold the Git
2121
content.
2222
2323
The --git option is not actually required. The git-fast-export file format
2424
is currently the only VCS interchange format that Fossil understands. But
25
-future versions of Fossil might be enhanced to understand other VCS
25
+future versions of Fossil might be enhanced to understand other VCS
2626
interchange formats, and so for compatibility, use of the
2727
--git option is recommended.
2828
2929
<h2>Fossil → Git</h2>
3030
@@ -43,21 +43,60 @@
4343
Note that the "fossil export --git" command only exports the versioned files.
4444
Tickets and wiki and events are not exported, since Git does not understand
4545
those concepts.
4646
4747
As with the "import" command, the --git option is not required
48
-since the git-fast-export file format is currently the only VCS interchange
48
+since the git-fast-export file format is currently the only VCS interchange
4949
format that Fossil will generate. However,
5050
future versions of Fossil might add the ability to generate other
51
-VCS interchange formats, and so for compatibility, the use of the --git
51
+VCS interchange formats, and so for compatibility, the use of the --git
5252
option recommended.
5353
54
-An anonymous user sends this comment:
55
-
56
-<blockquote>
57
-The main Fossil branch is called "trunk", while the main git branch is
58
-called "master". After you've exported your FOSSIL repo to git, you won't
59
-see any files and gitk will complain about a missing "HEAD". You can
60
-resolve this problem by merging "trunk" with "master"
61
-(first verify using git status that you are on the "master" branch):
62
-<tt>git merge trunk</tt>
63
-</blockquote>
54
+<h2>Bidirectional Synchronization</h2>
55
+Fossil also has the ability to synchronize with a Git repository via repeated
56
+imports and/or exports. To do this, it uses marks files to store a record of
57
+artifacts which are known by both Git and Fossil to exist at a given point in
58
+time.
59
+
60
+To illustrate, consider the example of a remote Fossil repository that a
61
+user wants to import into a local Git repository. First, the user would clone
62
+the remote repository and import it into a new Git repository:
63
+
64
+<blockquote><pre>
65
+fossil clone /path/to/remote/repo.fossil repo.fossil
66
+mkdir repo
67
+cd repo
68
+fossil open ../repo.fossil
69
+mkdir ../repo.git
70
+cd ../repo.git
71
+git init .
72
+fossil export --git --export-marks ../repo/fossil.marks \
73
+ ../repo.fossil | git fast-import \
74
+ --export-marks=../repo/git.marks
75
+</pre></blockquote>
76
+
77
+Once the import has completed, the user would need to <tt>git checkout
78
+trunk</tt>. At any point after this, new changes can be imported from the
79
+remote Fossil repository:
80
+
81
+<blockquote><pre>
82
+cd ../repo
83
+fossil pull
84
+cd ../repo.git
85
+fossil export --git --import-marks ../repo/fossil.marks \
86
+ --export-marks ../repo/fossil.marks \
87
+ ../repo.fossil | git fast-import \
88
+ --import-marks=../repo/git.marks \
89
+ --export-marks=../repo/git.marks
90
+</pre></blockquote>
91
+
92
+Changes in the Git repository can be exported to the Fossil repository and then
93
+pushed to the remote:
94
+
95
+<blockquote><pre>
96
+git fast-export --import-marks=../repo/git.marks \
97
+ --export-marks=../repo/git.marks --all | fossil import --git \
98
+ --incremental --import-marks ../repo/fossil.marks \
99
+ --export-marks ../repo/fossil.marks ../repo.fossil
100
+cd ../repo
101
+fossil push
102
+</pre></blockquote>
64103
--- www/inout.wiki
+++ www/inout.wiki
@@ -1,10 +1,10 @@
1 <title>Import And Export</title>
2
3 Fossil has the ability to import and export repositories from and to
4 [http://git-scm.com/ | Git]. And since most other version control
5 systems will also import/export from Git, that means that you can
6 import/export a Fossil repository to most version control systems using
7 Git as an intermediary.
8
9 <h2>Git → Fossil</h2>
10
@@ -20,11 +20,11 @@
20 command is the name of a new Fossil repository that is created to hold the Git
21 content.
22
23 The --git option is not actually required. The git-fast-export file format
24 is currently the only VCS interchange format that Fossil understands. But
25 future versions of Fossil might be enhanced to understand other VCS
26 interchange formats, and so for compatibility, use of the
27 --git option is recommended.
28
29 <h2>Fossil → Git</h2>
30
@@ -43,21 +43,60 @@
43 Note that the "fossil export --git" command only exports the versioned files.
44 Tickets and wiki and events are not exported, since Git does not understand
45 those concepts.
46
47 As with the "import" command, the --git option is not required
48 since the git-fast-export file format is currently the only VCS interchange
49 format that Fossil will generate. However,
50 future versions of Fossil might add the ability to generate other
51 VCS interchange formats, and so for compatibility, the use of the --git
52 option recommended.
53
54 An anonymous user sends this comment:
55
56 <blockquote>
57 The main Fossil branch is called "trunk", while the main git branch is
58 called "master". After you've exported your FOSSIL repo to git, you won't
59 see any files and gitk will complain about a missing "HEAD". You can
60 resolve this problem by merging "trunk" with "master"
61 (first verify using git status that you are on the "master" branch):
62 <tt>git merge trunk</tt>
63 </blockquote>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
--- www/inout.wiki
+++ www/inout.wiki
@@ -1,10 +1,10 @@
1 <title>Import And Export</title>
2
3 Fossil has the ability to import and export repositories from and to
4 [http://git-scm.com/ | Git]. And since most other version control
5 systems will also import/export from Git, that means that you can
6 import/export a Fossil repository to most version control systems using
7 Git as an intermediary.
8
9 <h2>Git → Fossil</h2>
10
@@ -20,11 +20,11 @@
20 command is the name of a new Fossil repository that is created to hold the Git
21 content.
22
23 The --git option is not actually required. The git-fast-export file format
24 is currently the only VCS interchange format that Fossil understands. But
25 future versions of Fossil might be enhanced to understand other VCS
26 interchange formats, and so for compatibility, use of the
27 --git option is recommended.
28
29 <h2>Fossil → Git</h2>
30
@@ -43,21 +43,60 @@
43 Note that the "fossil export --git" command only exports the versioned files.
44 Tickets and wiki and events are not exported, since Git does not understand
45 those concepts.
46
47 As with the "import" command, the --git option is not required
48 since the git-fast-export file format is currently the only VCS interchange
49 format that Fossil will generate. However,
50 future versions of Fossil might add the ability to generate other
51 VCS interchange formats, and so for compatibility, the use of the --git
52 option recommended.
53
54 <h2>Bidirectional Synchronization</h2>
55 Fossil also has the ability to synchronize with a Git repository via repeated
56 imports and/or exports. To do this, it uses marks files to store a record of
57 artifacts which are known by both Git and Fossil to exist at a given point in
58 time.
59
60 To illustrate, consider the example of a remote Fossil repository that a
61 user wants to import into a local Git repository. First, the user would clone
62 the remote repository and import it into a new Git repository:
63
64 <blockquote><pre>
65 fossil clone /path/to/remote/repo.fossil repo.fossil
66 mkdir repo
67 cd repo
68 fossil open ../repo.fossil
69 mkdir ../repo.git
70 cd ../repo.git
71 git init .
72 fossil export --git --export-marks ../repo/fossil.marks \
73 ../repo.fossil | git fast-import \
74 --export-marks=../repo/git.marks
75 </pre></blockquote>
76
77 Once the import has completed, the user would need to <tt>git checkout
78 trunk</tt>. At any point after this, new changes can be imported from the
79 remote Fossil repository:
80
81 <blockquote><pre>
82 cd ../repo
83 fossil pull
84 cd ../repo.git
85 fossil export --git --import-marks ../repo/fossil.marks \
86 --export-marks ../repo/fossil.marks \
87 ../repo.fossil | git fast-import \
88 --import-marks=../repo/git.marks \
89 --export-marks=../repo/git.marks
90 </pre></blockquote>
91
92 Changes in the Git repository can be exported to the Fossil repository and then
93 pushed to the remote:
94
95 <blockquote><pre>
96 git fast-export --import-marks=../repo/git.marks \
97 --export-marks=../repo/git.marks --all | fossil import --git \
98 --incremental --import-marks ../repo/fossil.marks \
99 --export-marks ../repo/fossil.marks ../repo.fossil
100 cd ../repo
101 fossil push
102 </pre></blockquote>
103
+13 -13
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -2,24 +2,24 @@
22
33
<h1>1.0 Introduction</h1>
44
55
The build process for Fossil is tricky in that the source code
66
needs to be processed by three different preprocessor programs
7
-before it is compiled. Most users will download a
7
+before it is compiled. Most users will download a
88
[http://www.fossil-scm.org/download.html | precompiled binary]
99
so this is of no consequence to them, and even those who
10
-want to compile the code themselves can use one of the
11
-[./build.wiki | existing makefiles].
10
+want to compile the code themselves can use one of the
11
+[./build.wiki | existing makefiles].
1212
So must people do not need to be concerned with the
1313
build complexities of Fossil. But hard-core developers who desire
1414
a deep understanding of how Fossil is put together can benefit
1515
from reviewing this article.
1616
1717
<a name="srctour"></a>
1818
<h1>2.0 Source Code Tour</h1>
1919
20
-The source code for Fossil is found in the
20
+The source code for Fossil is found in the
2121
[/dir?ci=trunk&name=src | src/] subdirectory of the
2222
source tree. The src/ subdirectory contains all code, including
2323
the code for the separate preprocessor programs.
2424
2525
Each preprocessor program is a separate C program implemented in
@@ -50,11 +50,11 @@
5050
The TH1 script engine is implemented using files:
5151
5252
7. th.c
5353
8. th.h
5454
55
-These two files are imports like the SQLite source files,
55
+These two files are imports like the SQLite source files,
5656
and so are not preprocessed.
5757
5858
The VERSION.h header file is generated from other information sources
5959
using a small program called:
6060
@@ -86,11 +86,11 @@
8686
8787
13. main.mk
8888
8989
The main.mk makefile is invoked from the Makefile in the top-level
9090
directory. The main.mk is generated by makemake.tcl and should not
91
-be hand edited. Other makefiles generated by makemake.tcl are in
91
+be hand edited. Other makefiles generated by makemake.tcl are in
9292
other subdirectories (currently all in the win/ subdirectory).
9393
9494
All the other files in the src/ subdirectory (79 files at the time of
9595
this writing) are C source code files that are subject to the
9696
preprocessing steps described below. In the sequel, we will call these
@@ -109,11 +109,11 @@
109109
(The "manifest" and "manifest.uuid" files are automatically generated and
110110
updated by Fossil itself. See the [/help/setting | fossil set manifest]
111111
command for additional information.)
112112
113113
The VERSION.h header file is generated by
114
-a C program: src/mkversion.c.
114
+a C program: src/mkversion.c.
115115
To run the VERSION.h generator, first compile the src/mkversion.c
116116
source file into a command-line program (named "mkversion.exe")
117117
then run:
118118
119119
<blockquote><pre>
@@ -126,11 +126,11 @@
126126
in the root of the source tree are the three arguments and
127127
the generated VERSION.h file appears on standard output.
128128
129129
The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
130130
The builtin_data.h file contains C-langauge byte-array definitions for
131
-the content of resource files used by Fossil. To generate the
131
+the content of resource files used by Fossil. To generate the
132132
builtin_data.h file, first compile the mkbuiltin.c program, then run:
133133
134134
<blockquote><pre>
135135
mkbuiltin.exe diff.tcl <i>OtherFiles...</i> &gt;builtin_data.h
136136
</pre></blockquote>
@@ -163,11 +163,11 @@
163163
Note that "src.c" in the above is a stand-in for the (79) regular source
164164
files of Fossil - all source files except for the exceptions described in
165165
section 2.0 above.
166166
167167
The output of the mkindex program is a header file that is #include-ed by
168
-the main.c source file during the final compilation step.
168
+the main.c source file during the final compilation step.
169169
170170
<h2>4.2 The translate preprocessor</h2>
171171
172172
The translate preprocessor looks for lines of source code that begin
173173
with "@" and converts those lines into string constants or (depending on
@@ -181,11 +181,11 @@
181181
</pre></blockquote>
182182
183183
In this case, the "src.c" file represents any single source file from the
184184
set of ordinary source files as described in section 2.0 above. Note that
185185
each source file is translated separately. By convention, the names of
186
-the translated source files are the names of the input sources with a
186
+the translated source files are the names of the input sources with a
187187
single "_" character at the end. But a new makefile can use any naming
188188
convention it wants - the "_" is not critical to the build process.
189189
190190
After being translated, the output files (the "src_.c" files) should be
191191
used for all subsequent preprocessing and compilation steps.
@@ -209,16 +209,16 @@
209209
<blockquote><pre>
210210
makeheaders src_.c:src.h sqlite3.h th.h VERSION.h
211211
</pre></blockquote>
212212
213213
In the example above the "src_.c" and "src.h" names represent all of the
214
-(79) ordinary C source files, each as a separate argument.
214
+(79) ordinary C source files, each as a separate argument.
215215
216216
<h1>5.0 Compilation</h1>
217217
218218
After all generated files have been created and all ordinary source files
219
-have been preprocessed, the generated and preprocessed files can be
219
+have been preprocessed, the generated and preprocessed files can be
220220
combined into a single executable using a C compiler. This can be done
221221
all at once, or each preprocessed source file can be compiled into a
222222
separate object code file and the resulting object code files linked
223223
together in a final step.
224224
@@ -247,11 +247,11 @@
247247
* -Dmain=sqlite3_main
248248
* -DSQLITE_OMIT_LOAD_EXTENSION=1
249249
250250
The "main()" routine in the shell must be changed into sqlite3_main()
251251
to prevent it from colliding with the real main() in Fossil, and to give
252
-Fossil an entry point to jump to when the
252
+Fossil an entry point to jump to when the
253253
[/help/sqlite3 | fossil sql] command is invoked.
254254
255255
All the other source code files can be compiled without any special
256256
options.
257257
258258
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -2,24 +2,24 @@
2
3 <h1>1.0 Introduction</h1>
4
5 The build process for Fossil is tricky in that the source code
6 needs to be processed by three different preprocessor programs
7 before it is compiled. Most users will download a
8 [http://www.fossil-scm.org/download.html | precompiled binary]
9 so this is of no consequence to them, and even those who
10 want to compile the code themselves can use one of the
11 [./build.wiki | existing makefiles].
12 So must people do not need to be concerned with the
13 build complexities of Fossil. But hard-core developers who desire
14 a deep understanding of how Fossil is put together can benefit
15 from reviewing this article.
16
17 <a name="srctour"></a>
18 <h1>2.0 Source Code Tour</h1>
19
20 The source code for Fossil is found in the
21 [/dir?ci=trunk&name=src | src/] subdirectory of the
22 source tree. The src/ subdirectory contains all code, including
23 the code for the separate preprocessor programs.
24
25 Each preprocessor program is a separate C program implemented in
@@ -50,11 +50,11 @@
50 The TH1 script engine is implemented using files:
51
52 7. th.c
53 8. th.h
54
55 These two files are imports like the SQLite source files,
56 and so are not preprocessed.
57
58 The VERSION.h header file is generated from other information sources
59 using a small program called:
60
@@ -86,11 +86,11 @@
86
87 13. main.mk
88
89 The main.mk makefile is invoked from the Makefile in the top-level
90 directory. The main.mk is generated by makemake.tcl and should not
91 be hand edited. Other makefiles generated by makemake.tcl are in
92 other subdirectories (currently all in the win/ subdirectory).
93
94 All the other files in the src/ subdirectory (79 files at the time of
95 this writing) are C source code files that are subject to the
96 preprocessing steps described below. In the sequel, we will call these
@@ -109,11 +109,11 @@
109 (The "manifest" and "manifest.uuid" files are automatically generated and
110 updated by Fossil itself. See the [/help/setting | fossil set manifest]
111 command for additional information.)
112
113 The VERSION.h header file is generated by
114 a C program: src/mkversion.c.
115 To run the VERSION.h generator, first compile the src/mkversion.c
116 source file into a command-line program (named "mkversion.exe")
117 then run:
118
119 <blockquote><pre>
@@ -126,11 +126,11 @@
126 in the root of the source tree are the three arguments and
127 the generated VERSION.h file appears on standard output.
128
129 The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
130 The builtin_data.h file contains C-langauge byte-array definitions for
131 the content of resource files used by Fossil. To generate the
132 builtin_data.h file, first compile the mkbuiltin.c program, then run:
133
134 <blockquote><pre>
135 mkbuiltin.exe diff.tcl <i>OtherFiles...</i> &gt;builtin_data.h
136 </pre></blockquote>
@@ -163,11 +163,11 @@
163 Note that "src.c" in the above is a stand-in for the (79) regular source
164 files of Fossil - all source files except for the exceptions described in
165 section 2.0 above.
166
167 The output of the mkindex program is a header file that is #include-ed by
168 the main.c source file during the final compilation step.
169
170 <h2>4.2 The translate preprocessor</h2>
171
172 The translate preprocessor looks for lines of source code that begin
173 with "@" and converts those lines into string constants or (depending on
@@ -181,11 +181,11 @@
181 </pre></blockquote>
182
183 In this case, the "src.c" file represents any single source file from the
184 set of ordinary source files as described in section 2.0 above. Note that
185 each source file is translated separately. By convention, the names of
186 the translated source files are the names of the input sources with a
187 single "_" character at the end. But a new makefile can use any naming
188 convention it wants - the "_" is not critical to the build process.
189
190 After being translated, the output files (the "src_.c" files) should be
191 used for all subsequent preprocessing and compilation steps.
@@ -209,16 +209,16 @@
209 <blockquote><pre>
210 makeheaders src_.c:src.h sqlite3.h th.h VERSION.h
211 </pre></blockquote>
212
213 In the example above the "src_.c" and "src.h" names represent all of the
214 (79) ordinary C source files, each as a separate argument.
215
216 <h1>5.0 Compilation</h1>
217
218 After all generated files have been created and all ordinary source files
219 have been preprocessed, the generated and preprocessed files can be
220 combined into a single executable using a C compiler. This can be done
221 all at once, or each preprocessed source file can be compiled into a
222 separate object code file and the resulting object code files linked
223 together in a final step.
224
@@ -247,11 +247,11 @@
247 * -Dmain=sqlite3_main
248 * -DSQLITE_OMIT_LOAD_EXTENSION=1
249
250 The "main()" routine in the shell must be changed into sqlite3_main()
251 to prevent it from colliding with the real main() in Fossil, and to give
252 Fossil an entry point to jump to when the
253 [/help/sqlite3 | fossil sql] command is invoked.
254
255 All the other source code files can be compiled without any special
256 options.
257
258
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -2,24 +2,24 @@
2
3 <h1>1.0 Introduction</h1>
4
5 The build process for Fossil is tricky in that the source code
6 needs to be processed by three different preprocessor programs
7 before it is compiled. Most users will download a
8 [http://www.fossil-scm.org/download.html | precompiled binary]
9 so this is of no consequence to them, and even those who
10 want to compile the code themselves can use one of the
11 [./build.wiki | existing makefiles].
12 So must people do not need to be concerned with the
13 build complexities of Fossil. But hard-core developers who desire
14 a deep understanding of how Fossil is put together can benefit
15 from reviewing this article.
16
17 <a name="srctour"></a>
18 <h1>2.0 Source Code Tour</h1>
19
20 The source code for Fossil is found in the
21 [/dir?ci=trunk&name=src | src/] subdirectory of the
22 source tree. The src/ subdirectory contains all code, including
23 the code for the separate preprocessor programs.
24
25 Each preprocessor program is a separate C program implemented in
@@ -50,11 +50,11 @@
50 The TH1 script engine is implemented using files:
51
52 7. th.c
53 8. th.h
54
55 These two files are imports like the SQLite source files,
56 and so are not preprocessed.
57
58 The VERSION.h header file is generated from other information sources
59 using a small program called:
60
@@ -86,11 +86,11 @@
86
87 13. main.mk
88
89 The main.mk makefile is invoked from the Makefile in the top-level
90 directory. The main.mk is generated by makemake.tcl and should not
91 be hand edited. Other makefiles generated by makemake.tcl are in
92 other subdirectories (currently all in the win/ subdirectory).
93
94 All the other files in the src/ subdirectory (79 files at the time of
95 this writing) are C source code files that are subject to the
96 preprocessing steps described below. In the sequel, we will call these
@@ -109,11 +109,11 @@
109 (The "manifest" and "manifest.uuid" files are automatically generated and
110 updated by Fossil itself. See the [/help/setting | fossil set manifest]
111 command for additional information.)
112
113 The VERSION.h header file is generated by
114 a C program: src/mkversion.c.
115 To run the VERSION.h generator, first compile the src/mkversion.c
116 source file into a command-line program (named "mkversion.exe")
117 then run:
118
119 <blockquote><pre>
@@ -126,11 +126,11 @@
126 in the root of the source tree are the three arguments and
127 the generated VERSION.h file appears on standard output.
128
129 The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
130 The builtin_data.h file contains C-langauge byte-array definitions for
131 the content of resource files used by Fossil. To generate the
132 builtin_data.h file, first compile the mkbuiltin.c program, then run:
133
134 <blockquote><pre>
135 mkbuiltin.exe diff.tcl <i>OtherFiles...</i> &gt;builtin_data.h
136 </pre></blockquote>
@@ -163,11 +163,11 @@
163 Note that "src.c" in the above is a stand-in for the (79) regular source
164 files of Fossil - all source files except for the exceptions described in
165 section 2.0 above.
166
167 The output of the mkindex program is a header file that is #include-ed by
168 the main.c source file during the final compilation step.
169
170 <h2>4.2 The translate preprocessor</h2>
171
172 The translate preprocessor looks for lines of source code that begin
173 with "@" and converts those lines into string constants or (depending on
@@ -181,11 +181,11 @@
181 </pre></blockquote>
182
183 In this case, the "src.c" file represents any single source file from the
184 set of ordinary source files as described in section 2.0 above. Note that
185 each source file is translated separately. By convention, the names of
186 the translated source files are the names of the input sources with a
187 single "_" character at the end. But a new makefile can use any naming
188 convention it wants - the "_" is not critical to the build process.
189
190 After being translated, the output files (the "src_.c" files) should be
191 used for all subsequent preprocessing and compilation steps.
@@ -209,16 +209,16 @@
209 <blockquote><pre>
210 makeheaders src_.c:src.h sqlite3.h th.h VERSION.h
211 </pre></blockquote>
212
213 In the example above the "src_.c" and "src.h" names represent all of the
214 (79) ordinary C source files, each as a separate argument.
215
216 <h1>5.0 Compilation</h1>
217
218 After all generated files have been created and all ordinary source files
219 have been preprocessed, the generated and preprocessed files can be
220 combined into a single executable using a C compiler. This can be done
221 all at once, or each preprocessed source file can be compiled into a
222 separate object code file and the resulting object code files linked
223 together in a final step.
224
@@ -247,11 +247,11 @@
247 * -Dmain=sqlite3_main
248 * -DSQLITE_OMIT_LOAD_EXTENSION=1
249
250 The "main()" routine in the shell must be changed into sqlite3_main()
251 to prevent it from colliding with the real main() in Fossil, and to give
252 Fossil an entry point to jump to when the
253 [/help/sqlite3 | fossil sql] command is invoked.
254
255 All the other source code files can be compiled without any special
256 options.
257
258
+48 -60
--- www/mkdownload.tcl
+++ www/mkdownload.tcl
@@ -1,41 +1,17 @@
11
#!/usr/bin/tclsh
22
#
3
-# Run this script to build the "download.html" page. Also generate
4
-# the fossil_download_checksums.html page.
3
+# Run this script to build and install the "download.html" page of
4
+# unversioned comment.
5
+#
6
+# Also generate the fossil_download_checksums.html page.
57
#
68
#
79
set out [open download.html w]
810
fconfigure $out -encoding utf-8 -translation lf
911
puts $out \
10
-{<!DOCTYPE html>
11
-<html>
12
- <head>
13
- <base href="https://www.fossil-scm.org/download.html" />
14
- <title>Fossil: Download</title>
15
- <link rel="alternate" type="application/rss+xml" title="RSS Feed"
16
- href="/fossil/timeline.rss" />
17
- <link rel="stylesheet" href="/fossil/style.css?default" type="text/css"
18
- media="screen" />
19
- </head>
20
-
21
- <body>
22
- <div class="header">
23
- <div class="title"><h1>Fossil</h1>Download</div>
24
- </div>
25
- <div class="mainmenu">
26
-<a href='/fossil/doc/trunk/www/index.wiki'>Home</a>
27
-<a href='/fossil/timeline?y=ci'>Timeline</a>
28
-<a href='/fossil/dir?ci=tip'>Code</a>
29
-<a href='/fossil/doc/trunk/www/permutedindex.html'>Docs</a>
30
-<a href='/fossil/brlist'>Branches</a>
31
-<a href='/fossil/ticket'>Tickets</a>
32
-<a href='/fossil/wiki'>Wiki</a>
33
-<a href='/download.html' class='active'>Download</a>
34
-</div>
35
-<div class="content">
36
-<p>
12
+{<div class='fossil-doc' data-title='Download Page'>
3713
3814
<center><font size=4>}
3915
puts $out \
4016
"<b>To install Fossil &rarr;</b> download the stand-alone executable"
4117
puts $out \
@@ -45,46 +21,57 @@
4521
<a href="http://download.opensuse.org/repositories/home:/rmax:/fossil/">
4622
here.</a>
4723
Cryptographic checksums for download files are
4824
<a href="http://www.hwaci.com/fossil_download_checksums.html">here</a>.
4925
</small></p>
50
-</center>
51
-
5226
<table cellpadding="10">
5327
}
5428
55
-# Find all all unique timestamps.
29
+# Find all unique timestamps.
5630
#
57
-foreach file [glob -nocomplain download/fossil-*.zip] {
58
- if {[regexp -- {-(\d\.\d+).zip$} $file all version]} {
31
+set in [open {|fossil uv list} rb]
32
+while {[gets $in line]>0} {
33
+ set fn [lindex $line 5]
34
+ set filesize($fn) [lindex $line 3]
35
+ if {[regexp -- {-(\d\.\d+)\.(tar\.gz|zip)$} $fn all version]} {
36
+ set filehash($fn) [lindex $line 1]
5937
set avers($version) 1
6038
}
6139
}
40
+close $in
41
+
42
+set vdate(1.36) 2016-10-24
43
+set vdate(1.35) 2016-06-14
44
+set vdate(1.34) 2016-11-02
6245
6346
# Do all versions from newest to oldest
6447
#
6548
foreach vers [lsort -decr -real [array names avers]] {
66
- set hr "/fossil/timeline?c=version-$vers;y=ci"
49
+ # set hr "../timeline?c=version-$vers;y=ci"
50
+ set v2 v[string map {. _} $vers]
51
+ set hr "../doc/trunk/www/changes.wiki#$v2"
6752
puts $out "<tr><td colspan=6 align=left><hr>"
68
- puts $out "<center><b><a href=\"$hr\">Version $vers</a></b></center>"
53
+ puts $out "<center><b><a href=\"$hr\">Version $vers</a>"
54
+ if {[info exists vdate($vers)]} {
55
+ set hr2 "../timeline?c=version-$vers&amp;y=ci"
56
+ puts $out " (<a href='$hr2'>$vdate($vers)</a>)"
57
+ }
58
+ puts $out "</b></center>"
6959
puts $out "</td></tr>"
7060
puts $out "<tr>"
7161
7262
foreach {prefix img desc} {
7363
fossil-linux-x86 linux.gif {Linux 3.x x86}
74
- fossil-macosx-x86 mac.gif {Mac 10.x x86}
64
+ fossil-macosx mac.gif {Mac 10.x x86}
7565
fossil-openbsd-x86 openbsd.gif {OpenBSD 5.x x86}
7666
fossil-w32 win32.gif {Windows}
7767
fossil-src src.gif {Source Tarball}
7868
} {
79
- set basename download/$prefix-$vers
80
- set filename $basename.tar.gz
81
- if {![file exists $basename.tar.gz]} {
82
- set filename $basename.zip
83
- }
84
- if {[file exists $filename]} {
85
- set size [file size $filename]
69
+ set glob download/$prefix*-$vers*
70
+ set filename [array names filesize $glob]
71
+ if {[info exists filesize($filename)]} {
72
+ set size [set filesize($filename)]
8673
set units bytes
8774
if {$size>1024*1024} {
8875
set size [format %.2f [expr {$size/(1024.0*1024.0)}]]
8976
set units MiB
9077
} elseif {$size>1024} {
@@ -97,26 +84,23 @@
9784
} else {
9885
puts $out "<td>&nbsp;</td>"
9986
}
10087
}
10188
puts $out "</tr>"
102
- if {[file exists download/releasenotes-$vers.html]} {
103
- puts $out "<tr><td colspan=6 align=left>"
104
- set rn [open download/releasenotes-$vers.html]
105
- fconfigure $rn -encoding utf-8
106
- puts $out "[read $rn]"
107
- close $rn
108
- puts $out "</td></tr>"
109
- }
89
+#
90
+# if {[info exists filesize(download/releasenotes-$vers.html)]} {
91
+# puts $out "<tr><td colspan=6 align=left>"
92
+# set rn [|open uv cat download/releasenotes-$vers.html]
93
+# fconfigure $rn -encoding utf-8
94
+# puts $out "[read $rn]"
95
+# close $rn
96
+# puts $out "</td></tr>"
97
+# }
11098
}
11199
puts $out "<tr><td colspan=5><hr></td></tr>"
112100
113
-puts $out {</table></div>
114
-</body>
115
-</html>
116
-}
117
-
101
+puts $out {</table></center></div>}
118102
close $out
119103
120104
# Generate the checksum page
121105
#
122106
set out [open fossil_download_checksums.html w]
@@ -128,11 +112,15 @@
128112
<p>The following table shows the SHA1 checksums for the precompiled
129113
binaries available on the
130114
<a href="/download.html">Fossil website</a>.</p>
131115
<pre>}
132116
133
-foreach file [lsort [glob -nocomplain download/fossil-*.zip]] {
134
- set sha1sum [lindex [exec sha1sum $file] 0]
135
- puts $out "$sha1sum [file tail $file]"
117
+foreach {line} [split [exec fossil sql "SELECT hash, name FROM unversioned\
118
+ WHERE name GLOB '*.tar.gz' OR\
119
+ name GLOB '*.zip'"] \n] {
120
+ set x [split $line |]
121
+ set hash [lindex $x 0]
122
+ set nm [file tail [lindex $x 1]]
123
+ puts $out "$hash $nm"
136124
}
137125
puts $out {</pre></body></html>}
138126
close $out
139127
--- www/mkdownload.tcl
+++ www/mkdownload.tcl
@@ -1,41 +1,17 @@
1 #!/usr/bin/tclsh
2 #
3 # Run this script to build the "download.html" page. Also generate
4 # the fossil_download_checksums.html page.
 
 
5 #
6 #
7 set out [open download.html w]
8 fconfigure $out -encoding utf-8 -translation lf
9 puts $out \
10 {<!DOCTYPE html>
11 <html>
12 <head>
13 <base href="https://www.fossil-scm.org/download.html" />
14 <title>Fossil: Download</title>
15 <link rel="alternate" type="application/rss+xml" title="RSS Feed"
16 href="/fossil/timeline.rss" />
17 <link rel="stylesheet" href="/fossil/style.css?default" type="text/css"
18 media="screen" />
19 </head>
20
21 <body>
22 <div class="header">
23 <div class="title"><h1>Fossil</h1>Download</div>
24 </div>
25 <div class="mainmenu">
26 <a href='/fossil/doc/trunk/www/index.wiki'>Home</a>
27 <a href='/fossil/timeline?y=ci'>Timeline</a>
28 <a href='/fossil/dir?ci=tip'>Code</a>
29 <a href='/fossil/doc/trunk/www/permutedindex.html'>Docs</a>
30 <a href='/fossil/brlist'>Branches</a>
31 <a href='/fossil/ticket'>Tickets</a>
32 <a href='/fossil/wiki'>Wiki</a>
33 <a href='/download.html' class='active'>Download</a>
34 </div>
35 <div class="content">
36 <p>
37
38 <center><font size=4>}
39 puts $out \
40 "<b>To install Fossil &rarr;</b> download the stand-alone executable"
41 puts $out \
@@ -45,46 +21,57 @@
45 <a href="http://download.opensuse.org/repositories/home:/rmax:/fossil/">
46 here.</a>
47 Cryptographic checksums for download files are
48 <a href="http://www.hwaci.com/fossil_download_checksums.html">here</a>.
49 </small></p>
50 </center>
51
52 <table cellpadding="10">
53 }
54
55 # Find all all unique timestamps.
56 #
57 foreach file [glob -nocomplain download/fossil-*.zip] {
58 if {[regexp -- {-(\d\.\d+).zip$} $file all version]} {
 
 
 
 
59 set avers($version) 1
60 }
61 }
 
 
 
 
 
62
63 # Do all versions from newest to oldest
64 #
65 foreach vers [lsort -decr -real [array names avers]] {
66 set hr "/fossil/timeline?c=version-$vers;y=ci"
 
 
67 puts $out "<tr><td colspan=6 align=left><hr>"
68 puts $out "<center><b><a href=\"$hr\">Version $vers</a></b></center>"
 
 
 
 
 
69 puts $out "</td></tr>"
70 puts $out "<tr>"
71
72 foreach {prefix img desc} {
73 fossil-linux-x86 linux.gif {Linux 3.x x86}
74 fossil-macosx-x86 mac.gif {Mac 10.x x86}
75 fossil-openbsd-x86 openbsd.gif {OpenBSD 5.x x86}
76 fossil-w32 win32.gif {Windows}
77 fossil-src src.gif {Source Tarball}
78 } {
79 set basename download/$prefix-$vers
80 set filename $basename.tar.gz
81 if {![file exists $basename.tar.gz]} {
82 set filename $basename.zip
83 }
84 if {[file exists $filename]} {
85 set size [file size $filename]
86 set units bytes
87 if {$size>1024*1024} {
88 set size [format %.2f [expr {$size/(1024.0*1024.0)}]]
89 set units MiB
90 } elseif {$size>1024} {
@@ -97,26 +84,23 @@
97 } else {
98 puts $out "<td>&nbsp;</td>"
99 }
100 }
101 puts $out "</tr>"
102 if {[file exists download/releasenotes-$vers.html]} {
103 puts $out "<tr><td colspan=6 align=left>"
104 set rn [open download/releasenotes-$vers.html]
105 fconfigure $rn -encoding utf-8
106 puts $out "[read $rn]"
107 close $rn
108 puts $out "</td></tr>"
109 }
 
110 }
111 puts $out "<tr><td colspan=5><hr></td></tr>"
112
113 puts $out {</table></div>
114 </body>
115 </html>
116 }
117
118 close $out
119
120 # Generate the checksum page
121 #
122 set out [open fossil_download_checksums.html w]
@@ -128,11 +112,15 @@
128 <p>The following table shows the SHA1 checksums for the precompiled
129 binaries available on the
130 <a href="/download.html">Fossil website</a>.</p>
131 <pre>}
132
133 foreach file [lsort [glob -nocomplain download/fossil-*.zip]] {
134 set sha1sum [lindex [exec sha1sum $file] 0]
135 puts $out "$sha1sum [file tail $file]"
 
 
 
 
136 }
137 puts $out {</pre></body></html>}
138 close $out
139
--- www/mkdownload.tcl
+++ www/mkdownload.tcl
@@ -1,41 +1,17 @@
1 #!/usr/bin/tclsh
2 #
3 # Run this script to build and install the "download.html" page of
4 # unversioned comment.
5 #
6 # Also generate the fossil_download_checksums.html page.
7 #
8 #
9 set out [open download.html w]
10 fconfigure $out -encoding utf-8 -translation lf
11 puts $out \
12 {<div class='fossil-doc' data-title='Download Page'>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
14 <center><font size=4>}
15 puts $out \
16 "<b>To install Fossil &rarr;</b> download the stand-alone executable"
17 puts $out \
@@ -45,46 +21,57 @@
21 <a href="http://download.opensuse.org/repositories/home:/rmax:/fossil/">
22 here.</a>
23 Cryptographic checksums for download files are
24 <a href="http://www.hwaci.com/fossil_download_checksums.html">here</a>.
25 </small></p>
 
 
26 <table cellpadding="10">
27 }
28
29 # Find all unique timestamps.
30 #
31 set in [open {|fossil uv list} rb]
32 while {[gets $in line]>0} {
33 set fn [lindex $line 5]
34 set filesize($fn) [lindex $line 3]
35 if {[regexp -- {-(\d\.\d+)\.(tar\.gz|zip)$} $fn all version]} {
36 set filehash($fn) [lindex $line 1]
37 set avers($version) 1
38 }
39 }
40 close $in
41
42 set vdate(1.36) 2016-10-24
43 set vdate(1.35) 2016-06-14
44 set vdate(1.34) 2016-11-02
45
46 # Do all versions from newest to oldest
47 #
48 foreach vers [lsort -decr -real [array names avers]] {
49 # set hr "../timeline?c=version-$vers;y=ci"
50 set v2 v[string map {. _} $vers]
51 set hr "../doc/trunk/www/changes.wiki#$v2"
52 puts $out "<tr><td colspan=6 align=left><hr>"
53 puts $out "<center><b><a href=\"$hr\">Version $vers</a>"
54 if {[info exists vdate($vers)]} {
55 set hr2 "../timeline?c=version-$vers&amp;y=ci"
56 puts $out " (<a href='$hr2'>$vdate($vers)</a>)"
57 }
58 puts $out "</b></center>"
59 puts $out "</td></tr>"
60 puts $out "<tr>"
61
62 foreach {prefix img desc} {
63 fossil-linux-x86 linux.gif {Linux 3.x x86}
64 fossil-macosx mac.gif {Mac 10.x x86}
65 fossil-openbsd-x86 openbsd.gif {OpenBSD 5.x x86}
66 fossil-w32 win32.gif {Windows}
67 fossil-src src.gif {Source Tarball}
68 } {
69 set glob download/$prefix*-$vers*
70 set filename [array names filesize $glob]
71 if {[info exists filesize($filename)]} {
72 set size [set filesize($filename)]
 
 
 
73 set units bytes
74 if {$size>1024*1024} {
75 set size [format %.2f [expr {$size/(1024.0*1024.0)}]]
76 set units MiB
77 } elseif {$size>1024} {
@@ -97,26 +84,23 @@
84 } else {
85 puts $out "<td>&nbsp;</td>"
86 }
87 }
88 puts $out "</tr>"
89 #
90 # if {[info exists filesize(download/releasenotes-$vers.html)]} {
91 # puts $out "<tr><td colspan=6 align=left>"
92 # set rn [|open uv cat download/releasenotes-$vers.html]
93 # fconfigure $rn -encoding utf-8
94 # puts $out "[read $rn]"
95 # close $rn
96 # puts $out "</td></tr>"
97 # }
98 }
99 puts $out "<tr><td colspan=5><hr></td></tr>"
100
101 puts $out {</table></center></div>}
 
 
 
 
102 close $out
103
104 # Generate the checksum page
105 #
106 set out [open fossil_download_checksums.html w]
@@ -128,11 +112,15 @@
112 <p>The following table shows the SHA1 checksums for the precompiled
113 binaries available on the
114 <a href="/download.html">Fossil website</a>.</p>
115 <pre>}
116
117 foreach {line} [split [exec fossil sql "SELECT hash, name FROM unversioned\
118 WHERE name GLOB '*.tar.gz' OR\
119 name GLOB '*.zip'"] \n] {
120 set x [split $line |]
121 set hash [lindex $x 0]
122 set nm [file tail [lindex $x 1]]
123 puts $out "$hash $nm"
124 }
125 puts $out {</pre></body></html>}
126 close $out
127
--- www/newrepo.wiki
+++ www/newrepo.wiki
@@ -53,11 +53,11 @@
5353
5454
<verbatim>
5555
stephan@ludo:~/fossil$ mkdir demo
5656
stephan@ludo:~/fossil$ cd demo
5757
stephan@ludo:~/fossil/demo$ fossil open ../demo.fossil
58
-stephan@ludo:~/fossil/demo$
58
+stephan@ludo:~/fossil/demo$
5959
</verbatim>
6060
6161
That creates a file called <tt>_FOSSIL_</tt> in the current
6262
directory, and this file contains all kinds of fossil-related
6363
information about your local repository. You can ignore it
6464
--- www/newrepo.wiki
+++ www/newrepo.wiki
@@ -53,11 +53,11 @@
53
54 <verbatim>
55 stephan@ludo:~/fossil$ mkdir demo
56 stephan@ludo:~/fossil$ cd demo
57 stephan@ludo:~/fossil/demo$ fossil open ../demo.fossil
58 stephan@ludo:~/fossil/demo$
59 </verbatim>
60
61 That creates a file called <tt>_FOSSIL_</tt> in the current
62 directory, and this file contains all kinds of fossil-related
63 information about your local repository. You can ignore it
64
--- www/newrepo.wiki
+++ www/newrepo.wiki
@@ -53,11 +53,11 @@
53
54 <verbatim>
55 stephan@ludo:~/fossil$ mkdir demo
56 stephan@ludo:~/fossil$ cd demo
57 stephan@ludo:~/fossil/demo$ fossil open ../demo.fossil
58 stephan@ludo:~/fossil/demo$
59 </verbatim>
60
61 That creates a file called <tt>_FOSSIL_</tt> in the current
62 directory, and this file contains all kinds of fossil-related
63 information about your local repository. You can ignore it
64
+5 -5
--- www/pop.wiki
+++ www/pop.wiki
@@ -4,18 +4,18 @@
44
This page attempts to define the foundational principals upon
55
which Fossil is built.
66
</p>
77
88
<ul>
9
-<li><p>A project consists of source files, wiki pages, and
9
+<li><p>A project consists of source files, wiki pages, and
1010
trouble tickets, and control files (collectively "artifacts").
1111
All historical copies of all artifacts
1212
are saved. The project maintains an audit
1313
trail.</p></li>
1414
1515
<li><p>A project resides in one or more repositories. Each
16
-repository is administered and operates independently
16
+repository is administered and operates independently
1717
of the others.</p></li>
1818
1919
<li><p>Each repository has both global and local state. The
2020
global state is common to all repositories (or at least
2121
has the potential to be shared in common when the
@@ -24,28 +24,28 @@
2424
The global state represents the content of the project.
2525
The local state identifies the authorized users and
2626
access policies for a particular repository.</p></li>
2727
2828
<li><p>The global state of a repository is an unordered
29
-collection of artifacts. Each artifact is named by
29
+collection of artifacts. Each artifact is named by
3030
its SHA1 hash encoded in lowercase hexadecimal.
3131
In many contexts, the name can be
3232
abbreviated to a unique prefix. A five- or six-character
3333
prefix usually suffices to uniquely identify a file.</p></li>
3434
3535
<li><p>Because artifacts are named by their SHA1 hash, all artifacts
36
-are immutable. Any change to the content of an artifact also
36
+are immutable. Any change to the content of an artifact also
3737
changes the hash that forms the artifacts name, thus
3838
creating a new artifact. Both the old original version of the
3939
artifact and the new change are preserved under different names.</p></li>
4040
4141
<li><p>It is theoretically possible for two artifacts with different
4242
content to share the same hash. But finding two such
4343
artifacts is so incredibly difficult and unlikely that we
4444
consider it to be an impossibility.</p></li>
4545
46
-<li><p>The signature of an artifact is the SHA1 hash of the
46
+<li><p>The signature of an artifact is the SHA1 hash of the
4747
artifact itself, exactly as it would appear in a disk file. No prefix
4848
or meta-information about the artifact is added before computing
4949
the hash. So you can
5050
always find the SHA1 signature of a file by using the
5151
"sha1sum" command-line utility.</p></li>
5252
--- www/pop.wiki
+++ www/pop.wiki
@@ -4,18 +4,18 @@
4 This page attempts to define the foundational principals upon
5 which Fossil is built.
6 </p>
7
8 <ul>
9 <li><p>A project consists of source files, wiki pages, and
10 trouble tickets, and control files (collectively "artifacts").
11 All historical copies of all artifacts
12 are saved. The project maintains an audit
13 trail.</p></li>
14
15 <li><p>A project resides in one or more repositories. Each
16 repository is administered and operates independently
17 of the others.</p></li>
18
19 <li><p>Each repository has both global and local state. The
20 global state is common to all repositories (or at least
21 has the potential to be shared in common when the
@@ -24,28 +24,28 @@
24 The global state represents the content of the project.
25 The local state identifies the authorized users and
26 access policies for a particular repository.</p></li>
27
28 <li><p>The global state of a repository is an unordered
29 collection of artifacts. Each artifact is named by
30 its SHA1 hash encoded in lowercase hexadecimal.
31 In many contexts, the name can be
32 abbreviated to a unique prefix. A five- or six-character
33 prefix usually suffices to uniquely identify a file.</p></li>
34
35 <li><p>Because artifacts are named by their SHA1 hash, all artifacts
36 are immutable. Any change to the content of an artifact also
37 changes the hash that forms the artifacts name, thus
38 creating a new artifact. Both the old original version of the
39 artifact and the new change are preserved under different names.</p></li>
40
41 <li><p>It is theoretically possible for two artifacts with different
42 content to share the same hash. But finding two such
43 artifacts is so incredibly difficult and unlikely that we
44 consider it to be an impossibility.</p></li>
45
46 <li><p>The signature of an artifact is the SHA1 hash of the
47 artifact itself, exactly as it would appear in a disk file. No prefix
48 or meta-information about the artifact is added before computing
49 the hash. So you can
50 always find the SHA1 signature of a file by using the
51 "sha1sum" command-line utility.</p></li>
52
--- www/pop.wiki
+++ www/pop.wiki
@@ -4,18 +4,18 @@
4 This page attempts to define the foundational principals upon
5 which Fossil is built.
6 </p>
7
8 <ul>
9 <li><p>A project consists of source files, wiki pages, and
10 trouble tickets, and control files (collectively "artifacts").
11 All historical copies of all artifacts
12 are saved. The project maintains an audit
13 trail.</p></li>
14
15 <li><p>A project resides in one or more repositories. Each
16 repository is administered and operates independently
17 of the others.</p></li>
18
19 <li><p>Each repository has both global and local state. The
20 global state is common to all repositories (or at least
21 has the potential to be shared in common when the
@@ -24,28 +24,28 @@
24 The global state represents the content of the project.
25 The local state identifies the authorized users and
26 access policies for a particular repository.</p></li>
27
28 <li><p>The global state of a repository is an unordered
29 collection of artifacts. Each artifact is named by
30 its SHA1 hash encoded in lowercase hexadecimal.
31 In many contexts, the name can be
32 abbreviated to a unique prefix. A five- or six-character
33 prefix usually suffices to uniquely identify a file.</p></li>
34
35 <li><p>Because artifacts are named by their SHA1 hash, all artifacts
36 are immutable. Any change to the content of an artifact also
37 changes the hash that forms the artifacts name, thus
38 creating a new artifact. Both the old original version of the
39 artifact and the new change are preserved under different names.</p></li>
40
41 <li><p>It is theoretically possible for two artifacts with different
42 content to share the same hash. But finding two such
43 artifacts is so incredibly difficult and unlikely that we
44 consider it to be an impossibility.</p></li>
45
46 <li><p>The signature of an artifact is the SHA1 hash of the
47 artifact itself, exactly as it would appear in a disk file. No prefix
48 or meta-information about the artifact is added before computing
49 the hash. So you can
50 always find the SHA1 signature of a file by using the
51 "sha1sum" command-line utility.</p></li>
52
--- www/private.wiki
+++ www/private.wiki
@@ -41,11 +41,11 @@
4141
<h2>Syncing Private Branches</h2>
4242
4343
A private branch normally stays on the one repository where it was
4444
originally created. But sometimes you want to share private branches
4545
with another repository. For example, you might be building a cross-platform
46
-application and have separate repositories on your Windows laptop,
46
+application and have separate repositories on your Windows laptop,
4747
your Linux desktop, and your iMac. You can transfer private branches
4848
between these machines by using the --private option on the "sync",
4949
"push", "pull", and "clone" commands. For example, if you are running
5050
"fossil server" on your Linux box and you want to clone that repository
5151
to your Mac, including all private branches, use:
@@ -67,11 +67,11 @@
6767
only enable "x" for local repositories when you need to share private
6868
branches.
6969
7070
Private branch sync only works if you use the --private command-line option.
7171
Private branches are never synced via the auto-sync mechanism. Once
72
-again, this restriction is designed to make it hard to accidently
72
+again, this restriction is designed to make it hard to accidently
7373
push private branches beyond their intended audience.
7474
7575
<h2>Purging Private Branches</h2>
7676
7777
You can remove all private branches from a repository using this command:
@@ -85,10 +85,10 @@
8585
removed, they cannot be retrieved (unless you have synced them to another
8686
repository.) So be careful with the command.
8787
8888
<h2>Additional Notes</h2>
8989
90
-All of the features above apply to <u>all</u> private branches in a
90
+All of the features above apply to <u>all</u> private branches in a
9191
single repository at once. There is no mechanism in Fossil (currently)
9292
that allows you to push, pull, clone, sync, or scrub and individual
9393
private branch within a repository that contains multiple private
9494
branches.
9595
--- www/private.wiki
+++ www/private.wiki
@@ -41,11 +41,11 @@
41 <h2>Syncing Private Branches</h2>
42
43 A private branch normally stays on the one repository where it was
44 originally created. But sometimes you want to share private branches
45 with another repository. For example, you might be building a cross-platform
46 application and have separate repositories on your Windows laptop,
47 your Linux desktop, and your iMac. You can transfer private branches
48 between these machines by using the --private option on the "sync",
49 "push", "pull", and "clone" commands. For example, if you are running
50 "fossil server" on your Linux box and you want to clone that repository
51 to your Mac, including all private branches, use:
@@ -67,11 +67,11 @@
67 only enable "x" for local repositories when you need to share private
68 branches.
69
70 Private branch sync only works if you use the --private command-line option.
71 Private branches are never synced via the auto-sync mechanism. Once
72 again, this restriction is designed to make it hard to accidently
73 push private branches beyond their intended audience.
74
75 <h2>Purging Private Branches</h2>
76
77 You can remove all private branches from a repository using this command:
@@ -85,10 +85,10 @@
85 removed, they cannot be retrieved (unless you have synced them to another
86 repository.) So be careful with the command.
87
88 <h2>Additional Notes</h2>
89
90 All of the features above apply to <u>all</u> private branches in a
91 single repository at once. There is no mechanism in Fossil (currently)
92 that allows you to push, pull, clone, sync, or scrub and individual
93 private branch within a repository that contains multiple private
94 branches.
95
--- www/private.wiki
+++ www/private.wiki
@@ -41,11 +41,11 @@
41 <h2>Syncing Private Branches</h2>
42
43 A private branch normally stays on the one repository where it was
44 originally created. But sometimes you want to share private branches
45 with another repository. For example, you might be building a cross-platform
46 application and have separate repositories on your Windows laptop,
47 your Linux desktop, and your iMac. You can transfer private branches
48 between these machines by using the --private option on the "sync",
49 "push", "pull", and "clone" commands. For example, if you are running
50 "fossil server" on your Linux box and you want to clone that repository
51 to your Mac, including all private branches, use:
@@ -67,11 +67,11 @@
67 only enable "x" for local repositories when you need to share private
68 branches.
69
70 Private branch sync only works if you use the --private command-line option.
71 Private branches are never synced via the auto-sync mechanism. Once
72 again, this restriction is designed to make it hard to accidently
73 push private branches beyond their intended audience.
74
75 <h2>Purging Private Branches</h2>
76
77 You can remove all private branches from a repository using this command:
@@ -85,10 +85,10 @@
85 removed, they cannot be retrieved (unless you have synced them to another
86 repository.) So be careful with the command.
87
88 <h2>Additional Notes</h2>
89
90 All of the features above apply to <u>all</u> private branches in a
91 single repository at once. There is no mechanism in Fossil (currently)
92 that allows you to push, pull, clone, sync, or scrub and individual
93 private branch within a repository that contains multiple private
94 branches.
95
+10 -10
--- www/qandc.wiki
+++ www/qandc.wiki
@@ -22,11 +22,11 @@
2222
<li> Integrated <a href="wikitheory.wiki">wiki</a>. </li>
2323
<li> Integrated <a href="bugtheory.wiki">bug tracking</a> </li>
2424
<li> Immutable artifacts </li>
2525
<li> Self-contained, stand-alone executable that can be run in
2626
a <a href="http://en.wikipedia.org/wiki/Chroot">chroot jail</a> </li>
27
- <li> Simple, well-defined,
27
+ <li> Simple, well-defined,
2828
<a href="fileformat.wiki">enduring file format</a> </li>
2929
<li> Integrated <a href="webui.wiki">web interface</a> </li>
3030
</ol>
3131
</blockquote>
3232
@@ -36,11 +36,11 @@
3636
<ol>
3737
<li> Fossil is distributed. You can view and/or edit tickets, wiki, and
3838
code while off network, then sync your changes later. With Trac, you
3939
can only view and edit tickets and wiki while you are connected to
4040
the server. </li>
41
- <li> Fossil is lightweight and fully self-contained. It is very easy
41
+ <li> Fossil is lightweight and fully self-contained. It is very easy
4242
to setup on a low-resource machine. Fossil does not require an
4343
administrator.</li>
4444
<li> Fossil integrates code versioning into the same repository with
4545
wiki and tickets. There is nothing extra to add or install.
4646
Fossil is an all-in-one turnkey solution. </li>
@@ -48,25 +48,25 @@
4848
</blockquote>
4949
5050
<b>Love the concept here. Anyone using this for real work yet?</b>
5151
5252
<blockquote>
53
-Fossil is <a href="http://www.fossil-scm.org/">self-hosting</a>.
53
+Fossil is <a href="http://www.fossil-scm.org/">self-hosting</a>.
5454
In fact, this page was probably delivered
5555
to your web-browser via a working fossil instance. The same virtual
5656
machine that hosts http://www.fossil-scm.org/
5757
(a <a href="http://www.linode.com/">Linode 720</a>)
5858
also hosts 24 other fossil repositories for various small projects.
59
-The documentation files for
59
+The documentation files for
6060
<a href="http://www.sqlite.org/">SQLite</a> are hosted in a
6161
fossil repository <a href="http://www.sqlite.org/docsrc/">here</a>,
6262
for example.
6363
Other projects are also adopting fossil. But fossil does not yet have
6464
the massive user base of git or mercurial.
6565
</blockquote>
6666
67
-<b>Fossil looks like the bug tracker that would be in your
67
+<b>Fossil looks like the bug tracker that would be in your
6868
Linksys Router's administration screen.</b>
6969
7070
<blockquote>
7171
<p>I take a pragmatic approach to software: form follows function.
7272
To me, it is more important to have a reliable, fast, efficient,
@@ -83,11 +83,11 @@
8383
keeps the bug-tracking database in a versioned file. That file can
8484
then be pushed and pulled along with the rest repository.</b>
8585
8686
<blockquote>
8787
<p>Fossil already <u>does</u> push and pull bugs along with the files
88
-in your repository.
88
+in your repository.
8989
But fossil does <u>not</u> track bugs as files in the source tree.
9090
That approach to bug tracking was rejected for three reasons:</p>
9191
9292
<ol>
9393
<li> Check-ins in fossil are immutable. So if
@@ -108,11 +108,11 @@
108108
109109
<p>These points are reiterated in the opening paragraphs of
110110
the <a href="bugtheory.wiki">Bug-Tracking In Fossil</a> document.</p>
111111
</blockquote>
112112
113
-<b>Fossil is already the name of a plan9 versioned
113
+<b>Fossil is already the name of a plan9 versioned
114114
append-only filesystem.</b>
115115
116116
<blockquote>
117117
I did not know that. Perhaps they selected the name for the same reason that
118118
I did: because a repository with immutable artifacts preserves
@@ -137,22 +137,22 @@
137137
Subversion or Bazaar.</b>
138138
139139
<blockquote>
140140
<p>I have no doubt that Trac has many features that fossil lacks. But that
141141
is not the point. Fossil has several key features that Trac lacks and that
142
-I need: most notably the fact that
142
+I need: most notably the fact that
143143
fossil supports disconnected operation.</p>
144144
145145
<p>As for bloat: Fossil is a single self-contained executable.
146
-You do not need any other packages
146
+You do not need any other packages
147147
(diff, patch, merge, cvs, svn, rcs, git, python, perl, tcl, apache,
148148
sqlite, and so forth)
149149
in order to run fossil. Fossil runs just fine in a chroot jail all
150150
by itself. And the self-contained fossil
151151
executable is much less than 1MB in size. (Update 2015-01-12: Fossil has
152
-grown in the years since the previous sentence was written but is still
152
+grown in the years since the previous sentence was written but is still
153153
much less than 2MB according to "size" when compiled using -Os on x64 Linux.)
154154
Fossil is the very opposite of bloat.</p>
155155
</blockquote>
156156
157157
158158
</nowiki>
159159
--- www/qandc.wiki
+++ www/qandc.wiki
@@ -22,11 +22,11 @@
22 <li> Integrated <a href="wikitheory.wiki">wiki</a>. </li>
23 <li> Integrated <a href="bugtheory.wiki">bug tracking</a> </li>
24 <li> Immutable artifacts </li>
25 <li> Self-contained, stand-alone executable that can be run in
26 a <a href="http://en.wikipedia.org/wiki/Chroot">chroot jail</a> </li>
27 <li> Simple, well-defined,
28 <a href="fileformat.wiki">enduring file format</a> </li>
29 <li> Integrated <a href="webui.wiki">web interface</a> </li>
30 </ol>
31 </blockquote>
32
@@ -36,11 +36,11 @@
36 <ol>
37 <li> Fossil is distributed. You can view and/or edit tickets, wiki, and
38 code while off network, then sync your changes later. With Trac, you
39 can only view and edit tickets and wiki while you are connected to
40 the server. </li>
41 <li> Fossil is lightweight and fully self-contained. It is very easy
42 to setup on a low-resource machine. Fossil does not require an
43 administrator.</li>
44 <li> Fossil integrates code versioning into the same repository with
45 wiki and tickets. There is nothing extra to add or install.
46 Fossil is an all-in-one turnkey solution. </li>
@@ -48,25 +48,25 @@
48 </blockquote>
49
50 <b>Love the concept here. Anyone using this for real work yet?</b>
51
52 <blockquote>
53 Fossil is <a href="http://www.fossil-scm.org/">self-hosting</a>.
54 In fact, this page was probably delivered
55 to your web-browser via a working fossil instance. The same virtual
56 machine that hosts http://www.fossil-scm.org/
57 (a <a href="http://www.linode.com/">Linode 720</a>)
58 also hosts 24 other fossil repositories for various small projects.
59 The documentation files for
60 <a href="http://www.sqlite.org/">SQLite</a> are hosted in a
61 fossil repository <a href="http://www.sqlite.org/docsrc/">here</a>,
62 for example.
63 Other projects are also adopting fossil. But fossil does not yet have
64 the massive user base of git or mercurial.
65 </blockquote>
66
67 <b>Fossil looks like the bug tracker that would be in your
68 Linksys Router's administration screen.</b>
69
70 <blockquote>
71 <p>I take a pragmatic approach to software: form follows function.
72 To me, it is more important to have a reliable, fast, efficient,
@@ -83,11 +83,11 @@
83 keeps the bug-tracking database in a versioned file. That file can
84 then be pushed and pulled along with the rest repository.</b>
85
86 <blockquote>
87 <p>Fossil already <u>does</u> push and pull bugs along with the files
88 in your repository.
89 But fossil does <u>not</u> track bugs as files in the source tree.
90 That approach to bug tracking was rejected for three reasons:</p>
91
92 <ol>
93 <li> Check-ins in fossil are immutable. So if
@@ -108,11 +108,11 @@
108
109 <p>These points are reiterated in the opening paragraphs of
110 the <a href="bugtheory.wiki">Bug-Tracking In Fossil</a> document.</p>
111 </blockquote>
112
113 <b>Fossil is already the name of a plan9 versioned
114 append-only filesystem.</b>
115
116 <blockquote>
117 I did not know that. Perhaps they selected the name for the same reason that
118 I did: because a repository with immutable artifacts preserves
@@ -137,22 +137,22 @@
137 Subversion or Bazaar.</b>
138
139 <blockquote>
140 <p>I have no doubt that Trac has many features that fossil lacks. But that
141 is not the point. Fossil has several key features that Trac lacks and that
142 I need: most notably the fact that
143 fossil supports disconnected operation.</p>
144
145 <p>As for bloat: Fossil is a single self-contained executable.
146 You do not need any other packages
147 (diff, patch, merge, cvs, svn, rcs, git, python, perl, tcl, apache,
148 sqlite, and so forth)
149 in order to run fossil. Fossil runs just fine in a chroot jail all
150 by itself. And the self-contained fossil
151 executable is much less than 1MB in size. (Update 2015-01-12: Fossil has
152 grown in the years since the previous sentence was written but is still
153 much less than 2MB according to "size" when compiled using -Os on x64 Linux.)
154 Fossil is the very opposite of bloat.</p>
155 </blockquote>
156
157
158 </nowiki>
159
--- www/qandc.wiki
+++ www/qandc.wiki
@@ -22,11 +22,11 @@
22 <li> Integrated <a href="wikitheory.wiki">wiki</a>. </li>
23 <li> Integrated <a href="bugtheory.wiki">bug tracking</a> </li>
24 <li> Immutable artifacts </li>
25 <li> Self-contained, stand-alone executable that can be run in
26 a <a href="http://en.wikipedia.org/wiki/Chroot">chroot jail</a> </li>
27 <li> Simple, well-defined,
28 <a href="fileformat.wiki">enduring file format</a> </li>
29 <li> Integrated <a href="webui.wiki">web interface</a> </li>
30 </ol>
31 </blockquote>
32
@@ -36,11 +36,11 @@
36 <ol>
37 <li> Fossil is distributed. You can view and/or edit tickets, wiki, and
38 code while off network, then sync your changes later. With Trac, you
39 can only view and edit tickets and wiki while you are connected to
40 the server. </li>
41 <li> Fossil is lightweight and fully self-contained. It is very easy
42 to setup on a low-resource machine. Fossil does not require an
43 administrator.</li>
44 <li> Fossil integrates code versioning into the same repository with
45 wiki and tickets. There is nothing extra to add or install.
46 Fossil is an all-in-one turnkey solution. </li>
@@ -48,25 +48,25 @@
48 </blockquote>
49
50 <b>Love the concept here. Anyone using this for real work yet?</b>
51
52 <blockquote>
53 Fossil is <a href="http://www.fossil-scm.org/">self-hosting</a>.
54 In fact, this page was probably delivered
55 to your web-browser via a working fossil instance. The same virtual
56 machine that hosts http://www.fossil-scm.org/
57 (a <a href="http://www.linode.com/">Linode 720</a>)
58 also hosts 24 other fossil repositories for various small projects.
59 The documentation files for
60 <a href="http://www.sqlite.org/">SQLite</a> are hosted in a
61 fossil repository <a href="http://www.sqlite.org/docsrc/">here</a>,
62 for example.
63 Other projects are also adopting fossil. But fossil does not yet have
64 the massive user base of git or mercurial.
65 </blockquote>
66
67 <b>Fossil looks like the bug tracker that would be in your
68 Linksys Router's administration screen.</b>
69
70 <blockquote>
71 <p>I take a pragmatic approach to software: form follows function.
72 To me, it is more important to have a reliable, fast, efficient,
@@ -83,11 +83,11 @@
83 keeps the bug-tracking database in a versioned file. That file can
84 then be pushed and pulled along with the rest repository.</b>
85
86 <blockquote>
87 <p>Fossil already <u>does</u> push and pull bugs along with the files
88 in your repository.
89 But fossil does <u>not</u> track bugs as files in the source tree.
90 That approach to bug tracking was rejected for three reasons:</p>
91
92 <ol>
93 <li> Check-ins in fossil are immutable. So if
@@ -108,11 +108,11 @@
108
109 <p>These points are reiterated in the opening paragraphs of
110 the <a href="bugtheory.wiki">Bug-Tracking In Fossil</a> document.</p>
111 </blockquote>
112
113 <b>Fossil is already the name of a plan9 versioned
114 append-only filesystem.</b>
115
116 <blockquote>
117 I did not know that. Perhaps they selected the name for the same reason that
118 I did: because a repository with immutable artifacts preserves
@@ -137,22 +137,22 @@
137 Subversion or Bazaar.</b>
138
139 <blockquote>
140 <p>I have no doubt that Trac has many features that fossil lacks. But that
141 is not the point. Fossil has several key features that Trac lacks and that
142 I need: most notably the fact that
143 fossil supports disconnected operation.</p>
144
145 <p>As for bloat: Fossil is a single self-contained executable.
146 You do not need any other packages
147 (diff, patch, merge, cvs, svn, rcs, git, python, perl, tcl, apache,
148 sqlite, and so forth)
149 in order to run fossil. Fossil runs just fine in a chroot jail all
150 by itself. And the self-contained fossil
151 executable is much less than 1MB in size. (Update 2015-01-12: Fossil has
152 grown in the years since the previous sentence was written but is still
153 much less than 2MB according to "size" when compiled using -Os on x64 Linux.)
154 Fossil is the very opposite of bloat.</p>
155 </blockquote>
156
157
158 </nowiki>
159
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -5,16 +5,16 @@
55
and painlessly.</p>
66
77
<h2>Installing</h2>
88
99
<p>Fossil is a single self-contained C program. You need to
10
- either download a
10
+ either download a
1111
<a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
1212
or <a href="build.wiki">compile it yourself</a> from sources.
1313
Install fossil by putting the fossil binary
1414
someplace on your $PATH.</p>
15
-
15
+
1616
<a name="fslclone"></a>
1717
<h2>General Work Flow</h2>
1818
1919
<p>Fossil works with repository files (a database with the project's
2020
complete history) and with checked-out local trees (the working directory
@@ -34,11 +34,11 @@
3434
3535
<h2>Starting A New Project</h2>
3636
3737
<p>To start a new project with fossil, create a new empty repository
3838
this way: ([/help/init | more info]) </p>
39
-
39
+
4040
<blockquote>
4141
<b>fossil init </b><i> repository-filename</i>
4242
</blockquote>
4343
4444
<h2>Cloning An Existing Repository</h2>
@@ -46,36 +46,36 @@
4646
<p>Most fossil operations interact with a repository that is on the
4747
local disk drive, not on a remote system. Hence, before accessing
4848
a remote repository it is necessary to make a local copy of that
4949
repository. Making a local copy of a remote repository is called
5050
"cloning".</p>
51
-
51
+
5252
<p>Clone a remote repository as follows: ([/help/clone | more info])</p>
53
-
53
+
5454
<blockquote>
5555
<b>fossil clone</b> <i>URL repository-filename</i>
5656
</blockquote>
57
-
57
+
5858
<p>The <i>URL</i> specifies the fossil repository
5959
you want to clone. The <i>repository-filename</i> is the new local
6060
filename into which the cloned repository will be written. For
6161
example:
62
-
62
+
6363
<blockquote>
6464
<b>fossil clone http://www.fossil-scm.org/ myclone.fossil</b>
6565
</blockquote>
6666
67
- <p>If the remote repository requires a login, include a
67
+ <p>If the remote repository requires a login, include a
6868
userid in the URL like this:
6969
7070
<blockquote>
7171
<b>fossil clone http://</b><i>userid</i><b>@www.fossil-scm.org/ myclone.fossil</b>
7272
</blockquote>
73
-
73
+
7474
7575
<p>You will be prompted separately for the password.
76
- Use "%HH" escapes for special characters in the userid.
76
+ Use "%HH" escapes for special characters in the userid.
7777
Examples: "%40" in place of "@" and "%2F" in place of "/".
7878
7979
<p>If you are behind a restrictive firewall, you might need
8080
to <a href="#proxy">specify an HTTP proxy</a>.</p>
8181
@@ -85,31 +85,31 @@
8585
information above and beyond the versioned files, including some
8686
sensitive information such as password hashes and email addresses. If you
8787
want to share Fossil repositories directly, consider running the
8888
[/help/scrub|fossil scrub] command to remove sensitive information
8989
before transmitting the file.
90
-
90
+
9191
<h2>Importing From Another Version Control System</h2>
9292
9393
<p>Rather than start a new project, or clone an existing Fossil project,
94
- you might prefer to
94
+ you might prefer to
9595
<a href="./inout.wiki">import an existing Git project</a>
9696
into Fossil using the [/help/import | fossil import] command.
9797
9898
<h2>Checking Out A Local Tree</h2>
9999
100100
<p>To work on a project in fossil, you need to check out a local
101101
copy of the source tree. Create the directory you want to be
102102
the root of your tree and cd into that directory. Then
103103
do this: ([/help/open | more info])</p>
104
-
104
+
105105
<blockquote>
106106
<b>fossil open </b><i> repository-filename</i>
107107
</blockquote>
108
-
108
+
109109
<p>This leaves you with the newest version of the tree
110
- checked out.
110
+ checked out.
111111
From anywhere underneath the root of your local tree, you
112112
can type commands like the following to find out the status of
113113
your local tree:</p>
114114
115115
<blockquote>
@@ -122,11 +122,11 @@
122122
<b>[/help/branch | fossil branch]</b><br>
123123
</blockquote>
124124
125125
<p>Note that Fossil allows you to make multiple check-outs in
126126
separate directories from the same repository. This enables you,
127
- for example, to do builds from multiple branches or versions at
127
+ for example, to do builds from multiple branches or versions at
128128
the same time without having to generate extra clones.</p>
129129
130130
<p>To switch a checkout between different versions and branches,
131131
use:</p>
132132
@@ -140,17 +140,17 @@
140140
version, whereas [/help/checkout | checkout] does not
141141
automatically sync and does a "hard" switch, overwriting local
142142
changes if told to do so.</p>
143143
144144
<h2>Configuring Your Local Repository</h2>
145
-
145
+
146146
<p>When you create a new repository, either by cloning an existing
147147
project or create a new project of your own, you usually want to do some
148148
local configuration. This is easily accomplished using the web-server
149149
that is built into fossil. Start the fossil webserver like this:
150150
([/help/ui | more info])</p>
151
-
151
+
152152
<blockquote>
153153
<b>fossil ui </b><i> repository-filename</i>
154154
</blockquote>
155155
156156
<p>You can omit the <i>repository-filename</i> from the command above
@@ -163,15 +163,15 @@
163163
where to find your web browser using a command like this:</p>
164164
165165
<blockquote>
166166
<b>fossil setting web-browser </b><i> path-to-web-browser</i>
167167
</blockquote>
168
-
168
+
169169
<p>By default, fossil does not require a login for HTTP connections
170170
coming in from the IP loopback address 127.0.0.1. You can, and perhaps
171171
should, change this after you create a few users.</p>
172
-
172
+
173173
<p>When you are finished configuring, just press Control-C or use
174174
the <b>kill</b> command to shut down the mini-server.</p>
175175
176176
<h2>Making Changes</h2>
177177
@@ -194,18 +194,18 @@
194194
<p>You will be prompted for check-in comments using whatever editor
195195
is specified by your VISUAL or EDITOR environment variable.</p>
196196
197197
In the default configuration, the [/help/commit|commit]
198198
command will also automatically [/help/push|push] your changes, but that
199
- feature can be disabled. (More information about
199
+ feature can be disabled. (More information about
200200
[./concepts.wiki#workflow|autosync] and how to disable it.)
201
- Remember that your coworkers can not see your changes until you
201
+ Remember that your coworkers can not see your changes until you
202202
commit and push them.</p>
203203
204204
<h2>Sharing Changes</h2>
205205
206
- <p>When [./concepts.wiki#workflow|autosync] is turned off,
206
+ <p>When [./concepts.wiki#workflow|autosync] is turned off,
207207
the changes you [/help/commit | commit] are only
208208
on your local repository.
209209
To share those changes with other repositories, do:</p>
210210
211211
<blockquote>
@@ -241,11 +241,11 @@
241241
the <i>VERSION</i>, then fossil moves you to the
242242
latest version of the branch your are currently on.</p>
243243
244244
<p>The default behavior is for [./concepts.wiki#workflow|autosync] to
245245
be turned on. That means that a [/help/pull|pull] automatically occurs
246
- when you run [/help/update|update] and a [/help/push|push] happens
246
+ when you run [/help/update|update] and a [/help/push|push] happens
247247
automatically after you [/help/commit|commit]. So in normal practice,
248248
the push, pull, and sync commands are rarely used. But it is important
249249
to know about them, all the same.</p>
250250
251251
<blockquote>
@@ -342,11 +342,11 @@
342342
<li>[./server.wiki#cgi|CGI]
343343
<li>[./server.wiki#scgi|SCGI]
344344
</ul>
345345
346346
<p>The [./selfhost.wiki | self-hosting fossil repositories] use
347
- CGI.
347
+ CGI.
348348
349349
<a name="proxy"></a>
350350
<h2>HTTP Proxies</h2>
351351
352352
<p>If you are behind a restrictive firewall that requires you to use
@@ -382,11 +382,11 @@
382382
<p>Or unset the environment variable. The fossil setting for the
383383
HTTP proxy takes precedence over the environment variable and the
384384
command-line option overrides both. If you have an persistent
385385
proxy setting that you want to override for a one-time sync, that
386386
is easily done on the command-line. For example, to sync with
387
- a co-workers repository on your LAN, you might type:</p>
387
+ a co-workers repository on your LAN, you might type:</p>
388388
389389
<blockquote>
390390
<b>fossil sync http://192.168.1.36:8080/ --proxy off</b>
391391
</blockquote>
392392
393393
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -5,16 +5,16 @@
5 and painlessly.</p>
6
7 <h2>Installing</h2>
8
9 <p>Fossil is a single self-contained C program. You need to
10 either download a
11 <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
12 or <a href="build.wiki">compile it yourself</a> from sources.
13 Install fossil by putting the fossil binary
14 someplace on your $PATH.</p>
15
16 <a name="fslclone"></a>
17 <h2>General Work Flow</h2>
18
19 <p>Fossil works with repository files (a database with the project's
20 complete history) and with checked-out local trees (the working directory
@@ -34,11 +34,11 @@
34
35 <h2>Starting A New Project</h2>
36
37 <p>To start a new project with fossil, create a new empty repository
38 this way: ([/help/init | more info]) </p>
39
40 <blockquote>
41 <b>fossil init </b><i> repository-filename</i>
42 </blockquote>
43
44 <h2>Cloning An Existing Repository</h2>
@@ -46,36 +46,36 @@
46 <p>Most fossil operations interact with a repository that is on the
47 local disk drive, not on a remote system. Hence, before accessing
48 a remote repository it is necessary to make a local copy of that
49 repository. Making a local copy of a remote repository is called
50 "cloning".</p>
51
52 <p>Clone a remote repository as follows: ([/help/clone | more info])</p>
53
54 <blockquote>
55 <b>fossil clone</b> <i>URL repository-filename</i>
56 </blockquote>
57
58 <p>The <i>URL</i> specifies the fossil repository
59 you want to clone. The <i>repository-filename</i> is the new local
60 filename into which the cloned repository will be written. For
61 example:
62
63 <blockquote>
64 <b>fossil clone http://www.fossil-scm.org/ myclone.fossil</b>
65 </blockquote>
66
67 <p>If the remote repository requires a login, include a
68 userid in the URL like this:
69
70 <blockquote>
71 <b>fossil clone http://</b><i>userid</i><b>@www.fossil-scm.org/ myclone.fossil</b>
72 </blockquote>
73
74
75 <p>You will be prompted separately for the password.
76 Use "%HH" escapes for special characters in the userid.
77 Examples: "%40" in place of "@" and "%2F" in place of "/".
78
79 <p>If you are behind a restrictive firewall, you might need
80 to <a href="#proxy">specify an HTTP proxy</a>.</p>
81
@@ -85,31 +85,31 @@
85 information above and beyond the versioned files, including some
86 sensitive information such as password hashes and email addresses. If you
87 want to share Fossil repositories directly, consider running the
88 [/help/scrub|fossil scrub] command to remove sensitive information
89 before transmitting the file.
90
91 <h2>Importing From Another Version Control System</h2>
92
93 <p>Rather than start a new project, or clone an existing Fossil project,
94 you might prefer to
95 <a href="./inout.wiki">import an existing Git project</a>
96 into Fossil using the [/help/import | fossil import] command.
97
98 <h2>Checking Out A Local Tree</h2>
99
100 <p>To work on a project in fossil, you need to check out a local
101 copy of the source tree. Create the directory you want to be
102 the root of your tree and cd into that directory. Then
103 do this: ([/help/open | more info])</p>
104
105 <blockquote>
106 <b>fossil open </b><i> repository-filename</i>
107 </blockquote>
108
109 <p>This leaves you with the newest version of the tree
110 checked out.
111 From anywhere underneath the root of your local tree, you
112 can type commands like the following to find out the status of
113 your local tree:</p>
114
115 <blockquote>
@@ -122,11 +122,11 @@
122 <b>[/help/branch | fossil branch]</b><br>
123 </blockquote>
124
125 <p>Note that Fossil allows you to make multiple check-outs in
126 separate directories from the same repository. This enables you,
127 for example, to do builds from multiple branches or versions at
128 the same time without having to generate extra clones.</p>
129
130 <p>To switch a checkout between different versions and branches,
131 use:</p>
132
@@ -140,17 +140,17 @@
140 version, whereas [/help/checkout | checkout] does not
141 automatically sync and does a "hard" switch, overwriting local
142 changes if told to do so.</p>
143
144 <h2>Configuring Your Local Repository</h2>
145
146 <p>When you create a new repository, either by cloning an existing
147 project or create a new project of your own, you usually want to do some
148 local configuration. This is easily accomplished using the web-server
149 that is built into fossil. Start the fossil webserver like this:
150 ([/help/ui | more info])</p>
151
152 <blockquote>
153 <b>fossil ui </b><i> repository-filename</i>
154 </blockquote>
155
156 <p>You can omit the <i>repository-filename</i> from the command above
@@ -163,15 +163,15 @@
163 where to find your web browser using a command like this:</p>
164
165 <blockquote>
166 <b>fossil setting web-browser </b><i> path-to-web-browser</i>
167 </blockquote>
168
169 <p>By default, fossil does not require a login for HTTP connections
170 coming in from the IP loopback address 127.0.0.1. You can, and perhaps
171 should, change this after you create a few users.</p>
172
173 <p>When you are finished configuring, just press Control-C or use
174 the <b>kill</b> command to shut down the mini-server.</p>
175
176 <h2>Making Changes</h2>
177
@@ -194,18 +194,18 @@
194 <p>You will be prompted for check-in comments using whatever editor
195 is specified by your VISUAL or EDITOR environment variable.</p>
196
197 In the default configuration, the [/help/commit|commit]
198 command will also automatically [/help/push|push] your changes, but that
199 feature can be disabled. (More information about
200 [./concepts.wiki#workflow|autosync] and how to disable it.)
201 Remember that your coworkers can not see your changes until you
202 commit and push them.</p>
203
204 <h2>Sharing Changes</h2>
205
206 <p>When [./concepts.wiki#workflow|autosync] is turned off,
207 the changes you [/help/commit | commit] are only
208 on your local repository.
209 To share those changes with other repositories, do:</p>
210
211 <blockquote>
@@ -241,11 +241,11 @@
241 the <i>VERSION</i>, then fossil moves you to the
242 latest version of the branch your are currently on.</p>
243
244 <p>The default behavior is for [./concepts.wiki#workflow|autosync] to
245 be turned on. That means that a [/help/pull|pull] automatically occurs
246 when you run [/help/update|update] and a [/help/push|push] happens
247 automatically after you [/help/commit|commit]. So in normal practice,
248 the push, pull, and sync commands are rarely used. But it is important
249 to know about them, all the same.</p>
250
251 <blockquote>
@@ -342,11 +342,11 @@
342 <li>[./server.wiki#cgi|CGI]
343 <li>[./server.wiki#scgi|SCGI]
344 </ul>
345
346 <p>The [./selfhost.wiki | self-hosting fossil repositories] use
347 CGI.
348
349 <a name="proxy"></a>
350 <h2>HTTP Proxies</h2>
351
352 <p>If you are behind a restrictive firewall that requires you to use
@@ -382,11 +382,11 @@
382 <p>Or unset the environment variable. The fossil setting for the
383 HTTP proxy takes precedence over the environment variable and the
384 command-line option overrides both. If you have an persistent
385 proxy setting that you want to override for a one-time sync, that
386 is easily done on the command-line. For example, to sync with
387 a co-workers repository on your LAN, you might type:</p>
388
389 <blockquote>
390 <b>fossil sync http://192.168.1.36:8080/ --proxy off</b>
391 </blockquote>
392
393
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -5,16 +5,16 @@
5 and painlessly.</p>
6
7 <h2>Installing</h2>
8
9 <p>Fossil is a single self-contained C program. You need to
10 either download a
11 <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
12 or <a href="build.wiki">compile it yourself</a> from sources.
13 Install fossil by putting the fossil binary
14 someplace on your $PATH.</p>
15
16 <a name="fslclone"></a>
17 <h2>General Work Flow</h2>
18
19 <p>Fossil works with repository files (a database with the project's
20 complete history) and with checked-out local trees (the working directory
@@ -34,11 +34,11 @@
34
35 <h2>Starting A New Project</h2>
36
37 <p>To start a new project with fossil, create a new empty repository
38 this way: ([/help/init | more info]) </p>
39
40 <blockquote>
41 <b>fossil init </b><i> repository-filename</i>
42 </blockquote>
43
44 <h2>Cloning An Existing Repository</h2>
@@ -46,36 +46,36 @@
46 <p>Most fossil operations interact with a repository that is on the
47 local disk drive, not on a remote system. Hence, before accessing
48 a remote repository it is necessary to make a local copy of that
49 repository. Making a local copy of a remote repository is called
50 "cloning".</p>
51
52 <p>Clone a remote repository as follows: ([/help/clone | more info])</p>
53
54 <blockquote>
55 <b>fossil clone</b> <i>URL repository-filename</i>
56 </blockquote>
57
58 <p>The <i>URL</i> specifies the fossil repository
59 you want to clone. The <i>repository-filename</i> is the new local
60 filename into which the cloned repository will be written. For
61 example:
62
63 <blockquote>
64 <b>fossil clone http://www.fossil-scm.org/ myclone.fossil</b>
65 </blockquote>
66
67 <p>If the remote repository requires a login, include a
68 userid in the URL like this:
69
70 <blockquote>
71 <b>fossil clone http://</b><i>userid</i><b>@www.fossil-scm.org/ myclone.fossil</b>
72 </blockquote>
73
74
75 <p>You will be prompted separately for the password.
76 Use "%HH" escapes for special characters in the userid.
77 Examples: "%40" in place of "@" and "%2F" in place of "/".
78
79 <p>If you are behind a restrictive firewall, you might need
80 to <a href="#proxy">specify an HTTP proxy</a>.</p>
81
@@ -85,31 +85,31 @@
85 information above and beyond the versioned files, including some
86 sensitive information such as password hashes and email addresses. If you
87 want to share Fossil repositories directly, consider running the
88 [/help/scrub|fossil scrub] command to remove sensitive information
89 before transmitting the file.
90
91 <h2>Importing From Another Version Control System</h2>
92
93 <p>Rather than start a new project, or clone an existing Fossil project,
94 you might prefer to
95 <a href="./inout.wiki">import an existing Git project</a>
96 into Fossil using the [/help/import | fossil import] command.
97
98 <h2>Checking Out A Local Tree</h2>
99
100 <p>To work on a project in fossil, you need to check out a local
101 copy of the source tree. Create the directory you want to be
102 the root of your tree and cd into that directory. Then
103 do this: ([/help/open | more info])</p>
104
105 <blockquote>
106 <b>fossil open </b><i> repository-filename</i>
107 </blockquote>
108
109 <p>This leaves you with the newest version of the tree
110 checked out.
111 From anywhere underneath the root of your local tree, you
112 can type commands like the following to find out the status of
113 your local tree:</p>
114
115 <blockquote>
@@ -122,11 +122,11 @@
122 <b>[/help/branch | fossil branch]</b><br>
123 </blockquote>
124
125 <p>Note that Fossil allows you to make multiple check-outs in
126 separate directories from the same repository. This enables you,
127 for example, to do builds from multiple branches or versions at
128 the same time without having to generate extra clones.</p>
129
130 <p>To switch a checkout between different versions and branches,
131 use:</p>
132
@@ -140,17 +140,17 @@
140 version, whereas [/help/checkout | checkout] does not
141 automatically sync and does a "hard" switch, overwriting local
142 changes if told to do so.</p>
143
144 <h2>Configuring Your Local Repository</h2>
145
146 <p>When you create a new repository, either by cloning an existing
147 project or create a new project of your own, you usually want to do some
148 local configuration. This is easily accomplished using the web-server
149 that is built into fossil. Start the fossil webserver like this:
150 ([/help/ui | more info])</p>
151
152 <blockquote>
153 <b>fossil ui </b><i> repository-filename</i>
154 </blockquote>
155
156 <p>You can omit the <i>repository-filename</i> from the command above
@@ -163,15 +163,15 @@
163 where to find your web browser using a command like this:</p>
164
165 <blockquote>
166 <b>fossil setting web-browser </b><i> path-to-web-browser</i>
167 </blockquote>
168
169 <p>By default, fossil does not require a login for HTTP connections
170 coming in from the IP loopback address 127.0.0.1. You can, and perhaps
171 should, change this after you create a few users.</p>
172
173 <p>When you are finished configuring, just press Control-C or use
174 the <b>kill</b> command to shut down the mini-server.</p>
175
176 <h2>Making Changes</h2>
177
@@ -194,18 +194,18 @@
194 <p>You will be prompted for check-in comments using whatever editor
195 is specified by your VISUAL or EDITOR environment variable.</p>
196
197 In the default configuration, the [/help/commit|commit]
198 command will also automatically [/help/push|push] your changes, but that
199 feature can be disabled. (More information about
200 [./concepts.wiki#workflow|autosync] and how to disable it.)
201 Remember that your coworkers can not see your changes until you
202 commit and push them.</p>
203
204 <h2>Sharing Changes</h2>
205
206 <p>When [./concepts.wiki#workflow|autosync] is turned off,
207 the changes you [/help/commit | commit] are only
208 on your local repository.
209 To share those changes with other repositories, do:</p>
210
211 <blockquote>
@@ -241,11 +241,11 @@
241 the <i>VERSION</i>, then fossil moves you to the
242 latest version of the branch your are currently on.</p>
243
244 <p>The default behavior is for [./concepts.wiki#workflow|autosync] to
245 be turned on. That means that a [/help/pull|pull] automatically occurs
246 when you run [/help/update|update] and a [/help/push|push] happens
247 automatically after you [/help/commit|commit]. So in normal practice,
248 the push, pull, and sync commands are rarely used. But it is important
249 to know about them, all the same.</p>
250
251 <blockquote>
@@ -342,11 +342,11 @@
342 <li>[./server.wiki#cgi|CGI]
343 <li>[./server.wiki#scgi|SCGI]
344 </ul>
345
346 <p>The [./selfhost.wiki | self-hosting fossil repositories] use
347 CGI.
348
349 <a name="proxy"></a>
350 <h2>HTTP Proxies</h2>
351
352 <p>If you are behind a restrictive firewall that requires you to use
@@ -382,11 +382,11 @@
382 <p>Or unset the environment variable. The fossil setting for the
383 HTTP proxy takes precedence over the environment variable and the
384 command-line option overrides both. If you have an persistent
385 proxy setting that you want to override for a one-time sync, that
386 is easily done on the command-line. For example, to sync with
387 a co-workers repository on your LAN, you might type:</p>
388
389 <blockquote>
390 <b>fossil sync http://192.168.1.36:8080/ --proxy off</b>
391 </blockquote>
392
393
+13 -13
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -5,19 +5,19 @@
55
by the creator of Fossil, so of course there is selection bias...
66
77
<h2>On The Usability Of Git:</h2>
88
99
<ol>
10
-<li>Git approaches the usability of iptables, which is to say, utterly
10
+<li>Git approaches the usability of iptables, which is to say, utterly
1111
unusable unless you have the manpage tattooed on you arm.
1212
1313
<blockquote>
1414
<i>by mml at [http://news.ycombinator.com/item?id=1433387]</i>
1515
</blockquote>
1616
1717
<li><nowiki>It's simplest to think of the state of your [git] repository
18
-as a point in a high-dimensional "code-space", in which branches are
18
+as a point in a high-dimensional "code-space", in which branches are
1919
represented as n-dimensional membranes, mapping the spatial loci of
2020
successive commits onto the projected manifold of each cloned
2121
repository.</nowiki>
2222
2323
<blockquote>
@@ -25,11 +25,11 @@
2525
</blockquote>
2626
2727
<li>Git is not a Prius. Git is a Model T.
2828
Its plumbing and wiring sticks out all over the place.
2929
You have to be a mechanic to operate it successfully or you'll be
30
-stuck on the side of the road when it breaks down.
30
+stuck on the side of the road when it breaks down.
3131
And it <b>will</b> break down.
3232
3333
<blockquote>
3434
<i>Nick Farina at [http://nfarina.com/post/9868516270/git-is-simpler]</i>
3535
</blockquote>
@@ -39,11 +39,11 @@
3939
<blockquote>
4040
<i>Linus Torvalds - 2005-04-07 22:13:13<br>
4141
Commit comment on the very first source-code check-in for git
4242
</blockquote>
4343
44
-<li>I've been experimenting a lot with git at work.
44
+<li>I've been experimenting a lot with git at work.
4545
Damn, it's complicated.
4646
It has things to trip you up with that sane people just wouldn't ever both with
4747
including the ability to allow you to commit stuff in such a way that you can't find
4848
it again afterwards (!!!)
4949
Demented workflow complexity on acid?
@@ -104,19 +104,19 @@
104104
105105
<blockquote>
106106
<i>Joe Prostko at [http://www.mail-archive.com/[email protected]/msg16716.html]
107107
</blockquote>
108108
109
-<li>Fossil is awesome!!! I have never seen an app like that before,
109
+<li>Fossil is awesome!!! I have never seen an app like that before,
110110
such simplicity and flexibility!!!
111111
112112
<blockquote>
113113
<i>zengr at [http://stackoverflow.com/questions/138621/best-version-control-for-lone-developer]</i>
114114
</blockquote>
115115
116116
<li>This is my favourite VCS. I can carry it on a USB. And it's a complete system, with it's own
117
-server, ticketing system, Wiki pages, and a very, very helpful timeline visualization. And
117
+server, ticketing system, Wiki pages, and a very, very helpful timeline visualization. And
118118
the entire program in a single file!
119119
120120
<blockquote>
121121
<i>thunderbong commenting on hacker news: [https://news.ycombinator.com/item?id=9131619]</i>
122122
</blockquote>
@@ -127,30 +127,30 @@
127127
128128
<h2>On Git Versus Fossil</h2>
129129
130130
<ol>
131131
<li value=15>
132
-Just want to say thanks for fossil making my life easier....
132
+Just want to say thanks for fossil making my life easier....
133133
Also <nowiki>[for]</nowiki> not having a misanthropic command line interface.
134134
135135
<blockquote>
136136
<i>Joshua Paine at [http://www.mail-archive.com/[email protected]/msg02736.html]</i>
137137
</blockquote>
138138
139139
<li>We use it at a large university to manage code that small teams write.
140
-The runs everywhere, ease of installation and portability is something that
141
-seems to be a good fit with the environment we have (highly ditrobuted,
142
-sometimes very restrictive firewalls, OSX/Win/Linux). We are happy with it
143
-and teaching a Msc/Phd student (read complete novice) fossil has just
140
+The runs everywhere, ease of installation and portability is something that
141
+seems to be a good fit with the environment we have (highly ditrobuted,
142
+sometimes very restrictive firewalls, OSX/Win/Linux). We are happy with it
143
+and teaching a Msc/Phd student (read complete novice) fossil has just
144144
been a smoother ride than Git was.
145145
146146
<blockquote>
147147
<i>viablepanic at [http://www.reddit.com/r/programming/comments/bxcto/why_not_fossil_scm/]</i>
148148
</blockquote>
149149
150
-<li>In the fossil community - and hence in fossil itself - development history
151
-is pretty much sacrosanct. The very name "fossil" was to chosen to
150
+<li>In the fossil community - and hence in fossil itself - development history
151
+is pretty much sacrosanct. The very name "fossil" was to chosen to
152152
reflect the unchanging nature of things in that history.
153153
154154
<p>In git (or rather, the git community), the development history is part of
155155
the published aspect of the project, so it provides tools for rearranging
156156
that history so you can present what you "should" have done rather
157157
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -5,19 +5,19 @@
5 by the creator of Fossil, so of course there is selection bias...
6
7 <h2>On The Usability Of Git:</h2>
8
9 <ol>
10 <li>Git approaches the usability of iptables, which is to say, utterly
11 unusable unless you have the manpage tattooed on you arm.
12
13 <blockquote>
14 <i>by mml at [http://news.ycombinator.com/item?id=1433387]</i>
15 </blockquote>
16
17 <li><nowiki>It's simplest to think of the state of your [git] repository
18 as a point in a high-dimensional "code-space", in which branches are
19 represented as n-dimensional membranes, mapping the spatial loci of
20 successive commits onto the projected manifold of each cloned
21 repository.</nowiki>
22
23 <blockquote>
@@ -25,11 +25,11 @@
25 </blockquote>
26
27 <li>Git is not a Prius. Git is a Model T.
28 Its plumbing and wiring sticks out all over the place.
29 You have to be a mechanic to operate it successfully or you'll be
30 stuck on the side of the road when it breaks down.
31 And it <b>will</b> break down.
32
33 <blockquote>
34 <i>Nick Farina at [http://nfarina.com/post/9868516270/git-is-simpler]</i>
35 </blockquote>
@@ -39,11 +39,11 @@
39 <blockquote>
40 <i>Linus Torvalds - 2005-04-07 22:13:13<br>
41 Commit comment on the very first source-code check-in for git
42 </blockquote>
43
44 <li>I've been experimenting a lot with git at work.
45 Damn, it's complicated.
46 It has things to trip you up with that sane people just wouldn't ever both with
47 including the ability to allow you to commit stuff in such a way that you can't find
48 it again afterwards (!!!)
49 Demented workflow complexity on acid?
@@ -104,19 +104,19 @@
104
105 <blockquote>
106 <i>Joe Prostko at [http://www.mail-archive.com/[email protected]/msg16716.html]
107 </blockquote>
108
109 <li>Fossil is awesome!!! I have never seen an app like that before,
110 such simplicity and flexibility!!!
111
112 <blockquote>
113 <i>zengr at [http://stackoverflow.com/questions/138621/best-version-control-for-lone-developer]</i>
114 </blockquote>
115
116 <li>This is my favourite VCS. I can carry it on a USB. And it's a complete system, with it's own
117 server, ticketing system, Wiki pages, and a very, very helpful timeline visualization. And
118 the entire program in a single file!
119
120 <blockquote>
121 <i>thunderbong commenting on hacker news: [https://news.ycombinator.com/item?id=9131619]</i>
122 </blockquote>
@@ -127,30 +127,30 @@
127
128 <h2>On Git Versus Fossil</h2>
129
130 <ol>
131 <li value=15>
132 Just want to say thanks for fossil making my life easier....
133 Also <nowiki>[for]</nowiki> not having a misanthropic command line interface.
134
135 <blockquote>
136 <i>Joshua Paine at [http://www.mail-archive.com/[email protected]/msg02736.html]</i>
137 </blockquote>
138
139 <li>We use it at a large university to manage code that small teams write.
140 The runs everywhere, ease of installation and portability is something that
141 seems to be a good fit with the environment we have (highly ditrobuted,
142 sometimes very restrictive firewalls, OSX/Win/Linux). We are happy with it
143 and teaching a Msc/Phd student (read complete novice) fossil has just
144 been a smoother ride than Git was.
145
146 <blockquote>
147 <i>viablepanic at [http://www.reddit.com/r/programming/comments/bxcto/why_not_fossil_scm/]</i>
148 </blockquote>
149
150 <li>In the fossil community - and hence in fossil itself - development history
151 is pretty much sacrosanct. The very name "fossil" was to chosen to
152 reflect the unchanging nature of things in that history.
153
154 <p>In git (or rather, the git community), the development history is part of
155 the published aspect of the project, so it provides tools for rearranging
156 that history so you can present what you "should" have done rather
157
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -5,19 +5,19 @@
5 by the creator of Fossil, so of course there is selection bias...
6
7 <h2>On The Usability Of Git:</h2>
8
9 <ol>
10 <li>Git approaches the usability of iptables, which is to say, utterly
11 unusable unless you have the manpage tattooed on you arm.
12
13 <blockquote>
14 <i>by mml at [http://news.ycombinator.com/item?id=1433387]</i>
15 </blockquote>
16
17 <li><nowiki>It's simplest to think of the state of your [git] repository
18 as a point in a high-dimensional "code-space", in which branches are
19 represented as n-dimensional membranes, mapping the spatial loci of
20 successive commits onto the projected manifold of each cloned
21 repository.</nowiki>
22
23 <blockquote>
@@ -25,11 +25,11 @@
25 </blockquote>
26
27 <li>Git is not a Prius. Git is a Model T.
28 Its plumbing and wiring sticks out all over the place.
29 You have to be a mechanic to operate it successfully or you'll be
30 stuck on the side of the road when it breaks down.
31 And it <b>will</b> break down.
32
33 <blockquote>
34 <i>Nick Farina at [http://nfarina.com/post/9868516270/git-is-simpler]</i>
35 </blockquote>
@@ -39,11 +39,11 @@
39 <blockquote>
40 <i>Linus Torvalds - 2005-04-07 22:13:13<br>
41 Commit comment on the very first source-code check-in for git
42 </blockquote>
43
44 <li>I've been experimenting a lot with git at work.
45 Damn, it's complicated.
46 It has things to trip you up with that sane people just wouldn't ever both with
47 including the ability to allow you to commit stuff in such a way that you can't find
48 it again afterwards (!!!)
49 Demented workflow complexity on acid?
@@ -104,19 +104,19 @@
104
105 <blockquote>
106 <i>Joe Prostko at [http://www.mail-archive.com/[email protected]/msg16716.html]
107 </blockquote>
108
109 <li>Fossil is awesome!!! I have never seen an app like that before,
110 such simplicity and flexibility!!!
111
112 <blockquote>
113 <i>zengr at [http://stackoverflow.com/questions/138621/best-version-control-for-lone-developer]</i>
114 </blockquote>
115
116 <li>This is my favourite VCS. I can carry it on a USB. And it's a complete system, with it's own
117 server, ticketing system, Wiki pages, and a very, very helpful timeline visualization. And
118 the entire program in a single file!
119
120 <blockquote>
121 <i>thunderbong commenting on hacker news: [https://news.ycombinator.com/item?id=9131619]</i>
122 </blockquote>
@@ -127,30 +127,30 @@
127
128 <h2>On Git Versus Fossil</h2>
129
130 <ol>
131 <li value=15>
132 Just want to say thanks for fossil making my life easier....
133 Also <nowiki>[for]</nowiki> not having a misanthropic command line interface.
134
135 <blockquote>
136 <i>Joshua Paine at [http://www.mail-archive.com/[email protected]/msg02736.html]</i>
137 </blockquote>
138
139 <li>We use it at a large university to manage code that small teams write.
140 The runs everywhere, ease of installation and portability is something that
141 seems to be a good fit with the environment we have (highly ditrobuted,
142 sometimes very restrictive firewalls, OSX/Win/Linux). We are happy with it
143 and teaching a Msc/Phd student (read complete novice) fossil has just
144 been a smoother ride than Git was.
145
146 <blockquote>
147 <i>viablepanic at [http://www.reddit.com/r/programming/comments/bxcto/why_not_fossil_scm/]</i>
148 </blockquote>
149
150 <li>In the fossil community - and hence in fossil itself - development history
151 is pretty much sacrosanct. The very name "fossil" was to chosen to
152 reflect the unchanging nature of things in that history.
153
154 <p>In git (or rather, the git community), the development history is part of
155 the published aspect of the project, so it provides tools for rearranging
156 that history so you can present what you "should" have done rather
157
+12 -12
--- www/reviews.wiki
+++ www/reviews.wiki
@@ -1,8 +1,8 @@
11
<title>Reviews</title>
22
<b>External links:</b>
3
-
3
+
44
* [http://nixtu.blogspot.com/2010/03/fossil-dvcs-on-go-first-impressions.html |
55
Fossil DVCS on the Go - First Impressions]
66
* [http://blog.mired.org/2011/02/fossil-sweet-spot-in-vcs-space.html |
77
Fossil - a sweet spot in the VCS space] by Mike Meyer.
88
* [http://blog.s11n.net/?p=72|Four reasons to take a closer look at the Fossil SCM] by Stephan Beal
@@ -22,27 +22,27 @@
2222
2323
2424
<b>Joshua Paine on 2010-10-22:</b>
2525
2626
<blockquote>
27
-With one of my several hats on, I'm in a small team using git. Another
28
-team member just checked some stuff into trunk that should have been on
29
-a branch. Nothing else had happened since, so in fossil I would have
30
-just edited that commit and put it on a new branch. In git that can't
31
-actually be done without danger once other people have pulled, so I had
32
-to create a new commit rolling back the changes, then branch and cherry
33
-pick the earlier changes, then figure out how to make my new branch
34
-shared instead of private. Just want to say thanks for fossil making my
35
-life easier on most of my projects, and being able to move commits to
36
-another branch after the fact and shared-by-default branches are good
27
+With one of my several hats on, I'm in a small team using git. Another
28
+team member just checked some stuff into trunk that should have been on
29
+a branch. Nothing else had happened since, so in fossil I would have
30
+just edited that commit and put it on a new branch. In git that can't
31
+actually be done without danger once other people have pulled, so I had
32
+to create a new commit rolling back the changes, then branch and cherry
33
+pick the earlier changes, then figure out how to make my new branch
34
+shared instead of private. Just want to say thanks for fossil making my
35
+life easier on most of my projects, and being able to move commits to
36
+another branch after the fact and shared-by-default branches are good
3737
features. Also not having a misanthropic command line interface.
3838
</blockquote>
3939
4040
<b>Stephan Beal writes on 2009-01-11:</b>
4141
4242
<blockquote>
43
-Sometime in late 2007 I came across a link to fossil on
43
+Sometime in late 2007 I came across a link to fossil on
4444
<a href="http://www.sqlite.org/">sqlite.org</a>. It
4545
was a good thing I bookmarked it, because I was never able to find the
4646
link again (it might have been in a bug report or something). The
4747
reasons I first took a close look at it were (A) it stemmed from the
4848
sqlite project, which I've held in high regards for years (e.g. I
4949
--- www/reviews.wiki
+++ www/reviews.wiki
@@ -1,8 +1,8 @@
1 <title>Reviews</title>
2 <b>External links:</b>
3
4 * [http://nixtu.blogspot.com/2010/03/fossil-dvcs-on-go-first-impressions.html |
5 Fossil DVCS on the Go - First Impressions]
6 * [http://blog.mired.org/2011/02/fossil-sweet-spot-in-vcs-space.html |
7 Fossil - a sweet spot in the VCS space] by Mike Meyer.
8 * [http://blog.s11n.net/?p=72|Four reasons to take a closer look at the Fossil SCM] by Stephan Beal
@@ -22,27 +22,27 @@
22
23
24 <b>Joshua Paine on 2010-10-22:</b>
25
26 <blockquote>
27 With one of my several hats on, I'm in a small team using git. Another
28 team member just checked some stuff into trunk that should have been on
29 a branch. Nothing else had happened since, so in fossil I would have
30 just edited that commit and put it on a new branch. In git that can't
31 actually be done without danger once other people have pulled, so I had
32 to create a new commit rolling back the changes, then branch and cherry
33 pick the earlier changes, then figure out how to make my new branch
34 shared instead of private. Just want to say thanks for fossil making my
35 life easier on most of my projects, and being able to move commits to
36 another branch after the fact and shared-by-default branches are good
37 features. Also not having a misanthropic command line interface.
38 </blockquote>
39
40 <b>Stephan Beal writes on 2009-01-11:</b>
41
42 <blockquote>
43 Sometime in late 2007 I came across a link to fossil on
44 <a href="http://www.sqlite.org/">sqlite.org</a>. It
45 was a good thing I bookmarked it, because I was never able to find the
46 link again (it might have been in a bug report or something). The
47 reasons I first took a close look at it were (A) it stemmed from the
48 sqlite project, which I've held in high regards for years (e.g. I
49
--- www/reviews.wiki
+++ www/reviews.wiki
@@ -1,8 +1,8 @@
1 <title>Reviews</title>
2 <b>External links:</b>
3
4 * [http://nixtu.blogspot.com/2010/03/fossil-dvcs-on-go-first-impressions.html |
5 Fossil DVCS on the Go - First Impressions]
6 * [http://blog.mired.org/2011/02/fossil-sweet-spot-in-vcs-space.html |
7 Fossil - a sweet spot in the VCS space] by Mike Meyer.
8 * [http://blog.s11n.net/?p=72|Four reasons to take a closer look at the Fossil SCM] by Stephan Beal
@@ -22,27 +22,27 @@
22
23
24 <b>Joshua Paine on 2010-10-22:</b>
25
26 <blockquote>
27 With one of my several hats on, I'm in a small team using git. Another
28 team member just checked some stuff into trunk that should have been on
29 a branch. Nothing else had happened since, so in fossil I would have
30 just edited that commit and put it on a new branch. In git that can't
31 actually be done without danger once other people have pulled, so I had
32 to create a new commit rolling back the changes, then branch and cherry
33 pick the earlier changes, then figure out how to make my new branch
34 shared instead of private. Just want to say thanks for fossil making my
35 life easier on most of my projects, and being able to move commits to
36 another branch after the fact and shared-by-default branches are good
37 features. Also not having a misanthropic command line interface.
38 </blockquote>
39
40 <b>Stephan Beal writes on 2009-01-11:</b>
41
42 <blockquote>
43 Sometime in late 2007 I came across a link to fossil on
44 <a href="http://www.sqlite.org/">sqlite.org</a>. It
45 was a good thing I bookmarked it, because I was never able to find the
46 link again (it might have been in a bug report or something). The
47 reasons I first took a close look at it were (A) it stemmed from the
48 sqlite project, which I've held in high regards for years (e.g. I
49
--- www/selfcheck.wiki
+++ www/selfcheck.wiki
@@ -14,11 +14,11 @@
1414
lost. The integrity checks are doing their job well.</p>
1515
1616
<h2>Atomic Check-ins With Rollback</h2>
1717
1818
The fossil repository is stored in an
19
-<a href="http://www.sqlite.org/">SQLite</a> database file.
19
+<a href="http://www.sqlite.org/">SQLite</a> database file.
2020
([./tech_overview.wiki | Addition information] about the repository
2121
file format.)
2222
SQLite is very mature and stable and has been in wide-spread use for many
2323
years, so we are confident it will not cause repository
2424
corruption. SQLite
@@ -61,11 +61,11 @@
6161
message is printed and the transaction rolls back.
6262
6363
So, in other words, fossil always checks to make sure it can
6464
re-extract a file before it commits a change to that file.
6565
Hence bugs in fossil are unlikely to corrupt the repository in
66
-a way that prevents us from extracting historical versions of
66
+a way that prevents us from extracting historical versions of
6767
files.
6868
6969
<h2>Checksum Over All Files In A Check-in</h2>
7070
7171
Manifest artifacts that define a check-in have two fields (the
@@ -102,7 +102,7 @@
102102
<a href="http://en.wikipedia.org/wiki/The_Tortoise_and_the_Hare">tortoise</a>:
103103
reliability is more important than raw speed. The developers of
104104
fossil see no merit in getting the wrong answer quickly.
105105
106106
Fossil may not be the fastest versioning system, but it is "fast enough".
107
-Fossil runs quickly enough to stay out of the developers way.
107
+Fossil runs quickly enough to stay out of the developers way.
108108
Most operations complete in under a second.
109109
--- www/selfcheck.wiki
+++ www/selfcheck.wiki
@@ -14,11 +14,11 @@
14 lost. The integrity checks are doing their job well.</p>
15
16 <h2>Atomic Check-ins With Rollback</h2>
17
18 The fossil repository is stored in an
19 <a href="http://www.sqlite.org/">SQLite</a> database file.
20 ([./tech_overview.wiki | Addition information] about the repository
21 file format.)
22 SQLite is very mature and stable and has been in wide-spread use for many
23 years, so we are confident it will not cause repository
24 corruption. SQLite
@@ -61,11 +61,11 @@
61 message is printed and the transaction rolls back.
62
63 So, in other words, fossil always checks to make sure it can
64 re-extract a file before it commits a change to that file.
65 Hence bugs in fossil are unlikely to corrupt the repository in
66 a way that prevents us from extracting historical versions of
67 files.
68
69 <h2>Checksum Over All Files In A Check-in</h2>
70
71 Manifest artifacts that define a check-in have two fields (the
@@ -102,7 +102,7 @@
102 <a href="http://en.wikipedia.org/wiki/The_Tortoise_and_the_Hare">tortoise</a>:
103 reliability is more important than raw speed. The developers of
104 fossil see no merit in getting the wrong answer quickly.
105
106 Fossil may not be the fastest versioning system, but it is "fast enough".
107 Fossil runs quickly enough to stay out of the developers way.
108 Most operations complete in under a second.
109
--- www/selfcheck.wiki
+++ www/selfcheck.wiki
@@ -14,11 +14,11 @@
14 lost. The integrity checks are doing their job well.</p>
15
16 <h2>Atomic Check-ins With Rollback</h2>
17
18 The fossil repository is stored in an
19 <a href="http://www.sqlite.org/">SQLite</a> database file.
20 ([./tech_overview.wiki | Addition information] about the repository
21 file format.)
22 SQLite is very mature and stable and has been in wide-spread use for many
23 years, so we are confident it will not cause repository
24 corruption. SQLite
@@ -61,11 +61,11 @@
61 message is printed and the transaction rolls back.
62
63 So, in other words, fossil always checks to make sure it can
64 re-extract a file before it commits a change to that file.
65 Hence bugs in fossil are unlikely to corrupt the repository in
66 a way that prevents us from extracting historical versions of
67 files.
68
69 <h2>Checksum Over All Files In A Check-in</h2>
70
71 Manifest artifacts that define a check-in have two fields (the
@@ -102,7 +102,7 @@
102 <a href="http://en.wikipedia.org/wiki/The_Tortoise_and_the_Hare">tortoise</a>:
103 reliability is more important than raw speed. The developers of
104 fossil see no merit in getting the wrong answer quickly.
105
106 Fossil may not be the fastest versioning system, but it is "fast enough".
107 Fossil runs quickly enough to stay out of the developers way.
108 Most operations complete in under a second.
109
--- www/selfhost.wiki
+++ www/selfhost.wiki
@@ -7,23 +7,23 @@
77
2. [http://www2.fossil-scm.org/]
88
3. [http://www3.fossil-scm.org/site.cgi]
99
1010
1111
The canonical repository is (1). Repositories (2) and (3) automatically
12
-stay in synchronization with (1) via a
12
+stay in synchronization with (1) via a
1313
<a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes
1414
"fossil sync" at regular intervals.
1515
1616
Note that the two secondary repositories are more than just read-only mirrors.
1717
All three servers support full read/write capabilities.
18
-Changes (such as new tickets or wiki or check-ins) can be implemented
18
+Changes (such as new tickets or wiki or check-ins) can be implemented
1919
on any of the three servers and those changes automatically propagate to the
2020
other two servers.
2121
2222
Server (1) runs as a CGI script on a
2323
<a href="http://www.linode.com/">Linode 1024</a> located in Dallas, TX
24
-- on the same virtual machine that
24
+- on the same virtual machine that
2525
hosts <a href="http://www.sqlite.org/">SQLite</a> and over a
2626
dozen other smaller projects. This demonstrates that Fossil can run on
2727
a low-power host processor.
2828
Multiple fossil-based projects can easily be hosted on the same machine,
2929
even if that machine is itself one of several dozen virtual machines on
@@ -34,17 +34,17 @@
3434
#!/usr/bin/fossil
3535
repository: /fossil/fossil.fossil
3636
</pre></blockquote>
3737
3838
Server (3) runs as a CGI script on a shared hosting account at
39
-<a href="http://www.he.net/">Hurricane Electric</a> in Fremont, CA.
39
+<a href="http://www.he.net/">Hurricane Electric</a> in Fremont, CA.
4040
This server demonstrates the ability of
4141
Fossil to run on an economical shared-host web account with no
4242
privileges beyond port 80 HTTP access and CGI. It is not necessary
4343
to have a dedicated computer with administrator privileges to run Fossil.
44
-As far as we are aware,
45
-Fossil is the only full-featured configuration management system
44
+As far as we are aware,
45
+Fossil is the only full-featured configuration management system
4646
that can run in
4747
such a restricted environment. The CGI script that runs on the
4848
Hurricane Electric server is the same as the CGI script shown above,
4949
except that the pathnames are modified to suit the environment:
5050
5151
--- www/selfhost.wiki
+++ www/selfhost.wiki
@@ -7,23 +7,23 @@
7 2. [http://www2.fossil-scm.org/]
8 3. [http://www3.fossil-scm.org/site.cgi]
9
10
11 The canonical repository is (1). Repositories (2) and (3) automatically
12 stay in synchronization with (1) via a
13 <a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes
14 "fossil sync" at regular intervals.
15
16 Note that the two secondary repositories are more than just read-only mirrors.
17 All three servers support full read/write capabilities.
18 Changes (such as new tickets or wiki or check-ins) can be implemented
19 on any of the three servers and those changes automatically propagate to the
20 other two servers.
21
22 Server (1) runs as a CGI script on a
23 <a href="http://www.linode.com/">Linode 1024</a> located in Dallas, TX
24 - on the same virtual machine that
25 hosts <a href="http://www.sqlite.org/">SQLite</a> and over a
26 dozen other smaller projects. This demonstrates that Fossil can run on
27 a low-power host processor.
28 Multiple fossil-based projects can easily be hosted on the same machine,
29 even if that machine is itself one of several dozen virtual machines on
@@ -34,17 +34,17 @@
34 #!/usr/bin/fossil
35 repository: /fossil/fossil.fossil
36 </pre></blockquote>
37
38 Server (3) runs as a CGI script on a shared hosting account at
39 <a href="http://www.he.net/">Hurricane Electric</a> in Fremont, CA.
40 This server demonstrates the ability of
41 Fossil to run on an economical shared-host web account with no
42 privileges beyond port 80 HTTP access and CGI. It is not necessary
43 to have a dedicated computer with administrator privileges to run Fossil.
44 As far as we are aware,
45 Fossil is the only full-featured configuration management system
46 that can run in
47 such a restricted environment. The CGI script that runs on the
48 Hurricane Electric server is the same as the CGI script shown above,
49 except that the pathnames are modified to suit the environment:
50
51
--- www/selfhost.wiki
+++ www/selfhost.wiki
@@ -7,23 +7,23 @@
7 2. [http://www2.fossil-scm.org/]
8 3. [http://www3.fossil-scm.org/site.cgi]
9
10
11 The canonical repository is (1). Repositories (2) and (3) automatically
12 stay in synchronization with (1) via a
13 <a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes
14 "fossil sync" at regular intervals.
15
16 Note that the two secondary repositories are more than just read-only mirrors.
17 All three servers support full read/write capabilities.
18 Changes (such as new tickets or wiki or check-ins) can be implemented
19 on any of the three servers and those changes automatically propagate to the
20 other two servers.
21
22 Server (1) runs as a CGI script on a
23 <a href="http://www.linode.com/">Linode 1024</a> located in Dallas, TX
24 - on the same virtual machine that
25 hosts <a href="http://www.sqlite.org/">SQLite</a> and over a
26 dozen other smaller projects. This demonstrates that Fossil can run on
27 a low-power host processor.
28 Multiple fossil-based projects can easily be hosted on the same machine,
29 even if that machine is itself one of several dozen virtual machines on
@@ -34,17 +34,17 @@
34 #!/usr/bin/fossil
35 repository: /fossil/fossil.fossil
36 </pre></blockquote>
37
38 Server (3) runs as a CGI script on a shared hosting account at
39 <a href="http://www.he.net/">Hurricane Electric</a> in Fremont, CA.
40 This server demonstrates the ability of
41 Fossil to run on an economical shared-host web account with no
42 privileges beyond port 80 HTTP access and CGI. It is not necessary
43 to have a dedicated computer with administrator privileges to run Fossil.
44 As far as we are aware,
45 Fossil is the only full-featured configuration management system
46 that can run in
47 such a restricted environment. The CGI script that runs on the
48 Hurricane Electric server is the same as the CGI script shown above,
49 except that the pathnames are modified to suit the environment:
50
51
+21 -21
--- www/server.wiki
+++ www/server.wiki
@@ -2,11 +2,11 @@
22
<h2>Introduction</h2><blockquote>
33
<p>A server is not necessary to use Fossil, but a server does help in collaborating with
44
peers. A Fossil server also works well as a complete website for a project.
55
For example, the complete [https://www.fossil-scm.org/] website, including the
66
page you are now reading,
7
-is just a Fossil server displaying the content of the
7
+is just a Fossil server displaying the content of the
88
self-hosting repository for Fossil.</p>
99
<p>This article is a guide for setting up your own Fossil server.
1010
<p>See "[./aboutcgi.wiki|How CGI Works In Fossil]" for background
1111
information on the underlying CGI technology.
1212
See "[./sync.wiki|The Fossil Sync Protocol]" for information on the
@@ -18,11 +18,11 @@
1818
<li>A stand-alone server
1919
<li>Using inetd or xinetd or stunnel
2020
<li>CGI
2121
<li>SCGI (a.k.a. SimpleCGI)
2222
</ol>
23
-Each of these can serve either a single repository, or a directory hierarchy
23
+Each of these can serve either a single repository, or a directory hierarchy
2424
containing many repositories with names ending in ".fossil".
2525
</blockquote>
2626
<a name="standalone"></a>
2727
<h2>Standalone server</h2><blockquote>
2828
The easiest way to set up a Fossil server is to use either the
@@ -34,16 +34,16 @@
3434
<p>
3535
The <i>REPOSITORY</i> argument is either the name of the repository file, or
3636
a directory containing many repositories.
3737
Both of these commands start a Fossil server, usually on TCP port 8080, though
3838
a higher numbered port might also be used if 8080 is already occupied. You can
39
-access these using URLs of the form <b>http://localhost:8080/</b>, or if
39
+access these using URLs of the form <b>http://localhost:8080/</b>, or if
4040
<i>REPOSITORY</i> is a directory, URLs of the form
4141
<b>http://localhost:8080/</b><i>repo</i><b>/</b> where <i>repo</i> is the base
4242
name of the repository file without the ".fossil" suffix.
4343
The difference between "ui" and "server" is that "ui" will
44
-also start a web browser and points it
44
+also start a web browser and point it
4545
to the URL mentioned above, and the "ui" command binds to
4646
the loopback IP address (127.0.0.1) only so that the "ui" command cannot be
4747
used to serve content to a different machine.
4848
</p>
4949
<p>
@@ -75,23 +75,23 @@
7575
need to modify the pathnames for your particular setup.
7676
The final argument is either the name of the fossil repository to be served,
7777
or a directory containing multiple repositories.
7878
</p>
7979
<p>
80
-If you use a non-standard TCP port on
81
-systems where the port-specification must be a symbolic name and cannot be
80
+If you use a non-standard TCP port on
81
+systems where the port-specification must be a symbolic name and cannot be
8282
numeric, add the desired name and port to /etc/services. For example, if
8383
you want your Fossil server running on TCP port 12345 instead of 80, you
8484
will need to add:
8585
<blockquote>
8686
<pre>
8787
fossil 12345/tcp #fossil server
8888
</pre>
8989
</blockquote>
90
-and use the symbolic name ('fossil' in this example) instead of the numeral ('12345')
91
-in inetd.conf. For details, see the relevant section in your system's documentation, e.g.
92
-the [https://www.freebsd.org/doc/en/books/handbook/network-inetd.html|FreeBSD Handbook] in
90
+and use the symbolic name ('fossil' in this example) instead of the numeral ('12345')
91
+in inetd.conf. For details, see the relevant section in your system's documentation, e.g.
92
+the [https://www.freebsd.org/doc/en/books/handbook/network-inetd.html|FreeBSD Handbook] in
9393
case you use FreeBSD.
9494
</p>
9595
<p>
9696
If your system is running xinetd, then the configuration is likely to be
9797
in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
@@ -119,11 +119,11 @@
119119
jail for the user who owns the fossil repository before reading any information
120120
off of the wire.
121121
</p>
122122
<p>
123123
Inetd or xinetd must be enabled, and must be (re)started whenever their configuration
124
-changes - consult your system's documentation for details.
124
+changes - consult your system's documentation for details.
125125
</p>
126126
<p>
127127
[https://www.stunnel.org/ | Stunnel version 5] is an inetd-like process that
128128
accepts and decodes SSL-encrypted connections. Fossil can be run directly from
129129
stunnel in a manner similar to inetd and xinetd. This can be used to provide
@@ -137,15 +137,15 @@
137137
TIMEOUTclose = 0
138138
exec = /usr/bin/fossil
139139
execargs = /usr/bin/fossil http /home/fossil/ubercool.fossil --https
140140
</nowiki></pre></blockquote>
141141
See the stunnel5 documentation for further details about the /etc/stunnel/stunnel.conf
142
-configuration file. Note that the [/help/http|fossil http] command should include
142
+configuration file. Note that the [/help/http|fossil http] command should include
143143
the --https option to let Fossil know to use "https" instead of "http" as the scheme
144144
on generated hyperlinks.
145145
<p>
146
-Using inetd or xinetd or stunnel is a more complex setup
146
+Using inetd or xinetd or stunnel is a more complex setup
147147
than the "standalone" server, but it has the
148148
advantage of only using system resources when an actual connection is
149149
attempted. If no-one ever connects to that port, a Fossil server will
150150
not (automatically) run. It has the disadvantage of requiring "root" access
151151
and therefore may not normally be available to lower-priced "shared" servers
@@ -155,11 +155,11 @@
155155
<a name="cgi"></a>
156156
<h2>Fossil as CGI</h2><blockquote>
157157
<p>
158158
A Fossil server can also be run from an ordinary web server as a CGI program.
159159
This feature allows Fossil to be seamlessly integrated into a larger website.
160
-CGI is how the [./selfhost.wiki | self-hosting fossil repositories] are
160
+CGI is how the [./selfhost.wiki | self-hosting fossil repositories] are
161161
implemented.
162162
</p>
163163
<p>
164164
To run Fossil as CGI, create a CGI script (here called "repo") in the CGI directory
165165
of your web server and having content like this:
@@ -184,12 +184,12 @@
184184
script itself must be executable for the user under which it will run (which often differs
185185
from the one running the web server - consult your site's documentation or administrator).</li>
186186
<li>The repository file AND the directory containing it must be writable by the same account
187187
which executes the Fossil binary (again, this might differ from the WWW user). The directory
188188
needs to be writable so that sqlite can write its journal files.</li>
189
-<li>Fossil must be able to create temporary files, the default directory
190
-for which depends on the OS. When the CGI process is operating within
189
+<li>Fossil must be able to create temporary files, the default directory
190
+for which depends on the OS. When the CGI process is operating within
191191
a chroot, ensure that this directory exists and is readable/writeable
192192
by the user who executes the Fossil binary.</li>
193193
</ul>
194194
</p>
195195
@@ -219,11 +219,11 @@
219219
220220
<a name="scgi"></a>
221221
<h2>Fossil as SCGI</h2><blockquote>
222222
223223
<p>
224
-The [/help/server|fossil server] command, described above as a way of
224
+The [/help/server|fossil server] command, described above as a way of
225225
starting a stand-alone web server, can also be used for SCGI. Simply add
226226
the --scgi command-line option and the stand-alone server will interpret
227227
and respond to the SimpleCGI or SCGI protocol rather than raw HTTP. This can
228228
be used in combination with a webserver (such as [http://nginx.org|Nginx])
229229
that does not support CGI. A typical Nginx configuration to support SCGI
@@ -284,27 +284,27 @@
284284
</blockquote>
285285
286286
<a name="loadmgmt"></a>
287287
<h2>Managing Server Load</h2><blockquote>
288288
<p>
289
-A Fossil server is very efficient and normally presents a very light
289
+A Fossil server is very efficient and normally presents a very light
290290
load on the server.
291291
The Fossil [./selfhost.wiki | self-hosting server] is a 1/24th slice VM at
292292
[http://www.linode.com | Linode.com] hosting 65 other repositories in
293293
addition to Fossil (and including some very high-traffic sites such
294294
as [http://www.sqlite.org] and [http://system.data.sqlite.org]) and
295295
it has a typical load of 0.05 to 0.1. A single HTTP request to Fossil
296296
normally takes less than 10 milliseconds of CPU time to complete. So
297
-requests can be arriving at a continuous rate of 20 or more per second
297
+requests can be arriving at a continuous rate of 20 or more per second
298298
and the CPU can still be mostly idle.
299299
<p>
300
-However, there are some Fossil web pages that can consume large
300
+However, there are some Fossil web pages that can consume large
301301
amounts of CPU time, especially on repositories with a large number
302302
of files or with long revision histories. High CPU usage pages include
303303
[/help?cmd=/zip | /zip], [/help?cmd=/tarball | /tarball],
304304
[/help?cmd=/annotate | /annotate] and others. On very large repositories,
305
-these commands can take 15 seconds or more of CPU time.
305
+these commands can take 15 seconds or more of CPU time.
306306
If these kinds of requests arrive too quickly, the load average on the
307307
server can grow dramatically, making the server unresponsive.
308308
<p>
309309
Fossil provides two capabilities to help avoid server overload problems
310310
due to excessive requests to expensive pages:
@@ -312,11 +312,11 @@
312312
<li><p>An optional cache is available that remembers the 10 most recently
313313
requested /zip or /tarball pages and returns the precomputed answer
314314
if the same page is requested again.
315315
<li><p>Page requests can be configured to fail with a
316316
[http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3 | "503 Server Overload"]
317
- HTTP error if an expensive request is received while the host load
317
+ HTTP error if an expensive request is received while the host load
318318
average is too high.
319319
</ol>
320320
Both of these load-control mechanisms are turned off by default, but they
321321
are recommended for high-traffic sites.
322322
<p>
323323
--- www/server.wiki
+++ www/server.wiki
@@ -2,11 +2,11 @@
2 <h2>Introduction</h2><blockquote>
3 <p>A server is not necessary to use Fossil, but a server does help in collaborating with
4 peers. A Fossil server also works well as a complete website for a project.
5 For example, the complete [https://www.fossil-scm.org/] website, including the
6 page you are now reading,
7 is just a Fossil server displaying the content of the
8 self-hosting repository for Fossil.</p>
9 <p>This article is a guide for setting up your own Fossil server.
10 <p>See "[./aboutcgi.wiki|How CGI Works In Fossil]" for background
11 information on the underlying CGI technology.
12 See "[./sync.wiki|The Fossil Sync Protocol]" for information on the
@@ -18,11 +18,11 @@
18 <li>A stand-alone server
19 <li>Using inetd or xinetd or stunnel
20 <li>CGI
21 <li>SCGI (a.k.a. SimpleCGI)
22 </ol>
23 Each of these can serve either a single repository, or a directory hierarchy
24 containing many repositories with names ending in ".fossil".
25 </blockquote>
26 <a name="standalone"></a>
27 <h2>Standalone server</h2><blockquote>
28 The easiest way to set up a Fossil server is to use either the
@@ -34,16 +34,16 @@
34 <p>
35 The <i>REPOSITORY</i> argument is either the name of the repository file, or
36 a directory containing many repositories.
37 Both of these commands start a Fossil server, usually on TCP port 8080, though
38 a higher numbered port might also be used if 8080 is already occupied. You can
39 access these using URLs of the form <b>http://localhost:8080/</b>, or if
40 <i>REPOSITORY</i> is a directory, URLs of the form
41 <b>http://localhost:8080/</b><i>repo</i><b>/</b> where <i>repo</i> is the base
42 name of the repository file without the ".fossil" suffix.
43 The difference between "ui" and "server" is that "ui" will
44 also start a web browser and points it
45 to the URL mentioned above, and the "ui" command binds to
46 the loopback IP address (127.0.0.1) only so that the "ui" command cannot be
47 used to serve content to a different machine.
48 </p>
49 <p>
@@ -75,23 +75,23 @@
75 need to modify the pathnames for your particular setup.
76 The final argument is either the name of the fossil repository to be served,
77 or a directory containing multiple repositories.
78 </p>
79 <p>
80 If you use a non-standard TCP port on
81 systems where the port-specification must be a symbolic name and cannot be
82 numeric, add the desired name and port to /etc/services. For example, if
83 you want your Fossil server running on TCP port 12345 instead of 80, you
84 will need to add:
85 <blockquote>
86 <pre>
87 fossil 12345/tcp #fossil server
88 </pre>
89 </blockquote>
90 and use the symbolic name ('fossil' in this example) instead of the numeral ('12345')
91 in inetd.conf. For details, see the relevant section in your system's documentation, e.g.
92 the [https://www.freebsd.org/doc/en/books/handbook/network-inetd.html|FreeBSD Handbook] in
93 case you use FreeBSD.
94 </p>
95 <p>
96 If your system is running xinetd, then the configuration is likely to be
97 in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
@@ -119,11 +119,11 @@
119 jail for the user who owns the fossil repository before reading any information
120 off of the wire.
121 </p>
122 <p>
123 Inetd or xinetd must be enabled, and must be (re)started whenever their configuration
124 changes - consult your system's documentation for details.
125 </p>
126 <p>
127 [https://www.stunnel.org/ | Stunnel version 5] is an inetd-like process that
128 accepts and decodes SSL-encrypted connections. Fossil can be run directly from
129 stunnel in a manner similar to inetd and xinetd. This can be used to provide
@@ -137,15 +137,15 @@
137 TIMEOUTclose = 0
138 exec = /usr/bin/fossil
139 execargs = /usr/bin/fossil http /home/fossil/ubercool.fossil --https
140 </nowiki></pre></blockquote>
141 See the stunnel5 documentation for further details about the /etc/stunnel/stunnel.conf
142 configuration file. Note that the [/help/http|fossil http] command should include
143 the --https option to let Fossil know to use "https" instead of "http" as the scheme
144 on generated hyperlinks.
145 <p>
146 Using inetd or xinetd or stunnel is a more complex setup
147 than the "standalone" server, but it has the
148 advantage of only using system resources when an actual connection is
149 attempted. If no-one ever connects to that port, a Fossil server will
150 not (automatically) run. It has the disadvantage of requiring "root" access
151 and therefore may not normally be available to lower-priced "shared" servers
@@ -155,11 +155,11 @@
155 <a name="cgi"></a>
156 <h2>Fossil as CGI</h2><blockquote>
157 <p>
158 A Fossil server can also be run from an ordinary web server as a CGI program.
159 This feature allows Fossil to be seamlessly integrated into a larger website.
160 CGI is how the [./selfhost.wiki | self-hosting fossil repositories] are
161 implemented.
162 </p>
163 <p>
164 To run Fossil as CGI, create a CGI script (here called "repo") in the CGI directory
165 of your web server and having content like this:
@@ -184,12 +184,12 @@
184 script itself must be executable for the user under which it will run (which often differs
185 from the one running the web server - consult your site's documentation or administrator).</li>
186 <li>The repository file AND the directory containing it must be writable by the same account
187 which executes the Fossil binary (again, this might differ from the WWW user). The directory
188 needs to be writable so that sqlite can write its journal files.</li>
189 <li>Fossil must be able to create temporary files, the default directory
190 for which depends on the OS. When the CGI process is operating within
191 a chroot, ensure that this directory exists and is readable/writeable
192 by the user who executes the Fossil binary.</li>
193 </ul>
194 </p>
195
@@ -219,11 +219,11 @@
219
220 <a name="scgi"></a>
221 <h2>Fossil as SCGI</h2><blockquote>
222
223 <p>
224 The [/help/server|fossil server] command, described above as a way of
225 starting a stand-alone web server, can also be used for SCGI. Simply add
226 the --scgi command-line option and the stand-alone server will interpret
227 and respond to the SimpleCGI or SCGI protocol rather than raw HTTP. This can
228 be used in combination with a webserver (such as [http://nginx.org|Nginx])
229 that does not support CGI. A typical Nginx configuration to support SCGI
@@ -284,27 +284,27 @@
284 </blockquote>
285
286 <a name="loadmgmt"></a>
287 <h2>Managing Server Load</h2><blockquote>
288 <p>
289 A Fossil server is very efficient and normally presents a very light
290 load on the server.
291 The Fossil [./selfhost.wiki | self-hosting server] is a 1/24th slice VM at
292 [http://www.linode.com | Linode.com] hosting 65 other repositories in
293 addition to Fossil (and including some very high-traffic sites such
294 as [http://www.sqlite.org] and [http://system.data.sqlite.org]) and
295 it has a typical load of 0.05 to 0.1. A single HTTP request to Fossil
296 normally takes less than 10 milliseconds of CPU time to complete. So
297 requests can be arriving at a continuous rate of 20 or more per second
298 and the CPU can still be mostly idle.
299 <p>
300 However, there are some Fossil web pages that can consume large
301 amounts of CPU time, especially on repositories with a large number
302 of files or with long revision histories. High CPU usage pages include
303 [/help?cmd=/zip | /zip], [/help?cmd=/tarball | /tarball],
304 [/help?cmd=/annotate | /annotate] and others. On very large repositories,
305 these commands can take 15 seconds or more of CPU time.
306 If these kinds of requests arrive too quickly, the load average on the
307 server can grow dramatically, making the server unresponsive.
308 <p>
309 Fossil provides two capabilities to help avoid server overload problems
310 due to excessive requests to expensive pages:
@@ -312,11 +312,11 @@
312 <li><p>An optional cache is available that remembers the 10 most recently
313 requested /zip or /tarball pages and returns the precomputed answer
314 if the same page is requested again.
315 <li><p>Page requests can be configured to fail with a
316 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3 | "503 Server Overload"]
317 HTTP error if an expensive request is received while the host load
318 average is too high.
319 </ol>
320 Both of these load-control mechanisms are turned off by default, but they
321 are recommended for high-traffic sites.
322 <p>
323
--- www/server.wiki
+++ www/server.wiki
@@ -2,11 +2,11 @@
2 <h2>Introduction</h2><blockquote>
3 <p>A server is not necessary to use Fossil, but a server does help in collaborating with
4 peers. A Fossil server also works well as a complete website for a project.
5 For example, the complete [https://www.fossil-scm.org/] website, including the
6 page you are now reading,
7 is just a Fossil server displaying the content of the
8 self-hosting repository for Fossil.</p>
9 <p>This article is a guide for setting up your own Fossil server.
10 <p>See "[./aboutcgi.wiki|How CGI Works In Fossil]" for background
11 information on the underlying CGI technology.
12 See "[./sync.wiki|The Fossil Sync Protocol]" for information on the
@@ -18,11 +18,11 @@
18 <li>A stand-alone server
19 <li>Using inetd or xinetd or stunnel
20 <li>CGI
21 <li>SCGI (a.k.a. SimpleCGI)
22 </ol>
23 Each of these can serve either a single repository, or a directory hierarchy
24 containing many repositories with names ending in ".fossil".
25 </blockquote>
26 <a name="standalone"></a>
27 <h2>Standalone server</h2><blockquote>
28 The easiest way to set up a Fossil server is to use either the
@@ -34,16 +34,16 @@
34 <p>
35 The <i>REPOSITORY</i> argument is either the name of the repository file, or
36 a directory containing many repositories.
37 Both of these commands start a Fossil server, usually on TCP port 8080, though
38 a higher numbered port might also be used if 8080 is already occupied. You can
39 access these using URLs of the form <b>http://localhost:8080/</b>, or if
40 <i>REPOSITORY</i> is a directory, URLs of the form
41 <b>http://localhost:8080/</b><i>repo</i><b>/</b> where <i>repo</i> is the base
42 name of the repository file without the ".fossil" suffix.
43 The difference between "ui" and "server" is that "ui" will
44 also start a web browser and point it
45 to the URL mentioned above, and the "ui" command binds to
46 the loopback IP address (127.0.0.1) only so that the "ui" command cannot be
47 used to serve content to a different machine.
48 </p>
49 <p>
@@ -75,23 +75,23 @@
75 need to modify the pathnames for your particular setup.
76 The final argument is either the name of the fossil repository to be served,
77 or a directory containing multiple repositories.
78 </p>
79 <p>
80 If you use a non-standard TCP port on
81 systems where the port-specification must be a symbolic name and cannot be
82 numeric, add the desired name and port to /etc/services. For example, if
83 you want your Fossil server running on TCP port 12345 instead of 80, you
84 will need to add:
85 <blockquote>
86 <pre>
87 fossil 12345/tcp #fossil server
88 </pre>
89 </blockquote>
90 and use the symbolic name ('fossil' in this example) instead of the numeral ('12345')
91 in inetd.conf. For details, see the relevant section in your system's documentation, e.g.
92 the [https://www.freebsd.org/doc/en/books/handbook/network-inetd.html|FreeBSD Handbook] in
93 case you use FreeBSD.
94 </p>
95 <p>
96 If your system is running xinetd, then the configuration is likely to be
97 in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
@@ -119,11 +119,11 @@
119 jail for the user who owns the fossil repository before reading any information
120 off of the wire.
121 </p>
122 <p>
123 Inetd or xinetd must be enabled, and must be (re)started whenever their configuration
124 changes - consult your system's documentation for details.
125 </p>
126 <p>
127 [https://www.stunnel.org/ | Stunnel version 5] is an inetd-like process that
128 accepts and decodes SSL-encrypted connections. Fossil can be run directly from
129 stunnel in a manner similar to inetd and xinetd. This can be used to provide
@@ -137,15 +137,15 @@
137 TIMEOUTclose = 0
138 exec = /usr/bin/fossil
139 execargs = /usr/bin/fossil http /home/fossil/ubercool.fossil --https
140 </nowiki></pre></blockquote>
141 See the stunnel5 documentation for further details about the /etc/stunnel/stunnel.conf
142 configuration file. Note that the [/help/http|fossil http] command should include
143 the --https option to let Fossil know to use "https" instead of "http" as the scheme
144 on generated hyperlinks.
145 <p>
146 Using inetd or xinetd or stunnel is a more complex setup
147 than the "standalone" server, but it has the
148 advantage of only using system resources when an actual connection is
149 attempted. If no-one ever connects to that port, a Fossil server will
150 not (automatically) run. It has the disadvantage of requiring "root" access
151 and therefore may not normally be available to lower-priced "shared" servers
@@ -155,11 +155,11 @@
155 <a name="cgi"></a>
156 <h2>Fossil as CGI</h2><blockquote>
157 <p>
158 A Fossil server can also be run from an ordinary web server as a CGI program.
159 This feature allows Fossil to be seamlessly integrated into a larger website.
160 CGI is how the [./selfhost.wiki | self-hosting fossil repositories] are
161 implemented.
162 </p>
163 <p>
164 To run Fossil as CGI, create a CGI script (here called "repo") in the CGI directory
165 of your web server and having content like this:
@@ -184,12 +184,12 @@
184 script itself must be executable for the user under which it will run (which often differs
185 from the one running the web server - consult your site's documentation or administrator).</li>
186 <li>The repository file AND the directory containing it must be writable by the same account
187 which executes the Fossil binary (again, this might differ from the WWW user). The directory
188 needs to be writable so that sqlite can write its journal files.</li>
189 <li>Fossil must be able to create temporary files, the default directory
190 for which depends on the OS. When the CGI process is operating within
191 a chroot, ensure that this directory exists and is readable/writeable
192 by the user who executes the Fossil binary.</li>
193 </ul>
194 </p>
195
@@ -219,11 +219,11 @@
219
220 <a name="scgi"></a>
221 <h2>Fossil as SCGI</h2><blockquote>
222
223 <p>
224 The [/help/server|fossil server] command, described above as a way of
225 starting a stand-alone web server, can also be used for SCGI. Simply add
226 the --scgi command-line option and the stand-alone server will interpret
227 and respond to the SimpleCGI or SCGI protocol rather than raw HTTP. This can
228 be used in combination with a webserver (such as [http://nginx.org|Nginx])
229 that does not support CGI. A typical Nginx configuration to support SCGI
@@ -284,27 +284,27 @@
284 </blockquote>
285
286 <a name="loadmgmt"></a>
287 <h2>Managing Server Load</h2><blockquote>
288 <p>
289 A Fossil server is very efficient and normally presents a very light
290 load on the server.
291 The Fossil [./selfhost.wiki | self-hosting server] is a 1/24th slice VM at
292 [http://www.linode.com | Linode.com] hosting 65 other repositories in
293 addition to Fossil (and including some very high-traffic sites such
294 as [http://www.sqlite.org] and [http://system.data.sqlite.org]) and
295 it has a typical load of 0.05 to 0.1. A single HTTP request to Fossil
296 normally takes less than 10 milliseconds of CPU time to complete. So
297 requests can be arriving at a continuous rate of 20 or more per second
298 and the CPU can still be mostly idle.
299 <p>
300 However, there are some Fossil web pages that can consume large
301 amounts of CPU time, especially on repositories with a large number
302 of files or with long revision histories. High CPU usage pages include
303 [/help?cmd=/zip | /zip], [/help?cmd=/tarball | /tarball],
304 [/help?cmd=/annotate | /annotate] and others. On very large repositories,
305 these commands can take 15 seconds or more of CPU time.
306 If these kinds of requests arrive too quickly, the load average on the
307 server can grow dramatically, making the server unresponsive.
308 <p>
309 Fossil provides two capabilities to help avoid server overload problems
310 due to excessive requests to expensive pages:
@@ -312,11 +312,11 @@
312 <li><p>An optional cache is available that remembers the 10 most recently
313 requested /zip or /tarball pages and returns the precomputed answer
314 if the same page is requested again.
315 <li><p>Page requests can be configured to fail with a
316 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3 | "503 Server Overload"]
317 HTTP error if an expensive request is received while the host load
318 average is too high.
319 </ol>
320 Both of these load-control mechanisms are turned off by default, but they
321 are recommended for high-traffic sites.
322 <p>
323
--- www/settings.wiki
+++ www/settings.wiki
@@ -4,11 +4,11 @@
44
55
Settings control the behaviour of fossil. They are set with the
66
<tt>fossil settings</tt> command, or through the web interface in
77
the Settings page in the Admin section.
88
9
-For a list of all settings, view the Settings page, or type
9
+For a list of all settings, view the Settings page, or type
1010
<tt>fossil help settings</tt> from the command line.
1111
1212
1313
<h3>Repository settings</h3>
1414
@@ -16,17 +16,17 @@
1616
a subset of settings are copied to your local repository.
1717
1818
If you make a change to a setting on your local repository, it is not
1919
synced back to the server when you <tt>push</tt> or <tt>sync</tt>. If
2020
you make a change on the server, you need to manually make the change on
21
-all repositories which are cloned from this repository.
21
+all repositories which are cloned from this repository.
2222
2323
You can also set a setting globally on your local machine. The value
2424
will be used for all repositories cloned to your machine, unless
2525
overridden explicitly in a particular repository. Global settings can be
2626
set by using the <tt>-global</tt> option on the <tt>fossil settings</tt>
27
-command.
27
+command.
2828
2929
<h3>"Versionable" settings</h3>
3030
3131
Most of the settings control the behaviour of fossil on your local
3232
machine, largely acting to reflect your preference on how you want to
3333
--- www/settings.wiki
+++ www/settings.wiki
@@ -4,11 +4,11 @@
4
5 Settings control the behaviour of fossil. They are set with the
6 <tt>fossil settings</tt> command, or through the web interface in
7 the Settings page in the Admin section.
8
9 For a list of all settings, view the Settings page, or type
10 <tt>fossil help settings</tt> from the command line.
11
12
13 <h3>Repository settings</h3>
14
@@ -16,17 +16,17 @@
16 a subset of settings are copied to your local repository.
17
18 If you make a change to a setting on your local repository, it is not
19 synced back to the server when you <tt>push</tt> or <tt>sync</tt>. If
20 you make a change on the server, you need to manually make the change on
21 all repositories which are cloned from this repository.
22
23 You can also set a setting globally on your local machine. The value
24 will be used for all repositories cloned to your machine, unless
25 overridden explicitly in a particular repository. Global settings can be
26 set by using the <tt>-global</tt> option on the <tt>fossil settings</tt>
27 command.
28
29 <h3>"Versionable" settings</h3>
30
31 Most of the settings control the behaviour of fossil on your local
32 machine, largely acting to reflect your preference on how you want to
33
--- www/settings.wiki
+++ www/settings.wiki
@@ -4,11 +4,11 @@
4
5 Settings control the behaviour of fossil. They are set with the
6 <tt>fossil settings</tt> command, or through the web interface in
7 the Settings page in the Admin section.
8
9 For a list of all settings, view the Settings page, or type
10 <tt>fossil help settings</tt> from the command line.
11
12
13 <h3>Repository settings</h3>
14
@@ -16,17 +16,17 @@
16 a subset of settings are copied to your local repository.
17
18 If you make a change to a setting on your local repository, it is not
19 synced back to the server when you <tt>push</tt> or <tt>sync</tt>. If
20 you make a change on the server, you need to manually make the change on
21 all repositories which are cloned from this repository.
22
23 You can also set a setting globally on your local machine. The value
24 will be used for all repositories cloned to your machine, unless
25 overridden explicitly in a particular repository. Global settings can be
26 set by using the <tt>-global</tt> option on the <tt>fossil settings</tt>
27 command.
28
29 <h3>"Versionable" settings</h3>
30
31 Most of the settings control the behaviour of fossil on your local
32 machine, largely acting to reflect your preference on how you want to
33
+10 -10
--- www/shunning.wiki
+++ www/shunning.wiki
@@ -2,11 +2,11 @@
22
<h1 align="center">Deleting Content From Fossil</h1>
33
44
Fossil is designed to keep all historical content forever. Users
55
of Fossil are discouraged from "deleting" content simply because it
66
has become obsolete. Old content is part of the historical record
7
-(part of the "fossil record") and should be maintained indefinitely.
7
+(part of the "fossil record") and should be maintained indefinitely.
88
Such is the design intent of Fossil.
99
1010
Nevertheless, there may occasionally arise legitimate reasons for
1111
deleting content. Such reasons might include:
1212
@@ -21,35 +21,35 @@
2121
disrupting the operation of Fossil.
2222
2323
<h2>Shunning</h2>
2424
2525
Fossil provides a mechanism called "shunning" for removing content from
26
-a repository.
26
+a repository.
2727
2828
Every Fossil repository maintains a list of the SHA1 hash names of
2929
"shunned" artifacts.
30
-Fossil will refuse to push or pull any shunned artifact.
30
+Fossil will refuse to push or pull any shunned artifact.
3131
Furthermore, all shunned artifacts (but not the shunning list
3232
itself) are removed from the
3333
repository whenever the repository is reconstructed using the
3434
"rebuild" command.
3535
3636
<h3>Shunning lists are local state</h3>
3737
3838
The shunning list is part of the local state of a Fossil repository.
39
-In other words, shunning does not propagate to a remote repository
39
+In other words, shunning does not propagate to a remote repository
4040
using the normal "sync" mechanism. An artifact can be
4141
shunned from one repository but be allowed to exist in another. The fact that
4242
the shunning list does not propagate is a security feature. If the
4343
shunning list propagated then a malicious user (or
4444
a bug in the fossil code) might introduce a shun record that would
45
-propagate through all repositories in a network and permanently
45
+propagate through all repositories in a network and permanently
4646
destroy vital information. By refusing to propagate the shunning list,
47
-Fossil ensures that no remote user will ever be able to remove
47
+Fossil ensures that no remote user will ever be able to remove
4848
information from your personal repositories without your permission.
4949
50
-The shunning list does not propagate to a remote repository
50
+The shunning list does not propagate to a remote repository
5151
by the normal "sync" mechanism,
5252
but it is still possible to copy shuns from one repository to another
5353
using the "configuration" command:
5454
5555
<b>fossil configuration pull shun</b> <i>remote-url</i><br>
@@ -56,12 +56,12 @@
5656
<b>fossil configuration push shun</b> <i>remote-url</i>
5757
5858
The two command above will pull or push shunning lists from or to
5959
the <i>remote-url</i> indicated and merge the lists on the receiving
6060
end. "Admin" privilege on the remote server is required in order to
61
-push a shun list. In contrast, the shunning list will be automatically
62
-received by default as part of a normal client "pull" operation unless
61
+push a shun list. In contrast, the shunning list will be automatically
62
+received by default as part of a normal client "pull" operation unless
6363
disabled by the "<tt>auto-shun</tt>" setting.
6464
6565
Note that the shunning list remains in the repository even after the
6666
shunned artifact has been removed. This is to prevent the artifact
6767
from being reintroduced into the repository the next time it syncs with
@@ -68,11 +68,11 @@
6868
another repository that has not shunned the artifact.
6969
7070
<h3>Managing the shunning list</h3>
7171
7272
The complete shunning list for a repository can be viewed by a user
73
-with "admin" privilege on the "/shun" URL of the web interface to Fossil.
73
+with "admin" privilege on the "/shun" URL of the web interface to Fossil.
7474
That URL is accessible under the "Admin" button on the default menu
7575
bar. Items can be added to or removed from the shunning list. "Sync"
7676
operations are inhibited as soon as the artifact is added to the
7777
shunning list, but the content of the artifact is not actually removed
7878
from the repository until the next time the repository is rebuilt.
7979
--- www/shunning.wiki
+++ www/shunning.wiki
@@ -2,11 +2,11 @@
2 <h1 align="center">Deleting Content From Fossil</h1>
3
4 Fossil is designed to keep all historical content forever. Users
5 of Fossil are discouraged from "deleting" content simply because it
6 has become obsolete. Old content is part of the historical record
7 (part of the "fossil record") and should be maintained indefinitely.
8 Such is the design intent of Fossil.
9
10 Nevertheless, there may occasionally arise legitimate reasons for
11 deleting content. Such reasons might include:
12
@@ -21,35 +21,35 @@
21 disrupting the operation of Fossil.
22
23 <h2>Shunning</h2>
24
25 Fossil provides a mechanism called "shunning" for removing content from
26 a repository.
27
28 Every Fossil repository maintains a list of the SHA1 hash names of
29 "shunned" artifacts.
30 Fossil will refuse to push or pull any shunned artifact.
31 Furthermore, all shunned artifacts (but not the shunning list
32 itself) are removed from the
33 repository whenever the repository is reconstructed using the
34 "rebuild" command.
35
36 <h3>Shunning lists are local state</h3>
37
38 The shunning list is part of the local state of a Fossil repository.
39 In other words, shunning does not propagate to a remote repository
40 using the normal "sync" mechanism. An artifact can be
41 shunned from one repository but be allowed to exist in another. The fact that
42 the shunning list does not propagate is a security feature. If the
43 shunning list propagated then a malicious user (or
44 a bug in the fossil code) might introduce a shun record that would
45 propagate through all repositories in a network and permanently
46 destroy vital information. By refusing to propagate the shunning list,
47 Fossil ensures that no remote user will ever be able to remove
48 information from your personal repositories without your permission.
49
50 The shunning list does not propagate to a remote repository
51 by the normal "sync" mechanism,
52 but it is still possible to copy shuns from one repository to another
53 using the "configuration" command:
54
55 <b>fossil configuration pull shun</b> <i>remote-url</i><br>
@@ -56,12 +56,12 @@
56 <b>fossil configuration push shun</b> <i>remote-url</i>
57
58 The two command above will pull or push shunning lists from or to
59 the <i>remote-url</i> indicated and merge the lists on the receiving
60 end. "Admin" privilege on the remote server is required in order to
61 push a shun list. In contrast, the shunning list will be automatically
62 received by default as part of a normal client "pull" operation unless
63 disabled by the "<tt>auto-shun</tt>" setting.
64
65 Note that the shunning list remains in the repository even after the
66 shunned artifact has been removed. This is to prevent the artifact
67 from being reintroduced into the repository the next time it syncs with
@@ -68,11 +68,11 @@
68 another repository that has not shunned the artifact.
69
70 <h3>Managing the shunning list</h3>
71
72 The complete shunning list for a repository can be viewed by a user
73 with "admin" privilege on the "/shun" URL of the web interface to Fossil.
74 That URL is accessible under the "Admin" button on the default menu
75 bar. Items can be added to or removed from the shunning list. "Sync"
76 operations are inhibited as soon as the artifact is added to the
77 shunning list, but the content of the artifact is not actually removed
78 from the repository until the next time the repository is rebuilt.
79
--- www/shunning.wiki
+++ www/shunning.wiki
@@ -2,11 +2,11 @@
2 <h1 align="center">Deleting Content From Fossil</h1>
3
4 Fossil is designed to keep all historical content forever. Users
5 of Fossil are discouraged from "deleting" content simply because it
6 has become obsolete. Old content is part of the historical record
7 (part of the "fossil record") and should be maintained indefinitely.
8 Such is the design intent of Fossil.
9
10 Nevertheless, there may occasionally arise legitimate reasons for
11 deleting content. Such reasons might include:
12
@@ -21,35 +21,35 @@
21 disrupting the operation of Fossil.
22
23 <h2>Shunning</h2>
24
25 Fossil provides a mechanism called "shunning" for removing content from
26 a repository.
27
28 Every Fossil repository maintains a list of the SHA1 hash names of
29 "shunned" artifacts.
30 Fossil will refuse to push or pull any shunned artifact.
31 Furthermore, all shunned artifacts (but not the shunning list
32 itself) are removed from the
33 repository whenever the repository is reconstructed using the
34 "rebuild" command.
35
36 <h3>Shunning lists are local state</h3>
37
38 The shunning list is part of the local state of a Fossil repository.
39 In other words, shunning does not propagate to a remote repository
40 using the normal "sync" mechanism. An artifact can be
41 shunned from one repository but be allowed to exist in another. The fact that
42 the shunning list does not propagate is a security feature. If the
43 shunning list propagated then a malicious user (or
44 a bug in the fossil code) might introduce a shun record that would
45 propagate through all repositories in a network and permanently
46 destroy vital information. By refusing to propagate the shunning list,
47 Fossil ensures that no remote user will ever be able to remove
48 information from your personal repositories without your permission.
49
50 The shunning list does not propagate to a remote repository
51 by the normal "sync" mechanism,
52 but it is still possible to copy shuns from one repository to another
53 using the "configuration" command:
54
55 <b>fossil configuration pull shun</b> <i>remote-url</i><br>
@@ -56,12 +56,12 @@
56 <b>fossil configuration push shun</b> <i>remote-url</i>
57
58 The two command above will pull or push shunning lists from or to
59 the <i>remote-url</i> indicated and merge the lists on the receiving
60 end. "Admin" privilege on the remote server is required in order to
61 push a shun list. In contrast, the shunning list will be automatically
62 received by default as part of a normal client "pull" operation unless
63 disabled by the "<tt>auto-shun</tt>" setting.
64
65 Note that the shunning list remains in the repository even after the
66 shunned artifact has been removed. This is to prevent the artifact
67 from being reintroduced into the repository the next time it syncs with
@@ -68,11 +68,11 @@
68 another repository that has not shunned the artifact.
69
70 <h3>Managing the shunning list</h3>
71
72 The complete shunning list for a repository can be viewed by a user
73 with "admin" privilege on the "/shun" URL of the web interface to Fossil.
74 That URL is accessible under the "Admin" button on the default menu
75 bar. Items can be added to or removed from the shunning list. "Sync"
76 operations are inhibited as soon as the artifact is added to the
77 shunning list, but the content of the artifact is not actually removed
78 from the repository until the next time the repository is rebuilt.
79
+3 -3
--- www/stats.wiki
+++ www/stats.wiki
@@ -1,9 +1,9 @@
11
<title>Fossil Performance</title>
22
<h1 align="center">Performance Statistics</h1>
33
4
-The questions will inevitably arise: How does Fossil perform?
4
+The questions will inevitably arise: How does Fossil perform?
55
Does it use a lot of disk space or bandwidth? Is it scalable?
66
77
In an attempt to answers these questions, this report looks at several
88
projects that use fossil for configuration management and examines how
99
well they are working. The following table is a summary of the results.
@@ -96,21 +96,21 @@
9696
every ticket, and every check-in is a separate "artifact". One way to
9797
think of a Fossil project is as a bag of artifacts. Of course, there is
9898
a lot more than this going on in Fossil. Many of the artifacts have meaning
9999
and are related to other artifacts. But at a low level (for example when
100100
synchronizing two instances of the same project) the only thing that matters
101
-is the unordered collection of artifacts. In fact, one of the key
101
+is the unordered collection of artifacts. In fact, one of the key
102102
characteristics of Fossil is that the entire project history can be
103103
reconstructed simply by scanning the artifacts in an arbitrary order.
104104
105105
The number of check-ins is the number of times that the "commit" command
106106
has been run. A single check-in might change a 3 or 4 files, or it might
107107
change dozens or hundreds of files. Regardless of the number of files
108108
changed, it still only counts as one check-in.
109109
110110
The "Uncompressed Size" is the total size of all the artifacts within
111
-the repository assuming they were all uncompressed and stored
111
+the repository assuming they were all uncompressed and stored
112112
separately on the disk. Fossil makes use of delta compression between related
113113
versions of the same file, and then uses zlib compression on the resulting
114114
deltas. The total resulting repository size is shown after the uncompressed
115115
size.
116116
117117
--- www/stats.wiki
+++ www/stats.wiki
@@ -1,9 +1,9 @@
1 <title>Fossil Performance</title>
2 <h1 align="center">Performance Statistics</h1>
3
4 The questions will inevitably arise: How does Fossil perform?
5 Does it use a lot of disk space or bandwidth? Is it scalable?
6
7 In an attempt to answers these questions, this report looks at several
8 projects that use fossil for configuration management and examines how
9 well they are working. The following table is a summary of the results.
@@ -96,21 +96,21 @@
96 every ticket, and every check-in is a separate "artifact". One way to
97 think of a Fossil project is as a bag of artifacts. Of course, there is
98 a lot more than this going on in Fossil. Many of the artifacts have meaning
99 and are related to other artifacts. But at a low level (for example when
100 synchronizing two instances of the same project) the only thing that matters
101 is the unordered collection of artifacts. In fact, one of the key
102 characteristics of Fossil is that the entire project history can be
103 reconstructed simply by scanning the artifacts in an arbitrary order.
104
105 The number of check-ins is the number of times that the "commit" command
106 has been run. A single check-in might change a 3 or 4 files, or it might
107 change dozens or hundreds of files. Regardless of the number of files
108 changed, it still only counts as one check-in.
109
110 The "Uncompressed Size" is the total size of all the artifacts within
111 the repository assuming they were all uncompressed and stored
112 separately on the disk. Fossil makes use of delta compression between related
113 versions of the same file, and then uses zlib compression on the resulting
114 deltas. The total resulting repository size is shown after the uncompressed
115 size.
116
117
--- www/stats.wiki
+++ www/stats.wiki
@@ -1,9 +1,9 @@
1 <title>Fossil Performance</title>
2 <h1 align="center">Performance Statistics</h1>
3
4 The questions will inevitably arise: How does Fossil perform?
5 Does it use a lot of disk space or bandwidth? Is it scalable?
6
7 In an attempt to answers these questions, this report looks at several
8 projects that use fossil for configuration management and examines how
9 well they are working. The following table is a summary of the results.
@@ -96,21 +96,21 @@
96 every ticket, and every check-in is a separate "artifact". One way to
97 think of a Fossil project is as a bag of artifacts. Of course, there is
98 a lot more than this going on in Fossil. Many of the artifacts have meaning
99 and are related to other artifacts. But at a low level (for example when
100 synchronizing two instances of the same project) the only thing that matters
101 is the unordered collection of artifacts. In fact, one of the key
102 characteristics of Fossil is that the entire project history can be
103 reconstructed simply by scanning the artifacts in an arbitrary order.
104
105 The number of check-ins is the number of times that the "commit" command
106 has been run. A single check-in might change a 3 or 4 files, or it might
107 change dozens or hundreds of files. Regardless of the number of files
108 changed, it still only counts as one check-in.
109
110 The "Uncompressed Size" is the total size of all the artifacts within
111 the repository assuming they were all uncompressed and stored
112 separately on the disk. Fossil makes use of delta compression between related
113 versions of the same file, and then uses zlib compression on the resulting
114 deltas. The total resulting repository size is shown after the uncompressed
115 size.
116
117
+9 -9
--- www/sync.wiki
+++ www/sync.wiki
@@ -1,8 +1,8 @@
11
<title>The Fossil Sync Protocol</title>
22
3
-<p>This document describes the wire protocol used to synchronize
3
+<p>This document describes the wire protocol used to synchronize
44
content between two Fossil repositories.</p>
55
66
<h2>1.0 Overview</h2>
77
88
<p>The global state of a fossil repository consists of an unordered
@@ -22,11 +22,11 @@
2222
shared to a few hundred.</p>
2323
2424
<p>Each repository also has local state. The local state determines
2525
the web-page formatting preferences, authorized users, ticket formats,
2626
and similar information that varies from one repository to another.
27
-The local state is not using transferred during a sync. Except,
27
+The local state is not using transferred during a sync. Except,
2828
some local state is transferred during a [/help?cmd=clone|clone]
2929
in order to initialize the local state of the new repository. And
3030
the [/help?cmd=configuration|config push] and
3131
[/help?cmd=configuration|config pull]
3232
commands can be an administrator to sync local state.</p>
@@ -40,15 +40,15 @@
4040
request.</p>
4141
4242
<p>The server might be running as an independent server
4343
using the <b>server</b> command, or it might be launched from
4444
inetd or xinetd using the <b>http</b> command. Or the server might
45
-be launched from CGI.
45
+be launched from CGI.
4646
(See "[./server.wiki|How To Configure A Fossil Server]" for details.)
4747
The specifics of how the server listens
4848
for incoming HTTP requests is immaterial to this protocol.
49
-The important point is that the server is listening for requests and
49
+The important point is that the server is listening for requests and
5050
the client is the issuer of the requests.</p>
5151
5252
<p>A single push, pull, or sync might involve multiple HTTP requests.
5353
The client maintains state between all requests. But on the server
5454
side, each request is independent. The server does not preserve
@@ -55,11 +55,11 @@
5555
any information about the client from one request to the next.</p>
5656
5757
<h4>2.0.1 Encrypted Transport</h4>
5858
5959
<p>In the current implementation of Fossil, the server only
60
-understands HTTP requests. The client can send either
60
+understands HTTP requests. The client can send either
6161
clear-text HTTP requests or encrypted HTTPS requests. But when
6262
HTTPS requests are sent, they first must be decrypted by a webserver
6363
or proxy before being passed to the Fossil server. This limitation
6464
may be relaxed in a future release.</p>
6565
@@ -220,11 +220,11 @@
220220
introduced to improve the speed of the transfer of content by sending the
221221
compressed artifact directly from the server database to the client.</p>
222222
223223
<p>Compressed File cards are similar to File cards, sharing the same
224224
in-line "payload" data characteristics and also the same treatment of
225
-direct content or delta content. It comes in two different formats
225
+direct content or delta content. Cfile cards come in two different formats
226226
depending on whether the artifact is sent directly or as a delta from
227227
some other artifact.</p>
228228
229229
<blockquote>
230230
<b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
@@ -277,11 +277,11 @@
277277
for the unversioned file, or "<b>-</b>" for deleted content.
278278
The <i>size</i> field is the (uncompressed) size of the content
279279
in bytes. The <i>flags</i> field is an integer which is interpreted
280280
as an array of bits. The 0x0004 bit of <i>flags</i> indicates that
281281
the <i>content</i> is to be omitted. The content might be omitted if
282
-it is too large to transmit, or if the send merely wants to update the
282
+it is too large to transmit, or if the sender merely wants to update the
283283
modification time of the file without changing the files content.
284284
The <i>content</i> is the (uncompressed) content of the file.
285285
286286
<p>The receiver should only accept the uvfile card if the hash and
287287
size match the content and if the mtime is newer than any existing
@@ -398,21 +398,21 @@
398398
identified by the first argument is private on the sender and should
399399
be ignored unless a "--private" [/help?cmd=sync|sync] is occurring.
400400
401401
<h4>3.6.1 Unversioned Igot Cards</h4>
402402
403
-<p>Zero or more "uvigot" cards are sent from client to server when
403
+<p>Zero or more "uvigot" cards are sent from server to client when
404404
synchronizing unversioned content. The format of a uvigot card is
405405
as follows:
406406
407407
<blockquote>
408408
<b>uvigot</b> <i>name mtime hash size</i>
409409
</blockquote>
410410
411411
<p>The <i>name</i> argument is the name of an unversioned file.
412412
The <i>mtime</i> is the last modification time of the unversioned file
413
-in seconds since 1970.
413
+in seconds since 1970.
414414
The <i>hash</i> is the SHA1 hash of the unversioned file content, or
415415
"<b>-</b>" if the file has been deleted.
416416
The <i>size</i> is the uncompressed size of the file in bytes.
417417
418418
<p>When the server sees a "pragma uv-hash" card for which the hash
419419
--- www/sync.wiki
+++ www/sync.wiki
@@ -1,8 +1,8 @@
1 <title>The Fossil Sync Protocol</title>
2
3 <p>This document describes the wire protocol used to synchronize
4 content between two Fossil repositories.</p>
5
6 <h2>1.0 Overview</h2>
7
8 <p>The global state of a fossil repository consists of an unordered
@@ -22,11 +22,11 @@
22 shared to a few hundred.</p>
23
24 <p>Each repository also has local state. The local state determines
25 the web-page formatting preferences, authorized users, ticket formats,
26 and similar information that varies from one repository to another.
27 The local state is not using transferred during a sync. Except,
28 some local state is transferred during a [/help?cmd=clone|clone]
29 in order to initialize the local state of the new repository. And
30 the [/help?cmd=configuration|config push] and
31 [/help?cmd=configuration|config pull]
32 commands can be an administrator to sync local state.</p>
@@ -40,15 +40,15 @@
40 request.</p>
41
42 <p>The server might be running as an independent server
43 using the <b>server</b> command, or it might be launched from
44 inetd or xinetd using the <b>http</b> command. Or the server might
45 be launched from CGI.
46 (See "[./server.wiki|How To Configure A Fossil Server]" for details.)
47 The specifics of how the server listens
48 for incoming HTTP requests is immaterial to this protocol.
49 The important point is that the server is listening for requests and
50 the client is the issuer of the requests.</p>
51
52 <p>A single push, pull, or sync might involve multiple HTTP requests.
53 The client maintains state between all requests. But on the server
54 side, each request is independent. The server does not preserve
@@ -55,11 +55,11 @@
55 any information about the client from one request to the next.</p>
56
57 <h4>2.0.1 Encrypted Transport</h4>
58
59 <p>In the current implementation of Fossil, the server only
60 understands HTTP requests. The client can send either
61 clear-text HTTP requests or encrypted HTTPS requests. But when
62 HTTPS requests are sent, they first must be decrypted by a webserver
63 or proxy before being passed to the Fossil server. This limitation
64 may be relaxed in a future release.</p>
65
@@ -220,11 +220,11 @@
220 introduced to improve the speed of the transfer of content by sending the
221 compressed artifact directly from the server database to the client.</p>
222
223 <p>Compressed File cards are similar to File cards, sharing the same
224 in-line "payload" data characteristics and also the same treatment of
225 direct content or delta content. It comes in two different formats
226 depending on whether the artifact is sent directly or as a delta from
227 some other artifact.</p>
228
229 <blockquote>
230 <b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
@@ -277,11 +277,11 @@
277 for the unversioned file, or "<b>-</b>" for deleted content.
278 The <i>size</i> field is the (uncompressed) size of the content
279 in bytes. The <i>flags</i> field is an integer which is interpreted
280 as an array of bits. The 0x0004 bit of <i>flags</i> indicates that
281 the <i>content</i> is to be omitted. The content might be omitted if
282 it is too large to transmit, or if the send merely wants to update the
283 modification time of the file without changing the files content.
284 The <i>content</i> is the (uncompressed) content of the file.
285
286 <p>The receiver should only accept the uvfile card if the hash and
287 size match the content and if the mtime is newer than any existing
@@ -398,21 +398,21 @@
398 identified by the first argument is private on the sender and should
399 be ignored unless a "--private" [/help?cmd=sync|sync] is occurring.
400
401 <h4>3.6.1 Unversioned Igot Cards</h4>
402
403 <p>Zero or more "uvigot" cards are sent from client to server when
404 synchronizing unversioned content. The format of a uvigot card is
405 as follows:
406
407 <blockquote>
408 <b>uvigot</b> <i>name mtime hash size</i>
409 </blockquote>
410
411 <p>The <i>name</i> argument is the name of an unversioned file.
412 The <i>mtime</i> is the last modification time of the unversioned file
413 in seconds since 1970.
414 The <i>hash</i> is the SHA1 hash of the unversioned file content, or
415 "<b>-</b>" if the file has been deleted.
416 The <i>size</i> is the uncompressed size of the file in bytes.
417
418 <p>When the server sees a "pragma uv-hash" card for which the hash
419
--- www/sync.wiki
+++ www/sync.wiki
@@ -1,8 +1,8 @@
1 <title>The Fossil Sync Protocol</title>
2
3 <p>This document describes the wire protocol used to synchronize
4 content between two Fossil repositories.</p>
5
6 <h2>1.0 Overview</h2>
7
8 <p>The global state of a fossil repository consists of an unordered
@@ -22,11 +22,11 @@
22 shared to a few hundred.</p>
23
24 <p>Each repository also has local state. The local state determines
25 the web-page formatting preferences, authorized users, ticket formats,
26 and similar information that varies from one repository to another.
27 The local state is not using transferred during a sync. Except,
28 some local state is transferred during a [/help?cmd=clone|clone]
29 in order to initialize the local state of the new repository. And
30 the [/help?cmd=configuration|config push] and
31 [/help?cmd=configuration|config pull]
32 commands can be an administrator to sync local state.</p>
@@ -40,15 +40,15 @@
40 request.</p>
41
42 <p>The server might be running as an independent server
43 using the <b>server</b> command, or it might be launched from
44 inetd or xinetd using the <b>http</b> command. Or the server might
45 be launched from CGI.
46 (See "[./server.wiki|How To Configure A Fossil Server]" for details.)
47 The specifics of how the server listens
48 for incoming HTTP requests is immaterial to this protocol.
49 The important point is that the server is listening for requests and
50 the client is the issuer of the requests.</p>
51
52 <p>A single push, pull, or sync might involve multiple HTTP requests.
53 The client maintains state between all requests. But on the server
54 side, each request is independent. The server does not preserve
@@ -55,11 +55,11 @@
55 any information about the client from one request to the next.</p>
56
57 <h4>2.0.1 Encrypted Transport</h4>
58
59 <p>In the current implementation of Fossil, the server only
60 understands HTTP requests. The client can send either
61 clear-text HTTP requests or encrypted HTTPS requests. But when
62 HTTPS requests are sent, they first must be decrypted by a webserver
63 or proxy before being passed to the Fossil server. This limitation
64 may be relaxed in a future release.</p>
65
@@ -220,11 +220,11 @@
220 introduced to improve the speed of the transfer of content by sending the
221 compressed artifact directly from the server database to the client.</p>
222
223 <p>Compressed File cards are similar to File cards, sharing the same
224 in-line "payload" data characteristics and also the same treatment of
225 direct content or delta content. Cfile cards come in two different formats
226 depending on whether the artifact is sent directly or as a delta from
227 some other artifact.</p>
228
229 <blockquote>
230 <b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br>
@@ -277,11 +277,11 @@
277 for the unversioned file, or "<b>-</b>" for deleted content.
278 The <i>size</i> field is the (uncompressed) size of the content
279 in bytes. The <i>flags</i> field is an integer which is interpreted
280 as an array of bits. The 0x0004 bit of <i>flags</i> indicates that
281 the <i>content</i> is to be omitted. The content might be omitted if
282 it is too large to transmit, or if the sender merely wants to update the
283 modification time of the file without changing the files content.
284 The <i>content</i> is the (uncompressed) content of the file.
285
286 <p>The receiver should only accept the uvfile card if the hash and
287 size match the content and if the mtime is newer than any existing
@@ -398,21 +398,21 @@
398 identified by the first argument is private on the sender and should
399 be ignored unless a "--private" [/help?cmd=sync|sync] is occurring.
400
401 <h4>3.6.1 Unversioned Igot Cards</h4>
402
403 <p>Zero or more "uvigot" cards are sent from server to client when
404 synchronizing unversioned content. The format of a uvigot card is
405 as follows:
406
407 <blockquote>
408 <b>uvigot</b> <i>name mtime hash size</i>
409 </blockquote>
410
411 <p>The <i>name</i> argument is the name of an unversioned file.
412 The <i>mtime</i> is the last modification time of the unversioned file
413 in seconds since 1970.
414 The <i>hash</i> is the SHA1 hash of the unversioned file content, or
415 "<b>-</b>" if the file has been deleted.
416 The <i>size</i> is the uncompressed size of the file in bytes.
417
418 <p>When the server sees a "pragma uv-hash" card for which the hash
419
+28 -5
--- www/th1.md
+++ www/th1.md
@@ -164,20 +164,22 @@
164164
* render
165165
* repository
166166
* searchable
167167
* setParameter
168168
* setting
169
+ * stime
169170
* styleHeader
170171
* styleFooter
171172
* tclEval
172173
* tclExpr
173174
* tclInvoke
174175
* tclIsSafe
175176
* tclMakeSafe
176177
* tclReady
177178
* trace
178
- * stime
179
+ * unversioned content
180
+ * unversioned list
179181
* utime
180182
* verifyCsrf
181183
* wiki
182184
183185
Each of the commands above is documented by a block comment above their
@@ -249,11 +251,11 @@
249251
250252
Renders STRING as wiki content; however, only links are handled. No
251253
other markup is processed.
252254
253255
<a name="dir"></a>TH1 dir Command
--------------------------------------------
256
+---------------------------------
254257
255258
* dir CHECKIN ?GLOB? ?DETAILS?
256259
257260
Returns a list containing all files in CHECKIN. If GLOB is given only
258261
the files matching the pattern GLOB within CHECKIN will be returned.
@@ -400,11 +402,11 @@
400402
401403
Returns one more than the number of \n characters in STRING. But
402404
never returns less than MIN or more than MAX.
403405
404406
<a name="markdown"></a>TH1 markdown Command
----------------------------------------------
407
+-------------------------------------------
405408
406409
* markdown STRING
407410
408411
Renders the input string as markdown. The result is a two-element list.
409412
The first element contains the body, rendered as HTML. The second element
@@ -517,10 +519,18 @@
517519
-----------------------------------------
518520
519521
* setting name
520522
521523
Gets and returns the value of the specified setting.
524
+
525
+<a name="stime"></a>TH1 stime Command
526
+-------------------------------------
527
+
528
+ * stime
529
+
530
+Returns the number of microseconds of CPU time consumed by the current
531
+process in system space.
522532
523533
<a name="styleHeader"></a>TH1 styleHeader Command
524534
-------------------------------------------------
525535
526536
* styleHeader TITLE
@@ -577,11 +587,11 @@
577587
578588
Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
579589
will be created automatically if it has not been already.
580590
581591
<a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
----------------------------------------------
592
+-------------------------------------------------
582593
583594
**This command requires the Tcl integration feature.**
584595
585596
* tclMakeSafe
586597
@@ -603,17 +613,26 @@
603613
604614
* trace STRING
605615
606616
Generates a TH1 trace message if TH1 tracing is enabled.
607617
608
-<a name="stime"></a>TH1 stime Command
--------------------------------------
618
+<a name="unversioned_content"></a>TH1 unversioned content Command
619
+-----------------------------------------------------------------
620
+
621
+ * unversioned content FILENAME
622
+
623
+Attempts to locate the specified unversioned file and return its contents.
624
+An error is generated if the repository is not open or the unversioned file
625
+cannot be found.
626
+
627
+<a name="unversioned_list"></a>TH1 unversioned list Command
628
+-----------------------------------------------------------
609629
610
- * stime
630
+ * unversioned list
611631
612
-Returns the number of microseconds of CPU time consumed by the current
613
-process in system space.
632
+Returns a list of the names of all unversioned files held in the local
633
+repository. An error is generated if the repository is not open.
614634
615635
<a name="utime"></a>TH1 utime Command
616636
-------------------------------------
617637
618638
* utime
619639
--- www/th1.md
+++ www/th1.md
@@ -164,20 +164,22 @@
164 * render
165 * repository
166 * searchable
167 * setParameter
168 * setting
 
169 * styleHeader
170 * styleFooter
171 * tclEval
172 * tclExpr
173 * tclInvoke
174 * tclIsSafe
175 * tclMakeSafe
176 * tclReady
177 * trace
178 * stime
 
179 * utime
180 * verifyCsrf
181 * wiki
182
183 Each of the commands above is documented by a block comment above their
@@ -249,11 +251,11 @@
249
250 Renders STRING as wiki content; however, only links are handled. No
251 other markup is processed.
252
253 <a name="dir"></a>TH1 dir Command
--------------------------------------------
 
254
255 * dir CHECKIN ?GLOB? ?DETAILS?
256
257 Returns a list containing all files in CHECKIN. If GLOB is given only
258 the files matching the pattern GLOB within CHECKIN will be returned.
@@ -400,11 +402,11 @@
400
401 Returns one more than the number of \n characters in STRING. But
402 never returns less than MIN or more than MAX.
403
404 <a name="markdown"></a>TH1 markdown Command
----------------------------------------------
 
405
406 * markdown STRING
407
408 Renders the input string as markdown. The result is a two-element list.
409 The first element contains the body, rendered as HTML. The second element
@@ -517,10 +519,18 @@
517 -----------------------------------------
518
519 * setting name
520
521 Gets and returns the value of the specified setting.
 
 
 
 
 
 
 
 
522
523 <a name="styleHeader"></a>TH1 styleHeader Command
524 -------------------------------------------------
525
526 * styleHeader TITLE
@@ -577,11 +587,11 @@
577
578 Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
579 will be created automatically if it has not been already.
580
581 <a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
----------------------------------------------
 
582
583 **This command requires the Tcl integration feature.**
584
585 * tclMakeSafe
586
@@ -603,17 +613,26 @@
603
604 * trace STRING
605
606 Generates a TH1 trace message if TH1 tracing is enabled.
607
608 <a name="stime"></a>TH1 stime Command
--------------------------------------
 
 
 
 
 
 
 
 
 
 
 
609
610 * stime
611
612 Returns the number of microseconds of CPU time consumed by the current
613 process in system space.
614
615 <a name="utime"></a>TH1 utime Command
616 -------------------------------------
617
618 * utime
619
--- www/th1.md
+++ www/th1.md
@@ -164,20 +164,22 @@
164 * render
165 * repository
166 * searchable
167 * setParameter
168 * setting
169 * stime
170 * styleHeader
171 * styleFooter
172 * tclEval
173 * tclExpr
174 * tclInvoke
175 * tclIsSafe
176 * tclMakeSafe
177 * tclReady
178 * trace
179 * unversioned content
180 * unversioned list
181 * utime
182 * verifyCsrf
183 * wiki
184
185 Each of the commands above is documented by a block comment above their
@@ -249,11 +251,11 @@
251
252 Renders STRING as wiki content; however, only links are handled. No
253 other markup is processed.
254
255 <a name="dir"></a>TH1 dir Command
--------------------------------------------
256 ---------------------------------
257
258 * dir CHECKIN ?GLOB? ?DETAILS?
259
260 Returns a list containing all files in CHECKIN. If GLOB is given only
261 the files matching the pattern GLOB within CHECKIN will be returned.
@@ -400,11 +402,11 @@
402
403 Returns one more than the number of \n characters in STRING. But
404 never returns less than MIN or more than MAX.
405
406 <a name="markdown"></a>TH1 markdown Command
----------------------------------------------
407 -------------------------------------------
408
409 * markdown STRING
410
411 Renders the input string as markdown. The result is a two-element list.
412 The first element contains the body, rendered as HTML. The second element
@@ -517,10 +519,18 @@
519 -----------------------------------------
520
521 * setting name
522
523 Gets and returns the value of the specified setting.
524
525 <a name="stime"></a>TH1 stime Command
526 -------------------------------------
527
528 * stime
529
530 Returns the number of microseconds of CPU time consumed by the current
531 process in system space.
532
533 <a name="styleHeader"></a>TH1 styleHeader Command
534 -------------------------------------------------
535
536 * styleHeader TITLE
@@ -577,11 +587,11 @@
587
588 Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
589 will be created automatically if it has not been already.
590
591 <a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
----------------------------------------------
592 -------------------------------------------------
593
594 **This command requires the Tcl integration feature.**
595
596 * tclMakeSafe
597
@@ -603,17 +613,26 @@
613
614 * trace STRING
615
616 Generates a TH1 trace message if TH1 tracing is enabled.
617
 
--------------------------------------
618 <a name="unversioned_content"></a>TH1 unversioned content Command
619 -----------------------------------------------------------------
620
621 * unversioned content FILENAME
622
623 Attempts to locate the specified unversioned file and return its contents.
624 An error is generated if the repository is not open or the unversioned file
625 cannot be found.
626
627 <a name="unversioned_list"></a>TH1 unversioned list Command
628 -----------------------------------------------------------
629
630 * unversioned list
631
632 Returns a list of the names of all unversioned files held in the local
633 repository. An error is generated if the repository is not open.
634
635 <a name="utime"></a>TH1 utime Command
636 -------------------------------------
637
638 * utime
639
--- www/theory1.wiki
+++ www/theory1.wiki
@@ -16,18 +16,18 @@
1616
1717
<h2>Fossil Is A NoSQL Database</h2>
1818
1919
We begin with the first question: Fossil is not based on a distributed
2020
NoSQL database because Fossil <u><i>is</i></u> a distributed NoSQL database.
21
-Fossil is <u>not</u> based on SQLite.
21
+Fossil is <u>not</u> based on SQLite.
2222
The current implementation of Fossil uses
2323
SQLite as a local store for the content of the distributed database and as
2424
a cache for meta-information about the distributed database that is precomputed
2525
for quick and easy presentation. But the use of SQLite in this role is an
2626
implementation detail and is not fundamental to the design. Some future
2727
version of Fossil might do away with SQLite and substitute a pile-of-files or
28
-a key/value database in place of SQLite.
28
+a key/value database in place of SQLite.
2929
(Actually, that is very unlikely
3030
to happen since SQLite works amazingly well in its current role, but the point
3131
is that omitting SQLite from Fossil is a theoretical possibility.)
3232
3333
The underlying database that Fossil implements has nothing to do with
@@ -64,11 +64,11 @@
6464
a NoSQL database) and there is the local relational database. The
6565
bag-of-artifacts database has a fixed format and is what defines a Fossil
6666
repository. Fossil will never modify the file format of the bag-of-artifacts
6767
database in an incompatible way because to do so would be to make something
6868
that is no longer "Fossil". The local relational database, on the other hand,
69
-is a cache that contains information derived from the bag-of-artifacts.
69
+is a cache that contains information derived from the bag-of-artifacts.
7070
The schema of the local relational database changes from time to time as
7171
the Fossil implementation is enhanced, and the content is recomputed from
7272
the unchanging bag of artifacts. The local relational database is an
7373
implementation detail which currently happens to use SQLite.
7474
@@ -89,11 +89,11 @@
8989
the first question.
9090
9191
<h2>SQL Is A High-Level Scripting Language</h2>
9292
9393
The second concern states that Fossil does not use a high-level scripting
94
-language. But that is not true. Fossil uses SQL (as implemented by SQLite)
94
+language. But that is not true. Fossil uses SQL (as implemented by SQLite)
9595
as its scripting language.
9696
9797
This misunderstanding likely arises because people fail
9898
to appreciate that SQL is a programming language. People are taught that SQL
9999
is a "query language" as if that were somehow different from a
@@ -125,11 +125,11 @@
125125
out using SQL statements. It is true that these SQL statements are glued
126126
together with C code, but it turns out that C works surprisingly well in
127127
that role. Several early prototypes of Fossil were written in a scripting
128128
language (TCL). We normally find that TCL programs are shorter than the
129129
equivalent C code by a factor of 10 or more. But in the case of Fossil,
130
-the use of TCL was actually making the code longer and more difficult to
130
+the use of TCL was actually making the code longer and more difficult to
131131
understand.
132132
And so in the final design, we switched from TCL to C in order to make
133133
the code easier to implement and debug.
134134
135135
Without the advantages of having SQLite built in, the design might well
136136
--- www/theory1.wiki
+++ www/theory1.wiki
@@ -16,18 +16,18 @@
16
17 <h2>Fossil Is A NoSQL Database</h2>
18
19 We begin with the first question: Fossil is not based on a distributed
20 NoSQL database because Fossil <u><i>is</i></u> a distributed NoSQL database.
21 Fossil is <u>not</u> based on SQLite.
22 The current implementation of Fossil uses
23 SQLite as a local store for the content of the distributed database and as
24 a cache for meta-information about the distributed database that is precomputed
25 for quick and easy presentation. But the use of SQLite in this role is an
26 implementation detail and is not fundamental to the design. Some future
27 version of Fossil might do away with SQLite and substitute a pile-of-files or
28 a key/value database in place of SQLite.
29 (Actually, that is very unlikely
30 to happen since SQLite works amazingly well in its current role, but the point
31 is that omitting SQLite from Fossil is a theoretical possibility.)
32
33 The underlying database that Fossil implements has nothing to do with
@@ -64,11 +64,11 @@
64 a NoSQL database) and there is the local relational database. The
65 bag-of-artifacts database has a fixed format and is what defines a Fossil
66 repository. Fossil will never modify the file format of the bag-of-artifacts
67 database in an incompatible way because to do so would be to make something
68 that is no longer "Fossil". The local relational database, on the other hand,
69 is a cache that contains information derived from the bag-of-artifacts.
70 The schema of the local relational database changes from time to time as
71 the Fossil implementation is enhanced, and the content is recomputed from
72 the unchanging bag of artifacts. The local relational database is an
73 implementation detail which currently happens to use SQLite.
74
@@ -89,11 +89,11 @@
89 the first question.
90
91 <h2>SQL Is A High-Level Scripting Language</h2>
92
93 The second concern states that Fossil does not use a high-level scripting
94 language. But that is not true. Fossil uses SQL (as implemented by SQLite)
95 as its scripting language.
96
97 This misunderstanding likely arises because people fail
98 to appreciate that SQL is a programming language. People are taught that SQL
99 is a "query language" as if that were somehow different from a
@@ -125,11 +125,11 @@
125 out using SQL statements. It is true that these SQL statements are glued
126 together with C code, but it turns out that C works surprisingly well in
127 that role. Several early prototypes of Fossil were written in a scripting
128 language (TCL). We normally find that TCL programs are shorter than the
129 equivalent C code by a factor of 10 or more. But in the case of Fossil,
130 the use of TCL was actually making the code longer and more difficult to
131 understand.
132 And so in the final design, we switched from TCL to C in order to make
133 the code easier to implement and debug.
134
135 Without the advantages of having SQLite built in, the design might well
136
--- www/theory1.wiki
+++ www/theory1.wiki
@@ -16,18 +16,18 @@
16
17 <h2>Fossil Is A NoSQL Database</h2>
18
19 We begin with the first question: Fossil is not based on a distributed
20 NoSQL database because Fossil <u><i>is</i></u> a distributed NoSQL database.
21 Fossil is <u>not</u> based on SQLite.
22 The current implementation of Fossil uses
23 SQLite as a local store for the content of the distributed database and as
24 a cache for meta-information about the distributed database that is precomputed
25 for quick and easy presentation. But the use of SQLite in this role is an
26 implementation detail and is not fundamental to the design. Some future
27 version of Fossil might do away with SQLite and substitute a pile-of-files or
28 a key/value database in place of SQLite.
29 (Actually, that is very unlikely
30 to happen since SQLite works amazingly well in its current role, but the point
31 is that omitting SQLite from Fossil is a theoretical possibility.)
32
33 The underlying database that Fossil implements has nothing to do with
@@ -64,11 +64,11 @@
64 a NoSQL database) and there is the local relational database. The
65 bag-of-artifacts database has a fixed format and is what defines a Fossil
66 repository. Fossil will never modify the file format of the bag-of-artifacts
67 database in an incompatible way because to do so would be to make something
68 that is no longer "Fossil". The local relational database, on the other hand,
69 is a cache that contains information derived from the bag-of-artifacts.
70 The schema of the local relational database changes from time to time as
71 the Fossil implementation is enhanced, and the content is recomputed from
72 the unchanging bag of artifacts. The local relational database is an
73 implementation detail which currently happens to use SQLite.
74
@@ -89,11 +89,11 @@
89 the first question.
90
91 <h2>SQL Is A High-Level Scripting Language</h2>
92
93 The second concern states that Fossil does not use a high-level scripting
94 language. But that is not true. Fossil uses SQL (as implemented by SQLite)
95 as its scripting language.
96
97 This misunderstanding likely arises because people fail
98 to appreciate that SQL is a programming language. People are taught that SQL
99 is a "query language" as if that were somehow different from a
@@ -125,11 +125,11 @@
125 out using SQL statements. It is true that these SQL statements are glued
126 together with C code, but it turns out that C works surprisingly well in
127 that role. Several early prototypes of Fossil were written in a scripting
128 language (TCL). We normally find that TCL programs are shorter than the
129 equivalent C code by a factor of 10 or more. But in the case of Fossil,
130 the use of TCL was actually making the code longer and more difficult to
131 understand.
132 And so in the final design, we switched from TCL to C in order to make
133 the code easier to implement and debug.
134
135 Without the advantages of having SQLite built in, the design might well
136
+1 -2
--- www/webui.wiki
+++ www/webui.wiki
@@ -25,12 +25,11 @@
2525
There are no extra programs to install or setup.
2626
Everything you need is already pre-configured and built into the
2727
self-contained, stand-alone Fossil executable.
2828
2929
As an example of how useful this web interface can be,
30
-the entire [./index.wiki | Fossil website] (except for the
31
-[http://www.fossil-scm.org/download.html | download page]),
30
+the entire [./index.wiki | Fossil website],
3231
including the document you are now reading,
3332
is rendered using the Fossil web interface, with no enhancements,
3433
and little customization.
3534
3635
<blockquote>
3736
--- www/webui.wiki
+++ www/webui.wiki
@@ -25,12 +25,11 @@
25 There are no extra programs to install or setup.
26 Everything you need is already pre-configured and built into the
27 self-contained, stand-alone Fossil executable.
28
29 As an example of how useful this web interface can be,
30 the entire [./index.wiki | Fossil website] (except for the
31 [http://www.fossil-scm.org/download.html | download page]),
32 including the document you are now reading,
33 is rendered using the Fossil web interface, with no enhancements,
34 and little customization.
35
36 <blockquote>
37
--- www/webui.wiki
+++ www/webui.wiki
@@ -25,12 +25,11 @@
25 There are no extra programs to install or setup.
26 Everything you need is already pre-configured and built into the
27 self-contained, stand-alone Fossil executable.
28
29 As an example of how useful this web interface can be,
30 the entire [./index.wiki | Fossil website],
 
31 including the document you are now reading,
32 is rendered using the Fossil web interface, with no enhancements,
33 and little customization.
34
35 <blockquote>
36
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -37,10 +37,11 @@
3737
<li>Failed disk-drives cause no loss of work
3838
<li>Avoid wasting time doing manual file copying
3939
<li>Avoid human errors during manual backups
4040
</ol>
4141
</ol>
42
+<a name='definitions'></a>
4243
<li><p><b>Definitions</b></p>
4344
<ul>
4445
<li><p><b>Project</b> &rarr;
4546
a collection of computer files that serve some common
4647
purpose. Often the project is a software application and the
@@ -59,12 +60,12 @@
5960
project that has files scattered hither and yon all over
6061
the disk. In other words, Fossil only works for projects
6162
where the files are laid out such that they can be archived
6263
into a ZIP file or tarball.
6364
</ul>
64
- <li><p><b>Repository</b>
65
- (also called "repo") &rarr; a single file that contains
65
+ <li><p><b>Repository</b> &rarr;
66
+ (also called "repo") a single file that contains
6667
all historical versions of all files in a project. A repo is similar
6768
to a ZIP archive in that it is a single file that stores compressed
6869
versions of many other files. Files can be extracted from the
6970
repo and new files can be added to the repo, just as with a ZIP
7071
archive. But a repo has other capabilities above and beyond
7172
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -37,10 +37,11 @@
37 <li>Failed disk-drives cause no loss of work
38 <li>Avoid wasting time doing manual file copying
39 <li>Avoid human errors during manual backups
40 </ol>
41 </ol>
 
42 <li><p><b>Definitions</b></p>
43 <ul>
44 <li><p><b>Project</b> &rarr;
45 a collection of computer files that serve some common
46 purpose. Often the project is a software application and the
@@ -59,12 +60,12 @@
59 project that has files scattered hither and yon all over
60 the disk. In other words, Fossil only works for projects
61 where the files are laid out such that they can be archived
62 into a ZIP file or tarball.
63 </ul>
64 <li><p><b>Repository</b>
65 (also called "repo") &rarr; a single file that contains
66 all historical versions of all files in a project. A repo is similar
67 to a ZIP archive in that it is a single file that stores compressed
68 versions of many other files. Files can be extracted from the
69 repo and new files can be added to the repo, just as with a ZIP
70 archive. But a repo has other capabilities above and beyond
71
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -37,10 +37,11 @@
37 <li>Failed disk-drives cause no loss of work
38 <li>Avoid wasting time doing manual file copying
39 <li>Avoid human errors during manual backups
40 </ol>
41 </ol>
42 <a name='definitions'></a>
43 <li><p><b>Definitions</b></p>
44 <ul>
45 <li><p><b>Project</b> &rarr;
46 a collection of computer files that serve some common
47 purpose. Often the project is a software application and the
@@ -59,12 +60,12 @@
60 project that has files scattered hither and yon all over
61 the disk. In other words, Fossil only works for projects
62 where the files are laid out such that they can be archived
63 into a ZIP file or tarball.
64 </ul>
65 <li><p><b>Repository</b> &rarr;
66 (also called "repo") a single file that contains
67 all historical versions of all files in a project. A repo is similar
68 to a ZIP archive in that it is a single file that stores compressed
69 versions of many other files. Files can be extracted from the
70 repo and new files can be added to the repo, just as with a ZIP
71 archive. But a repo has other capabilities above and beyond
72
--- www/wikitheory.wiki
+++ www/wikitheory.wiki
@@ -34,26 +34,26 @@
3434
the wiki page will fork. The web interface will display whichever edit
3535
was checked in last. The other edit can be found in the history. The
3636
file format will support merging the branches back together, but there
3737
is no mechanism in the user interface (yet) to perform the merge.
3838
39
-Every change to a wiki page is a separate
39
+Every change to a wiki page is a separate
4040
[./fileformat.wiki | control artifact]
4141
of type [./fileformat.wiki#wikichng | "Wiki Page"].
4242
4343
<h2>Embedded Documentation</h2>
4444
4545
Files in the source tree that use the ".wiki", ".md", or ".markdown" suffixes
46
-can be accessed and displayed using special URLs to the fossil server.
46
+can be accessed and displayed using special URLs to the fossil server.
4747
This allows
48
-project documentation to be stored in the source tree and accessed
48
+project documentation to be stored in the source tree and accessed
4949
online. (Details are described [./embeddeddoc.wiki | separately].)
5050
5151
Some projects prefer to store their documentation in wiki. There is nothing
5252
wrong with that. But other projects prefer to keep documentation as part
5353
of the source tree, so that it is versioned along with the source tree and
54
-so that only developers with check-in privileges can change it.
54
+so that only developers with check-in privileges can change it.
5555
Embedded documentation serves this latter purpose. Both forms of documentation
5656
use the exact same markup. Some projects may choose to
5757
use both forms of documentation at the same time. Because the same
5858
format is used, it is trivial to move a file from wiki to embedded documentation
5959
or back again as the project evolves.
6060
--- www/wikitheory.wiki
+++ www/wikitheory.wiki
@@ -34,26 +34,26 @@
34 the wiki page will fork. The web interface will display whichever edit
35 was checked in last. The other edit can be found in the history. The
36 file format will support merging the branches back together, but there
37 is no mechanism in the user interface (yet) to perform the merge.
38
39 Every change to a wiki page is a separate
40 [./fileformat.wiki | control artifact]
41 of type [./fileformat.wiki#wikichng | "Wiki Page"].
42
43 <h2>Embedded Documentation</h2>
44
45 Files in the source tree that use the ".wiki", ".md", or ".markdown" suffixes
46 can be accessed and displayed using special URLs to the fossil server.
47 This allows
48 project documentation to be stored in the source tree and accessed
49 online. (Details are described [./embeddeddoc.wiki | separately].)
50
51 Some projects prefer to store their documentation in wiki. There is nothing
52 wrong with that. But other projects prefer to keep documentation as part
53 of the source tree, so that it is versioned along with the source tree and
54 so that only developers with check-in privileges can change it.
55 Embedded documentation serves this latter purpose. Both forms of documentation
56 use the exact same markup. Some projects may choose to
57 use both forms of documentation at the same time. Because the same
58 format is used, it is trivial to move a file from wiki to embedded documentation
59 or back again as the project evolves.
60
--- www/wikitheory.wiki
+++ www/wikitheory.wiki
@@ -34,26 +34,26 @@
34 the wiki page will fork. The web interface will display whichever edit
35 was checked in last. The other edit can be found in the history. The
36 file format will support merging the branches back together, but there
37 is no mechanism in the user interface (yet) to perform the merge.
38
39 Every change to a wiki page is a separate
40 [./fileformat.wiki | control artifact]
41 of type [./fileformat.wiki#wikichng | "Wiki Page"].
42
43 <h2>Embedded Documentation</h2>
44
45 Files in the source tree that use the ".wiki", ".md", or ".markdown" suffixes
46 can be accessed and displayed using special URLs to the fossil server.
47 This allows
48 project documentation to be stored in the source tree and accessed
49 online. (Details are described [./embeddeddoc.wiki | separately].)
50
51 Some projects prefer to store their documentation in wiki. There is nothing
52 wrong with that. But other projects prefer to keep documentation as part
53 of the source tree, so that it is versioned along with the source tree and
54 so that only developers with check-in privileges can change it.
55 Embedded documentation serves this latter purpose. Both forms of documentation
56 use the exact same markup. Some projects may choose to
57 use both forms of documentation at the same time. Because the same
58 format is used, it is trivial to move a file from wiki to embedded documentation
59 or back again as the project evolves.
60

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button