Fossil SCM

Merge trunk (docker experiment continuing, but not yet in working state!)

jan.nijtmans 2014-11-04 16:22 docker merge
Commit 96d1add988b3be64468c5b63a1a342aff7d226bd
85 files changed +1 +19 -8 +8 -8 +36 -1 +2 -2 +2 -2 +1 +9 -9 +4 -3 +20 -17 +1 -1 +14 +2 -2 +36 -28 +2 -2 +32 -33 +32 -33 +10 -10 +10 -10 +12 -398 +69 -71 +27 -27 +2 -4 +2 -2 +12 -12 +2 -2 +6 -8 +7 -7 +2 -2 +6 -7 +1 -1 +1 -1 +2 -2 +9 -11 +9 -9 +5 -6 +3 -2 +14 -17 +14 -17 +9 -8 +30 -2 +140 -26 +26 -9 +4 -4 +61 +3 -3 +4 -4 +10 -10 +18 -14 +9 -8 +5 -7 +10 -10 +2 -2 +12 -4 +13 -1 +9 -9 +2 -2 +4 +315 -232 +2 -2 +7 -7 +47 -24 +7 -3 +7 -6 +116 -83 +21 -23 +7 -7 +9 -8 +5 -3 +3 -3 +2 -2 +5 -14 +4 -4 +33 -27 +16 -13 +16 -13 +6 -3 +25 -9 +42 -10 +42 -10 +53 -4 +41 -1 +2 +1 -1
+1
--- auto.def
+++ auto.def
@@ -278,10 +278,11 @@
278278
}
279279
}
280280
cc-check-function-in-lib iconv iconv
281281
cc-check-functions utime
282282
cc-check-functions usleep
283
+cc-check-functions strchrnul
283284
284285
# Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
285286
if {![cc-check-functions getloadavg]} {
286287
define FOSSIL_OMIT_LOAD_AVERAGE 1
287288
msg-result "Load average support unavailable"
288289
--- auto.def
+++ auto.def
@@ -278,10 +278,11 @@
278 }
279 }
280 cc-check-function-in-lib iconv iconv
281 cc-check-functions utime
282 cc-check-functions usleep
 
283
284 # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
285 if {![cc-check-functions getloadavg]} {
286 define FOSSIL_OMIT_LOAD_AVERAGE 1
287 msg-result "Load average support unavailable"
288
--- auto.def
+++ auto.def
@@ -278,10 +278,11 @@
278 }
279 }
280 cc-check-function-in-lib iconv iconv
281 cc-check-functions utime
282 cc-check-functions usleep
283 cc-check-functions strchrnul
284
285 # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
286 if {![cc-check-functions getloadavg]} {
287 define FOSSIL_OMIT_LOAD_AVERAGE 1
288 msg-result "Load average support unavailable"
289
+19 -8
--- src/allrepo.c
+++ src/allrepo.c
@@ -98,10 +98,12 @@
9898
** carefully review the local checkouts to be operated upon
9999
** and the --whatif option to carefully review the files to
100100
** be deleted beforehand is highly recommended. The command
101101
** line options supported by the clean command itself, if any
102102
** are present, are passed along verbatim.
103
+**
104
+** dbstat Run the "dbstat" command on all repositories.
103105
**
104106
** extras Shows "extra" files from all local checkouts. The command
105107
** line options supported by the extra command itself, if any
106108
** are present, are passed along verbatim.
107109
**
@@ -129,11 +131,11 @@
129131
** sync Run a "sync" on all repositories. Only the --verbose
130132
** option is supported.
131133
**
132134
** setting Run the "setting", "set", or "unset" commands on all
133135
** set repositories. These command are particularly useful in
134
-** unset conjunection with the "max-loadavg" setting which cannot
136
+** unset conjunction with the "max-loadavg" setting which cannot
135137
** otherwise be set globally.
136138
**
137139
** Repositories are automatically added to the set of known repositories
138140
** when one of the following commands are run against the repository:
139141
** clone, info, pull, push, or sync. Even previously ignored repositories
@@ -190,10 +192,16 @@
190192
collect_argument_value(&extra, "keep");
191193
collect_argument(&extra, "temp",0);
192194
collect_argument(&extra, "verbose","v");
193195
collect_argument(&extra, "whatif",0);
194196
useCheckouts = 1;
197
+ }else if( strncmp(zCmd, "dbstat", n)==0 ){
198
+ zCmd = "dbstat --omit-version-info -R";
199
+ showLabel = 1;
200
+ quiet = 1;
201
+ collect_argument(&extra, "brief", "b");
202
+ collect_argument(&extra, "db-check", 0);
195203
}else if( strncmp(zCmd, "extras", n)==0 ){
196204
if( showFile ){
197205
zCmd = "extras --chdir";
198206
}else{
199207
zCmd = "extras --header --chdir";
@@ -249,19 +257,22 @@
249257
int j;
250258
useCheckouts = find_option("ckout","c",0)!=0;
251259
verify_all_options();
252260
db_begin_transaction();
253261
for(j=3; j<g.argc; j++){
254
- char *zSql = mprintf("DELETE FROM global_config"
255
- " WHERE name GLOB '%s:%q'",
256
- useCheckouts?"ckout":"repo", g.argv[j]);
262
+ Blob sql;
263
+ blob_zero(&sql);
264
+ blob_append_sql(&sql,
265
+ "DELETE FROM global_config WHERE name GLOB '%s:%q'",
266
+ useCheckouts?"ckout":"repo", g.argv[j]
267
+ );
257268
if( dryRunFlag ){
258
- fossil_print("%s\n", zSql);
269
+ fossil_print("%s\n", blob_sql_text(&sql));
259270
}else{
260
- db_multi_exec("%s", zSql);
271
+ db_multi_exec("%s", blob_sql_text(&sql));
261272
}
262
- fossil_free(zSql);
273
+ blob_reset(&sql);
263274
}
264275
db_end_transaction(0);
265276
return;
266277
}else if( strncmp(zCmd, "info", n)==0 ){
267278
zCmd = "info";
@@ -338,9 +349,9 @@
338349
if( nToDel>0 ){
339350
const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
340351
if( dryRunFlag ){
341352
fossil_print("%s\n", zSql);
342353
}else{
343
- db_multi_exec(zSql);
354
+ db_multi_exec("%s", zSql /*safe-for-%s*/ );
344355
}
345356
}
346357
}
347358
--- src/allrepo.c
+++ src/allrepo.c
@@ -98,10 +98,12 @@
98 ** carefully review the local checkouts to be operated upon
99 ** and the --whatif option to carefully review the files to
100 ** be deleted beforehand is highly recommended. The command
101 ** line options supported by the clean command itself, if any
102 ** are present, are passed along verbatim.
 
 
103 **
104 ** extras Shows "extra" files from all local checkouts. The command
105 ** line options supported by the extra command itself, if any
106 ** are present, are passed along verbatim.
107 **
@@ -129,11 +131,11 @@
129 ** sync Run a "sync" on all repositories. Only the --verbose
130 ** option is supported.
131 **
132 ** setting Run the "setting", "set", or "unset" commands on all
133 ** set repositories. These command are particularly useful in
134 ** unset conjunection with the "max-loadavg" setting which cannot
135 ** otherwise be set globally.
136 **
137 ** Repositories are automatically added to the set of known repositories
138 ** when one of the following commands are run against the repository:
139 ** clone, info, pull, push, or sync. Even previously ignored repositories
@@ -190,10 +192,16 @@
190 collect_argument_value(&extra, "keep");
191 collect_argument(&extra, "temp",0);
192 collect_argument(&extra, "verbose","v");
193 collect_argument(&extra, "whatif",0);
194 useCheckouts = 1;
 
 
 
 
 
 
195 }else if( strncmp(zCmd, "extras", n)==0 ){
196 if( showFile ){
197 zCmd = "extras --chdir";
198 }else{
199 zCmd = "extras --header --chdir";
@@ -249,19 +257,22 @@
249 int j;
250 useCheckouts = find_option("ckout","c",0)!=0;
251 verify_all_options();
252 db_begin_transaction();
253 for(j=3; j<g.argc; j++){
254 char *zSql = mprintf("DELETE FROM global_config"
255 " WHERE name GLOB '%s:%q'",
256 useCheckouts?"ckout":"repo", g.argv[j]);
 
 
 
257 if( dryRunFlag ){
258 fossil_print("%s\n", zSql);
259 }else{
260 db_multi_exec("%s", zSql);
261 }
262 fossil_free(zSql);
263 }
264 db_end_transaction(0);
265 return;
266 }else if( strncmp(zCmd, "info", n)==0 ){
267 zCmd = "info";
@@ -338,9 +349,9 @@
338 if( nToDel>0 ){
339 const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
340 if( dryRunFlag ){
341 fossil_print("%s\n", zSql);
342 }else{
343 db_multi_exec(zSql);
344 }
345 }
346 }
347
--- src/allrepo.c
+++ src/allrepo.c
@@ -98,10 +98,12 @@
98 ** carefully review the local checkouts to be operated upon
99 ** and the --whatif option to carefully review the files to
100 ** be deleted beforehand is highly recommended. The command
101 ** line options supported by the clean command itself, if any
102 ** are present, are passed along verbatim.
103 **
104 ** dbstat Run the "dbstat" command on all repositories.
105 **
106 ** extras Shows "extra" files from all local checkouts. The command
107 ** line options supported by the extra command itself, if any
108 ** are present, are passed along verbatim.
109 **
@@ -129,11 +131,11 @@
131 ** sync Run a "sync" on all repositories. Only the --verbose
132 ** option is supported.
133 **
134 ** setting Run the "setting", "set", or "unset" commands on all
135 ** set repositories. These command are particularly useful in
136 ** unset conjunction with the "max-loadavg" setting which cannot
137 ** otherwise be set globally.
138 **
139 ** Repositories are automatically added to the set of known repositories
140 ** when one of the following commands are run against the repository:
141 ** clone, info, pull, push, or sync. Even previously ignored repositories
@@ -190,10 +192,16 @@
192 collect_argument_value(&extra, "keep");
193 collect_argument(&extra, "temp",0);
194 collect_argument(&extra, "verbose","v");
195 collect_argument(&extra, "whatif",0);
196 useCheckouts = 1;
197 }else if( strncmp(zCmd, "dbstat", n)==0 ){
198 zCmd = "dbstat --omit-version-info -R";
199 showLabel = 1;
200 quiet = 1;
201 collect_argument(&extra, "brief", "b");
202 collect_argument(&extra, "db-check", 0);
203 }else if( strncmp(zCmd, "extras", n)==0 ){
204 if( showFile ){
205 zCmd = "extras --chdir";
206 }else{
207 zCmd = "extras --header --chdir";
@@ -249,19 +257,22 @@
257 int j;
258 useCheckouts = find_option("ckout","c",0)!=0;
259 verify_all_options();
260 db_begin_transaction();
261 for(j=3; j<g.argc; j++){
262 Blob sql;
263 blob_zero(&sql);
264 blob_append_sql(&sql,
265 "DELETE FROM global_config WHERE name GLOB '%s:%q'",
266 useCheckouts?"ckout":"repo", g.argv[j]
267 );
268 if( dryRunFlag ){
269 fossil_print("%s\n", blob_sql_text(&sql));
270 }else{
271 db_multi_exec("%s", blob_sql_text(&sql));
272 }
273 blob_reset(&sql);
274 }
275 db_end_transaction(0);
276 return;
277 }else if( strncmp(zCmd, "info", n)==0 ){
278 zCmd = "info";
@@ -338,9 +349,9 @@
349 if( nToDel>0 ){
350 const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
351 if( dryRunFlag ){
352 fossil_print("%s\n", zSql);
353 }else{
354 db_multi_exec("%s", zSql /*safe-for-%s*/ );
355 }
356 }
357 }
358
+8 -8
--- src/attach.c
+++ src/attach.c
@@ -40,31 +40,31 @@
4040
Stmt q;
4141
4242
if( zPage && zTkt ) zTkt = 0;
4343
login_check_credentials();
4444
blob_zero(&sql);
45
- blob_appendf(&sql,
45
+ blob_append_sql(&sql,
4646
"SELECT datetime(mtime%s), src, target, filename,"
4747
" comment, user,"
4848
" (SELECT uuid FROM blob WHERE rid=attachid), attachid"
4949
" FROM attachment",
5050
timeline_utc()
5151
);
5252
if( zPage ){
5353
if( g.perm.RdWiki==0 ) login_needed();
5454
style_header("Attachments To %h", zPage);
55
- blob_appendf(&sql, " WHERE target=%Q", zPage);
55
+ blob_append_sql(&sql, " WHERE target=%Q", zPage);
5656
}else if( zTkt ){
5757
if( g.perm.RdTkt==0 ) login_needed();
5858
style_header("Attachments To Ticket %S", zTkt);
59
- blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt);
59
+ blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt);
6060
}else{
6161
if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
6262
style_header("All Attachments");
6363
}
64
- blob_appendf(&sql, " ORDER BY mtime DESC");
65
- db_prepare(&q, "%s", blob_str(&sql));
64
+ blob_append_sql(&sql, " ORDER BY mtime DESC");
65
+ db_prepare(&q, "%s", blob_sql_text(&sql));
6666
@ <ol>
6767
while( db_step(&q)==SQLITE_ROW ){
6868
const char *zDate = db_column_text(&q, 0);
6969
const char *zSrc = db_column_text(&q, 1);
7070
const char *zTarget = db_column_text(&q, 2);
@@ -377,11 +377,11 @@
377377
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378378
#if 0
379379
/* Shunning here needs to get both the attachment control artifact and
380380
** the object that is attached. */
381381
if( g.perm.Admin ){
382
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
382
+ if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){
383383
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
384384
g.zTop, zUuid);
385385
}else{
386386
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
387387
g.zTop, zUuid);
@@ -390,17 +390,17 @@
390390
#endif
391391
pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
392392
if( pAttach==0 ) fossil_redirect_home();
393393
zTarget = pAttach->zAttachTarget;
394394
zSrc = pAttach->zAttachSrc;
395
- ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc);
395
+ ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc);
396396
zName = pAttach->zAttachName;
397397
zDesc = pAttach->zComment;
398398
zMime = mimetype_from_name(zName);
399399
fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400400
if( validate16(zTarget, strlen(zTarget))
401
- && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget)
401
+ && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget)
402402
){
403403
zTktUuid = zTarget;
404404
if( !g.perm.RdTkt ){ login_needed(); return; }
405405
if( g.perm.WrTkt ){
406406
style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407407
--- src/attach.c
+++ src/attach.c
@@ -40,31 +40,31 @@
40 Stmt q;
41
42 if( zPage && zTkt ) zTkt = 0;
43 login_check_credentials();
44 blob_zero(&sql);
45 blob_appendf(&sql,
46 "SELECT datetime(mtime%s), src, target, filename,"
47 " comment, user,"
48 " (SELECT uuid FROM blob WHERE rid=attachid), attachid"
49 " FROM attachment",
50 timeline_utc()
51 );
52 if( zPage ){
53 if( g.perm.RdWiki==0 ) login_needed();
54 style_header("Attachments To %h", zPage);
55 blob_appendf(&sql, " WHERE target=%Q", zPage);
56 }else if( zTkt ){
57 if( g.perm.RdTkt==0 ) login_needed();
58 style_header("Attachments To Ticket %S", zTkt);
59 blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt);
60 }else{
61 if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
62 style_header("All Attachments");
63 }
64 blob_appendf(&sql, " ORDER BY mtime DESC");
65 db_prepare(&q, "%s", blob_str(&sql));
66 @ <ol>
67 while( db_step(&q)==SQLITE_ROW ){
68 const char *zDate = db_column_text(&q, 0);
69 const char *zSrc = db_column_text(&q, 1);
70 const char *zTarget = db_column_text(&q, 2);
@@ -377,11 +377,11 @@
377 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378 #if 0
379 /* Shunning here needs to get both the attachment control artifact and
380 ** the object that is attached. */
381 if( g.perm.Admin ){
382 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
383 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
384 g.zTop, zUuid);
385 }else{
386 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
387 g.zTop, zUuid);
@@ -390,17 +390,17 @@
390 #endif
391 pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
392 if( pAttach==0 ) fossil_redirect_home();
393 zTarget = pAttach->zAttachTarget;
394 zSrc = pAttach->zAttachSrc;
395 ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc);
396 zName = pAttach->zAttachName;
397 zDesc = pAttach->zComment;
398 zMime = mimetype_from_name(zName);
399 fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400 if( validate16(zTarget, strlen(zTarget))
401 && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget)
402 ){
403 zTktUuid = zTarget;
404 if( !g.perm.RdTkt ){ login_needed(); return; }
405 if( g.perm.WrTkt ){
406 style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407
--- src/attach.c
+++ src/attach.c
@@ -40,31 +40,31 @@
40 Stmt q;
41
42 if( zPage && zTkt ) zTkt = 0;
43 login_check_credentials();
44 blob_zero(&sql);
45 blob_append_sql(&sql,
46 "SELECT datetime(mtime%s), src, target, filename,"
47 " comment, user,"
48 " (SELECT uuid FROM blob WHERE rid=attachid), attachid"
49 " FROM attachment",
50 timeline_utc()
51 );
52 if( zPage ){
53 if( g.perm.RdWiki==0 ) login_needed();
54 style_header("Attachments To %h", zPage);
55 blob_append_sql(&sql, " WHERE target=%Q", zPage);
56 }else if( zTkt ){
57 if( g.perm.RdTkt==0 ) login_needed();
58 style_header("Attachments To Ticket %S", zTkt);
59 blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt);
60 }else{
61 if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
62 style_header("All Attachments");
63 }
64 blob_append_sql(&sql, " ORDER BY mtime DESC");
65 db_prepare(&q, "%s", blob_sql_text(&sql));
66 @ <ol>
67 while( db_step(&q)==SQLITE_ROW ){
68 const char *zDate = db_column_text(&q, 0);
69 const char *zSrc = db_column_text(&q, 1);
70 const char *zTarget = db_column_text(&q, 2);
@@ -377,11 +377,11 @@
377 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378 #if 0
379 /* Shunning here needs to get both the attachment control artifact and
380 ** the object that is attached. */
381 if( g.perm.Admin ){
382 if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){
383 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
384 g.zTop, zUuid);
385 }else{
386 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
387 g.zTop, zUuid);
@@ -390,17 +390,17 @@
390 #endif
391 pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
392 if( pAttach==0 ) fossil_redirect_home();
393 zTarget = pAttach->zAttachTarget;
394 zSrc = pAttach->zAttachSrc;
395 ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc);
396 zName = pAttach->zAttachName;
397 zDesc = pAttach->zComment;
398 zMime = mimetype_from_name(zName);
399 fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400 if( validate16(zTarget, strlen(zTarget))
401 && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget)
402 ){
403 zTktUuid = zTarget;
404 if( !g.perm.RdTkt ){ login_needed(); return; }
405 if( g.perm.WrTkt ){
406 style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407
+36 -1
--- src/blob.c
+++ src/blob.c
@@ -34,14 +34,20 @@
3434
*/
3535
struct Blob {
3636
unsigned int nUsed; /* Number of bytes used in aData[] */
3737
unsigned int nAlloc; /* Number of bytes allocated for aData[] */
3838
unsigned int iCursor; /* Next character of input to parse */
39
+ unsigned int blobFlags; /* One or more BLOBFLAG_* bits */
3940
char *aData; /* Where the information is stored */
4041
void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
4142
};
4243
44
+/*
45
+** Allowed values for Blob.blobFlags
46
+*/
47
+#define BLOBFLAG_NotSQL 0x0001 /* Non-SQL text */
48
+
4349
/*
4450
** The current size of a Blob
4551
*/
4652
#define blob_size(X) ((X)->nUsed)
4753
@@ -148,10 +154,11 @@
148154
free(pBlob->aData);
149155
pBlob->aData = 0;
150156
pBlob->nAlloc = 0;
151157
pBlob->nUsed = 0;
152158
pBlob->iCursor = 0;
159
+ pBlob->blobFlags = 0;
153160
}else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
154161
char *pNew = fossil_realloc(pBlob->aData, newSize);
155162
pBlob->aData = pNew;
156163
pBlob->nAlloc = newSize;
157164
if( pBlob->nUsed>pBlob->nAlloc ){
@@ -162,11 +169,11 @@
162169
163170
/*
164171
** An initializer for Blobs
165172
*/
166173
#if INTERFACE
167
-#define BLOB_INITIALIZER {0,0,0,0,blobReallocMalloc}
174
+#define BLOB_INITIALIZER {0,0,0,0,0,blobReallocMalloc}
168175
#endif
169176
const Blob empty_blob = BLOB_INITIALIZER;
170177
171178
/*
172179
** A reallocation function for when the initial string is in unmanaged
@@ -217,10 +224,11 @@
217224
}else{
218225
if( size<=0 ) size = strlen(zData);
219226
pBlob->nUsed = pBlob->nAlloc = size;
220227
pBlob->aData = (char*)zData;
221228
pBlob->iCursor = 0;
229
+ pBlob->blobFlags = 0;
222230
pBlob->xRealloc = blobReallocStatic;
223231
}
224232
}
225233
226234
/*
@@ -248,10 +256,11 @@
248256
assert_blob_is_reset(pBlob);
249257
pBlob->nUsed = 0;
250258
pBlob->nAlloc = 1;
251259
pBlob->aData = (char*)zEmpty;
252260
pBlob->iCursor = 0;
261
+ pBlob->blobFlags = 0;
253262
pBlob->xRealloc = blobReallocStatic;
254263
}
255264
256265
/*
257266
** Append text or data to the end of a blob.
@@ -292,10 +301,24 @@
292301
if( p->aData[p->nUsed]!=0 ){
293302
blob_materialize(p);
294303
}
295304
return p->aData;
296305
}
306
+
307
+/*
308
+** Return a pointer to a null-terminated string for a blob that has
309
+** been created using blob_append_sql() and not blob_appendf(). If
310
+** text was ever added using blob_appendf() then throw an error.
311
+*/
312
+char *blob_sql_text(Blob *p){
313
+ blob_is_init(p);
314
+ if( (p->blobFlags & BLOBFLAG_NotSQL) ){
315
+ fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text");
316
+ }
317
+ return blob_str(p);
318
+}
319
+
297320
298321
/*
299322
** Return a pointer to a null-terminated string for a blob.
300323
**
301324
** WARNING: If the blob is ephemeral, it might cause a '\000'
@@ -671,13 +694,25 @@
671694
return i;
672695
}
673696
674697
/*
675698
** Do printf-style string rendering and append the results to a blob.
699
+**
700
+** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
701
+** whereas blob_append_sql() does not.
676702
*/
677703
void blob_appendf(Blob *pBlob, const char *zFormat, ...){
678704
if( pBlob ){
705
+ va_list ap;
706
+ va_start(ap, zFormat);
707
+ vxprintf(pBlob, zFormat, ap);
708
+ va_end(ap);
709
+ pBlob->blobFlags |= BLOBFLAG_NotSQL;
710
+ }
711
+}
712
+void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
713
+ if( pBlob ){
679714
va_list ap;
680715
va_start(ap, zFormat);
681716
vxprintf(pBlob, zFormat, ap);
682717
va_end(ap);
683718
}
684719
--- src/blob.c
+++ src/blob.c
@@ -34,14 +34,20 @@
34 */
35 struct Blob {
36 unsigned int nUsed; /* Number of bytes used in aData[] */
37 unsigned int nAlloc; /* Number of bytes allocated for aData[] */
38 unsigned int iCursor; /* Next character of input to parse */
 
39 char *aData; /* Where the information is stored */
40 void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
41 };
42
 
 
 
 
 
43 /*
44 ** The current size of a Blob
45 */
46 #define blob_size(X) ((X)->nUsed)
47
@@ -148,10 +154,11 @@
148 free(pBlob->aData);
149 pBlob->aData = 0;
150 pBlob->nAlloc = 0;
151 pBlob->nUsed = 0;
152 pBlob->iCursor = 0;
 
153 }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
154 char *pNew = fossil_realloc(pBlob->aData, newSize);
155 pBlob->aData = pNew;
156 pBlob->nAlloc = newSize;
157 if( pBlob->nUsed>pBlob->nAlloc ){
@@ -162,11 +169,11 @@
162
163 /*
164 ** An initializer for Blobs
165 */
166 #if INTERFACE
167 #define BLOB_INITIALIZER {0,0,0,0,blobReallocMalloc}
168 #endif
169 const Blob empty_blob = BLOB_INITIALIZER;
170
171 /*
172 ** A reallocation function for when the initial string is in unmanaged
@@ -217,10 +224,11 @@
217 }else{
218 if( size<=0 ) size = strlen(zData);
219 pBlob->nUsed = pBlob->nAlloc = size;
220 pBlob->aData = (char*)zData;
221 pBlob->iCursor = 0;
 
222 pBlob->xRealloc = blobReallocStatic;
223 }
224 }
225
226 /*
@@ -248,10 +256,11 @@
248 assert_blob_is_reset(pBlob);
249 pBlob->nUsed = 0;
250 pBlob->nAlloc = 1;
251 pBlob->aData = (char*)zEmpty;
252 pBlob->iCursor = 0;
 
253 pBlob->xRealloc = blobReallocStatic;
254 }
255
256 /*
257 ** Append text or data to the end of a blob.
@@ -292,10 +301,24 @@
292 if( p->aData[p->nUsed]!=0 ){
293 blob_materialize(p);
294 }
295 return p->aData;
296 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
298 /*
299 ** Return a pointer to a null-terminated string for a blob.
300 **
301 ** WARNING: If the blob is ephemeral, it might cause a '\000'
@@ -671,13 +694,25 @@
671 return i;
672 }
673
674 /*
675 ** Do printf-style string rendering and append the results to a blob.
 
 
 
676 */
677 void blob_appendf(Blob *pBlob, const char *zFormat, ...){
678 if( pBlob ){
 
 
 
 
 
 
 
 
 
679 va_list ap;
680 va_start(ap, zFormat);
681 vxprintf(pBlob, zFormat, ap);
682 va_end(ap);
683 }
684
--- src/blob.c
+++ src/blob.c
@@ -34,14 +34,20 @@
34 */
35 struct Blob {
36 unsigned int nUsed; /* Number of bytes used in aData[] */
37 unsigned int nAlloc; /* Number of bytes allocated for aData[] */
38 unsigned int iCursor; /* Next character of input to parse */
39 unsigned int blobFlags; /* One or more BLOBFLAG_* bits */
40 char *aData; /* Where the information is stored */
41 void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
42 };
43
44 /*
45 ** Allowed values for Blob.blobFlags
46 */
47 #define BLOBFLAG_NotSQL 0x0001 /* Non-SQL text */
48
49 /*
50 ** The current size of a Blob
51 */
52 #define blob_size(X) ((X)->nUsed)
53
@@ -148,10 +154,11 @@
154 free(pBlob->aData);
155 pBlob->aData = 0;
156 pBlob->nAlloc = 0;
157 pBlob->nUsed = 0;
158 pBlob->iCursor = 0;
159 pBlob->blobFlags = 0;
160 }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
161 char *pNew = fossil_realloc(pBlob->aData, newSize);
162 pBlob->aData = pNew;
163 pBlob->nAlloc = newSize;
164 if( pBlob->nUsed>pBlob->nAlloc ){
@@ -162,11 +169,11 @@
169
170 /*
171 ** An initializer for Blobs
172 */
173 #if INTERFACE
174 #define BLOB_INITIALIZER {0,0,0,0,0,blobReallocMalloc}
175 #endif
176 const Blob empty_blob = BLOB_INITIALIZER;
177
178 /*
179 ** A reallocation function for when the initial string is in unmanaged
@@ -217,10 +224,11 @@
224 }else{
225 if( size<=0 ) size = strlen(zData);
226 pBlob->nUsed = pBlob->nAlloc = size;
227 pBlob->aData = (char*)zData;
228 pBlob->iCursor = 0;
229 pBlob->blobFlags = 0;
230 pBlob->xRealloc = blobReallocStatic;
231 }
232 }
233
234 /*
@@ -248,10 +256,11 @@
256 assert_blob_is_reset(pBlob);
257 pBlob->nUsed = 0;
258 pBlob->nAlloc = 1;
259 pBlob->aData = (char*)zEmpty;
260 pBlob->iCursor = 0;
261 pBlob->blobFlags = 0;
262 pBlob->xRealloc = blobReallocStatic;
263 }
264
265 /*
266 ** Append text or data to the end of a blob.
@@ -292,10 +301,24 @@
301 if( p->aData[p->nUsed]!=0 ){
302 blob_materialize(p);
303 }
304 return p->aData;
305 }
306
307 /*
308 ** Return a pointer to a null-terminated string for a blob that has
309 ** been created using blob_append_sql() and not blob_appendf(). If
310 ** text was ever added using blob_appendf() then throw an error.
311 */
312 char *blob_sql_text(Blob *p){
313 blob_is_init(p);
314 if( (p->blobFlags & BLOBFLAG_NotSQL) ){
315 fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text");
316 }
317 return blob_str(p);
318 }
319
320
321 /*
322 ** Return a pointer to a null-terminated string for a blob.
323 **
324 ** WARNING: If the blob is ephemeral, it might cause a '\000'
@@ -671,13 +694,25 @@
694 return i;
695 }
696
697 /*
698 ** Do printf-style string rendering and append the results to a blob.
699 **
700 ** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
701 ** whereas blob_append_sql() does not.
702 */
703 void blob_appendf(Blob *pBlob, const char *zFormat, ...){
704 if( pBlob ){
705 va_list ap;
706 va_start(ap, zFormat);
707 vxprintf(pBlob, zFormat, ap);
708 va_end(ap);
709 pBlob->blobFlags |= BLOBFLAG_NotSQL;
710 }
711 }
712 void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
713 if( pBlob ){
714 va_list ap;
715 va_start(ap, zFormat);
716 vxprintf(pBlob, zFormat, ap);
717 va_end(ap);
718 }
719
+2 -2
--- src/branch.c
+++ src/branch.c
@@ -300,12 +300,12 @@
300300
if( colorTest ){
301301
showClosed = 0;
302302
showAll = 1;
303303
}
304304
305
- style_header(showClosed ? "Closed Branches" :
306
- showAll ? "All Branches" : "Open Branches");
305
+ style_header("%s", showClosed ? "Closed Branches" :
306
+ showAll ? "All Branches" : "Open Branches");
307307
style_submenu_element("Timeline", "Timeline", "brtimeline");
308308
if( showClosed ){
309309
style_submenu_element("All", "All", "brlist?all");
310310
style_submenu_element("Open","Open","brlist");
311311
}else if( showAll ){
312312
--- src/branch.c
+++ src/branch.c
@@ -300,12 +300,12 @@
300 if( colorTest ){
301 showClosed = 0;
302 showAll = 1;
303 }
304
305 style_header(showClosed ? "Closed Branches" :
306 showAll ? "All Branches" : "Open Branches");
307 style_submenu_element("Timeline", "Timeline", "brtimeline");
308 if( showClosed ){
309 style_submenu_element("All", "All", "brlist?all");
310 style_submenu_element("Open","Open","brlist");
311 }else if( showAll ){
312
--- src/branch.c
+++ src/branch.c
@@ -300,12 +300,12 @@
300 if( colorTest ){
301 showClosed = 0;
302 showAll = 1;
303 }
304
305 style_header("%s", showClosed ? "Closed Branches" :
306 showAll ? "All Branches" : "Open Branches");
307 style_submenu_element("Timeline", "Timeline", "brtimeline");
308 if( showClosed ){
309 style_submenu_element("All", "All", "brlist?all");
310 style_submenu_element("Open","Open","brlist");
311 }else if( showAll ){
312
+2 -2
--- src/browse.c
+++ src/browse.c
@@ -759,11 +759,11 @@
759759
db_prepare(&ins,
760760
"INSERT INTO temp.fileage(fid, pathname)"
761761
" SELECT rid, :path FROM blob WHERE uuid=:uuid"
762762
);
763763
while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764
- if(zGlob && !strglob(zGlob, pFile->zName)) continue;
764
+ if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
765765
db_bind_text(&ins, ":uuid", pFile->zUuid);
766766
db_bind_text(&ins, ":path", pFile->zName);
767767
db_step(&ins);
768768
db_reset(&ins);
769769
nFile++;
@@ -828,11 +828,11 @@
828828
rid = symbolic_name_to_rid(zName, "ci");
829829
if( rid==0 ){
830830
fossil_fatal("not a valid check-in: %s", zName);
831831
}
832832
style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
833
- style_header("File Ages", zName);
833
+ style_header("File Ages");
834834
zGlob = P("glob");
835835
compute_fileage(rid,zGlob);
836836
baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837837
zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838838
@ <h2>File Ages For Check-in
839839
840840
ADDED src/builtin.c
--- src/browse.c
+++ src/browse.c
@@ -759,11 +759,11 @@
759 db_prepare(&ins,
760 "INSERT INTO temp.fileage(fid, pathname)"
761 " SELECT rid, :path FROM blob WHERE uuid=:uuid"
762 );
763 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764 if(zGlob && !strglob(zGlob, pFile->zName)) continue;
765 db_bind_text(&ins, ":uuid", pFile->zUuid);
766 db_bind_text(&ins, ":path", pFile->zName);
767 db_step(&ins);
768 db_reset(&ins);
769 nFile++;
@@ -828,11 +828,11 @@
828 rid = symbolic_name_to_rid(zName, "ci");
829 if( rid==0 ){
830 fossil_fatal("not a valid check-in: %s", zName);
831 }
832 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
833 style_header("File Ages", zName);
834 zGlob = P("glob");
835 compute_fileage(rid,zGlob);
836 baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837 zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838 @ <h2>File Ages For Check-in
839
840 DDED src/builtin.c
--- src/browse.c
+++ src/browse.c
@@ -759,11 +759,11 @@
759 db_prepare(&ins,
760 "INSERT INTO temp.fileage(fid, pathname)"
761 " SELECT rid, :path FROM blob WHERE uuid=:uuid"
762 );
763 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764 if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
765 db_bind_text(&ins, ":uuid", pFile->zUuid);
766 db_bind_text(&ins, ":path", pFile->zName);
767 db_step(&ins);
768 db_reset(&ins);
769 nFile++;
@@ -828,11 +828,11 @@
828 rid = symbolic_name_to_rid(zName, "ci");
829 if( rid==0 ){
830 fossil_fatal("not a valid check-in: %s", zName);
831 }
832 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
833 style_header("File Ages");
834 zGlob = P("glob");
835 compute_fileage(rid,zGlob);
836 baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837 zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838 @ <h2>File Ages For Check-in
839
840 DDED src/builtin.c
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -0,0 +1 @@
1
+sizeof(aBuiltinFilesizeof(aBuiltinFil/if(==0 )
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -0,0 +1 @@
 
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -0,0 +1 @@
1 sizeof(aBuiltinFilesizeof(aBuiltinFil/if(==0 )
+9 -9
--- src/cache.c
+++ src/cache.c
@@ -61,11 +61,11 @@
6161
fossil_free(zDbName);
6262
if( rc ){
6363
sqlite3_close(db);
6464
return 0;
6565
}
66
- rc = sqlite3_exec(db,
66
+ rc = sqlite3_exec(db,
6767
"PRAGMA page_size=8192;"
6868
"CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
6969
"CREATE TABLE IF NOT EXISTS cache("
7070
"key TEXT PRIMARY KEY," /* Key used to access the cache */
7171
"id INT REFERENCES blob," /* The cache content */
@@ -94,11 +94,11 @@
9494
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
9595
if( rc ){
9696
sqlite3_finalize(pStmt);
9797
pStmt = 0;
9898
}
99
- return pStmt;
99
+ return pStmt;
100100
}
101101
102102
/*
103103
** This routine implements an SQL function that renders a large integer
104104
** compactly: ex: 12.3MB
@@ -153,11 +153,11 @@
153153
if( pStmt==0 ) goto cache_write_end;
154154
sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
155155
SQLITE_STATIC);
156156
if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
157157
sqlite3_finalize(pStmt);
158
- pStmt = cacheStmt(db,
158
+ pStmt = cacheStmt(db,
159159
"INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
160160
"VALUES(?1,?2,strftime('%s','now'),1,?3)"
161161
);
162162
if( pStmt==0 ) goto cache_write_end;
163163
sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
@@ -202,27 +202,27 @@
202202
203203
db = cacheOpen(0);
204204
if( db==0 ) return 0;
205205
sqlite3_busy_timeout(db, 10000);
206206
sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
207
- pStmt = cacheStmt(db,
207
+ pStmt = cacheStmt(db,
208208
"SELECT blob.data FROM cache, blob"
209209
" WHERE cache.key=?1 AND cache.id=blob.id");
210210
if( pStmt==0 ) goto cache_read_done;
211211
sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
212212
if( sqlite3_step(pStmt)==SQLITE_ROW ){
213213
blob_append(pContent, sqlite3_column_blob(pStmt, 0),
214214
sqlite3_column_bytes(pStmt, 0));
215215
rc = 1;
216216
sqlite3_reset(pStmt);
217
- pStmt = cacheStmt(db,
217
+ pStmt = cacheStmt(db,
218218
"UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
219219
" WHERE key=?1");
220220
if( pStmt ){
221221
sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
222222
sqlite3_step(pStmt);
223
- }
223
+ }
224224
}
225225
sqlite3_finalize(pStmt);
226226
cache_read_done:
227227
sqlite3_exec(db, "COMMIT", 0, 0, 0);
228228
sqlite3_close(db);
@@ -256,11 +256,11 @@
256256
sqlite3_stmt *pStmt;
257257
258258
db_find_and_open_repository(0,0);
259259
zCmd = g.argc>=3 ? g.argv[2] : "";
260260
nCmd = (int)strlen(zCmd);
261
- if( nCmd<=1 ){
261
+ if( nCmd<=1 ){
262262
fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
263263
}
264264
if( strncmp(zCmd, "init", nCmd)==0 ){
265265
db = cacheOpen(0);
266266
sqlite3_close(db);
@@ -290,11 +290,11 @@
290290
fossil_print("cache does not exist\n");
291291
}else{
292292
int nEntry = 0;
293293
char *zDbName = cacheName();
294294
cache_register_sizename(db);
295
- pStmt = cacheStmt(db,
295
+ pStmt = cacheStmt(db,
296296
"SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
297297
" FROM cache"
298298
" ORDER BY tm DESC"
299299
);
300300
if( pStmt ){
@@ -338,11 +338,11 @@
338338
if( db==0 ){
339339
@ The web-page cache is disabled for this repository
340340
}else{
341341
char *zDbName = cacheName();
342342
cache_register_sizename(db);
343
- pStmt = cacheStmt(db,
343
+ pStmt = cacheStmt(db,
344344
"SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
345345
" FROM cache"
346346
" ORDER BY tm DESC"
347347
);
348348
if( pStmt ){
349349
--- src/cache.c
+++ src/cache.c
@@ -61,11 +61,11 @@
61 fossil_free(zDbName);
62 if( rc ){
63 sqlite3_close(db);
64 return 0;
65 }
66 rc = sqlite3_exec(db,
67 "PRAGMA page_size=8192;"
68 "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
69 "CREATE TABLE IF NOT EXISTS cache("
70 "key TEXT PRIMARY KEY," /* Key used to access the cache */
71 "id INT REFERENCES blob," /* The cache content */
@@ -94,11 +94,11 @@
94 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
95 if( rc ){
96 sqlite3_finalize(pStmt);
97 pStmt = 0;
98 }
99 return pStmt;
100 }
101
102 /*
103 ** This routine implements an SQL function that renders a large integer
104 ** compactly: ex: 12.3MB
@@ -153,11 +153,11 @@
153 if( pStmt==0 ) goto cache_write_end;
154 sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
155 SQLITE_STATIC);
156 if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
157 sqlite3_finalize(pStmt);
158 pStmt = cacheStmt(db,
159 "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
160 "VALUES(?1,?2,strftime('%s','now'),1,?3)"
161 );
162 if( pStmt==0 ) goto cache_write_end;
163 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
@@ -202,27 +202,27 @@
202
203 db = cacheOpen(0);
204 if( db==0 ) return 0;
205 sqlite3_busy_timeout(db, 10000);
206 sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
207 pStmt = cacheStmt(db,
208 "SELECT blob.data FROM cache, blob"
209 " WHERE cache.key=?1 AND cache.id=blob.id");
210 if( pStmt==0 ) goto cache_read_done;
211 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
212 if( sqlite3_step(pStmt)==SQLITE_ROW ){
213 blob_append(pContent, sqlite3_column_blob(pStmt, 0),
214 sqlite3_column_bytes(pStmt, 0));
215 rc = 1;
216 sqlite3_reset(pStmt);
217 pStmt = cacheStmt(db,
218 "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
219 " WHERE key=?1");
220 if( pStmt ){
221 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
222 sqlite3_step(pStmt);
223 }
224 }
225 sqlite3_finalize(pStmt);
226 cache_read_done:
227 sqlite3_exec(db, "COMMIT", 0, 0, 0);
228 sqlite3_close(db);
@@ -256,11 +256,11 @@
256 sqlite3_stmt *pStmt;
257
258 db_find_and_open_repository(0,0);
259 zCmd = g.argc>=3 ? g.argv[2] : "";
260 nCmd = (int)strlen(zCmd);
261 if( nCmd<=1 ){
262 fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
263 }
264 if( strncmp(zCmd, "init", nCmd)==0 ){
265 db = cacheOpen(0);
266 sqlite3_close(db);
@@ -290,11 +290,11 @@
290 fossil_print("cache does not exist\n");
291 }else{
292 int nEntry = 0;
293 char *zDbName = cacheName();
294 cache_register_sizename(db);
295 pStmt = cacheStmt(db,
296 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
297 " FROM cache"
298 " ORDER BY tm DESC"
299 );
300 if( pStmt ){
@@ -338,11 +338,11 @@
338 if( db==0 ){
339 @ The web-page cache is disabled for this repository
340 }else{
341 char *zDbName = cacheName();
342 cache_register_sizename(db);
343 pStmt = cacheStmt(db,
344 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
345 " FROM cache"
346 " ORDER BY tm DESC"
347 );
348 if( pStmt ){
349
--- src/cache.c
+++ src/cache.c
@@ -61,11 +61,11 @@
61 fossil_free(zDbName);
62 if( rc ){
63 sqlite3_close(db);
64 return 0;
65 }
66 rc = sqlite3_exec(db,
67 "PRAGMA page_size=8192;"
68 "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
69 "CREATE TABLE IF NOT EXISTS cache("
70 "key TEXT PRIMARY KEY," /* Key used to access the cache */
71 "id INT REFERENCES blob," /* The cache content */
@@ -94,11 +94,11 @@
94 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
95 if( rc ){
96 sqlite3_finalize(pStmt);
97 pStmt = 0;
98 }
99 return pStmt;
100 }
101
102 /*
103 ** This routine implements an SQL function that renders a large integer
104 ** compactly: ex: 12.3MB
@@ -153,11 +153,11 @@
153 if( pStmt==0 ) goto cache_write_end;
154 sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
155 SQLITE_STATIC);
156 if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
157 sqlite3_finalize(pStmt);
158 pStmt = cacheStmt(db,
159 "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
160 "VALUES(?1,?2,strftime('%s','now'),1,?3)"
161 );
162 if( pStmt==0 ) goto cache_write_end;
163 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
@@ -202,27 +202,27 @@
202
203 db = cacheOpen(0);
204 if( db==0 ) return 0;
205 sqlite3_busy_timeout(db, 10000);
206 sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
207 pStmt = cacheStmt(db,
208 "SELECT blob.data FROM cache, blob"
209 " WHERE cache.key=?1 AND cache.id=blob.id");
210 if( pStmt==0 ) goto cache_read_done;
211 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
212 if( sqlite3_step(pStmt)==SQLITE_ROW ){
213 blob_append(pContent, sqlite3_column_blob(pStmt, 0),
214 sqlite3_column_bytes(pStmt, 0));
215 rc = 1;
216 sqlite3_reset(pStmt);
217 pStmt = cacheStmt(db,
218 "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
219 " WHERE key=?1");
220 if( pStmt ){
221 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
222 sqlite3_step(pStmt);
223 }
224 }
225 sqlite3_finalize(pStmt);
226 cache_read_done:
227 sqlite3_exec(db, "COMMIT", 0, 0, 0);
228 sqlite3_close(db);
@@ -256,11 +256,11 @@
256 sqlite3_stmt *pStmt;
257
258 db_find_and_open_repository(0,0);
259 zCmd = g.argc>=3 ? g.argv[2] : "";
260 nCmd = (int)strlen(zCmd);
261 if( nCmd<=1 ){
262 fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
263 }
264 if( strncmp(zCmd, "init", nCmd)==0 ){
265 db = cacheOpen(0);
266 sqlite3_close(db);
@@ -290,11 +290,11 @@
290 fossil_print("cache does not exist\n");
291 }else{
292 int nEntry = 0;
293 char *zDbName = cacheName();
294 cache_register_sizename(db);
295 pStmt = cacheStmt(db,
296 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
297 " FROM cache"
298 " ORDER BY tm DESC"
299 );
300 if( pStmt ){
@@ -338,11 +338,11 @@
338 if( db==0 ){
339 @ The web-page cache is disabled for this repository
340 }else{
341 char *zDbName = cacheName();
342 cache_register_sizename(db);
343 pStmt = cacheStmt(db,
344 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
345 " FROM cache"
346 " ORDER BY tm DESC"
347 );
348 if( pStmt ){
349
+4 -3
--- src/cgi.c
+++ src/cgi.c
@@ -277,12 +277,12 @@
277277
** Return true if the response should be sent with Content-Encoding: gzip.
278278
*/
279279
static int is_gzippable(void){
280280
if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
281281
return strncmp(zContentType, "text/", 5)==0
282
- || strglob("application/*xml", zContentType)
283
- || strglob("application/*javascript", zContentType);
282
+ || sqlite3_strglob("application/*xml", zContentType)==0
283
+ || sqlite3_strglob("application/*javascript", zContentType)==0;
284284
}
285285
286286
/*
287287
** Do a normal HTTP reply
288288
*/
@@ -1712,11 +1712,12 @@
17121712
listen(listener,10);
17131713
fossil_print("Listening for %s requests on TCP port %d\n",
17141714
(flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
17151715
fflush(stdout);
17161716
if( zBrowser ){
1717
- zBrowser = mprintf(zBrowser, iPort);
1717
+ assert( strstr(zBrowser,"%d")!=0 );
1718
+ zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
17181719
#if defined(__CYGWIN__)
17191720
/* On Cygwin, we can do better than "echo" */
17201721
if( strncmp(zBrowser, "echo ", 5)==0 ){
17211722
wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
17221723
wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
17231724
--- src/cgi.c
+++ src/cgi.c
@@ -277,12 +277,12 @@
277 ** Return true if the response should be sent with Content-Encoding: gzip.
278 */
279 static int is_gzippable(void){
280 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
281 return strncmp(zContentType, "text/", 5)==0
282 || strglob("application/*xml", zContentType)
283 || strglob("application/*javascript", zContentType);
284 }
285
286 /*
287 ** Do a normal HTTP reply
288 */
@@ -1712,11 +1712,12 @@
1712 listen(listener,10);
1713 fossil_print("Listening for %s requests on TCP port %d\n",
1714 (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
1715 fflush(stdout);
1716 if( zBrowser ){
1717 zBrowser = mprintf(zBrowser, iPort);
 
1718 #if defined(__CYGWIN__)
1719 /* On Cygwin, we can do better than "echo" */
1720 if( strncmp(zBrowser, "echo ", 5)==0 ){
1721 wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
1722 wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
1723
--- src/cgi.c
+++ src/cgi.c
@@ -277,12 +277,12 @@
277 ** Return true if the response should be sent with Content-Encoding: gzip.
278 */
279 static int is_gzippable(void){
280 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
281 return strncmp(zContentType, "text/", 5)==0
282 || sqlite3_strglob("application/*xml", zContentType)==0
283 || sqlite3_strglob("application/*javascript", zContentType)==0;
284 }
285
286 /*
287 ** Do a normal HTTP reply
288 */
@@ -1712,11 +1712,12 @@
1712 listen(listener,10);
1713 fossil_print("Listening for %s requests on TCP port %d\n",
1714 (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
1715 fflush(stdout);
1716 if( zBrowser ){
1717 assert( strstr(zBrowser,"%d")!=0 );
1718 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
1719 #if defined(__CYGWIN__)
1720 /* On Cygwin, we can do better than "echo" */
1721 if( strncmp(zBrowser, "echo ", 5)==0 ){
1722 wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
1723 wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
1724
+20 -17
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
5252
zName = blob_str(&fname);
5353
if( fossil_strcmp(zName, ".")==0 ) {
5454
blob_reset(&where);
5555
break;
5656
}
57
- blob_appendf(&where, " %s (pathname=%Q %s) "
58
- "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
59
- (blob_size(&where)>0) ? "OR" : "AND", zName,
60
- filename_collation(), zName, filename_collation(),
61
- zName, filename_collation());
57
+ blob_append_sql(&where,
58
+ " %s (pathname=%Q %s) "
59
+ "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
60
+ (blob_size(&where)>0) ? "OR" : "AND", zName,
61
+ filename_collation(), zName, filename_collation(),
62
+ zName, filename_collation()
63
+ );
6264
}
6365
6466
db_prepare(&q,
6567
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
6668
" FROM vfile "
6769
" WHERE is_selected(id) %s"
6870
" AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
69
- blob_str(&where)
71
+ blob_sql_text(&where)
7072
);
7173
blob_zero(&rewrittenPathname);
7274
while( db_step(&q)==SQLITE_ROW ){
7375
const char *zPathname = db_column_text(&q,0);
7476
const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
313315
zName = blob_str(&fname);
314316
if( fossil_strcmp(zName, ".")==0 ) {
315317
blob_reset(&where);
316318
break;
317319
}
318
- blob_appendf(&where, " %s (pathname=%Q %s) "
319
- "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
320
- (blob_size(&where)>0) ? "OR" : "WHERE", zName,
321
- filename_collation(), zName, filename_collation(),
322
- zName, filename_collation());
320
+ blob_append_sql(&where,
321
+ " %s (pathname=%Q %s) "
322
+ "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
323
+ (blob_size(&where)>0) ? "OR" : "WHERE", zName,
324
+ filename_collation(), zName, filename_collation(),
325
+ zName, filename_collation()
326
+ );
323327
}
324328
vfile_check_signature(vid, 0);
325329
if( showAge ){
326330
db_prepare(&q,
327331
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
328332
" datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
329333
" FROM vfile %s"
330
- " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy
334
+ " ORDER BY %s",
335
+ vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
331336
);
332337
}else{
333338
db_prepare(&q,
334339
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
335340
" FROM vfile %s"
336
- " ORDER BY %s", blob_str(&where), zOrderBy
341
+ " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
337342
);
338343
}
339344
blob_reset(&where);
340345
while( db_step(&q)==SQLITE_ROW ){
341346
const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
908913
assert( g.aCommitFile==0 );
909914
if( g.argc>2 ){
910915
int ii, jj=0;
911916
Blob fname;
912917
Stmt q;
913
- const char *zCollate;
914918
Bag toCommit;
915919
916
- zCollate = filename_collation();
917920
blob_zero(&fname);
918921
bag_init(&toCommit);
919922
for(ii=2; ii<g.argc; ii++){
920923
int cnt = 0;
921924
file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
924927
return result;
925928
}
926929
db_prepare(&q,
927930
"SELECT id FROM vfile WHERE pathname=%Q %s"
928931
" OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
929
- blob_str(&fname), zCollate, blob_str(&fname),
930
- zCollate, blob_str(&fname), zCollate);
932
+ blob_str(&fname), filename_collation(), blob_str(&fname),
933
+ filename_collation(), blob_str(&fname), filename_collation());
931934
while( db_step(&q)==SQLITE_ROW ){
932935
cnt++;
933936
bag_insert(&toCommit, db_column_int(&q, 0));
934937
}
935938
db_finalize(&q);
936939
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ) {
54 blob_reset(&where);
55 break;
56 }
57 blob_appendf(&where, " %s (pathname=%Q %s) "
58 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
59 (blob_size(&where)>0) ? "OR" : "AND", zName,
60 filename_collation(), zName, filename_collation(),
61 zName, filename_collation());
 
 
62 }
63
64 db_prepare(&q,
65 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
66 " FROM vfile "
67 " WHERE is_selected(id) %s"
68 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
69 blob_str(&where)
70 );
71 blob_zero(&rewrittenPathname);
72 while( db_step(&q)==SQLITE_ROW ){
73 const char *zPathname = db_column_text(&q,0);
74 const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
313 zName = blob_str(&fname);
314 if( fossil_strcmp(zName, ".")==0 ) {
315 blob_reset(&where);
316 break;
317 }
318 blob_appendf(&where, " %s (pathname=%Q %s) "
319 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
320 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
321 filename_collation(), zName, filename_collation(),
322 zName, filename_collation());
 
 
323 }
324 vfile_check_signature(vid, 0);
325 if( showAge ){
326 db_prepare(&q,
327 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
328 " datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
329 " FROM vfile %s"
330 " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy
 
331 );
332 }else{
333 db_prepare(&q,
334 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
335 " FROM vfile %s"
336 " ORDER BY %s", blob_str(&where), zOrderBy
337 );
338 }
339 blob_reset(&where);
340 while( db_step(&q)==SQLITE_ROW ){
341 const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
908 assert( g.aCommitFile==0 );
909 if( g.argc>2 ){
910 int ii, jj=0;
911 Blob fname;
912 Stmt q;
913 const char *zCollate;
914 Bag toCommit;
915
916 zCollate = filename_collation();
917 blob_zero(&fname);
918 bag_init(&toCommit);
919 for(ii=2; ii<g.argc; ii++){
920 int cnt = 0;
921 file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
924 return result;
925 }
926 db_prepare(&q,
927 "SELECT id FROM vfile WHERE pathname=%Q %s"
928 " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
929 blob_str(&fname), zCollate, blob_str(&fname),
930 zCollate, blob_str(&fname), zCollate);
931 while( db_step(&q)==SQLITE_ROW ){
932 cnt++;
933 bag_insert(&toCommit, db_column_int(&q, 0));
934 }
935 db_finalize(&q);
936
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ) {
54 blob_reset(&where);
55 break;
56 }
57 blob_append_sql(&where,
58 " %s (pathname=%Q %s) "
59 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
60 (blob_size(&where)>0) ? "OR" : "AND", zName,
61 filename_collation(), zName, filename_collation(),
62 zName, filename_collation()
63 );
64 }
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
76 const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
315 zName = blob_str(&fname);
316 if( fossil_strcmp(zName, ".")==0 ) {
317 blob_reset(&where);
318 break;
319 }
320 blob_append_sql(&where,
321 " %s (pathname=%Q %s) "
322 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
323 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
324 filename_collation(), zName, filename_collation(),
325 zName, filename_collation()
326 );
327 }
328 vfile_check_signature(vid, 0);
329 if( showAge ){
330 db_prepare(&q,
331 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
332 " datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
333 " FROM vfile %s"
334 " ORDER BY %s",
335 vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
336 );
337 }else{
338 db_prepare(&q,
339 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
340 " FROM vfile %s"
341 " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
342 );
343 }
344 blob_reset(&where);
345 while( db_step(&q)==SQLITE_ROW ){
346 const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
913 assert( g.aCommitFile==0 );
914 if( g.argc>2 ){
915 int ii, jj=0;
916 Blob fname;
917 Stmt q;
 
918 Bag toCommit;
919
 
920 blob_zero(&fname);
921 bag_init(&toCommit);
922 for(ii=2; ii<g.argc; ii++){
923 int cnt = 0;
924 file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
927 return result;
928 }
929 db_prepare(&q,
930 "SELECT id FROM vfile WHERE pathname=%Q %s"
931 " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
932 blob_str(&fname), filename_collation(), blob_str(&fname),
933 filename_collation(), blob_str(&fname), filename_collation());
934 while( db_step(&q)==SQLITE_ROW ){
935 cnt++;
936 bag_insert(&toCommit, db_column_int(&q, 0));
937 }
938 db_finalize(&q);
939
+1 -1
--- src/checkout.c
+++ src/checkout.c
@@ -60,11 +60,11 @@
6060
Blob uuid;
6161
int vid;
6262
6363
blob_init(&uuid, zName, -1);
6464
if( name_to_uuid(&uuid, 1, "ci") ){
65
- fossil_fatal(g.zErrMsg);
65
+ fossil_fatal("%s", g.zErrMsg);
6666
}
6767
vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
6868
if( vid==0 ){
6969
fossil_fatal("no such check-in: %s", g.argv[2]);
7070
}
7171
7272
ADDED src/codecheck1.c
--- src/checkout.c
+++ src/checkout.c
@@ -60,11 +60,11 @@
60 Blob uuid;
61 int vid;
62
63 blob_init(&uuid, zName, -1);
64 if( name_to_uuid(&uuid, 1, "ci") ){
65 fossil_fatal(g.zErrMsg);
66 }
67 vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
68 if( vid==0 ){
69 fossil_fatal("no such check-in: %s", g.argv[2]);
70 }
71
72 DDED src/codecheck1.c
--- src/checkout.c
+++ src/checkout.c
@@ -60,11 +60,11 @@
60 Blob uuid;
61 int vid;
62
63 blob_init(&uuid, zName, -1);
64 if( name_to_uuid(&uuid, 1, "ci") ){
65 fossil_fatal("%s", g.zErrMsg);
66 }
67 vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
68 if( vid==0 ){
69 fossil_fatal("no such check-in: %s", g.argv[2]);
70 }
71
72 DDED src/codecheck1.c
--- a/src/codecheck1.c
+++ b/src/codecheck1.c
@@ -0,0 +1,14 @@
1
+/*
2
+** Copyright (c) 2014 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 Licensetimeline_utc ** Copyright (c) 2014 D. Richard Hipp
7
+**
8
+** This program is free software; you can redistribute it and/or
9
+** modify it under the terms of the Simplified BSD License (also
10
+** known as the "2-Clause Licensetimeline_utc(c) 2014 D. Richard Hipp
11
+**
12
+** This program is free software; you can redistribute it and/or
13
+** modify it under the terms of the Simplified BSD License (also
14
+** known as the "2-Clause Licensetimeline_utc
--- a/src/codecheck1.c
+++ b/src/codecheck1.c
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/codecheck1.c
+++ b/src/codecheck1.c
@@ -0,0 +1,14 @@
1 /*
2 ** Copyright (c) 2014 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 Licensetimeline_utc ** Copyright (c) 2014 D. Richard Hipp
7 **
8 ** This program is free software; you can redistribute it and/or
9 ** modify it under the terms of the Simplified BSD License (also
10 ** known as the "2-Clause Licensetimeline_utc(c) 2014 D. Richard Hipp
11 **
12 ** This program is free software; you can redistribute it and/or
13 ** modify it under the terms of the Simplified BSD License (also
14 ** known as the "2-Clause Licensetimeline_utc
+2 -2
--- src/comformat.c
+++ src/comformat.c
@@ -497,14 +497,14 @@
497497
zOrigText = mprintf("%s", blob_str(&fileData));
498498
blob_reset(&fileData);
499499
}
500500
}
501501
if( decode ){
502
- zText = mprintf(fromFile ? "%z" : "%s", zText);
502
+ zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText);
503503
defossilize(zText);
504504
if( zOrigText ){
505
- zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText);
505
+ zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText);
506506
defossilize(zOrigText);
507507
}
508508
}
509509
if( indent<0 ){
510510
indent = strlen(zPrefix);
511511
--- src/comformat.c
+++ src/comformat.c
@@ -497,14 +497,14 @@
497 zOrigText = mprintf("%s", blob_str(&fileData));
498 blob_reset(&fileData);
499 }
500 }
501 if( decode ){
502 zText = mprintf(fromFile ? "%z" : "%s", zText);
503 defossilize(zText);
504 if( zOrigText ){
505 zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText);
506 defossilize(zOrigText);
507 }
508 }
509 if( indent<0 ){
510 indent = strlen(zPrefix);
511
--- src/comformat.c
+++ src/comformat.c
@@ -497,14 +497,14 @@
497 zOrigText = mprintf("%s", blob_str(&fileData));
498 blob_reset(&fileData);
499 }
500 }
501 if( decode ){
502 zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText);
503 defossilize(zText);
504 if( zOrigText ){
505 zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText);
506 defossilize(zOrigText);
507 }
508 }
509 if( indent<0 ){
510 indent = strlen(zPrefix);
511
+36 -28
--- src/configure.c
+++ src/configure.c
@@ -194,19 +194,19 @@
194194
Blob x;
195195
int i;
196196
const char *zSep = "";
197197
198198
blob_zero(&x);
199
- blob_append(&x, "(", 1);
199
+ blob_append_sql(&x, "(");
200200
for(i=0; i<count(aConfig); i++){
201201
if( (aConfig[i].groupMask & iMask)==0 ) continue;
202202
if( aConfig[i].zName[0]=='@' ) continue;
203
- blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName);
203
+ blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName);
204204
zSep = ",";
205205
}
206
- blob_append(&x, ")", 1);
207
- return blob_str(&x);
206
+ blob_append_sql(&x, ")");
207
+ return blob_sql_text(&x);
208208
}
209209
210210
/*
211211
** Return the mask for the named configuration parameter if it can be
212212
** safely exported. Return 0 if the parameter is not safe to export.
@@ -361,11 +361,12 @@
361361
@ INSERT INTO _xfer_reportfmt
362362
@ SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
363363
@ INSERT INTO _xfer_user
364364
@ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
365365
;
366
- db_multi_exec(zSQL1);
366
+ assert( strchr(zSQL1,'%')==0 );
367
+ db_multi_exec(zSQL1 /*works-like:""*/);
367368
368369
/* When the replace flag is set, add triggers that run the first time
369370
** that new data is seen. The triggers run only once and delete all the
370371
** existing data.
371372
*/
@@ -390,11 +391,12 @@
390391
sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
391392
config_is_reset_function, 0, 0);
392393
sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
393394
config_reset_function, 0, 0);
394395
configHasBeenReset = 0;
395
- db_multi_exec(zSQL2);
396
+ assert( strchr(zSQL2,'%')==0 );
397
+ db_multi_exec(zSQL2 /*works-like:""*/);
396398
}
397399
}
398400
399401
/*
400402
** After receiving configuration data, call this routine to transfer
@@ -407,11 +409,12 @@
407409
@ DELETE FROM reportfmt;
408410
@ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
409411
@ DROP TABLE _xfer_user;
410412
@ DROP TABLE _xfer_reportfmt;
411413
;
412
- db_multi_exec(zSQL);
414
+ assert( strchr(zSQL,'%')==0 );
415
+ db_multi_exec(zSQL /*works-like:""*/);
413416
}
414417
415418
/*
416419
** Mask of modified configuration sets
417420
*/
@@ -563,35 +566,39 @@
563566
if( (thisMask & groupMask)==0 ) return;
564567
565568
blob_zero(&sql);
566569
if( groupMask & CONFIGSET_OVERWRITE ){
567570
if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
568
- db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]);
571
+ db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
569572
configHasBeenReset |= thisMask;
570573
}
571
- blob_append(&sql, "REPLACE INTO ", -1);
572
- }else{
573
- blob_append(&sql, "INSERT OR IGNORE INTO ", -1);
574
- }
575
- blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey);
576
- for(jj=2; jj<nToken; jj+=2){
577
- blob_appendf(&sql, ",%s", azToken[jj]);
578
- }
579
- blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]);
580
- for(jj=2; jj<nToken; jj+=2){
581
- blob_appendf(&sql, ",%s", azToken[jj+1]);
582
- }
583
- db_multi_exec("%s)", blob_str(&sql));
574
+ blob_append_sql(&sql, "REPLACE INTO ");
575
+ }else{
576
+ blob_append_sql(&sql, "INSERT OR IGNORE INTO ");
577
+ }
578
+ blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey);
579
+ for(jj=2; jj<nToken; jj+=2){
580
+ blob_append_sql(&sql, ",\"%w\"", azToken[jj]);
581
+ }
582
+ blob_append_sql(&sql,") VALUES(%s,%s",
583
+ azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/);
584
+ for(jj=2; jj<nToken; jj+=2){
585
+ blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/);
586
+ }
587
+ db_multi_exec("%s)", blob_sql_text(&sql));
584588
if( db_changes()==0 ){
585589
blob_reset(&sql);
586
- blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]);
590
+ blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s",
591
+ &zName[1], azToken[0]/*safe-for-%s*/);
587592
for(jj=2; jj<nToken; jj+=2){
588
- blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]);
593
+ blob_append_sql(&sql, ", \"%w\"=%s",
594
+ azToken[jj], azToken[jj+1]/*safe-for-%s*/);
589595
}
590
- blob_appendf(&sql, " WHERE %s=%s AND mtime<%s",
591
- aType[ii].zPrimKey, azToken[1], azToken[0]);
592
- db_multi_exec("%s", blob_str(&sql));
596
+ blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s",
597
+ aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/,
598
+ azToken[0]/*safe-for-%s*/);
599
+ db_multi_exec("%s", blob_sql_text(&sql));
593600
}
594601
blob_reset(&sql);
595602
rebuildMask |= thisMask;
596603
}else{
597604
/* Otherwise, the old format */
@@ -609,11 +616,11 @@
609616
/* Notice that we are evaluating arbitrary SQL received from the
610617
** client. But this can only happen if the client has authenticated
611618
** as an administrator, so presumably we trust the client at this
612619
** point.
613620
*/
614
- db_multi_exec("%s", blob_str(pContent));
621
+ db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/);
615622
}else{
616623
db_multi_exec(
617624
"REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
618625
zName, blob_str(pContent)
619626
);
@@ -966,11 +973,12 @@
966973
db_multi_exec("DELETE FROM concealed");
967974
}else if( fossil_strcmp(zName,"@shun")==0 ){
968975
db_multi_exec("DELETE FROM shun");
969976
}else if( fossil_strcmp(zName,"@reportfmt")==0 ){
970977
db_multi_exec("DELETE FROM reportfmt");
971
- db_multi_exec(zRepositorySchemaDefaultReports);
978
+ assert( strchr(zRepositorySchemaDefaultReports,'%')==0 );
979
+ db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/);
972980
}
973981
}
974982
db_end_transaction(0);
975983
fossil_print("Configuration reset to factory defaults.\n");
976984
fossil_print("To recover, use: %s %s import %s\n",
977985
--- src/configure.c
+++ src/configure.c
@@ -194,19 +194,19 @@
194 Blob x;
195 int i;
196 const char *zSep = "";
197
198 blob_zero(&x);
199 blob_append(&x, "(", 1);
200 for(i=0; i<count(aConfig); i++){
201 if( (aConfig[i].groupMask & iMask)==0 ) continue;
202 if( aConfig[i].zName[0]=='@' ) continue;
203 blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName);
204 zSep = ",";
205 }
206 blob_append(&x, ")", 1);
207 return blob_str(&x);
208 }
209
210 /*
211 ** Return the mask for the named configuration parameter if it can be
212 ** safely exported. Return 0 if the parameter is not safe to export.
@@ -361,11 +361,12 @@
361 @ INSERT INTO _xfer_reportfmt
362 @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
363 @ INSERT INTO _xfer_user
364 @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
365 ;
366 db_multi_exec(zSQL1);
 
367
368 /* When the replace flag is set, add triggers that run the first time
369 ** that new data is seen. The triggers run only once and delete all the
370 ** existing data.
371 */
@@ -390,11 +391,12 @@
390 sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
391 config_is_reset_function, 0, 0);
392 sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
393 config_reset_function, 0, 0);
394 configHasBeenReset = 0;
395 db_multi_exec(zSQL2);
 
396 }
397 }
398
399 /*
400 ** After receiving configuration data, call this routine to transfer
@@ -407,11 +409,12 @@
407 @ DELETE FROM reportfmt;
408 @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
409 @ DROP TABLE _xfer_user;
410 @ DROP TABLE _xfer_reportfmt;
411 ;
412 db_multi_exec(zSQL);
 
413 }
414
415 /*
416 ** Mask of modified configuration sets
417 */
@@ -563,35 +566,39 @@
563 if( (thisMask & groupMask)==0 ) return;
564
565 blob_zero(&sql);
566 if( groupMask & CONFIGSET_OVERWRITE ){
567 if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
568 db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]);
569 configHasBeenReset |= thisMask;
570 }
571 blob_append(&sql, "REPLACE INTO ", -1);
572 }else{
573 blob_append(&sql, "INSERT OR IGNORE INTO ", -1);
574 }
575 blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey);
576 for(jj=2; jj<nToken; jj+=2){
577 blob_appendf(&sql, ",%s", azToken[jj]);
578 }
579 blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]);
580 for(jj=2; jj<nToken; jj+=2){
581 blob_appendf(&sql, ",%s", azToken[jj+1]);
582 }
583 db_multi_exec("%s)", blob_str(&sql));
 
584 if( db_changes()==0 ){
585 blob_reset(&sql);
586 blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]);
 
587 for(jj=2; jj<nToken; jj+=2){
588 blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]);
 
589 }
590 blob_appendf(&sql, " WHERE %s=%s AND mtime<%s",
591 aType[ii].zPrimKey, azToken[1], azToken[0]);
592 db_multi_exec("%s", blob_str(&sql));
 
593 }
594 blob_reset(&sql);
595 rebuildMask |= thisMask;
596 }else{
597 /* Otherwise, the old format */
@@ -609,11 +616,11 @@
609 /* Notice that we are evaluating arbitrary SQL received from the
610 ** client. But this can only happen if the client has authenticated
611 ** as an administrator, so presumably we trust the client at this
612 ** point.
613 */
614 db_multi_exec("%s", blob_str(pContent));
615 }else{
616 db_multi_exec(
617 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
618 zName, blob_str(pContent)
619 );
@@ -966,11 +973,12 @@
966 db_multi_exec("DELETE FROM concealed");
967 }else if( fossil_strcmp(zName,"@shun")==0 ){
968 db_multi_exec("DELETE FROM shun");
969 }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
970 db_multi_exec("DELETE FROM reportfmt");
971 db_multi_exec(zRepositorySchemaDefaultReports);
 
972 }
973 }
974 db_end_transaction(0);
975 fossil_print("Configuration reset to factory defaults.\n");
976 fossil_print("To recover, use: %s %s import %s\n",
977
--- src/configure.c
+++ src/configure.c
@@ -194,19 +194,19 @@
194 Blob x;
195 int i;
196 const char *zSep = "";
197
198 blob_zero(&x);
199 blob_append_sql(&x, "(");
200 for(i=0; i<count(aConfig); i++){
201 if( (aConfig[i].groupMask & iMask)==0 ) continue;
202 if( aConfig[i].zName[0]=='@' ) continue;
203 blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName);
204 zSep = ",";
205 }
206 blob_append_sql(&x, ")");
207 return blob_sql_text(&x);
208 }
209
210 /*
211 ** Return the mask for the named configuration parameter if it can be
212 ** safely exported. Return 0 if the parameter is not safe to export.
@@ -361,11 +361,12 @@
361 @ INSERT INTO _xfer_reportfmt
362 @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
363 @ INSERT INTO _xfer_user
364 @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
365 ;
366 assert( strchr(zSQL1,'%')==0 );
367 db_multi_exec(zSQL1 /*works-like:""*/);
368
369 /* When the replace flag is set, add triggers that run the first time
370 ** that new data is seen. The triggers run only once and delete all the
371 ** existing data.
372 */
@@ -390,11 +391,12 @@
391 sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
392 config_is_reset_function, 0, 0);
393 sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
394 config_reset_function, 0, 0);
395 configHasBeenReset = 0;
396 assert( strchr(zSQL2,'%')==0 );
397 db_multi_exec(zSQL2 /*works-like:""*/);
398 }
399 }
400
401 /*
402 ** After receiving configuration data, call this routine to transfer
@@ -407,11 +409,12 @@
409 @ DELETE FROM reportfmt;
410 @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
411 @ DROP TABLE _xfer_user;
412 @ DROP TABLE _xfer_reportfmt;
413 ;
414 assert( strchr(zSQL,'%')==0 );
415 db_multi_exec(zSQL /*works-like:""*/);
416 }
417
418 /*
419 ** Mask of modified configuration sets
420 */
@@ -563,35 +566,39 @@
566 if( (thisMask & groupMask)==0 ) return;
567
568 blob_zero(&sql);
569 if( groupMask & CONFIGSET_OVERWRITE ){
570 if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
571 db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
572 configHasBeenReset |= thisMask;
573 }
574 blob_append_sql(&sql, "REPLACE INTO ");
575 }else{
576 blob_append_sql(&sql, "INSERT OR IGNORE INTO ");
577 }
578 blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey);
579 for(jj=2; jj<nToken; jj+=2){
580 blob_append_sql(&sql, ",\"%w\"", azToken[jj]);
581 }
582 blob_append_sql(&sql,") VALUES(%s,%s",
583 azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/);
584 for(jj=2; jj<nToken; jj+=2){
585 blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/);
586 }
587 db_multi_exec("%s)", blob_sql_text(&sql));
588 if( db_changes()==0 ){
589 blob_reset(&sql);
590 blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s",
591 &zName[1], azToken[0]/*safe-for-%s*/);
592 for(jj=2; jj<nToken; jj+=2){
593 blob_append_sql(&sql, ", \"%w\"=%s",
594 azToken[jj], azToken[jj+1]/*safe-for-%s*/);
595 }
596 blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s",
597 aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/,
598 azToken[0]/*safe-for-%s*/);
599 db_multi_exec("%s", blob_sql_text(&sql));
600 }
601 blob_reset(&sql);
602 rebuildMask |= thisMask;
603 }else{
604 /* Otherwise, the old format */
@@ -609,11 +616,11 @@
616 /* Notice that we are evaluating arbitrary SQL received from the
617 ** client. But this can only happen if the client has authenticated
618 ** as an administrator, so presumably we trust the client at this
619 ** point.
620 */
621 db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/);
622 }else{
623 db_multi_exec(
624 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
625 zName, blob_str(pContent)
626 );
@@ -966,11 +973,12 @@
973 db_multi_exec("DELETE FROM concealed");
974 }else if( fossil_strcmp(zName,"@shun")==0 ){
975 db_multi_exec("DELETE FROM shun");
976 }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
977 db_multi_exec("DELETE FROM reportfmt");
978 assert( strchr(zRepositorySchemaDefaultReports,'%')==0 );
979 db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/);
980 }
981 }
982 db_end_transaction(0);
983 fossil_print("Configuration reset to factory defaults.\n");
984 fossil_print("To recover, use: %s %s import %s\n",
985
+2 -2
--- src/content.c
+++ src/content.c
@@ -558,12 +558,12 @@
558558
}
559559
}else{
560560
/* We are creating a new entry */
561561
db_prepare(&s1,
562562
"INSERT INTO blob(rcvid,size,uuid,content)"
563
- "VALUES(%d,%d,'%b',:data)",
564
- g.rcvid, size, &hash
563
+ "VALUES(%d,%d,'%q',:data)",
564
+ g.rcvid, size, blob_str(&hash)
565565
);
566566
db_bind_blob(&s1, ":data", &cmpr);
567567
db_exec(&s1);
568568
rid = db_last_insert_rowid();
569569
if( !pBlob ){
570570
--- src/content.c
+++ src/content.c
@@ -558,12 +558,12 @@
558 }
559 }else{
560 /* We are creating a new entry */
561 db_prepare(&s1,
562 "INSERT INTO blob(rcvid,size,uuid,content)"
563 "VALUES(%d,%d,'%b',:data)",
564 g.rcvid, size, &hash
565 );
566 db_bind_blob(&s1, ":data", &cmpr);
567 db_exec(&s1);
568 rid = db_last_insert_rowid();
569 if( !pBlob ){
570
--- src/content.c
+++ src/content.c
@@ -558,12 +558,12 @@
558 }
559 }else{
560 /* We are creating a new entry */
561 db_prepare(&s1,
562 "INSERT INTO blob(rcvid,size,uuid,content)"
563 "VALUES(%d,%d,'%q',:data)",
564 g.rcvid, size, blob_str(&hash)
565 );
566 db_bind_blob(&s1, ":data", &cmpr);
567 db_exec(&s1);
568 rid = db_last_insert_rowid();
569 if( !pBlob ){
570
+32 -33
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177177
db.doRollback |= db.aHook[i].xHook();
178178
}
179179
while( db.pAllStmt ){
180180
db_finalize(db.pAllStmt);
181181
}
182
- db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
182
+ db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183183
db.doRollback = 0;
184184
}
185185
}
186186
187187
/*
@@ -664,17 +664,17 @@
664664
665665
db = db_open(zFileName);
666666
sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667667
rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668668
if( rc!=SQLITE_OK ){
669
- db_err(sqlite3_errmsg(db));
669
+ db_err("%s", sqlite3_errmsg(db));
670670
}
671671
va_start(ap, zSchema);
672672
while( (zSql = va_arg(ap, const char*))!=0 ){
673673
rc = sqlite3_exec(db, zSql, 0, 0, 0);
674674
if( rc!=SQLITE_OK ){
675
- db_err(sqlite3_errmsg(db));
675
+ db_err("%s", sqlite3_errmsg(db));
676676
}
677677
}
678678
va_end(ap);
679679
sqlite3_exec(db, "COMMIT", 0, 0, 0);
680680
sqlite3_close(db);
@@ -750,19 +750,19 @@
750750
751751
/*
752752
** Detaches the zLabel database.
753753
*/
754754
void db_detach(const char *zLabel){
755
- db_multi_exec("DETACH DATABASE %s", zLabel);
755
+ db_multi_exec("DETACH DATABASE %Q", zLabel);
756756
}
757757
758758
/*
759759
** zDbName is the name of a database file. Attach zDbName using
760760
** the name zLabel.
761761
*/
762762
void db_attach(const char *zDbName, const char *zLabel){
763
- db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
763
+ db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764764
}
765765
766766
/*
767767
** zDbName is the name of a database file. If no other database
768768
** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887887
static int db_local_table_exists_but_lacks_column(
888888
const char *zTable,
889889
const char *zColumn
890890
){
891891
char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892
- " WHERE name=='%s' /*scan*/",
892
+ " WHERE name==%Q /*scan*/",
893893
db_name("localdb"), zTable);
894894
int rc = 0;
895895
if( zDef ){
896896
char *zPattern = mprintf("* %s *", zColumn);
897
- rc = strglob(zPattern, zDef)==0;
897
+ rc = sqlite3_strglob(zPattern, zDef)!=0;
898898
fossil_free(zPattern);
899899
fossil_free(zDef);
900900
}
901901
return rc;
902902
}
@@ -919,19 +919,19 @@
919919
920920
/* If the "isexe" column is missing from the vfile table, then
921921
** add it now. This code added on 2010-03-06. After all users have
922922
** upgraded, this code can be safely deleted.
923923
*/
924
- if( !strglob("* isexe *", zVFileDef) ){
924
+ if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925925
db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926926
}
927927
928928
/* If "islink"/"isLink" columns are missing from tables, then
929929
** add them now. This code added on 2011-01-17 and 2011-08-27.
930930
** After all users have upgraded, this code can be safely deleted.
931931
*/
932
- if( !strglob("* islink *", zVFileDef) ){
932
+ if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933933
db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934934
if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935935
db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936936
}
937937
if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
11191119
** Return TRUE if the schema is out-of-date
11201120
*/
11211121
int db_schema_is_outofdate(void){
11221122
return db_exists("SELECT 1 FROM config"
11231123
" WHERE name='aux-schema'"
1124
- " AND value<>'%s'", AUX_SCHEMA);
1124
+ " AND value<>%Q", AUX_SCHEMA);
11251125
}
11261126
11271127
/*
11281128
** Return true if the database is writeable
11291129
*/
@@ -1349,17 +1349,17 @@
13491349
Blob x;
13501350
int i;
13511351
const char *zSep = "";
13521352
13531353
blob_zero(&x);
1354
- blob_append(&x, "(", 1);
1354
+ blob_append_sql(&x, "(");
13551355
for(i=0; ctrlSettings[i].name; i++){
1356
- blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1356
+ blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
13571357
zSep = ",";
13581358
}
1359
- blob_append(&x, ")", 1);
1360
- return blob_str(&x);
1359
+ blob_append_sql(&x, ")");
1360
+ return blob_sql_text(&x);
13611361
}
13621362
13631363
/*
13641364
** Fill an empty repository database with the basic information for a
13651365
** repository. This function is shared between 'create_repository_cmd'
@@ -1997,53 +1997,52 @@
19971997
** ckout:%s
19981998
**
19991999
** Where %s is the checkout root. The value is the repository file.
20002000
*/
20012001
void db_record_repository_filename(const char *zName){
2002
- const char *zCollation;
20032002
char *zRepoSetting;
20042003
char *zCkoutSetting;
20052004
Blob full;
20062005
if( zName==0 ){
20072006
if( !g.localOpen ) return;
20082007
zName = db_repository_filename();
20092008
}
20102009
file_canonical_name(zName, &full, 0);
2011
- zCollation = filename_collation();
2010
+ (void)filename_collation(); /* Initialize before connection swap */
20122011
db_swap_connections();
20132012
zRepoSetting = mprintf("repo:%q", blob_str(&full));
20142013
db_multi_exec(
2015
- "DELETE FROM global_config WHERE name %s = '%s';",
2016
- zCollation, zRepoSetting
2014
+ "DELETE FROM global_config WHERE name %s = %Q;",
2015
+ filename_collation(), zRepoSetting
20172016
);
20182017
db_multi_exec(
20192018
"INSERT OR IGNORE INTO global_config(name,value)"
2020
- "VALUES('%s',1);",
2019
+ "VALUES(%Q,1);",
20212020
zRepoSetting
20222021
);
20232022
fossil_free(zRepoSetting);
20242023
if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
20252024
Blob localRoot;
20262025
file_canonical_name(g.zLocalRoot, &localRoot, 1);
20272026
zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
20282027
db_multi_exec(
2029
- "DELETE FROM global_config WHERE name %s = '%s';",
2030
- zCollation, zCkoutSetting
2028
+ "DELETE FROM global_config WHERE name %s = %Q;",
2029
+ filename_collation(), zCkoutSetting
20312030
);
20322031
db_multi_exec(
20332032
"REPLACE INTO global_config(name, value)"
2034
- "VALUES('%s','%q');",
2033
+ "VALUES(%Q,%Q);",
20352034
zCkoutSetting, blob_str(&full)
20362035
);
20372036
db_swap_connections();
20382037
db_optional_sql("repository",
2039
- "DELETE FROM config WHERE name %s = '%s';",
2040
- zCollation, zCkoutSetting
2038
+ "DELETE FROM config WHERE name %s = %Q;",
2039
+ filename_collation(), zCkoutSetting
20412040
);
20422041
db_optional_sql("repository",
20432042
"REPLACE INTO config(name,value,mtime)"
2044
- "VALUES('%s',1,now());",
2043
+ "VALUES(%Q,1,now());",
20452044
zCkoutSetting
20462045
);
20472046
fossil_free(zCkoutSetting);
20482047
blob_reset(&localRoot);
20492048
}else{
@@ -2648,28 +2647,28 @@
26482647
zOrigSql += j+6;
26492648
j = -1;
26502649
}
26512650
}
26522651
blob_append(&newSql, zOrigSql, -1);
2653
- blob_appendf(&allSql,
2654
- "ALTER TABLE %s RENAME TO x_%s;\n"
2652
+ blob_append_sql(&allSql,
2653
+ "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
26552654
"%s WITHOUT ROWID;\n"
2656
- "INSERT INTO %s SELECT * FROM x_%s;\n"
2657
- "DROP TABLE x_%s;\n",
2658
- zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2655
+ "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2656
+ "DROP TABLE \"x_%w\";\n",
2657
+ zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
26592658
);
26602659
fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
26612660
blob_reset(&newSql);
26622661
}
2663
- blob_appendf(&allSql, "COMMIT;\n");
2662
+ blob_append_sql(&allSql, "COMMIT;\n");
26642663
db_finalize(&q);
26652664
if( dryRun ){
26662665
fossil_print("SQL that would have been evaluated:\n");
26672666
fossil_print("-------------------------------------------------------------\n");
2668
- fossil_print("%s", blob_str(&allSql));
2667
+ fossil_print("%s", blob_sql_text(&allSql));
26692668
}else{
2670
- db_multi_exec("%s", blob_str(&allSql));
2669
+ db_multi_exec("%s", blob_sql_text(&allSql));
26712670
}
26722671
blob_reset(&allSql);
26732672
db_close(1);
26742673
}
26752674
}
26762675
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err(sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err(sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %s", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name=='%s' /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = strglob(zPattern, zDef)==0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( !strglob("* isexe *", zVFileDef) ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( !strglob("* islink *", zVFileDef) ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>'%s'", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1349,17 +1349,17 @@
1349 Blob x;
1350 int i;
1351 const char *zSep = "";
1352
1353 blob_zero(&x);
1354 blob_append(&x, "(", 1);
1355 for(i=0; ctrlSettings[i].name; i++){
1356 blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1357 zSep = ",";
1358 }
1359 blob_append(&x, ")", 1);
1360 return blob_str(&x);
1361 }
1362
1363 /*
1364 ** Fill an empty repository database with the basic information for a
1365 ** repository. This function is shared between 'create_repository_cmd'
@@ -1997,53 +1997,52 @@
1997 ** ckout:%s
1998 **
1999 ** Where %s is the checkout root. The value is the repository file.
2000 */
2001 void db_record_repository_filename(const char *zName){
2002 const char *zCollation;
2003 char *zRepoSetting;
2004 char *zCkoutSetting;
2005 Blob full;
2006 if( zName==0 ){
2007 if( !g.localOpen ) return;
2008 zName = db_repository_filename();
2009 }
2010 file_canonical_name(zName, &full, 0);
2011 zCollation = filename_collation();
2012 db_swap_connections();
2013 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2014 db_multi_exec(
2015 "DELETE FROM global_config WHERE name %s = '%s';",
2016 zCollation, zRepoSetting
2017 );
2018 db_multi_exec(
2019 "INSERT OR IGNORE INTO global_config(name,value)"
2020 "VALUES('%s',1);",
2021 zRepoSetting
2022 );
2023 fossil_free(zRepoSetting);
2024 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2025 Blob localRoot;
2026 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2027 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2028 db_multi_exec(
2029 "DELETE FROM global_config WHERE name %s = '%s';",
2030 zCollation, zCkoutSetting
2031 );
2032 db_multi_exec(
2033 "REPLACE INTO global_config(name, value)"
2034 "VALUES('%s','%q');",
2035 zCkoutSetting, blob_str(&full)
2036 );
2037 db_swap_connections();
2038 db_optional_sql("repository",
2039 "DELETE FROM config WHERE name %s = '%s';",
2040 zCollation, zCkoutSetting
2041 );
2042 db_optional_sql("repository",
2043 "REPLACE INTO config(name,value,mtime)"
2044 "VALUES('%s',1,now());",
2045 zCkoutSetting
2046 );
2047 fossil_free(zCkoutSetting);
2048 blob_reset(&localRoot);
2049 }else{
@@ -2648,28 +2647,28 @@
2648 zOrigSql += j+6;
2649 j = -1;
2650 }
2651 }
2652 blob_append(&newSql, zOrigSql, -1);
2653 blob_appendf(&allSql,
2654 "ALTER TABLE %s RENAME TO x_%s;\n"
2655 "%s WITHOUT ROWID;\n"
2656 "INSERT INTO %s SELECT * FROM x_%s;\n"
2657 "DROP TABLE x_%s;\n",
2658 zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2659 );
2660 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2661 blob_reset(&newSql);
2662 }
2663 blob_appendf(&allSql, "COMMIT;\n");
2664 db_finalize(&q);
2665 if( dryRun ){
2666 fossil_print("SQL that would have been evaluated:\n");
2667 fossil_print("-------------------------------------------------------------\n");
2668 fossil_print("%s", blob_str(&allSql));
2669 }else{
2670 db_multi_exec("%s", blob_str(&allSql));
2671 }
2672 blob_reset(&allSql);
2673 db_close(1);
2674 }
2675 }
2676
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err("%s", sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err("%s", sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %Q", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name==%Q /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = sqlite3_strglob(zPattern, zDef)!=0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>%Q", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1349,17 +1349,17 @@
1349 Blob x;
1350 int i;
1351 const char *zSep = "";
1352
1353 blob_zero(&x);
1354 blob_append_sql(&x, "(");
1355 for(i=0; ctrlSettings[i].name; i++){
1356 blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
1357 zSep = ",";
1358 }
1359 blob_append_sql(&x, ")");
1360 return blob_sql_text(&x);
1361 }
1362
1363 /*
1364 ** Fill an empty repository database with the basic information for a
1365 ** repository. This function is shared between 'create_repository_cmd'
@@ -1997,53 +1997,52 @@
1997 ** ckout:%s
1998 **
1999 ** Where %s is the checkout root. The value is the repository file.
2000 */
2001 void db_record_repository_filename(const char *zName){
 
2002 char *zRepoSetting;
2003 char *zCkoutSetting;
2004 Blob full;
2005 if( zName==0 ){
2006 if( !g.localOpen ) return;
2007 zName = db_repository_filename();
2008 }
2009 file_canonical_name(zName, &full, 0);
2010 (void)filename_collation(); /* Initialize before connection swap */
2011 db_swap_connections();
2012 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2013 db_multi_exec(
2014 "DELETE FROM global_config WHERE name %s = %Q;",
2015 filename_collation(), zRepoSetting
2016 );
2017 db_multi_exec(
2018 "INSERT OR IGNORE INTO global_config(name,value)"
2019 "VALUES(%Q,1);",
2020 zRepoSetting
2021 );
2022 fossil_free(zRepoSetting);
2023 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2024 Blob localRoot;
2025 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2026 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2027 db_multi_exec(
2028 "DELETE FROM global_config WHERE name %s = %Q;",
2029 filename_collation(), zCkoutSetting
2030 );
2031 db_multi_exec(
2032 "REPLACE INTO global_config(name, value)"
2033 "VALUES(%Q,%Q);",
2034 zCkoutSetting, blob_str(&full)
2035 );
2036 db_swap_connections();
2037 db_optional_sql("repository",
2038 "DELETE FROM config WHERE name %s = %Q;",
2039 filename_collation(), zCkoutSetting
2040 );
2041 db_optional_sql("repository",
2042 "REPLACE INTO config(name,value,mtime)"
2043 "VALUES(%Q,1,now());",
2044 zCkoutSetting
2045 );
2046 fossil_free(zCkoutSetting);
2047 blob_reset(&localRoot);
2048 }else{
@@ -2648,28 +2647,28 @@
2647 zOrigSql += j+6;
2648 j = -1;
2649 }
2650 }
2651 blob_append(&newSql, zOrigSql, -1);
2652 blob_append_sql(&allSql,
2653 "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
2654 "%s WITHOUT ROWID;\n"
2655 "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2656 "DROP TABLE \"x_%w\";\n",
2657 zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
2658 );
2659 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2660 blob_reset(&newSql);
2661 }
2662 blob_append_sql(&allSql, "COMMIT;\n");
2663 db_finalize(&q);
2664 if( dryRun ){
2665 fossil_print("SQL that would have been evaluated:\n");
2666 fossil_print("-------------------------------------------------------------\n");
2667 fossil_print("%s", blob_sql_text(&allSql));
2668 }else{
2669 db_multi_exec("%s", blob_sql_text(&allSql));
2670 }
2671 blob_reset(&allSql);
2672 db_close(1);
2673 }
2674 }
2675
+32 -33
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177177
db.doRollback |= db.aHook[i].xHook();
178178
}
179179
while( db.pAllStmt ){
180180
db_finalize(db.pAllStmt);
181181
}
182
- db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
182
+ db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183183
db.doRollback = 0;
184184
}
185185
}
186186
187187
/*
@@ -664,17 +664,17 @@
664664
665665
db = db_open(zFileName);
666666
sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667667
rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668668
if( rc!=SQLITE_OK ){
669
- db_err(sqlite3_errmsg(db));
669
+ db_err("%s", sqlite3_errmsg(db));
670670
}
671671
va_start(ap, zSchema);
672672
while( (zSql = va_arg(ap, const char*))!=0 ){
673673
rc = sqlite3_exec(db, zSql, 0, 0, 0);
674674
if( rc!=SQLITE_OK ){
675
- db_err(sqlite3_errmsg(db));
675
+ db_err("%s", sqlite3_errmsg(db));
676676
}
677677
}
678678
va_end(ap);
679679
sqlite3_exec(db, "COMMIT", 0, 0, 0);
680680
sqlite3_close(db);
@@ -750,19 +750,19 @@
750750
751751
/*
752752
** Detaches the zLabel database.
753753
*/
754754
void db_detach(const char *zLabel){
755
- db_multi_exec("DETACH DATABASE %s", zLabel);
755
+ db_multi_exec("DETACH DATABASE %Q", zLabel);
756756
}
757757
758758
/*
759759
** zDbName is the name of a database file. Attach zDbName using
760760
** the name zLabel.
761761
*/
762762
void db_attach(const char *zDbName, const char *zLabel){
763
- db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
763
+ db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764764
}
765765
766766
/*
767767
** zDbName is the name of a database file. If no other database
768768
** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887887
static int db_local_table_exists_but_lacks_column(
888888
const char *zTable,
889889
const char *zColumn
890890
){
891891
char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892
- " WHERE name=='%s' /*scan*/",
892
+ " WHERE name==%Q /*scan*/",
893893
db_name("localdb"), zTable);
894894
int rc = 0;
895895
if( zDef ){
896896
char *zPattern = mprintf("* %s *", zColumn);
897
- rc = strglob(zPattern, zDef)==0;
897
+ rc = sqlite3_strglob(zPattern, zDef)!=0;
898898
fossil_free(zPattern);
899899
fossil_free(zDef);
900900
}
901901
return rc;
902902
}
@@ -919,19 +919,19 @@
919919
920920
/* If the "isexe" column is missing from the vfile table, then
921921
** add it now. This code added on 2010-03-06. After all users have
922922
** upgraded, this code can be safely deleted.
923923
*/
924
- if( !strglob("* isexe *", zVFileDef) ){
924
+ if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925925
db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926926
}
927927
928928
/* If "islink"/"isLink" columns are missing from tables, then
929929
** add them now. This code added on 2011-01-17 and 2011-08-27.
930930
** After all users have upgraded, this code can be safely deleted.
931931
*/
932
- if( !strglob("* islink *", zVFileDef) ){
932
+ if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933933
db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934934
if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935935
db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936936
}
937937
if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
11191119
** Return TRUE if the schema is out-of-date
11201120
*/
11211121
int db_schema_is_outofdate(void){
11221122
return db_exists("SELECT 1 FROM config"
11231123
" WHERE name='aux-schema'"
1124
- " AND value<>'%s'", AUX_SCHEMA);
1124
+ " AND value<>%Q", AUX_SCHEMA);
11251125
}
11261126
11271127
/*
11281128
** Return true if the database is writeable
11291129
*/
@@ -1349,17 +1349,17 @@
13491349
Blob x;
13501350
int i;
13511351
const char *zSep = "";
13521352
13531353
blob_zero(&x);
1354
- blob_append(&x, "(", 1);
1354
+ blob_append_sql(&x, "(");
13551355
for(i=0; ctrlSettings[i].name; i++){
1356
- blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1356
+ blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
13571357
zSep = ",";
13581358
}
1359
- blob_append(&x, ")", 1);
1360
- return blob_str(&x);
1359
+ blob_append_sql(&x, ")");
1360
+ return blob_sql_text(&x);
13611361
}
13621362
13631363
/*
13641364
** Fill an empty repository database with the basic information for a
13651365
** repository. This function is shared between 'create_repository_cmd'
@@ -1997,53 +1997,52 @@
19971997
** ckout:%s
19981998
**
19991999
** Where %s is the checkout root. The value is the repository file.
20002000
*/
20012001
void db_record_repository_filename(const char *zName){
2002
- const char *zCollation;
20032002
char *zRepoSetting;
20042003
char *zCkoutSetting;
20052004
Blob full;
20062005
if( zName==0 ){
20072006
if( !g.localOpen ) return;
20082007
zName = db_repository_filename();
20092008
}
20102009
file_canonical_name(zName, &full, 0);
2011
- zCollation = filename_collation();
2010
+ (void)filename_collation(); /* Initialize before connection swap */
20122011
db_swap_connections();
20132012
zRepoSetting = mprintf("repo:%q", blob_str(&full));
20142013
db_multi_exec(
2015
- "DELETE FROM global_config WHERE name %s = '%s';",
2016
- zCollation, zRepoSetting
2014
+ "DELETE FROM global_config WHERE name %s = %Q;",
2015
+ filename_collation(), zRepoSetting
20172016
);
20182017
db_multi_exec(
20192018
"INSERT OR IGNORE INTO global_config(name,value)"
2020
- "VALUES('%s',1);",
2019
+ "VALUES(%Q,1);",
20212020
zRepoSetting
20222021
);
20232022
fossil_free(zRepoSetting);
20242023
if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
20252024
Blob localRoot;
20262025
file_canonical_name(g.zLocalRoot, &localRoot, 1);
20272026
zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
20282027
db_multi_exec(
2029
- "DELETE FROM global_config WHERE name %s = '%s';",
2030
- zCollation, zCkoutSetting
2028
+ "DELETE FROM global_config WHERE name %s = %Q;",
2029
+ filename_collation(), zCkoutSetting
20312030
);
20322031
db_multi_exec(
20332032
"REPLACE INTO global_config(name, value)"
2034
- "VALUES('%s','%q');",
2033
+ "VALUES(%Q,%Q);",
20352034
zCkoutSetting, blob_str(&full)
20362035
);
20372036
db_swap_connections();
20382037
db_optional_sql("repository",
2039
- "DELETE FROM config WHERE name %s = '%s';",
2040
- zCollation, zCkoutSetting
2038
+ "DELETE FROM config WHERE name %s = %Q;",
2039
+ filename_collation(), zCkoutSetting
20412040
);
20422041
db_optional_sql("repository",
20432042
"REPLACE INTO config(name,value,mtime)"
2044
- "VALUES('%s',1,now());",
2043
+ "VALUES(%Q,1,now());",
20452044
zCkoutSetting
20462045
);
20472046
fossil_free(zCkoutSetting);
20482047
blob_reset(&localRoot);
20492048
}else{
@@ -2648,28 +2647,28 @@
26482647
zOrigSql += j+6;
26492648
j = -1;
26502649
}
26512650
}
26522651
blob_append(&newSql, zOrigSql, -1);
2653
- blob_appendf(&allSql,
2654
- "ALTER TABLE %s RENAME TO x_%s;\n"
2652
+ blob_append_sql(&allSql,
2653
+ "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
26552654
"%s WITHOUT ROWID;\n"
2656
- "INSERT INTO %s SELECT * FROM x_%s;\n"
2657
- "DROP TABLE x_%s;\n",
2658
- zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2655
+ "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2656
+ "DROP TABLE \"x_%w\";\n",
2657
+ zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
26592658
);
26602659
fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
26612660
blob_reset(&newSql);
26622661
}
2663
- blob_appendf(&allSql, "COMMIT;\n");
2662
+ blob_append_sql(&allSql, "COMMIT;\n");
26642663
db_finalize(&q);
26652664
if( dryRun ){
26662665
fossil_print("SQL that would have been evaluated:\n");
26672666
fossil_print("-------------------------------------------------------------\n");
2668
- fossil_print("%s", blob_str(&allSql));
2667
+ fossil_print("%s", blob_sql_text(&allSql));
26692668
}else{
2670
- db_multi_exec("%s", blob_str(&allSql));
2669
+ db_multi_exec("%s", blob_sql_text(&allSql));
26712670
}
26722671
blob_reset(&allSql);
26732672
db_close(1);
26742673
}
26752674
}
26762675
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err(sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err(sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %s", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name=='%s' /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = strglob(zPattern, zDef)==0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( !strglob("* isexe *", zVFileDef) ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( !strglob("* islink *", zVFileDef) ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>'%s'", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1349,17 +1349,17 @@
1349 Blob x;
1350 int i;
1351 const char *zSep = "";
1352
1353 blob_zero(&x);
1354 blob_append(&x, "(", 1);
1355 for(i=0; ctrlSettings[i].name; i++){
1356 blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1357 zSep = ",";
1358 }
1359 blob_append(&x, ")", 1);
1360 return blob_str(&x);
1361 }
1362
1363 /*
1364 ** Fill an empty repository database with the basic information for a
1365 ** repository. This function is shared between 'create_repository_cmd'
@@ -1997,53 +1997,52 @@
1997 ** ckout:%s
1998 **
1999 ** Where %s is the checkout root. The value is the repository file.
2000 */
2001 void db_record_repository_filename(const char *zName){
2002 const char *zCollation;
2003 char *zRepoSetting;
2004 char *zCkoutSetting;
2005 Blob full;
2006 if( zName==0 ){
2007 if( !g.localOpen ) return;
2008 zName = db_repository_filename();
2009 }
2010 file_canonical_name(zName, &full, 0);
2011 zCollation = filename_collation();
2012 db_swap_connections();
2013 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2014 db_multi_exec(
2015 "DELETE FROM global_config WHERE name %s = '%s';",
2016 zCollation, zRepoSetting
2017 );
2018 db_multi_exec(
2019 "INSERT OR IGNORE INTO global_config(name,value)"
2020 "VALUES('%s',1);",
2021 zRepoSetting
2022 );
2023 fossil_free(zRepoSetting);
2024 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2025 Blob localRoot;
2026 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2027 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2028 db_multi_exec(
2029 "DELETE FROM global_config WHERE name %s = '%s';",
2030 zCollation, zCkoutSetting
2031 );
2032 db_multi_exec(
2033 "REPLACE INTO global_config(name, value)"
2034 "VALUES('%s','%q');",
2035 zCkoutSetting, blob_str(&full)
2036 );
2037 db_swap_connections();
2038 db_optional_sql("repository",
2039 "DELETE FROM config WHERE name %s = '%s';",
2040 zCollation, zCkoutSetting
2041 );
2042 db_optional_sql("repository",
2043 "REPLACE INTO config(name,value,mtime)"
2044 "VALUES('%s',1,now());",
2045 zCkoutSetting
2046 );
2047 fossil_free(zCkoutSetting);
2048 blob_reset(&localRoot);
2049 }else{
@@ -2648,28 +2647,28 @@
2648 zOrigSql += j+6;
2649 j = -1;
2650 }
2651 }
2652 blob_append(&newSql, zOrigSql, -1);
2653 blob_appendf(&allSql,
2654 "ALTER TABLE %s RENAME TO x_%s;\n"
2655 "%s WITHOUT ROWID;\n"
2656 "INSERT INTO %s SELECT * FROM x_%s;\n"
2657 "DROP TABLE x_%s;\n",
2658 zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2659 );
2660 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2661 blob_reset(&newSql);
2662 }
2663 blob_appendf(&allSql, "COMMIT;\n");
2664 db_finalize(&q);
2665 if( dryRun ){
2666 fossil_print("SQL that would have been evaluated:\n");
2667 fossil_print("-------------------------------------------------------------\n");
2668 fossil_print("%s", blob_str(&allSql));
2669 }else{
2670 db_multi_exec("%s", blob_str(&allSql));
2671 }
2672 blob_reset(&allSql);
2673 db_close(1);
2674 }
2675 }
2676
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err("%s", sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err("%s", sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %Q", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name==%Q /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = sqlite3_strglob(zPattern, zDef)!=0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>%Q", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1349,17 +1349,17 @@
1349 Blob x;
1350 int i;
1351 const char *zSep = "";
1352
1353 blob_zero(&x);
1354 blob_append_sql(&x, "(");
1355 for(i=0; ctrlSettings[i].name; i++){
1356 blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
1357 zSep = ",";
1358 }
1359 blob_append_sql(&x, ")");
1360 return blob_sql_text(&x);
1361 }
1362
1363 /*
1364 ** Fill an empty repository database with the basic information for a
1365 ** repository. This function is shared between 'create_repository_cmd'
@@ -1997,53 +1997,52 @@
1997 ** ckout:%s
1998 **
1999 ** Where %s is the checkout root. The value is the repository file.
2000 */
2001 void db_record_repository_filename(const char *zName){
 
2002 char *zRepoSetting;
2003 char *zCkoutSetting;
2004 Blob full;
2005 if( zName==0 ){
2006 if( !g.localOpen ) return;
2007 zName = db_repository_filename();
2008 }
2009 file_canonical_name(zName, &full, 0);
2010 (void)filename_collation(); /* Initialize before connection swap */
2011 db_swap_connections();
2012 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2013 db_multi_exec(
2014 "DELETE FROM global_config WHERE name %s = %Q;",
2015 filename_collation(), zRepoSetting
2016 );
2017 db_multi_exec(
2018 "INSERT OR IGNORE INTO global_config(name,value)"
2019 "VALUES(%Q,1);",
2020 zRepoSetting
2021 );
2022 fossil_free(zRepoSetting);
2023 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2024 Blob localRoot;
2025 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2026 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2027 db_multi_exec(
2028 "DELETE FROM global_config WHERE name %s = %Q;",
2029 filename_collation(), zCkoutSetting
2030 );
2031 db_multi_exec(
2032 "REPLACE INTO global_config(name, value)"
2033 "VALUES(%Q,%Q);",
2034 zCkoutSetting, blob_str(&full)
2035 );
2036 db_swap_connections();
2037 db_optional_sql("repository",
2038 "DELETE FROM config WHERE name %s = %Q;",
2039 filename_collation(), zCkoutSetting
2040 );
2041 db_optional_sql("repository",
2042 "REPLACE INTO config(name,value,mtime)"
2043 "VALUES(%Q,1,now());",
2044 zCkoutSetting
2045 );
2046 fossil_free(zCkoutSetting);
2047 blob_reset(&localRoot);
2048 }else{
@@ -2648,28 +2647,28 @@
2647 zOrigSql += j+6;
2648 j = -1;
2649 }
2650 }
2651 blob_append(&newSql, zOrigSql, -1);
2652 blob_append_sql(&allSql,
2653 "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
2654 "%s WITHOUT ROWID;\n"
2655 "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2656 "DROP TABLE \"x_%w\";\n",
2657 zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
2658 );
2659 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2660 blob_reset(&newSql);
2661 }
2662 blob_append_sql(&allSql, "COMMIT;\n");
2663 db_finalize(&q);
2664 if( dryRun ){
2665 fossil_print("SQL that would have been evaluated:\n");
2666 fossil_print("-------------------------------------------------------------\n");
2667 fossil_print("%s", blob_sql_text(&allSql));
2668 }else{
2669 db_multi_exec("%s", blob_sql_text(&allSql));
2670 }
2671 blob_reset(&allSql);
2672 db_close(1);
2673 }
2674 }
2675
+10 -10
--- src/delta.c
+++ src/delta.c
@@ -65,11 +65,11 @@
6565
** The "u32" type must be an unsigned 32-bit integer. Adjust this
6666
*/
6767
typedef unsigned int u32;
6868
6969
/*
70
-** Must be a 16-bit value
70
+** Must be a 16-bit value
7171
*/
7272
typedef short int s16;
7373
typedef unsigned short int u16;
7474
7575
#endif /* INTERFACE */
@@ -82,11 +82,11 @@
8282
8383
/*
8484
** The current state of the rolling hash.
8585
**
8686
** z[] holds the values that have been hashed. z[] is a circular buffer.
87
-** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
87
+** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
8888
** the window.
8989
**
9090
** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
9191
** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
9292
** (Each index for z[] should be module NHASH, of course. The %NHASH operator
@@ -135,11 +135,11 @@
135135
136136
/*
137137
** Write an base-64 integer into the given buffer.
138138
*/
139139
static void putInt(unsigned int v, char **pz){
140
- static const char zDigits[] =
140
+ static const char zDigits[] =
141141
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
142142
/* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
143143
int i, j;
144144
char zBuf[20];
145145
if( v==0 ){
@@ -229,11 +229,11 @@
229229
}
230230
231231
/*
232232
** Create a new delta.
233233
**
234
-** The delta is written into a preallocated buffer, zDelta, which
234
+** The delta is written into a preallocated buffer, zDelta, which
235235
** should be at least 60 bytes longer than the target file, zOut.
236236
** The delta string will be NUL-terminated, but it might also contain
237237
** embedded NUL characters if either the zSrc or zOut files are
238238
** binary. This function returns the length of the delta string
239239
** in bytes, excluding the final NUL terminator character.
@@ -245,11 +245,11 @@
245245
** delta file z, a program can compute the size of the output file
246246
** simply by reading the first line and decoding the base-64 number
247247
** found there. The delta_output_size() routine does exactly this.
248248
**
249249
** After the initial size number, the delta consists of a series of
250
-** literal text segments and commands to copy from the SOURCE file.
250
+** literal text segments and commands to copy from the SOURCE file.
251251
** A copy command looks like this:
252252
**
253253
** NNN@MMM,
254254
**
255255
** where NNN is the number of bytes to be copied and MMM is the offset
@@ -283,11 +283,11 @@
283283
** search for a matching section in the source file. When a match
284284
** is found, a copy command is added to the delta. An effort is
285285
** made to extend the matching section to regions that come before
286286
** and after the 16-byte hash window. A copy command is only issued
287287
** if the result would use less space that just quoting the text
288
-** literally. Literal text is added to the delta for sections that
288
+** literally. Literal text is added to the delta for sections that
289289
** do not match or which can not be encoded efficiently using copy
290290
** commands.
291291
*/
292292
int delta_create(
293293
const char *zSrc, /* The source or pattern file */
@@ -356,13 +356,13 @@
356356
hv = hash_32bit(&h) % nHash;
357357
DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
358358
iBlock = landmark[hv];
359359
while( iBlock>=0 && (limit--)>0 ){
360360
/*
361
- ** The hash window has identified a potential match against
361
+ ** The hash window has identified a potential match against
362362
** landmark block iBlock. But we need to investigate further.
363
- **
363
+ **
364364
** Look for a region in zOut that matches zSrc. Anchor the search
365365
** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
366366
** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
367367
**
368368
** Set cnt equal to the length of the match and set ofst so that
@@ -468,16 +468,16 @@
468468
}
469469
/* Output the final checksum record. */
470470
putInt(checksum(zOut, lenOut), &zDelta);
471471
*(zDelta++) = ';';
472472
fossil_free(collide);
473
- return zDelta - zOrigDelta;
473
+ return zDelta - zOrigDelta;
474474
}
475475
476476
/*
477477
** Return the size (in bytes) of the output from applying
478
-** a delta.
478
+** a delta.
479479
**
480480
** This routine is provided so that an procedure that is able
481481
** to call delta_apply() can learn how much space is required
482482
** for the output and hence allocate nor more space that is really
483483
** needed.
484484
--- src/delta.c
+++ src/delta.c
@@ -65,11 +65,11 @@
65 ** The "u32" type must be an unsigned 32-bit integer. Adjust this
66 */
67 typedef unsigned int u32;
68
69 /*
70 ** Must be a 16-bit value
71 */
72 typedef short int s16;
73 typedef unsigned short int u16;
74
75 #endif /* INTERFACE */
@@ -82,11 +82,11 @@
82
83 /*
84 ** The current state of the rolling hash.
85 **
86 ** z[] holds the values that have been hashed. z[] is a circular buffer.
87 ** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
88 ** the window.
89 **
90 ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
91 ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
92 ** (Each index for z[] should be module NHASH, of course. The %NHASH operator
@@ -135,11 +135,11 @@
135
136 /*
137 ** Write an base-64 integer into the given buffer.
138 */
139 static void putInt(unsigned int v, char **pz){
140 static const char zDigits[] =
141 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
142 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
143 int i, j;
144 char zBuf[20];
145 if( v==0 ){
@@ -229,11 +229,11 @@
229 }
230
231 /*
232 ** Create a new delta.
233 **
234 ** The delta is written into a preallocated buffer, zDelta, which
235 ** should be at least 60 bytes longer than the target file, zOut.
236 ** The delta string will be NUL-terminated, but it might also contain
237 ** embedded NUL characters if either the zSrc or zOut files are
238 ** binary. This function returns the length of the delta string
239 ** in bytes, excluding the final NUL terminator character.
@@ -245,11 +245,11 @@
245 ** delta file z, a program can compute the size of the output file
246 ** simply by reading the first line and decoding the base-64 number
247 ** found there. The delta_output_size() routine does exactly this.
248 **
249 ** After the initial size number, the delta consists of a series of
250 ** literal text segments and commands to copy from the SOURCE file.
251 ** A copy command looks like this:
252 **
253 ** NNN@MMM,
254 **
255 ** where NNN is the number of bytes to be copied and MMM is the offset
@@ -283,11 +283,11 @@
283 ** search for a matching section in the source file. When a match
284 ** is found, a copy command is added to the delta. An effort is
285 ** made to extend the matching section to regions that come before
286 ** and after the 16-byte hash window. A copy command is only issued
287 ** if the result would use less space that just quoting the text
288 ** literally. Literal text is added to the delta for sections that
289 ** do not match or which can not be encoded efficiently using copy
290 ** commands.
291 */
292 int delta_create(
293 const char *zSrc, /* The source or pattern file */
@@ -356,13 +356,13 @@
356 hv = hash_32bit(&h) % nHash;
357 DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
358 iBlock = landmark[hv];
359 while( iBlock>=0 && (limit--)>0 ){
360 /*
361 ** The hash window has identified a potential match against
362 ** landmark block iBlock. But we need to investigate further.
363 **
364 ** Look for a region in zOut that matches zSrc. Anchor the search
365 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
366 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
367 **
368 ** Set cnt equal to the length of the match and set ofst so that
@@ -468,16 +468,16 @@
468 }
469 /* Output the final checksum record. */
470 putInt(checksum(zOut, lenOut), &zDelta);
471 *(zDelta++) = ';';
472 fossil_free(collide);
473 return zDelta - zOrigDelta;
474 }
475
476 /*
477 ** Return the size (in bytes) of the output from applying
478 ** a delta.
479 **
480 ** This routine is provided so that an procedure that is able
481 ** to call delta_apply() can learn how much space is required
482 ** for the output and hence allocate nor more space that is really
483 ** needed.
484
--- src/delta.c
+++ src/delta.c
@@ -65,11 +65,11 @@
65 ** The "u32" type must be an unsigned 32-bit integer. Adjust this
66 */
67 typedef unsigned int u32;
68
69 /*
70 ** Must be a 16-bit value
71 */
72 typedef short int s16;
73 typedef unsigned short int u16;
74
75 #endif /* INTERFACE */
@@ -82,11 +82,11 @@
82
83 /*
84 ** The current state of the rolling hash.
85 **
86 ** z[] holds the values that have been hashed. z[] is a circular buffer.
87 ** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
88 ** the window.
89 **
90 ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
91 ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
92 ** (Each index for z[] should be module NHASH, of course. The %NHASH operator
@@ -135,11 +135,11 @@
135
136 /*
137 ** Write an base-64 integer into the given buffer.
138 */
139 static void putInt(unsigned int v, char **pz){
140 static const char zDigits[] =
141 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
142 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
143 int i, j;
144 char zBuf[20];
145 if( v==0 ){
@@ -229,11 +229,11 @@
229 }
230
231 /*
232 ** Create a new delta.
233 **
234 ** The delta is written into a preallocated buffer, zDelta, which
235 ** should be at least 60 bytes longer than the target file, zOut.
236 ** The delta string will be NUL-terminated, but it might also contain
237 ** embedded NUL characters if either the zSrc or zOut files are
238 ** binary. This function returns the length of the delta string
239 ** in bytes, excluding the final NUL terminator character.
@@ -245,11 +245,11 @@
245 ** delta file z, a program can compute the size of the output file
246 ** simply by reading the first line and decoding the base-64 number
247 ** found there. The delta_output_size() routine does exactly this.
248 **
249 ** After the initial size number, the delta consists of a series of
250 ** literal text segments and commands to copy from the SOURCE file.
251 ** A copy command looks like this:
252 **
253 ** NNN@MMM,
254 **
255 ** where NNN is the number of bytes to be copied and MMM is the offset
@@ -283,11 +283,11 @@
283 ** search for a matching section in the source file. When a match
284 ** is found, a copy command is added to the delta. An effort is
285 ** made to extend the matching section to regions that come before
286 ** and after the 16-byte hash window. A copy command is only issued
287 ** if the result would use less space that just quoting the text
288 ** literally. Literal text is added to the delta for sections that
289 ** do not match or which can not be encoded efficiently using copy
290 ** commands.
291 */
292 int delta_create(
293 const char *zSrc, /* The source or pattern file */
@@ -356,13 +356,13 @@
356 hv = hash_32bit(&h) % nHash;
357 DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
358 iBlock = landmark[hv];
359 while( iBlock>=0 && (limit--)>0 ){
360 /*
361 ** The hash window has identified a potential match against
362 ** landmark block iBlock. But we need to investigate further.
363 **
364 ** Look for a region in zOut that matches zSrc. Anchor the search
365 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
366 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
367 **
368 ** Set cnt equal to the length of the match and set ofst so that
@@ -468,16 +468,16 @@
468 }
469 /* Output the final checksum record. */
470 putInt(checksum(zOut, lenOut), &zDelta);
471 *(zDelta++) = ';';
472 fossil_free(collide);
473 return zDelta - zOrigDelta;
474 }
475
476 /*
477 ** Return the size (in bytes) of the output from applying
478 ** a delta.
479 **
480 ** This routine is provided so that an procedure that is able
481 ** to call delta_apply() can learn how much space is required
482 ** for the output and hence allocate nor more space that is really
483 ** needed.
484
+10 -10
--- src/descendants.c
+++ src/descendants.c
@@ -389,22 +389,22 @@
389389
verify_all_options();
390390
391391
if( recomputeFlag ) leaf_rebuild();
392392
blob_zero(&sql);
393393
blob_append(&sql, timeline_query_for_tty(), -1);
394
- blob_appendf(&sql, " AND blob.rid IN leaf");
394
+ blob_append_sql(&sql, " AND blob.rid IN leaf");
395395
if( showClosed ){
396
- blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
396
+ blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
397397
}else if( !showAll ){
398
- blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
398
+ blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
399399
}
400400
if( byBranch ){
401401
db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
402402
" event.mtime DESC",
403
- blob_str(&sql));
403
+ blob_sql_text(&sql));
404404
}else{
405
- db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
405
+ db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
406406
}
407407
blob_reset(&sql);
408408
n = 0;
409409
while( db_step(&q)==SQLITE_ROW ){
410410
const char *zId = db_column_text(&q, 1);
@@ -474,17 +474,17 @@
474474
}else{
475475
@ <h1>Open leaves:</h1>
476476
}
477477
blob_zero(&sql);
478478
blob_append(&sql, timeline_query_for_www(), -1);
479
- blob_appendf(&sql, " AND blob.rid IN leaf");
479
+ blob_append_sql(&sql, " AND blob.rid IN leaf");
480480
if( showClosed ){
481
- blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
481
+ blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
482482
}else if( !showAll ){
483
- blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
483
+ blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
484484
}
485
- db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
485
+ db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
486486
blob_reset(&sql);
487487
www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
488488
db_finalize(&q);
489489
@ <br />
490490
style_footer();
@@ -508,11 +508,11 @@
508508
Stmt q;
509509
int rid;
510510
511511
bag_init(&seen);
512512
bag_init(&pending);
513
- db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
513
+ db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
514514
db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
515515
while( db_step(&q)==SQLITE_ROW ){
516516
int mid = db_column_int(&q, 0);
517517
bag_insert(&pending, mid);
518518
bag_insert(&seen, mid);
519519
520520
ADDED src/diff.tcl
--- src/descendants.c
+++ src/descendants.c
@@ -389,22 +389,22 @@
389 verify_all_options();
390
391 if( recomputeFlag ) leaf_rebuild();
392 blob_zero(&sql);
393 blob_append(&sql, timeline_query_for_tty(), -1);
394 blob_appendf(&sql, " AND blob.rid IN leaf");
395 if( showClosed ){
396 blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
397 }else if( !showAll ){
398 blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
399 }
400 if( byBranch ){
401 db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
402 " event.mtime DESC",
403 blob_str(&sql));
404 }else{
405 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
406 }
407 blob_reset(&sql);
408 n = 0;
409 while( db_step(&q)==SQLITE_ROW ){
410 const char *zId = db_column_text(&q, 1);
@@ -474,17 +474,17 @@
474 }else{
475 @ <h1>Open leaves:</h1>
476 }
477 blob_zero(&sql);
478 blob_append(&sql, timeline_query_for_www(), -1);
479 blob_appendf(&sql, " AND blob.rid IN leaf");
480 if( showClosed ){
481 blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
482 }else if( !showAll ){
483 blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
484 }
485 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
486 blob_reset(&sql);
487 www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
488 db_finalize(&q);
489 @ <br />
490 style_footer();
@@ -508,11 +508,11 @@
508 Stmt q;
509 int rid;
510
511 bag_init(&seen);
512 bag_init(&pending);
513 db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
514 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
515 while( db_step(&q)==SQLITE_ROW ){
516 int mid = db_column_int(&q, 0);
517 bag_insert(&pending, mid);
518 bag_insert(&seen, mid);
519
520 DDED src/diff.tcl
--- src/descendants.c
+++ src/descendants.c
@@ -389,22 +389,22 @@
389 verify_all_options();
390
391 if( recomputeFlag ) leaf_rebuild();
392 blob_zero(&sql);
393 blob_append(&sql, timeline_query_for_tty(), -1);
394 blob_append_sql(&sql, " AND blob.rid IN leaf");
395 if( showClosed ){
396 blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
397 }else if( !showAll ){
398 blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
399 }
400 if( byBranch ){
401 db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
402 " event.mtime DESC",
403 blob_sql_text(&sql));
404 }else{
405 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
406 }
407 blob_reset(&sql);
408 n = 0;
409 while( db_step(&q)==SQLITE_ROW ){
410 const char *zId = db_column_text(&q, 1);
@@ -474,17 +474,17 @@
474 }else{
475 @ <h1>Open leaves:</h1>
476 }
477 blob_zero(&sql);
478 blob_append(&sql, timeline_query_for_www(), -1);
479 blob_append_sql(&sql, " AND blob.rid IN leaf");
480 if( showClosed ){
481 blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
482 }else if( !showAll ){
483 blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
484 }
485 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
486 blob_reset(&sql);
487 www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
488 db_finalize(&q);
489 @ <br />
490 style_footer();
@@ -508,11 +508,11 @@
508 Stmt q;
509 int rid;
510
511 bag_init(&seen);
512 bag_init(&pending);
513 db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
514 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
515 while( db_step(&q)==SQLITE_ROW ){
516 int mid = db_column_int(&q, 0);
517 bag_insert(&pending, mid);
518 bag_insert(&seen, mid);
519
520 DDED src/diff.tcl

No diff available

+12 -398
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -142,17 +142,17 @@
142142
Blob cmd; /* Text of command to run */
143143
144144
if( !fIncludeBinary ){
145145
Blob file2;
146146
if( isBin1 ){
147
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
147
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
148148
return;
149149
}
150150
if( zBinGlob ){
151151
Glob *pBinary = glob_create(zBinGlob);
152152
if( glob_match(pBinary, zName) ){
153
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
153
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
154154
glob_free(pBinary);
155155
return;
156156
}
157157
glob_free(pBinary);
158158
}
@@ -163,11 +163,11 @@
163163
}else{
164164
blob_read_from_file(&file2, zFile2);
165165
}
166166
}
167167
if( looks_like_binary(&file2) ){
168
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
168
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
169169
blob_reset(&file2);
170170
return;
171171
}
172172
blob_reset(&file2);
173173
}
@@ -238,17 +238,17 @@
238238
char zTemp1[300];
239239
char zTemp2[300];
240240
241241
if( !fIncludeBinary ){
242242
if( isBin1 || isBin2 ){
243
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
243
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
244244
return;
245245
}
246246
if( zBinGlob ){
247247
Glob *pBinary = glob_create(zBinGlob);
248248
if( glob_match(pBinary, zName) ){
249
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
249
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
250250
glob_free(pBinary);
251251
return;
252252
}
253253
glob_free(pBinary);
254254
}
@@ -302,11 +302,11 @@
302302
int isBin;
303303
file_tree_name(zFileTreeName, &fname, 1);
304304
historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305305
fIncludeBinary ? 0 : &isBin, 0);
306306
if( !isLink != !file_wd_islink(zFrom) ){
307
- fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
307
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308308
}else{
309309
diff_file(&content, isBin, zFileTreeName, zFileTreeName,
310310
zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
311311
}
312312
blob_reset(&content);
@@ -346,11 +346,11 @@
346346
int rid = name_to_typed_rid(zFrom, "ci");
347347
if( !is_a_version(rid) ){
348348
fossil_fatal("no such check-in: %s", zFrom);
349349
}
350350
load_vfile_from_rid(rid);
351
- blob_appendf(&sql,
351
+ blob_append_sql(&sql,
352352
"SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
353353
" FROM vfile v1, vfile v2 "
354354
" WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
355355
" AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
356356
"UNION "
@@ -367,20 +367,20 @@
367367
" WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368368
" ORDER BY 1",
369369
rid, vid, rid, vid, vid, rid
370370
);
371371
}else{
372
- blob_appendf(&sql,
372
+ blob_append_sql(&sql,
373373
"SELECT pathname, deleted, chnged , rid==0, rid, islink"
374374
" FROM vfile"
375375
" WHERE vid=%d"
376376
" AND (deleted OR chnged OR rid==0)"
377377
" ORDER BY pathname",
378378
vid
379379
);
380380
}
381
- db_prepare(&q, blob_str(&sql));
381
+ db_prepare(&q, "%s", blob_sql_text(&sql));
382382
while( db_step(&q)==SQLITE_ROW ){
383383
const char *zPathname = db_column_text(&q,0);
384384
int isDeleted = db_column_int(&q, 1);
385385
int isChnged = db_column_int(&q,2);
386386
int isNew = db_column_int(&q,3);
@@ -408,11 +408,11 @@
408408
Blob content;
409409
int isBin;
410410
if( !isLink != !file_wd_islink(zFullName) ){
411411
diff_print_index(zPathname, diffFlags);
412412
diff_print_filenames(zPathname, zPathname, diffFlags);
413
- fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
413
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
414414
continue;
415415
}
416416
if( srcid>0 ){
417417
content_get(srcid, &content);
418418
}else{
@@ -462,11 +462,11 @@
462462
fIncludeBinary ? 0 : &isBin1, 0);
463463
historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464464
fIncludeBinary ? 0 : &isBin2, 0);
465465
if( isLink1 != isLink2 ){
466466
diff_print_filenames(zName, zName, diffFlags);
467
- fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
467
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
468468
}else{
469469
diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
470470
zBinGlob, fIncludeBinary, diffFlags);
471471
}
472472
blob_reset(&v1);
@@ -617,396 +617,10 @@
617617
zName = "diff-command";
618618
}
619619
return db_get(zName, zDefault);
620620
}
621621
622
-/* A Tcl/Tk script used to render diff output.
623
-*/
624
-static const char zDiffScript[] =
625
-@ set prog {
626
-@ package require Tk
627
-@
628
-@ array set CFG {
629
-@ TITLE {Fossil Diff}
630
-@ LN_COL_BG #dddddd
631
-@ LN_COL_FG #444444
632
-@ TXT_COL_BG #ffffff
633
-@ TXT_COL_FG #000000
634
-@ MKR_COL_BG #444444
635
-@ MKR_COL_FG #dddddd
636
-@ CHNG_BG #d0d0ff
637
-@ ADD_BG #c0ffc0
638
-@ RM_BG #ffc0c0
639
-@ HR_FG #888888
640
-@ HR_PAD_TOP 4
641
-@ HR_PAD_BTM 8
642
-@ FN_BG #444444
643
-@ FN_FG #ffffff
644
-@ FN_PAD 5
645
-@ ERR_FG #ee0000
646
-@ PADX 5
647
-@ WIDTH 80
648
-@ HEIGHT 45
649
-@ LB_HEIGHT 25
650
-@ }
651
-@
652
-@ if {![namespace exists ttk]} {
653
-@ interp alias {} ::ttk::scrollbar {} ::scrollbar
654
-@ interp alias {} ::ttk::menubutton {} ::menubutton
655
-@ }
656
-@
657
-@ proc dehtml {x} {
658
-@ set x [regsub -all {<[^>]*>} $x {}]
659
-@ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
660
-@ }
661
-@
662
-@ proc cols {} {
663
-@ return [list .lnA .txtA .mkr .lnB .txtB]
664
-@ }
665
-@
666
-@ proc colType {c} {
667
-@ regexp {[a-z]+} $c type
668
-@ return $type
669
-@ }
670
-@
671
-@ proc getLine {difftxt N iivar} {
672
-@ upvar $iivar ii
673
-@ if {$ii>=$N} {return -1}
674
-@ set x [lindex $difftxt $ii]
675
-@ incr ii
676
-@ return $x
677
-@ }
678
-@
679
-@ proc readDiffs {fossilcmd} {
680
-@ global difftxt
681
-@ if {![info exists difftxt]} {
682
-@ set in [open $fossilcmd r]
683
-@ fconfigure $in -encoding utf-8
684
-@ set difftxt [split [read $in] \n]
685
-@ close $in
686
-@ }
687
-@ set N [llength $difftxt]
688
-@ set ii 0
689
-@ set nDiffs 0
690
-@ array set widths {txt 0 ln 0 mkr 0}
691
-@ while {[set line [getLine $difftxt $N ii]] != -1} {
692
-@ set fn2 {}
693
-@ if {![regexp {^=+ (.*?) =+ versus =+ (.*?) =+$} $line all fn fn2]
694
-@ && ![regexp {^=+ (.*?) =+$} $line all fn]
695
-@ } {
696
-@ continue
697
-@ }
698
-@ set errMsg ""
699
-@ set line [getLine $difftxt $N ii]
700
-@ if {[string compare -length 6 $line "<table"]
701
-@ && ![regexp {<p[^>]*>(.+)} $line - errMsg]} {
702
-@ continue
703
-@ }
704
-@ incr nDiffs
705
-@ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
706
-@ .wfiles.lb insert end $fn
707
-@
708
-@ foreach c [cols] {
709
-@ if {$nDiffs > 1} {
710
-@ $c insert end \n -
711
-@ }
712
-@ if {[colType $c] eq "txt"} {
713
-@ $c insert end $fn\n fn
714
-@ if {$fn2!=""} {set fn $fn2}
715
-@ } else {
716
-@ $c insert end \n fn
717
-@ }
718
-@ $c insert end \n -
719
-@
720
-@ if {$errMsg ne ""} continue
721
-@ while {[getLine $difftxt $N ii] ne "<pre>"} continue
722
-@ set type [colType $c]
723
-@ set str {}
724
-@ while {[set line [getLine $difftxt $N ii]] ne "</pre>"} {
725
-@ set len [string length [dehtml $line]]
726
-@ if {$len > $widths($type)} {
727
-@ set widths($type) $len
728
-@ }
729
-@ append str $line\n
730
-@ }
731
-@
732
-@ set re {<span class="diff([a-z]+)">([^<]*)</span>}
733
-@ # Use \r as separator since it can't appear in the diff output (it gets
734
-@ # converted to a space).
735
-@ set str [regsub -all $re $str "\r\\1\r\\2\r"]
736
-@ foreach {pre class mid} [split $str \r] {
737
-@ if {$class ne ""} {
738
-@ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
739
-@ } else {
740
-@ $c insert end [dehtml $pre] -
741
-@ }
742
-@ }
743
-@ }
744
-@
745
-@ if {$errMsg ne ""} {
746
-@ foreach c {.txtA .txtB} {$c insert end [string trim $errMsg] err}
747
-@ foreach c [cols] {$c insert end \n -}
748
-@ }
749
-@ }
750
-@
751
-@ foreach c [cols] {
752
-@ set type [colType $c]
753
-@ if {$type ne "txt"} {
754
-@ $c config -width $widths($type)
755
-@ }
756
-@ $c config -state disabled
757
-@ }
758
-@ if {$nDiffs <= [.wfiles.lb cget -height]} {
759
-@ .wfiles.lb config -height $nDiffs
760
-@ grid remove .wfiles.sb
761
-@ }
762
-@
763
-@ return $nDiffs
764
-@ }
765
-@
766
-@ proc viewDiff {idx} {
767
-@ .txtA yview $idx
768
-@ .txtA xview moveto 0
769
-@ }
770
-@
771
-@ proc cycleDiffs {{reverse 0}} {
772
-@ if {$reverse} {
773
-@ set range [.txtA tag prevrange fn @0,0 1.0]
774
-@ if {$range eq ""} {
775
-@ viewDiff {fn.last -1c}
776
-@ } else {
777
-@ viewDiff [lindex $range 0]
778
-@ }
779
-@ } else {
780
-@ set range [.txtA tag nextrange fn {@0,0 +1c} end]
781
-@ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
782
-@ viewDiff fn.first
783
-@ } else {
784
-@ viewDiff [lindex $range 0]
785
-@ }
786
-@ }
787
-@ }
788
-@
789
-@ proc xvis {col} {
790
-@ set view [$col xview]
791
-@ return [expr {[lindex $view 1]-[lindex $view 0]}]
792
-@ }
793
-@
794
-@ proc scroll-x {args} {
795
-@ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
796
-@ eval $c xview $args
797
-@ }
798
-@
799
-@ interp alias {} scroll-y {} .txtA yview
800
-@
801
-@ proc noop {args} {}
802
-@
803
-@ proc enableSync {axis} {
804
-@ update idletasks
805
-@ interp alias {} sync-$axis {}
806
-@ rename _sync-$axis sync-$axis
807
-@ }
808
-@
809
-@ proc disableSync {axis} {
810
-@ rename sync-$axis _sync-$axis
811
-@ interp alias {} sync-$axis {} noop
812
-@ }
813
-@
814
-@ proc sync-x {col first last} {
815
-@ disableSync x
816
-@ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
817
-@ foreach side {A B} {
818
-@ set sb .sbx$side
819
-@ set xview [.txt$side xview]
820
-@ if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} {
821
-@ grid $sb
822
-@ eval $sb set $xview
823
-@ } else {
824
-@ grid remove $sb
825
-@ }
826
-@ }
827
-@ enableSync x
828
-@ }
829
-@
830
-@ proc sync-y {first last} {
831
-@ disableSync y
832
-@ foreach c [cols] {
833
-@ $c yview moveto $first
834
-@ }
835
-@ if {$first > 0 || $last < 1} {
836
-@ grid .sby
837
-@ .sby set $first $last
838
-@ } else {
839
-@ grid remove .sby
840
-@ }
841
-@ enableSync y
842
-@ }
843
-@
844
-@ wm withdraw .
845
-@ wm title . $CFG(TITLE)
846
-@ wm iconname . $CFG(TITLE)
847
-@ bind . <q> exit
848
-@ bind . <Destroy> {after 0 exit}
849
-@ bind . <Tab> {cycleDiffs; break}
850
-@ bind . <<PrevWindow>> {cycleDiffs 1; break}
851
-@ bind . <Return> {
852
-@ event generate .bb.files <1>
853
-@ event generate .bb.files <ButtonRelease-1>
854
-@ break
855
-@ }
856
-@ foreach {key axis args} {
857
-@ Up y {scroll -5 units}
858
-@ Down y {scroll 5 units}
859
-@ Left x {scroll -5 units}
860
-@ Right x {scroll 5 units}
861
-@ Prior y {scroll -1 page}
862
-@ Next y {scroll 1 page}
863
-@ Home y {moveto 0}
864
-@ End y {moveto 1}
865
-@ } {
866
-@ bind . <$key> "scroll-$axis $args; break"
867
-@ bind . <Shift-$key> continue
868
-@ }
869
-@
870
-@ frame .bb
871
-@ ::ttk::menubutton .bb.files -text "Files"
872
-@ toplevel .wfiles
873
-@ wm withdraw .wfiles
874
-@ update idletasks
875
-@ wm transient .wfiles .
876
-@ wm overrideredirect .wfiles 1
877
-@ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
878
-@ -yscroll {.wfiles.sb set}
879
-@ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
880
-@ grid .wfiles.lb .wfiles.sb -sticky ns
881
-@ bind .bb.files <1> {
882
-@ set x [winfo rootx %W]
883
-@ set y [expr {[winfo rooty %W]+[winfo height %W]}]
884
-@ wm geometry .wfiles +$x+$y
885
-@ wm deiconify .wfiles
886
-@ focus .wfiles.lb
887
-@ }
888
-@ bind .wfiles <FocusOut> {wm withdraw .wfiles}
889
-@ bind .wfiles <Escape> {focus .}
890
-@ foreach evt {1 Return} {
891
-@ bind .wfiles.lb <$evt> {
892
-@ catch {
893
-@ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
894
-@ viewDiff $idx
895
-@ }
896
-@ focus .
897
-@ break
898
-@ }
899
-@ }
900
-@ bind .wfiles.lb <Motion> {
901
-@ %W selection clear 0 end
902
-@ %W selection set @%x,%y
903
-@ }
904
-@
905
-@ foreach {side syncCol} {A .txtB B .txtA} {
906
-@ set ln .ln$side
907
-@ text $ln
908
-@ $ln tag config - -justify right
909
-@
910
-@ set txt .txt$side
911
-@ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
912
-@ -xscroll "sync-x $syncCol"
913
-@ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
914
-@ foreach tag {add rm chng} {
915
-@ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
916
-@ $txt tag lower $tag
917
-@ }
918
-@ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
919
-@ -justify center
920
-@ $txt tag config err -foreground $CFG(ERR_FG)
921
-@ }
922
-@ text .mkr
923
-@
924
-@ foreach c [cols] {
925
-@ set keyPrefix [string toupper [colType $c]]_COL_
926
-@ if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
927
-@ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
928
-@ -padx $CFG(PADX) -yscroll sync-y
929
-@ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
930
-@ -foreground $CFG(HR_FG)
931
-@ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
932
-@ bindtags $c ". $c Text all"
933
-@ bind $c <1> {focus %W}
934
-@ }
935
-@
936
-@ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
937
-@ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
938
-@ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
939
-@ frame .spacer
940
-@
941
-@ if {[readDiffs $fossilcmd] == 0} {
942
-@ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
943
-@ exit
944
-@ }
945
-@ update idletasks
946
-@
947
-@ proc saveDiff {} {
948
-@ set fn [tk_getSaveFile]
949
-@ if {$fn==""} return
950
-@ set out [open $fn wb]
951
-@ puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
952
-@ puts $out "# to see the graphical diff.\n#"
953
-@ puts $out "set fossilcmd {}"
954
-@ puts $out "set prog [list $::prog]"
955
-@ puts $out "set difftxt \173"
956
-@ foreach e $::difftxt {puts $out [list $e]}
957
-@ puts $out "\175"
958
-@ puts $out "eval \$prog"
959
-@ close $out
960
-@ }
961
-@ proc invertDiff {} {
962
-@ global CFG
963
-@ array set x [grid info .txtA]
964
-@ if {$x(-column)==1} {
965
-@ grid config .lnB -column 0
966
-@ grid config .txtB -column 1
967
-@ .txtB tag config add -background $CFG(RM_BG)
968
-@ grid config .lnA -column 3
969
-@ grid config .txtA -column 4
970
-@ .txtA tag config rm -background $CFG(ADD_BG)
971
-@ } else {
972
-@ grid config .lnA -column 0
973
-@ grid config .txtA -column 1
974
-@ .txtA tag config rm -background $CFG(RM_BG)
975
-@ grid config .lnB -column 3
976
-@ grid config .txtB -column 4
977
-@ .txtB tag config add -background $CFG(ADD_BG)
978
-@ }
979
-@ .mkr config -state normal
980
-@ set clt [.mkr search -all < 1.0 end]
981
-@ set cgt [.mkr search -all > 1.0 end]
982
-@ foreach c $clt {.mkr replace $c "$c +1 chars" >}
983
-@ foreach c $cgt {.mkr replace $c "$c +1 chars" <}
984
-@ .mkr config -state disabled
985
-@ }
986
-@ ::ttk::button .bb.quit -text {Quit} -command exit
987
-@ ::ttk::button .bb.invert -text {Invert} -command invertDiff
988
-@ ::ttk::button .bb.save -text {Save As...} -command saveDiff
989
-@ pack .bb.quit .bb.invert -side left
990
-@ if {$fossilcmd!=""} {pack .bb.save -side left}
991
-@ pack .bb.files -side left
992
-@ grid rowconfigure . 1 -weight 1
993
-@ grid columnconfigure . 1 -weight 1
994
-@ grid columnconfigure . 4 -weight 1
995
-@ grid .bb -row 0 -columnspan 6
996
-@ eval grid [cols] -row 1 -sticky nsew
997
-@ grid .sby -row 1 -column 5 -sticky ns
998
-@ grid .sbxA -row 2 -columnspan 2 -sticky ew
999
-@ grid .spacer -row 2 -column 2
1000
-@ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
1001
-@
1002
-@ .spacer config -height [winfo height .sbxA]
1003
-@ wm deiconify .
1004
-@ }
1005
-@ eval $prog
1006
-;
1007
-
1008622
/*
1009623
** Show diff output in a Tcl/Tk window, in response to the --tk option
1010624
** to the diff command.
1011625
**
1012626
** If fossil has direct access to a Tcl interpreter (either loaded
@@ -1040,11 +654,11 @@
1040654
int j;
1041655
blob_append(&script, " ", 1);
1042656
for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
1043657
}
1044658
}
1045
- blob_appendf(&script, "}\n%s", zDiffScript);
659
+ blob_appendf(&script, "}\n%s", builtin_file("diff.tcl", 0));
1046660
if( zTempFile ){
1047661
blob_write_to_file(&script, zTempFile);
1048662
fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
1049663
}else{
1050664
#if defined(FOSSIL_ENABLE_TCL)
1051665
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -142,17 +142,17 @@
142 Blob cmd; /* Text of command to run */
143
144 if( !fIncludeBinary ){
145 Blob file2;
146 if( isBin1 ){
147 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
148 return;
149 }
150 if( zBinGlob ){
151 Glob *pBinary = glob_create(zBinGlob);
152 if( glob_match(pBinary, zName) ){
153 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
154 glob_free(pBinary);
155 return;
156 }
157 glob_free(pBinary);
158 }
@@ -163,11 +163,11 @@
163 }else{
164 blob_read_from_file(&file2, zFile2);
165 }
166 }
167 if( looks_like_binary(&file2) ){
168 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
169 blob_reset(&file2);
170 return;
171 }
172 blob_reset(&file2);
173 }
@@ -238,17 +238,17 @@
238 char zTemp1[300];
239 char zTemp2[300];
240
241 if( !fIncludeBinary ){
242 if( isBin1 || isBin2 ){
243 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
244 return;
245 }
246 if( zBinGlob ){
247 Glob *pBinary = glob_create(zBinGlob);
248 if( glob_match(pBinary, zName) ){
249 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
250 glob_free(pBinary);
251 return;
252 }
253 glob_free(pBinary);
254 }
@@ -302,11 +302,11 @@
302 int isBin;
303 file_tree_name(zFileTreeName, &fname, 1);
304 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305 fIncludeBinary ? 0 : &isBin, 0);
306 if( !isLink != !file_wd_islink(zFrom) ){
307 fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
308 }else{
309 diff_file(&content, isBin, zFileTreeName, zFileTreeName,
310 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
311 }
312 blob_reset(&content);
@@ -346,11 +346,11 @@
346 int rid = name_to_typed_rid(zFrom, "ci");
347 if( !is_a_version(rid) ){
348 fossil_fatal("no such check-in: %s", zFrom);
349 }
350 load_vfile_from_rid(rid);
351 blob_appendf(&sql,
352 "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
353 " FROM vfile v1, vfile v2 "
354 " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
355 " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
356 "UNION "
@@ -367,20 +367,20 @@
367 " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368 " ORDER BY 1",
369 rid, vid, rid, vid, vid, rid
370 );
371 }else{
372 blob_appendf(&sql,
373 "SELECT pathname, deleted, chnged , rid==0, rid, islink"
374 " FROM vfile"
375 " WHERE vid=%d"
376 " AND (deleted OR chnged OR rid==0)"
377 " ORDER BY pathname",
378 vid
379 );
380 }
381 db_prepare(&q, blob_str(&sql));
382 while( db_step(&q)==SQLITE_ROW ){
383 const char *zPathname = db_column_text(&q,0);
384 int isDeleted = db_column_int(&q, 1);
385 int isChnged = db_column_int(&q,2);
386 int isNew = db_column_int(&q,3);
@@ -408,11 +408,11 @@
408 Blob content;
409 int isBin;
410 if( !isLink != !file_wd_islink(zFullName) ){
411 diff_print_index(zPathname, diffFlags);
412 diff_print_filenames(zPathname, zPathname, diffFlags);
413 fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
414 continue;
415 }
416 if( srcid>0 ){
417 content_get(srcid, &content);
418 }else{
@@ -462,11 +462,11 @@
462 fIncludeBinary ? 0 : &isBin1, 0);
463 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464 fIncludeBinary ? 0 : &isBin2, 0);
465 if( isLink1 != isLink2 ){
466 diff_print_filenames(zName, zName, diffFlags);
467 fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
468 }else{
469 diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
470 zBinGlob, fIncludeBinary, diffFlags);
471 }
472 blob_reset(&v1);
@@ -617,396 +617,10 @@
617 zName = "diff-command";
618 }
619 return db_get(zName, zDefault);
620 }
621
622 /* A Tcl/Tk script used to render diff output.
623 */
624 static const char zDiffScript[] =
625 @ set prog {
626 @ package require Tk
627 @
628 @ array set CFG {
629 @ TITLE {Fossil Diff}
630 @ LN_COL_BG #dddddd
631 @ LN_COL_FG #444444
632 @ TXT_COL_BG #ffffff
633 @ TXT_COL_FG #000000
634 @ MKR_COL_BG #444444
635 @ MKR_COL_FG #dddddd
636 @ CHNG_BG #d0d0ff
637 @ ADD_BG #c0ffc0
638 @ RM_BG #ffc0c0
639 @ HR_FG #888888
640 @ HR_PAD_TOP 4
641 @ HR_PAD_BTM 8
642 @ FN_BG #444444
643 @ FN_FG #ffffff
644 @ FN_PAD 5
645 @ ERR_FG #ee0000
646 @ PADX 5
647 @ WIDTH 80
648 @ HEIGHT 45
649 @ LB_HEIGHT 25
650 @ }
651 @
652 @ if {![namespace exists ttk]} {
653 @ interp alias {} ::ttk::scrollbar {} ::scrollbar
654 @ interp alias {} ::ttk::menubutton {} ::menubutton
655 @ }
656 @
657 @ proc dehtml {x} {
658 @ set x [regsub -all {<[^>]*>} $x {}]
659 @ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
660 @ }
661 @
662 @ proc cols {} {
663 @ return [list .lnA .txtA .mkr .lnB .txtB]
664 @ }
665 @
666 @ proc colType {c} {
667 @ regexp {[a-z]+} $c type
668 @ return $type
669 @ }
670 @
671 @ proc getLine {difftxt N iivar} {
672 @ upvar $iivar ii
673 @ if {$ii>=$N} {return -1}
674 @ set x [lindex $difftxt $ii]
675 @ incr ii
676 @ return $x
677 @ }
678 @
679 @ proc readDiffs {fossilcmd} {
680 @ global difftxt
681 @ if {![info exists difftxt]} {
682 @ set in [open $fossilcmd r]
683 @ fconfigure $in -encoding utf-8
684 @ set difftxt [split [read $in] \n]
685 @ close $in
686 @ }
687 @ set N [llength $difftxt]
688 @ set ii 0
689 @ set nDiffs 0
690 @ array set widths {txt 0 ln 0 mkr 0}
691 @ while {[set line [getLine $difftxt $N ii]] != -1} {
692 @ set fn2 {}
693 @ if {![regexp {^=+ (.*?) =+ versus =+ (.*?) =+$} $line all fn fn2]
694 @ && ![regexp {^=+ (.*?) =+$} $line all fn]
695 @ } {
696 @ continue
697 @ }
698 @ set errMsg ""
699 @ set line [getLine $difftxt $N ii]
700 @ if {[string compare -length 6 $line "<table"]
701 @ && ![regexp {<p[^>]*>(.+)} $line - errMsg]} {
702 @ continue
703 @ }
704 @ incr nDiffs
705 @ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
706 @ .wfiles.lb insert end $fn
707 @
708 @ foreach c [cols] {
709 @ if {$nDiffs > 1} {
710 @ $c insert end \n -
711 @ }
712 @ if {[colType $c] eq "txt"} {
713 @ $c insert end $fn\n fn
714 @ if {$fn2!=""} {set fn $fn2}
715 @ } else {
716 @ $c insert end \n fn
717 @ }
718 @ $c insert end \n -
719 @
720 @ if {$errMsg ne ""} continue
721 @ while {[getLine $difftxt $N ii] ne "<pre>"} continue
722 @ set type [colType $c]
723 @ set str {}
724 @ while {[set line [getLine $difftxt $N ii]] ne "</pre>"} {
725 @ set len [string length [dehtml $line]]
726 @ if {$len > $widths($type)} {
727 @ set widths($type) $len
728 @ }
729 @ append str $line\n
730 @ }
731 @
732 @ set re {<span class="diff([a-z]+)">([^<]*)</span>}
733 @ # Use \r as separator since it can't appear in the diff output (it gets
734 @ # converted to a space).
735 @ set str [regsub -all $re $str "\r\\1\r\\2\r"]
736 @ foreach {pre class mid} [split $str \r] {
737 @ if {$class ne ""} {
738 @ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
739 @ } else {
740 @ $c insert end [dehtml $pre] -
741 @ }
742 @ }
743 @ }
744 @
745 @ if {$errMsg ne ""} {
746 @ foreach c {.txtA .txtB} {$c insert end [string trim $errMsg] err}
747 @ foreach c [cols] {$c insert end \n -}
748 @ }
749 @ }
750 @
751 @ foreach c [cols] {
752 @ set type [colType $c]
753 @ if {$type ne "txt"} {
754 @ $c config -width $widths($type)
755 @ }
756 @ $c config -state disabled
757 @ }
758 @ if {$nDiffs <= [.wfiles.lb cget -height]} {
759 @ .wfiles.lb config -height $nDiffs
760 @ grid remove .wfiles.sb
761 @ }
762 @
763 @ return $nDiffs
764 @ }
765 @
766 @ proc viewDiff {idx} {
767 @ .txtA yview $idx
768 @ .txtA xview moveto 0
769 @ }
770 @
771 @ proc cycleDiffs {{reverse 0}} {
772 @ if {$reverse} {
773 @ set range [.txtA tag prevrange fn @0,0 1.0]
774 @ if {$range eq ""} {
775 @ viewDiff {fn.last -1c}
776 @ } else {
777 @ viewDiff [lindex $range 0]
778 @ }
779 @ } else {
780 @ set range [.txtA tag nextrange fn {@0,0 +1c} end]
781 @ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
782 @ viewDiff fn.first
783 @ } else {
784 @ viewDiff [lindex $range 0]
785 @ }
786 @ }
787 @ }
788 @
789 @ proc xvis {col} {
790 @ set view [$col xview]
791 @ return [expr {[lindex $view 1]-[lindex $view 0]}]
792 @ }
793 @
794 @ proc scroll-x {args} {
795 @ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
796 @ eval $c xview $args
797 @ }
798 @
799 @ interp alias {} scroll-y {} .txtA yview
800 @
801 @ proc noop {args} {}
802 @
803 @ proc enableSync {axis} {
804 @ update idletasks
805 @ interp alias {} sync-$axis {}
806 @ rename _sync-$axis sync-$axis
807 @ }
808 @
809 @ proc disableSync {axis} {
810 @ rename sync-$axis _sync-$axis
811 @ interp alias {} sync-$axis {} noop
812 @ }
813 @
814 @ proc sync-x {col first last} {
815 @ disableSync x
816 @ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
817 @ foreach side {A B} {
818 @ set sb .sbx$side
819 @ set xview [.txt$side xview]
820 @ if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} {
821 @ grid $sb
822 @ eval $sb set $xview
823 @ } else {
824 @ grid remove $sb
825 @ }
826 @ }
827 @ enableSync x
828 @ }
829 @
830 @ proc sync-y {first last} {
831 @ disableSync y
832 @ foreach c [cols] {
833 @ $c yview moveto $first
834 @ }
835 @ if {$first > 0 || $last < 1} {
836 @ grid .sby
837 @ .sby set $first $last
838 @ } else {
839 @ grid remove .sby
840 @ }
841 @ enableSync y
842 @ }
843 @
844 @ wm withdraw .
845 @ wm title . $CFG(TITLE)
846 @ wm iconname . $CFG(TITLE)
847 @ bind . <q> exit
848 @ bind . <Destroy> {after 0 exit}
849 @ bind . <Tab> {cycleDiffs; break}
850 @ bind . <<PrevWindow>> {cycleDiffs 1; break}
851 @ bind . <Return> {
852 @ event generate .bb.files <1>
853 @ event generate .bb.files <ButtonRelease-1>
854 @ break
855 @ }
856 @ foreach {key axis args} {
857 @ Up y {scroll -5 units}
858 @ Down y {scroll 5 units}
859 @ Left x {scroll -5 units}
860 @ Right x {scroll 5 units}
861 @ Prior y {scroll -1 page}
862 @ Next y {scroll 1 page}
863 @ Home y {moveto 0}
864 @ End y {moveto 1}
865 @ } {
866 @ bind . <$key> "scroll-$axis $args; break"
867 @ bind . <Shift-$key> continue
868 @ }
869 @
870 @ frame .bb
871 @ ::ttk::menubutton .bb.files -text "Files"
872 @ toplevel .wfiles
873 @ wm withdraw .wfiles
874 @ update idletasks
875 @ wm transient .wfiles .
876 @ wm overrideredirect .wfiles 1
877 @ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
878 @ -yscroll {.wfiles.sb set}
879 @ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
880 @ grid .wfiles.lb .wfiles.sb -sticky ns
881 @ bind .bb.files <1> {
882 @ set x [winfo rootx %W]
883 @ set y [expr {[winfo rooty %W]+[winfo height %W]}]
884 @ wm geometry .wfiles +$x+$y
885 @ wm deiconify .wfiles
886 @ focus .wfiles.lb
887 @ }
888 @ bind .wfiles <FocusOut> {wm withdraw .wfiles}
889 @ bind .wfiles <Escape> {focus .}
890 @ foreach evt {1 Return} {
891 @ bind .wfiles.lb <$evt> {
892 @ catch {
893 @ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
894 @ viewDiff $idx
895 @ }
896 @ focus .
897 @ break
898 @ }
899 @ }
900 @ bind .wfiles.lb <Motion> {
901 @ %W selection clear 0 end
902 @ %W selection set @%x,%y
903 @ }
904 @
905 @ foreach {side syncCol} {A .txtB B .txtA} {
906 @ set ln .ln$side
907 @ text $ln
908 @ $ln tag config - -justify right
909 @
910 @ set txt .txt$side
911 @ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
912 @ -xscroll "sync-x $syncCol"
913 @ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
914 @ foreach tag {add rm chng} {
915 @ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
916 @ $txt tag lower $tag
917 @ }
918 @ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
919 @ -justify center
920 @ $txt tag config err -foreground $CFG(ERR_FG)
921 @ }
922 @ text .mkr
923 @
924 @ foreach c [cols] {
925 @ set keyPrefix [string toupper [colType $c]]_COL_
926 @ if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
927 @ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
928 @ -padx $CFG(PADX) -yscroll sync-y
929 @ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
930 @ -foreground $CFG(HR_FG)
931 @ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
932 @ bindtags $c ". $c Text all"
933 @ bind $c <1> {focus %W}
934 @ }
935 @
936 @ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
937 @ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
938 @ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
939 @ frame .spacer
940 @
941 @ if {[readDiffs $fossilcmd] == 0} {
942 @ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
943 @ exit
944 @ }
945 @ update idletasks
946 @
947 @ proc saveDiff {} {
948 @ set fn [tk_getSaveFile]
949 @ if {$fn==""} return
950 @ set out [open $fn wb]
951 @ puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
952 @ puts $out "# to see the graphical diff.\n#"
953 @ puts $out "set fossilcmd {}"
954 @ puts $out "set prog [list $::prog]"
955 @ puts $out "set difftxt \173"
956 @ foreach e $::difftxt {puts $out [list $e]}
957 @ puts $out "\175"
958 @ puts $out "eval \$prog"
959 @ close $out
960 @ }
961 @ proc invertDiff {} {
962 @ global CFG
963 @ array set x [grid info .txtA]
964 @ if {$x(-column)==1} {
965 @ grid config .lnB -column 0
966 @ grid config .txtB -column 1
967 @ .txtB tag config add -background $CFG(RM_BG)
968 @ grid config .lnA -column 3
969 @ grid config .txtA -column 4
970 @ .txtA tag config rm -background $CFG(ADD_BG)
971 @ } else {
972 @ grid config .lnA -column 0
973 @ grid config .txtA -column 1
974 @ .txtA tag config rm -background $CFG(RM_BG)
975 @ grid config .lnB -column 3
976 @ grid config .txtB -column 4
977 @ .txtB tag config add -background $CFG(ADD_BG)
978 @ }
979 @ .mkr config -state normal
980 @ set clt [.mkr search -all < 1.0 end]
981 @ set cgt [.mkr search -all > 1.0 end]
982 @ foreach c $clt {.mkr replace $c "$c +1 chars" >}
983 @ foreach c $cgt {.mkr replace $c "$c +1 chars" <}
984 @ .mkr config -state disabled
985 @ }
986 @ ::ttk::button .bb.quit -text {Quit} -command exit
987 @ ::ttk::button .bb.invert -text {Invert} -command invertDiff
988 @ ::ttk::button .bb.save -text {Save As...} -command saveDiff
989 @ pack .bb.quit .bb.invert -side left
990 @ if {$fossilcmd!=""} {pack .bb.save -side left}
991 @ pack .bb.files -side left
992 @ grid rowconfigure . 1 -weight 1
993 @ grid columnconfigure . 1 -weight 1
994 @ grid columnconfigure . 4 -weight 1
995 @ grid .bb -row 0 -columnspan 6
996 @ eval grid [cols] -row 1 -sticky nsew
997 @ grid .sby -row 1 -column 5 -sticky ns
998 @ grid .sbxA -row 2 -columnspan 2 -sticky ew
999 @ grid .spacer -row 2 -column 2
1000 @ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
1001 @
1002 @ .spacer config -height [winfo height .sbxA]
1003 @ wm deiconify .
1004 @ }
1005 @ eval $prog
1006 ;
1007
1008 /*
1009 ** Show diff output in a Tcl/Tk window, in response to the --tk option
1010 ** to the diff command.
1011 **
1012 ** If fossil has direct access to a Tcl interpreter (either loaded
@@ -1040,11 +654,11 @@
1040 int j;
1041 blob_append(&script, " ", 1);
1042 for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
1043 }
1044 }
1045 blob_appendf(&script, "}\n%s", zDiffScript);
1046 if( zTempFile ){
1047 blob_write_to_file(&script, zTempFile);
1048 fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
1049 }else{
1050 #if defined(FOSSIL_ENABLE_TCL)
1051
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -142,17 +142,17 @@
142 Blob cmd; /* Text of command to run */
143
144 if( !fIncludeBinary ){
145 Blob file2;
146 if( isBin1 ){
147 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
148 return;
149 }
150 if( zBinGlob ){
151 Glob *pBinary = glob_create(zBinGlob);
152 if( glob_match(pBinary, zName) ){
153 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
154 glob_free(pBinary);
155 return;
156 }
157 glob_free(pBinary);
158 }
@@ -163,11 +163,11 @@
163 }else{
164 blob_read_from_file(&file2, zFile2);
165 }
166 }
167 if( looks_like_binary(&file2) ){
168 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
169 blob_reset(&file2);
170 return;
171 }
172 blob_reset(&file2);
173 }
@@ -238,17 +238,17 @@
238 char zTemp1[300];
239 char zTemp2[300];
240
241 if( !fIncludeBinary ){
242 if( isBin1 || isBin2 ){
243 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
244 return;
245 }
246 if( zBinGlob ){
247 Glob *pBinary = glob_create(zBinGlob);
248 if( glob_match(pBinary, zName) ){
249 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
250 glob_free(pBinary);
251 return;
252 }
253 glob_free(pBinary);
254 }
@@ -302,11 +302,11 @@
302 int isBin;
303 file_tree_name(zFileTreeName, &fname, 1);
304 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305 fIncludeBinary ? 0 : &isBin, 0);
306 if( !isLink != !file_wd_islink(zFrom) ){
307 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308 }else{
309 diff_file(&content, isBin, zFileTreeName, zFileTreeName,
310 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
311 }
312 blob_reset(&content);
@@ -346,11 +346,11 @@
346 int rid = name_to_typed_rid(zFrom, "ci");
347 if( !is_a_version(rid) ){
348 fossil_fatal("no such check-in: %s", zFrom);
349 }
350 load_vfile_from_rid(rid);
351 blob_append_sql(&sql,
352 "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
353 " FROM vfile v1, vfile v2 "
354 " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
355 " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
356 "UNION "
@@ -367,20 +367,20 @@
367 " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368 " ORDER BY 1",
369 rid, vid, rid, vid, vid, rid
370 );
371 }else{
372 blob_append_sql(&sql,
373 "SELECT pathname, deleted, chnged , rid==0, rid, islink"
374 " FROM vfile"
375 " WHERE vid=%d"
376 " AND (deleted OR chnged OR rid==0)"
377 " ORDER BY pathname",
378 vid
379 );
380 }
381 db_prepare(&q, "%s", blob_sql_text(&sql));
382 while( db_step(&q)==SQLITE_ROW ){
383 const char *zPathname = db_column_text(&q,0);
384 int isDeleted = db_column_int(&q, 1);
385 int isChnged = db_column_int(&q,2);
386 int isNew = db_column_int(&q,3);
@@ -408,11 +408,11 @@
408 Blob content;
409 int isBin;
410 if( !isLink != !file_wd_islink(zFullName) ){
411 diff_print_index(zPathname, diffFlags);
412 diff_print_filenames(zPathname, zPathname, diffFlags);
413 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
414 continue;
415 }
416 if( srcid>0 ){
417 content_get(srcid, &content);
418 }else{
@@ -462,11 +462,11 @@
462 fIncludeBinary ? 0 : &isBin1, 0);
463 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464 fIncludeBinary ? 0 : &isBin2, 0);
465 if( isLink1 != isLink2 ){
466 diff_print_filenames(zName, zName, diffFlags);
467 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
468 }else{
469 diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
470 zBinGlob, fIncludeBinary, diffFlags);
471 }
472 blob_reset(&v1);
@@ -617,396 +617,10 @@
617 zName = "diff-command";
618 }
619 return db_get(zName, zDefault);
620 }
621
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622 /*
623 ** Show diff output in a Tcl/Tk window, in response to the --tk option
624 ** to the diff command.
625 **
626 ** If fossil has direct access to a Tcl interpreter (either loaded
@@ -1040,11 +654,11 @@
654 int j;
655 blob_append(&script, " ", 1);
656 for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
657 }
658 }
659 blob_appendf(&script, "}\n%s", builtin_file("diff.tcl", 0));
660 if( zTempFile ){
661 blob_write_to_file(&script, zTempFile);
662 fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
663 }else{
664 #if defined(FOSSIL_ENABLE_TCL)
665
+69 -71
--- src/doc.c
+++ src/doc.c
@@ -26,11 +26,11 @@
2626
** Try to guess the mimetype from content.
2727
**
2828
** If the content is pure text, return NULL.
2929
**
3030
** For image types, attempt to return an appropriate mimetype
31
-** name like "image/gif" or "image/jpeg".
31
+** name like "image/gif" or "image/jpeg".
3232
**
3333
** For any other binary type, return "unknown/unknown".
3434
*/
3535
const char *mimetype_from_content(Blob *pBlob){
3636
int i;
@@ -83,11 +83,11 @@
8383
int i;
8484
int first, last;
8585
int len;
8686
char zSuffix[20];
8787
88
- /* A table of mimetypes based on file suffixes.
88
+ /* A table of mimetypes based on file suffixes.
8989
** Suffixes must be in sorted order so that we can do a binary
9090
** search to find the mime-type
9191
*/
9292
static const struct {
9393
const char *zSuffix; /* The file suffix */
@@ -487,11 +487,11 @@
487487
db_end_transaction(0);
488488
}
489489
blob_to_utf8_no_bom(&filebody, 0);
490490
491491
/* The file is now contained in the filebody blob. Deliver the
492
- ** file to the user
492
+ ** file to the user
493493
*/
494494
zMime = P("mimetype");
495495
if( zMime==0 ){
496496
zMime = mimetype_from_name(zName);
497497
}
@@ -501,11 +501,11 @@
501501
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
502502
" WHERE objid=%d AND type='ci'", vid));
503503
if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
504504
Blob title, tail;
505505
if( wiki_find_title(&filebody, &title, &tail) ){
506
- style_header(blob_str(&title));
506
+ style_header("%s", blob_str(&title));
507507
wiki_convert(&tail, 0, WIKI_BUTTONS);
508508
}else{
509509
style_header("Documentation");
510510
wiki_convert(&filebody, 0, WIKI_BUTTONS);
511511
}
@@ -513,11 +513,11 @@
513513
}else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
514514
Blob title = BLOB_INITIALIZER;
515515
Blob tail = BLOB_INITIALIZER;
516516
markdown_to_html(&filebody, &title, &tail);
517517
if( blob_size(&title)>0 ){
518
- style_header(blob_str(&title));
518
+ style_header("%s", blob_str(&title));
519519
}else{
520520
style_header("Documentation");
521521
}
522522
blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
523523
style_footer();
@@ -528,15 +528,13 @@
528528
@ </pre></blockquote>
529529
style_footer();
530530
#ifdef FOSSIL_ENABLE_TH1_DOCS
531531
}else if( db_get_boolean("th1-docs", 0) &&
532532
fossil_strcmp(zMime, "application/x-th1")==0 ){
533
- char *zHtml = htmlize(zName, -1);
534
- style_header(zHtml);
533
+ style_header("%h", zName);
535534
Th_Render(blob_str(&filebody));
536535
style_footer();
537
- fossil_free(zHtml);
538536
#endif
539537
}else{
540538
cgi_set_content_type(zMime);
541539
cgi_set_content(&filebody);
542540
}
@@ -546,79 +544,79 @@
546544
/* Jump here when unable to locate the document */
547545
db_end_transaction(0);
548546
style_header("Document Not Found");
549547
@ <p>No such document: %h(zName)</p>
550548
style_footer();
551
- return;
549
+ return;
552550
}
553551
554552
/*
555553
** The default logo.
556554
*/
557555
static const unsigned char aLogo[] = {
558
- 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
559
- 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
560
- 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
561
- 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
562
- 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
563
- 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
564
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
565
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
566
- 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
567
- 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
568
- 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
569
- 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
570
- 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
571
- 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
572
- 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
573
- 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
574
- 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
575
- 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
576
- 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
577
- 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
578
- 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
579
- 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
580
- 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
581
- 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
582
- 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
583
- 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
584
- 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
585
- 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
586
- 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
587
- 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
588
- 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
589
- 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
590
- 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
591
- 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
592
- 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
593
- 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
594
- 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
595
- 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
596
- 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
597
- 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
598
- 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
599
- 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
600
- 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
601
- 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
602
- 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
603
- 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
604
- 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
605
- 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
606
- 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
607
- 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
608
- 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
609
- 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
610
- 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
611
- 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
612
- 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
613
- 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
614
- 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
615
- 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
616
- 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
617
- 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
618
- 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
619
- 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
556
+ 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
557
+ 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
558
+ 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
559
+ 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
560
+ 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
561
+ 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
562
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
564
+ 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
565
+ 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
566
+ 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
567
+ 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
568
+ 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
569
+ 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
570
+ 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
571
+ 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
572
+ 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
573
+ 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
574
+ 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
575
+ 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
576
+ 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
577
+ 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
578
+ 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
579
+ 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
580
+ 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
581
+ 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
582
+ 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
583
+ 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
584
+ 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
585
+ 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
586
+ 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
587
+ 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
588
+ 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
589
+ 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
590
+ 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
591
+ 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
592
+ 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
593
+ 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
594
+ 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
595
+ 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
596
+ 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
597
+ 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
598
+ 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
599
+ 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
600
+ 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
601
+ 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
602
+ 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
603
+ 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
604
+ 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
605
+ 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
606
+ 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
607
+ 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
608
+ 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
609
+ 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
610
+ 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
611
+ 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
612
+ 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
613
+ 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
614
+ 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
615
+ 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
616
+ 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
617
+ 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
620618
};
621619
622620
/*
623621
** WEBPAGE: logo
624622
**
625623
--- src/doc.c
+++ src/doc.c
@@ -26,11 +26,11 @@
26 ** Try to guess the mimetype from content.
27 **
28 ** If the content is pure text, return NULL.
29 **
30 ** For image types, attempt to return an appropriate mimetype
31 ** name like "image/gif" or "image/jpeg".
32 **
33 ** For any other binary type, return "unknown/unknown".
34 */
35 const char *mimetype_from_content(Blob *pBlob){
36 int i;
@@ -83,11 +83,11 @@
83 int i;
84 int first, last;
85 int len;
86 char zSuffix[20];
87
88 /* A table of mimetypes based on file suffixes.
89 ** Suffixes must be in sorted order so that we can do a binary
90 ** search to find the mime-type
91 */
92 static const struct {
93 const char *zSuffix; /* The file suffix */
@@ -487,11 +487,11 @@
487 db_end_transaction(0);
488 }
489 blob_to_utf8_no_bom(&filebody, 0);
490
491 /* The file is now contained in the filebody blob. Deliver the
492 ** file to the user
493 */
494 zMime = P("mimetype");
495 if( zMime==0 ){
496 zMime = mimetype_from_name(zName);
497 }
@@ -501,11 +501,11 @@
501 Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
502 " WHERE objid=%d AND type='ci'", vid));
503 if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
504 Blob title, tail;
505 if( wiki_find_title(&filebody, &title, &tail) ){
506 style_header(blob_str(&title));
507 wiki_convert(&tail, 0, WIKI_BUTTONS);
508 }else{
509 style_header("Documentation");
510 wiki_convert(&filebody, 0, WIKI_BUTTONS);
511 }
@@ -513,11 +513,11 @@
513 }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
514 Blob title = BLOB_INITIALIZER;
515 Blob tail = BLOB_INITIALIZER;
516 markdown_to_html(&filebody, &title, &tail);
517 if( blob_size(&title)>0 ){
518 style_header(blob_str(&title));
519 }else{
520 style_header("Documentation");
521 }
522 blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
523 style_footer();
@@ -528,15 +528,13 @@
528 @ </pre></blockquote>
529 style_footer();
530 #ifdef FOSSIL_ENABLE_TH1_DOCS
531 }else if( db_get_boolean("th1-docs", 0) &&
532 fossil_strcmp(zMime, "application/x-th1")==0 ){
533 char *zHtml = htmlize(zName, -1);
534 style_header(zHtml);
535 Th_Render(blob_str(&filebody));
536 style_footer();
537 fossil_free(zHtml);
538 #endif
539 }else{
540 cgi_set_content_type(zMime);
541 cgi_set_content(&filebody);
542 }
@@ -546,79 +544,79 @@
546 /* Jump here when unable to locate the document */
547 db_end_transaction(0);
548 style_header("Document Not Found");
549 @ <p>No such document: %h(zName)</p>
550 style_footer();
551 return;
552 }
553
554 /*
555 ** The default logo.
556 */
557 static const unsigned char aLogo[] = {
558 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
559 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
560 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
561 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
562 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
563 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
564 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
565 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
566 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
567 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
568 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
569 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
570 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
571 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
572 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
573 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
574 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
575 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
576 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
577 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
578 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
579 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
580 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
581 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
582 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
583 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
584 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
585 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
586 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
587 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
588 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
589 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
590 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
591 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
592 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
593 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
594 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
595 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
596 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
597 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
598 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
599 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
600 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
601 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
602 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
603 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
604 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
605 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
606 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
607 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
608 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
609 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
610 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
611 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
612 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
613 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
614 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
615 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
616 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
617 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
618 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
619 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
620 };
621
622 /*
623 ** WEBPAGE: logo
624 **
625
--- src/doc.c
+++ src/doc.c
@@ -26,11 +26,11 @@
26 ** Try to guess the mimetype from content.
27 **
28 ** If the content is pure text, return NULL.
29 **
30 ** For image types, attempt to return an appropriate mimetype
31 ** name like "image/gif" or "image/jpeg".
32 **
33 ** For any other binary type, return "unknown/unknown".
34 */
35 const char *mimetype_from_content(Blob *pBlob){
36 int i;
@@ -83,11 +83,11 @@
83 int i;
84 int first, last;
85 int len;
86 char zSuffix[20];
87
88 /* A table of mimetypes based on file suffixes.
89 ** Suffixes must be in sorted order so that we can do a binary
90 ** search to find the mime-type
91 */
92 static const struct {
93 const char *zSuffix; /* The file suffix */
@@ -487,11 +487,11 @@
487 db_end_transaction(0);
488 }
489 blob_to_utf8_no_bom(&filebody, 0);
490
491 /* The file is now contained in the filebody blob. Deliver the
492 ** file to the user
493 */
494 zMime = P("mimetype");
495 if( zMime==0 ){
496 zMime = mimetype_from_name(zName);
497 }
@@ -501,11 +501,11 @@
501 Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
502 " WHERE objid=%d AND type='ci'", vid));
503 if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
504 Blob title, tail;
505 if( wiki_find_title(&filebody, &title, &tail) ){
506 style_header("%s", blob_str(&title));
507 wiki_convert(&tail, 0, WIKI_BUTTONS);
508 }else{
509 style_header("Documentation");
510 wiki_convert(&filebody, 0, WIKI_BUTTONS);
511 }
@@ -513,11 +513,11 @@
513 }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
514 Blob title = BLOB_INITIALIZER;
515 Blob tail = BLOB_INITIALIZER;
516 markdown_to_html(&filebody, &title, &tail);
517 if( blob_size(&title)>0 ){
518 style_header("%s", blob_str(&title));
519 }else{
520 style_header("Documentation");
521 }
522 blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
523 style_footer();
@@ -528,15 +528,13 @@
528 @ </pre></blockquote>
529 style_footer();
530 #ifdef FOSSIL_ENABLE_TH1_DOCS
531 }else if( db_get_boolean("th1-docs", 0) &&
532 fossil_strcmp(zMime, "application/x-th1")==0 ){
533 style_header("%h", zName);
 
534 Th_Render(blob_str(&filebody));
535 style_footer();
 
536 #endif
537 }else{
538 cgi_set_content_type(zMime);
539 cgi_set_content(&filebody);
540 }
@@ -546,79 +544,79 @@
544 /* Jump here when unable to locate the document */
545 db_end_transaction(0);
546 style_header("Document Not Found");
547 @ <p>No such document: %h(zName)</p>
548 style_footer();
549 return;
550 }
551
552 /*
553 ** The default logo.
554 */
555 static const unsigned char aLogo[] = {
556 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
557 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
558 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
559 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
560 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
561 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
564 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
565 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
566 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
567 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
568 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
569 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
570 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
571 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
572 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
573 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
574 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
575 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
576 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
577 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
578 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
579 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
580 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
581 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
582 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
583 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
584 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
585 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
586 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
587 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
588 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
589 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
590 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
591 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
592 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
593 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
594 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
595 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
596 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
597 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
598 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
599 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
600 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
601 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
602 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
603 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
604 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
605 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
606 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
607 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
608 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
609 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
610 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
611 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
612 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
613 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
614 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
615 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
616 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
617 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
618 };
619
620 /*
621 ** WEBPAGE: logo
622 **
623
+27 -27
--- src/encode.c
+++ src/encode.c
@@ -47,30 +47,30 @@
4747
}
4848
i = 0;
4949
zOut = fossil_malloc( count+1 );
5050
while( n-->0 && (c = *zIn)!=0 ){
5151
switch( c ){
52
- case '<':
52
+ case '<':
5353
zOut[i++] = '&';
5454
zOut[i++] = 'l';
5555
zOut[i++] = 't';
5656
zOut[i++] = ';';
5757
break;
58
- case '>':
58
+ case '>':
5959
zOut[i++] = '&';
6060
zOut[i++] = 'g';
6161
zOut[i++] = 't';
6262
zOut[i++] = ';';
6363
break;
64
- case '&':
64
+ case '&':
6565
zOut[i++] = '&';
6666
zOut[i++] = 'a';
6767
zOut[i++] = 'm';
6868
zOut[i++] = 'p';
6969
zOut[i++] = ';';
7070
break;
71
- case '"':
71
+ case '"':
7272
zOut[i++] = '&';
7373
zOut[i++] = 'q';
7474
zOut[i++] = 'u';
7575
zOut[i++] = 'o';
7676
zOut[i++] = 't';
@@ -181,11 +181,11 @@
181181
/*
182182
** Convert the input string into a form that is suitable for use as
183183
** a token in the HTTP protocol. Spaces are encoded as '+' and special
184184
** characters are encoded as "%HH" where HH is a two-digit hexidecimal
185185
** representation of the character. The "/" character is not encoded
186
-** by this routine.
186
+** by this routine.
187187
*/
188188
char *urlize(const char *z, int n){
189189
return EncodeHttp(z, n, 0);
190190
}
191191
@@ -327,11 +327,11 @@
327327
328328
329329
/*
330330
** The characters used for HTTP base64 encoding.
331331
*/
332
-static unsigned char zBase[] =
332
+static unsigned char zBase[] =
333333
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
334334
335335
/*
336336
** Encode a string using a base-64 encoding.
337337
** The encoding can be reversed using the <b>decode64</b> function.
@@ -366,11 +366,11 @@
366366
z64[n] = 0;
367367
return z64;
368368
}
369369
370370
/*
371
-** COMMAND: test-encode64
371
+** COMMAND: test-encode64
372372
** Usage: %fossil test-encode64 STRING
373373
*/
374374
void test_encode64_cmd(void){
375375
char *z;
376376
int i;
@@ -431,11 +431,11 @@
431431
*pnByte = j;
432432
return zData;
433433
}
434434
435435
/*
436
-** COMMAND: test-decode64
436
+** COMMAND: test-decode64
437437
** Usage: %fossil test-decode64 STRING
438438
*/
439439
void test_decode64_cmd(void){
440440
char *z;
441441
int i, n;
@@ -454,11 +454,11 @@
454454
*/
455455
456456
/*
457457
** The array used for encoding
458458
*/ /* 123456789 12345 */
459
-static const char zEncode[] = "0123456789abcdef";
459
+static const char zEncode[] = "0123456789abcdef";
460460
461461
/*
462462
** Encode a N-digit base-256 in base-16. Return zero on success
463463
** and non-zero if there is an error.
464464
*/
@@ -473,33 +473,33 @@
473473
}
474474
475475
/*
476476
** An array for translating single base-16 characters into a value.
477477
** Disallowed input characters have a value of 64. Upper and lower
478
-** case is the same.
478
+** case is the same.
479479
*/
480480
static const char zDecode[] = {
481
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
481
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
485485
64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
486486
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
487487
64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
488488
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
497497
};
498498
499499
/*
500
-** Decode a N-character base-16 number into base-256. N must be a
500
+** Decode a N-character base-16 number into base-256. N must be a
501501
** multiple of 2. The output buffer must be at least N/2 characters
502502
** in length
503503
*/
504504
int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
505505
int i, j;
@@ -545,11 +545,11 @@
545545
/* Randomness used for XOR-ing by the obscure() and unobscure() routines */
546546
static const unsigned char aObscurer[16] = {
547547
0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
548548
0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
549549
};
550
-
550
+
551551
552552
/*
553553
** Obscure plain text so that it is not easily readable.
554554
**
555555
** This is used for storing sensitive information (such as passwords) in a
@@ -562,11 +562,11 @@
562562
*/
563563
char *obscure(const char *zIn){
564564
int n, i;
565565
unsigned char salt;
566566
char *zOut;
567
-
567
+
568568
if( zIn==0 ) return 0;
569569
n = strlen(zIn);
570570
zOut = fossil_malloc( n*2+3 );
571571
sqlite3_randomness(1, &salt);
572572
zOut[n+1] = (char)salt;
@@ -578,17 +578,17 @@
578578
/*
579579
** Undo the obscuring of text performed by obscure(). Or, if the input is
580580
** not hexadecimal (meaning the input is not the output of obscure()) then
581581
** do the equivalent of strdup().
582582
**
583
-** The result is memory obtained from malloc that should be freed by the caller.
583
+** The result is memory obtained from malloc that should be freed by the caller.
584584
*/
585585
char *unobscure(const char *zIn){
586586
int n, i;
587587
unsigned char salt;
588588
char *zOut;
589
-
589
+
590590
if( zIn==0 ) return 0;
591591
n = strlen(zIn);
592592
zOut = fossil_malloc( n + 1 );
593593
if( n<2
594594
|| decode16((unsigned char*)zIn, &salt, 2)
595595
--- src/encode.c
+++ src/encode.c
@@ -47,30 +47,30 @@
47 }
48 i = 0;
49 zOut = fossil_malloc( count+1 );
50 while( n-->0 && (c = *zIn)!=0 ){
51 switch( c ){
52 case '<':
53 zOut[i++] = '&';
54 zOut[i++] = 'l';
55 zOut[i++] = 't';
56 zOut[i++] = ';';
57 break;
58 case '>':
59 zOut[i++] = '&';
60 zOut[i++] = 'g';
61 zOut[i++] = 't';
62 zOut[i++] = ';';
63 break;
64 case '&':
65 zOut[i++] = '&';
66 zOut[i++] = 'a';
67 zOut[i++] = 'm';
68 zOut[i++] = 'p';
69 zOut[i++] = ';';
70 break;
71 case '"':
72 zOut[i++] = '&';
73 zOut[i++] = 'q';
74 zOut[i++] = 'u';
75 zOut[i++] = 'o';
76 zOut[i++] = 't';
@@ -181,11 +181,11 @@
181 /*
182 ** Convert the input string into a form that is suitable for use as
183 ** a token in the HTTP protocol. Spaces are encoded as '+' and special
184 ** characters are encoded as "%HH" where HH is a two-digit hexidecimal
185 ** representation of the character. The "/" character is not encoded
186 ** by this routine.
187 */
188 char *urlize(const char *z, int n){
189 return EncodeHttp(z, n, 0);
190 }
191
@@ -327,11 +327,11 @@
327
328
329 /*
330 ** The characters used for HTTP base64 encoding.
331 */
332 static unsigned char zBase[] =
333 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
334
335 /*
336 ** Encode a string using a base-64 encoding.
337 ** The encoding can be reversed using the <b>decode64</b> function.
@@ -366,11 +366,11 @@
366 z64[n] = 0;
367 return z64;
368 }
369
370 /*
371 ** COMMAND: test-encode64
372 ** Usage: %fossil test-encode64 STRING
373 */
374 void test_encode64_cmd(void){
375 char *z;
376 int i;
@@ -431,11 +431,11 @@
431 *pnByte = j;
432 return zData;
433 }
434
435 /*
436 ** COMMAND: test-decode64
437 ** Usage: %fossil test-decode64 STRING
438 */
439 void test_decode64_cmd(void){
440 char *z;
441 int i, n;
@@ -454,11 +454,11 @@
454 */
455
456 /*
457 ** The array used for encoding
458 */ /* 123456789 12345 */
459 static const char zEncode[] = "0123456789abcdef";
460
461 /*
462 ** Encode a N-digit base-256 in base-16. Return zero on success
463 ** and non-zero if there is an error.
464 */
@@ -473,33 +473,33 @@
473 }
474
475 /*
476 ** An array for translating single base-16 characters into a value.
477 ** Disallowed input characters have a value of 64. Upper and lower
478 ** case is the same.
479 */
480 static const char zDecode[] = {
481 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
485 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
486 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
487 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
488 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
497 };
498
499 /*
500 ** Decode a N-character base-16 number into base-256. N must be a
501 ** multiple of 2. The output buffer must be at least N/2 characters
502 ** in length
503 */
504 int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
505 int i, j;
@@ -545,11 +545,11 @@
545 /* Randomness used for XOR-ing by the obscure() and unobscure() routines */
546 static const unsigned char aObscurer[16] = {
547 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
548 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
549 };
550
551
552 /*
553 ** Obscure plain text so that it is not easily readable.
554 **
555 ** This is used for storing sensitive information (such as passwords) in a
@@ -562,11 +562,11 @@
562 */
563 char *obscure(const char *zIn){
564 int n, i;
565 unsigned char salt;
566 char *zOut;
567
568 if( zIn==0 ) return 0;
569 n = strlen(zIn);
570 zOut = fossil_malloc( n*2+3 );
571 sqlite3_randomness(1, &salt);
572 zOut[n+1] = (char)salt;
@@ -578,17 +578,17 @@
578 /*
579 ** Undo the obscuring of text performed by obscure(). Or, if the input is
580 ** not hexadecimal (meaning the input is not the output of obscure()) then
581 ** do the equivalent of strdup().
582 **
583 ** The result is memory obtained from malloc that should be freed by the caller.
584 */
585 char *unobscure(const char *zIn){
586 int n, i;
587 unsigned char salt;
588 char *zOut;
589
590 if( zIn==0 ) return 0;
591 n = strlen(zIn);
592 zOut = fossil_malloc( n + 1 );
593 if( n<2
594 || decode16((unsigned char*)zIn, &salt, 2)
595
--- src/encode.c
+++ src/encode.c
@@ -47,30 +47,30 @@
47 }
48 i = 0;
49 zOut = fossil_malloc( count+1 );
50 while( n-->0 && (c = *zIn)!=0 ){
51 switch( c ){
52 case '<':
53 zOut[i++] = '&';
54 zOut[i++] = 'l';
55 zOut[i++] = 't';
56 zOut[i++] = ';';
57 break;
58 case '>':
59 zOut[i++] = '&';
60 zOut[i++] = 'g';
61 zOut[i++] = 't';
62 zOut[i++] = ';';
63 break;
64 case '&':
65 zOut[i++] = '&';
66 zOut[i++] = 'a';
67 zOut[i++] = 'm';
68 zOut[i++] = 'p';
69 zOut[i++] = ';';
70 break;
71 case '"':
72 zOut[i++] = '&';
73 zOut[i++] = 'q';
74 zOut[i++] = 'u';
75 zOut[i++] = 'o';
76 zOut[i++] = 't';
@@ -181,11 +181,11 @@
181 /*
182 ** Convert the input string into a form that is suitable for use as
183 ** a token in the HTTP protocol. Spaces are encoded as '+' and special
184 ** characters are encoded as "%HH" where HH is a two-digit hexidecimal
185 ** representation of the character. The "/" character is not encoded
186 ** by this routine.
187 */
188 char *urlize(const char *z, int n){
189 return EncodeHttp(z, n, 0);
190 }
191
@@ -327,11 +327,11 @@
327
328
329 /*
330 ** The characters used for HTTP base64 encoding.
331 */
332 static unsigned char zBase[] =
333 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
334
335 /*
336 ** Encode a string using a base-64 encoding.
337 ** The encoding can be reversed using the <b>decode64</b> function.
@@ -366,11 +366,11 @@
366 z64[n] = 0;
367 return z64;
368 }
369
370 /*
371 ** COMMAND: test-encode64
372 ** Usage: %fossil test-encode64 STRING
373 */
374 void test_encode64_cmd(void){
375 char *z;
376 int i;
@@ -431,11 +431,11 @@
431 *pnByte = j;
432 return zData;
433 }
434
435 /*
436 ** COMMAND: test-decode64
437 ** Usage: %fossil test-decode64 STRING
438 */
439 void test_decode64_cmd(void){
440 char *z;
441 int i, n;
@@ -454,11 +454,11 @@
454 */
455
456 /*
457 ** The array used for encoding
458 */ /* 123456789 12345 */
459 static const char zEncode[] = "0123456789abcdef";
460
461 /*
462 ** Encode a N-digit base-256 in base-16. Return zero on success
463 ** and non-zero if there is an error.
464 */
@@ -473,33 +473,33 @@
473 }
474
475 /*
476 ** An array for translating single base-16 characters into a value.
477 ** Disallowed input characters have a value of 64. Upper and lower
478 ** case is the same.
479 */
480 static const char zDecode[] = {
481 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
485 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
486 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
487 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
488 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
497 };
498
499 /*
500 ** Decode a N-character base-16 number into base-256. N must be a
501 ** multiple of 2. The output buffer must be at least N/2 characters
502 ** in length
503 */
504 int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
505 int i, j;
@@ -545,11 +545,11 @@
545 /* Randomness used for XOR-ing by the obscure() and unobscure() routines */
546 static const unsigned char aObscurer[16] = {
547 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
548 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
549 };
550
551
552 /*
553 ** Obscure plain text so that it is not easily readable.
554 **
555 ** This is used for storing sensitive information (such as passwords) in a
@@ -562,11 +562,11 @@
562 */
563 char *obscure(const char *zIn){
564 int n, i;
565 unsigned char salt;
566 char *zOut;
567
568 if( zIn==0 ) return 0;
569 n = strlen(zIn);
570 zOut = fossil_malloc( n*2+3 );
571 sqlite3_randomness(1, &salt);
572 zOut[n+1] = (char)salt;
@@ -578,17 +578,17 @@
578 /*
579 ** Undo the obscuring of text performed by obscure(). Or, if the input is
580 ** not hexadecimal (meaning the input is not the output of obscure()) then
581 ** do the equivalent of strdup().
582 **
583 ** The result is memory obtained from malloc that should be freed by the caller.
584 */
585 char *unobscure(const char *zIn){
586 int n, i;
587 unsigned char salt;
588 char *zOut;
589
590 if( zIn==0 ) return 0;
591 n = strlen(zIn);
592 zOut = fossil_malloc( n + 1 );
593 if( n<2
594 || decode16((unsigned char*)zIn, &salt, 2)
595
+2 -4
--- src/event.c
+++ src/event.c
@@ -119,11 +119,11 @@
119119
if( pEvent==0 ){
120120
fossil_fatal("Object #%d is not an event", rid);
121121
}
122122
blob_init(&fullbody, pEvent->zWiki, -1);
123123
if( wiki_find_title(&fullbody, &title, &tail) ){
124
- style_header(blob_str(&title));
124
+ style_header("%s", blob_str(&title));
125125
}else{
126126
style_header("Event %S", zEventId);
127127
tail = fullbody;
128128
}
129129
if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
@@ -203,11 +203,10 @@
203203
void eventedit_page(void){
204204
char *zTag;
205205
int rid = 0;
206206
Blob event;
207207
const char *zEventId;
208
- char *zHtmlPageName;
209208
int n;
210209
const char *z;
211210
char *zBody = (char*)P("w");
212211
char *zETime = (char*)P("t");
213212
const char *zComment = P("c");
@@ -364,12 +363,11 @@
364363
return;
365364
}
366365
if( zBody==0 ){
367366
zBody = mprintf("<i>Event Text</i>");
368367
}
369
- zHtmlPageName = mprintf("Edit Event %S", zEventId);
370
- style_header(zHtmlPageName);
368
+ style_header("Edit Event %S", zEventId);
371369
if( P("preview")!=0 ){
372370
Blob title, tail, com;
373371
@ <p><b>Timeline comment preview:</b></p>
374372
@ <blockquote>
375373
@ <table border="0">
376374
--- src/event.c
+++ src/event.c
@@ -119,11 +119,11 @@
119 if( pEvent==0 ){
120 fossil_fatal("Object #%d is not an event", rid);
121 }
122 blob_init(&fullbody, pEvent->zWiki, -1);
123 if( wiki_find_title(&fullbody, &title, &tail) ){
124 style_header(blob_str(&title));
125 }else{
126 style_header("Event %S", zEventId);
127 tail = fullbody;
128 }
129 if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
@@ -203,11 +203,10 @@
203 void eventedit_page(void){
204 char *zTag;
205 int rid = 0;
206 Blob event;
207 const char *zEventId;
208 char *zHtmlPageName;
209 int n;
210 const char *z;
211 char *zBody = (char*)P("w");
212 char *zETime = (char*)P("t");
213 const char *zComment = P("c");
@@ -364,12 +363,11 @@
364 return;
365 }
366 if( zBody==0 ){
367 zBody = mprintf("<i>Event Text</i>");
368 }
369 zHtmlPageName = mprintf("Edit Event %S", zEventId);
370 style_header(zHtmlPageName);
371 if( P("preview")!=0 ){
372 Blob title, tail, com;
373 @ <p><b>Timeline comment preview:</b></p>
374 @ <blockquote>
375 @ <table border="0">
376
--- src/event.c
+++ src/event.c
@@ -119,11 +119,11 @@
119 if( pEvent==0 ){
120 fossil_fatal("Object #%d is not an event", rid);
121 }
122 blob_init(&fullbody, pEvent->zWiki, -1);
123 if( wiki_find_title(&fullbody, &title, &tail) ){
124 style_header("%s", blob_str(&title));
125 }else{
126 style_header("Event %S", zEventId);
127 tail = fullbody;
128 }
129 if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
@@ -203,11 +203,10 @@
203 void eventedit_page(void){
204 char *zTag;
205 int rid = 0;
206 Blob event;
207 const char *zEventId;
 
208 int n;
209 const char *z;
210 char *zBody = (char*)P("w");
211 char *zETime = (char*)P("t");
212 const char *zComment = P("c");
@@ -364,12 +363,11 @@
363 return;
364 }
365 if( zBody==0 ){
366 zBody = mprintf("<i>Event Text</i>");
367 }
368 style_header("Edit Event %S", zEventId);
 
369 if( P("preview")!=0 ){
370 Blob title, tail, com;
371 @ <p><b>Timeline comment preview:</b></p>
372 @ <blockquote>
373 @ <table border="0">
374
+2 -2
--- src/export.c
+++ src/export.c
@@ -71,12 +71,12 @@
7171
/*
7272
** Found beginning of email address. Look for the end and extract
7373
** the part.
7474
*/
7575
zEmail = mprintf("%s", &zContact[i]);
76
- for(i=0; zEmail[i] && zEmail[i]!='>'; i++){}
77
- if( zEmail[i]=='>' ) zEmail[i+1] = 0;
76
+ for(j=0; zEmail[j] && zEmail[j]!='>'; j++){}
77
+ if( zEmail[j]=='>' ) zEmail[j+1] = 0;
7878
}else{
7979
/*
8080
** Found an end marker for email, but nothing else.
8181
*/
8282
zEmail = mprintf("<%s>", zUser);
8383
--- src/export.c
+++ src/export.c
@@ -71,12 +71,12 @@
71 /*
72 ** Found beginning of email address. Look for the end and extract
73 ** the part.
74 */
75 zEmail = mprintf("%s", &zContact[i]);
76 for(i=0; zEmail[i] && zEmail[i]!='>'; i++){}
77 if( zEmail[i]=='>' ) zEmail[i+1] = 0;
78 }else{
79 /*
80 ** Found an end marker for email, but nothing else.
81 */
82 zEmail = mprintf("<%s>", zUser);
83
--- src/export.c
+++ src/export.c
@@ -71,12 +71,12 @@
71 /*
72 ** Found beginning of email address. Look for the end and extract
73 ** the part.
74 */
75 zEmail = mprintf("%s", &zContact[i]);
76 for(j=0; zEmail[j] && zEmail[j]!='>'; j++){}
77 if( zEmail[j]=='>' ) zEmail[j+1] = 0;
78 }else{
79 /*
80 ** Found an end marker for email, but nothing else.
81 */
82 zEmail = mprintf("<%s>", zUser);
83
+12 -12
--- src/finfo.c
+++ src/finfo.c
@@ -319,11 +319,11 @@
319319
320320
zPrevDate[0] = 0;
321321
zFilename = PD("name","");
322322
url_add_parameter(&url, "name", zFilename);
323323
blob_zero(&sql);
324
- blob_appendf(&sql,
324
+ blob_append_sql(&sql,
325325
"SELECT"
326326
" datetime(event.mtime%s)," /* Date of change */
327327
" coalesce(event.ecomment, event.comment)," /* Check-in comment */
328328
" coalesce(event.euser, event.user)," /* User who made chng */
329329
" mlink.pid," /* Parent file rid */
@@ -338,44 +338,44 @@
338338
" mlink.pfnid", /* Previous filename */
339339
timeline_utc(), TAG_BRANCH
340340
);
341341
if( firstChngOnly ){
342342
#if 0
343
- blob_appendf(&sql, ", min(event.mtime)");
343
+ blob_append_sql(&sql, ", min(event.mtime)");
344344
#else
345
- blob_appendf(&sql,
345
+ blob_append_sql(&sql,
346346
", min(CASE (SELECT value FROM tagxref"
347347
" WHERE tagtype>0 AND tagid=%d"
348348
" AND tagxref.rid=mlink.mid)"
349349
" WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
350350
TAG_BRANCH);
351351
#endif
352352
}
353
- blob_appendf(&sql,
353
+ blob_append_sql(&sql,
354354
" FROM mlink, event"
355355
" WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
356356
" AND event.objid=mlink.mid",
357357
zFilename
358358
);
359359
if( baseCheckin ){
360360
compute_direct_ancestors(baseCheckin, 10000000);
361
- blob_appendf(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
361
+ blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
362362
}
363363
if( (zA = P("a"))!=0 ){
364
- blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
364
+ blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA);
365365
url_add_parameter(&url, "a", zA);
366366
}
367367
if( (zB = P("b"))!=0 ){
368
- blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
368
+ blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
369369
url_add_parameter(&url, "b", zB);
370370
}
371371
if( firstChngOnly ){
372
- blob_appendf(&sql, " GROUP BY mlink.fid");
372
+ blob_append_sql(&sql, " GROUP BY mlink.fid");
373373
}
374
- blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
374
+ blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
375375
if( (n = atoi(PD("n","0")))>0 ){
376
- blob_appendf(&sql, " LIMIT %d", n);
376
+ blob_append_sql(&sql, " LIMIT %d", n);
377377
url_add_parameter(&url, "n", P("n"));
378378
}
379379
if( baseCheckin==0 ){
380380
if( firstChngOnly ){
381381
style_submenu_element("Full", "Show all changes","%s",
@@ -384,11 +384,11 @@
384384
style_submenu_element("Simplified",
385385
"Show only first use of a change","%s",
386386
url_render(&url, "fco", 0, 0, 0));
387387
}
388388
}
389
- db_prepare(&q, blob_str(&sql));
389
+ db_prepare(&q, "%s", blob_sql_text(&sql));
390390
if( P("showsql")!=0 ){
391391
@ <p>SQL: %h(blob_str(&sql))</p>
392392
}
393393
blob_reset(&sql);
394394
blob_zero(&title);
@@ -473,11 +473,11 @@
473473
}else{
474474
@ <b>Deleted</b> by check-in
475475
}
476476
}
477477
hyperlink_to_uuid(zCkin);
478
- @ %w(zCom) (user:
478
+ @ %W(zCom) (user:
479479
hyperlink_to_user(zUser, zDate, "");
480480
@ branch: %h(zBr))
481481
if( g.perm.Hyperlink && zUuid ){
482482
const char *z = zFilename;
483483
@ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
484484
--- src/finfo.c
+++ src/finfo.c
@@ -319,11 +319,11 @@
319
320 zPrevDate[0] = 0;
321 zFilename = PD("name","");
322 url_add_parameter(&url, "name", zFilename);
323 blob_zero(&sql);
324 blob_appendf(&sql,
325 "SELECT"
326 " datetime(event.mtime%s)," /* Date of change */
327 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
328 " coalesce(event.euser, event.user)," /* User who made chng */
329 " mlink.pid," /* Parent file rid */
@@ -338,44 +338,44 @@
338 " mlink.pfnid", /* Previous filename */
339 timeline_utc(), TAG_BRANCH
340 );
341 if( firstChngOnly ){
342 #if 0
343 blob_appendf(&sql, ", min(event.mtime)");
344 #else
345 blob_appendf(&sql,
346 ", min(CASE (SELECT value FROM tagxref"
347 " WHERE tagtype>0 AND tagid=%d"
348 " AND tagxref.rid=mlink.mid)"
349 " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
350 TAG_BRANCH);
351 #endif
352 }
353 blob_appendf(&sql,
354 " FROM mlink, event"
355 " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
356 " AND event.objid=mlink.mid",
357 zFilename
358 );
359 if( baseCheckin ){
360 compute_direct_ancestors(baseCheckin, 10000000);
361 blob_appendf(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
362 }
363 if( (zA = P("a"))!=0 ){
364 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
365 url_add_parameter(&url, "a", zA);
366 }
367 if( (zB = P("b"))!=0 ){
368 blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
369 url_add_parameter(&url, "b", zB);
370 }
371 if( firstChngOnly ){
372 blob_appendf(&sql, " GROUP BY mlink.fid");
373 }
374 blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
375 if( (n = atoi(PD("n","0")))>0 ){
376 blob_appendf(&sql, " LIMIT %d", n);
377 url_add_parameter(&url, "n", P("n"));
378 }
379 if( baseCheckin==0 ){
380 if( firstChngOnly ){
381 style_submenu_element("Full", "Show all changes","%s",
@@ -384,11 +384,11 @@
384 style_submenu_element("Simplified",
385 "Show only first use of a change","%s",
386 url_render(&url, "fco", 0, 0, 0));
387 }
388 }
389 db_prepare(&q, blob_str(&sql));
390 if( P("showsql")!=0 ){
391 @ <p>SQL: %h(blob_str(&sql))</p>
392 }
393 blob_reset(&sql);
394 blob_zero(&title);
@@ -473,11 +473,11 @@
473 }else{
474 @ <b>Deleted</b> by check-in
475 }
476 }
477 hyperlink_to_uuid(zCkin);
478 @ %w(zCom) (user:
479 hyperlink_to_user(zUser, zDate, "");
480 @ branch: %h(zBr))
481 if( g.perm.Hyperlink && zUuid ){
482 const char *z = zFilename;
483 @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
484
--- src/finfo.c
+++ src/finfo.c
@@ -319,11 +319,11 @@
319
320 zPrevDate[0] = 0;
321 zFilename = PD("name","");
322 url_add_parameter(&url, "name", zFilename);
323 blob_zero(&sql);
324 blob_append_sql(&sql,
325 "SELECT"
326 " datetime(event.mtime%s)," /* Date of change */
327 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
328 " coalesce(event.euser, event.user)," /* User who made chng */
329 " mlink.pid," /* Parent file rid */
@@ -338,44 +338,44 @@
338 " mlink.pfnid", /* Previous filename */
339 timeline_utc(), TAG_BRANCH
340 );
341 if( firstChngOnly ){
342 #if 0
343 blob_append_sql(&sql, ", min(event.mtime)");
344 #else
345 blob_append_sql(&sql,
346 ", min(CASE (SELECT value FROM tagxref"
347 " WHERE tagtype>0 AND tagid=%d"
348 " AND tagxref.rid=mlink.mid)"
349 " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
350 TAG_BRANCH);
351 #endif
352 }
353 blob_append_sql(&sql,
354 " FROM mlink, event"
355 " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
356 " AND event.objid=mlink.mid",
357 zFilename
358 );
359 if( baseCheckin ){
360 compute_direct_ancestors(baseCheckin, 10000000);
361 blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
362 }
363 if( (zA = P("a"))!=0 ){
364 blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA);
365 url_add_parameter(&url, "a", zA);
366 }
367 if( (zB = P("b"))!=0 ){
368 blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
369 url_add_parameter(&url, "b", zB);
370 }
371 if( firstChngOnly ){
372 blob_append_sql(&sql, " GROUP BY mlink.fid");
373 }
374 blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
375 if( (n = atoi(PD("n","0")))>0 ){
376 blob_append_sql(&sql, " LIMIT %d", n);
377 url_add_parameter(&url, "n", P("n"));
378 }
379 if( baseCheckin==0 ){
380 if( firstChngOnly ){
381 style_submenu_element("Full", "Show all changes","%s",
@@ -384,11 +384,11 @@
384 style_submenu_element("Simplified",
385 "Show only first use of a change","%s",
386 url_render(&url, "fco", 0, 0, 0));
387 }
388 }
389 db_prepare(&q, "%s", blob_sql_text(&sql));
390 if( P("showsql")!=0 ){
391 @ <p>SQL: %h(blob_str(&sql))</p>
392 }
393 blob_reset(&sql);
394 blob_zero(&title);
@@ -473,11 +473,11 @@
473 }else{
474 @ <b>Deleted</b> by check-in
475 }
476 }
477 hyperlink_to_uuid(zCkin);
478 @ %W(zCom) (user:
479 hyperlink_to_user(zUser, zDate, "");
480 @ branch: %h(zBr))
481 if( g.perm.Hyperlink && zUuid ){
482 const char *z = zFilename;
483 @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
484
+2 -2
--- src/http.c
+++ src/http.c
@@ -167,11 +167,11 @@
167167
char *zPrompt;
168168
char *zHttpAuth = 0;
169169
if( !isatty(fileno(stdin)) ) return 0;
170170
zPrompt = mprintf("\n%s authorization required by\n%s\n",
171171
g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172
- fossil_print(zPrompt);
172
+ fossil_print("%s", zPrompt);
173173
free(zPrompt);
174174
if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
175175
zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
176176
}else{
177177
prompt_user("Basic Authorization user: ", &x);
@@ -214,11 +214,11 @@
214214
int i; /* Loop counter */
215215
int isError = 0; /* True if the reply is an error message */
216216
int isCompressed = 1; /* True if the reply is compressed */
217217
218218
if( transport_open(&g.url) ){
219
- fossil_warning(transport_errmsg(&g.url));
219
+ fossil_warning("%s", transport_errmsg(&g.url));
220220
return 1;
221221
}
222222
223223
/* Construct the login card and prepare the complete payload */
224224
blob_zero(&login);
225225
--- src/http.c
+++ src/http.c
@@ -167,11 +167,11 @@
167 char *zPrompt;
168 char *zHttpAuth = 0;
169 if( !isatty(fileno(stdin)) ) return 0;
170 zPrompt = mprintf("\n%s authorization required by\n%s\n",
171 g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172 fossil_print(zPrompt);
173 free(zPrompt);
174 if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
175 zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
176 }else{
177 prompt_user("Basic Authorization user: ", &x);
@@ -214,11 +214,11 @@
214 int i; /* Loop counter */
215 int isError = 0; /* True if the reply is an error message */
216 int isCompressed = 1; /* True if the reply is compressed */
217
218 if( transport_open(&g.url) ){
219 fossil_warning(transport_errmsg(&g.url));
220 return 1;
221 }
222
223 /* Construct the login card and prepare the complete payload */
224 blob_zero(&login);
225
--- src/http.c
+++ src/http.c
@@ -167,11 +167,11 @@
167 char *zPrompt;
168 char *zHttpAuth = 0;
169 if( !isatty(fileno(stdin)) ) return 0;
170 zPrompt = mprintf("\n%s authorization required by\n%s\n",
171 g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172 fossil_print("%s", zPrompt);
173 free(zPrompt);
174 if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
175 zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
176 }else{
177 prompt_user("Basic Authorization user: ", &x);
@@ -214,11 +214,11 @@
214 int i; /* Loop counter */
215 int isError = 0; /* True if the reply is an error message */
216 int isCompressed = 1; /* True if the reply is compressed */
217
218 if( transport_open(&g.url) ){
219 fossil_warning("%s", transport_errmsg(&g.url));
220 return 1;
221 }
222
223 /* Construct the login card and prepare the complete payload */
224 blob_zero(&login);
225
+6 -8
--- src/info.c
+++ src/info.c
@@ -535,20 +535,18 @@
535535
timeline_utc(), timeline_utc(), rid, rid
536536
);
537537
sideBySide = !is_false(PD("sbs","1"));
538538
if( db_step(&q1)==SQLITE_ROW ){
539539
const char *zUuid = db_column_text(&q1, 0);
540
- char *zTitle = mprintf("Check-in [%S]", zUuid);
541540
char *zEUser, *zEComment;
542541
const char *zUser;
543542
const char *zComment;
544543
const char *zDate;
545544
const char *zOrigDate;
546545
547
- style_header(zTitle);
546
+ style_header("Check-in [%S]", zUuid);
548547
login_anonymous_available();
549
- free(zTitle);
550548
zEUser = db_text(0,
551549
"SELECT value FROM tagxref"
552550
" WHERE tagid=%d AND rid=%d AND tagtype>0",
553551
TAG_USER, rid);
554552
zEComment = db_text(0,
@@ -1582,11 +1580,11 @@
15821580
login_check_credentials();
15831581
if( !g.perm.Read ){ login_needed(); return; }
15841582
if( rid==0 ) fossil_redirect_home();
15851583
if( g.perm.Admin ){
15861584
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1587
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1585
+ if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
15881586
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
15891587
g.zTop, zUuid);
15901588
}else{
15911589
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
15921590
g.zTop, zUuid);
@@ -1768,20 +1766,20 @@
17681766
login_check_credentials();
17691767
if( !g.perm.Read ){ login_needed(); return; }
17701768
if( rid==0 ) fossil_redirect_home();
17711769
if( g.perm.Admin ){
17721770
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1773
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1771
+ if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
17741772
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
17751773
g.zTop, zUuid);
17761774
}else{
17771775
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
17781776
g.zTop, zUuid);
17791777
}
17801778
}
17811779
if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1782
- style_header(descOnly ? "Artifact Description" : "Artifact Content");
1780
+ style_header("%s", descOnly ? "Artifact Description" : "Artifact Content");
17831781
zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
17841782
if( g.perm.Setup ){
17851783
@ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
17861784
}else{
17871785
@ <h2>Artifact %s(zUuid):</h2>
@@ -1884,11 +1882,11 @@
18841882
if( !g.perm.RdTkt ){ login_needed(); return; }
18851883
rid = name_to_rid_www("name");
18861884
if( rid==0 ){ fossil_redirect_home(); }
18871885
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
18881886
if( g.perm.Admin ){
1889
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1887
+ if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
18901888
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
18911889
g.zTop, zUuid);
18921890
}else{
18931891
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
18941892
g.zTop, zUuid);
@@ -2029,11 +2027,11 @@
20292027
cgi_set_parameter("src","info");
20302028
ambiguous_page();
20312029
return;
20322030
}
20332031
zName = blob_str(&uuid);
2034
- rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
2032
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
20352033
if( rid==0 ){
20362034
style_header("Broken Link");
20372035
@ <p>No such object: %h(zName)</p>
20382036
style_footer();
20392037
return;
20402038
--- src/info.c
+++ src/info.c
@@ -535,20 +535,18 @@
535 timeline_utc(), timeline_utc(), rid, rid
536 );
537 sideBySide = !is_false(PD("sbs","1"));
538 if( db_step(&q1)==SQLITE_ROW ){
539 const char *zUuid = db_column_text(&q1, 0);
540 char *zTitle = mprintf("Check-in [%S]", zUuid);
541 char *zEUser, *zEComment;
542 const char *zUser;
543 const char *zComment;
544 const char *zDate;
545 const char *zOrigDate;
546
547 style_header(zTitle);
548 login_anonymous_available();
549 free(zTitle);
550 zEUser = db_text(0,
551 "SELECT value FROM tagxref"
552 " WHERE tagid=%d AND rid=%d AND tagtype>0",
553 TAG_USER, rid);
554 zEComment = db_text(0,
@@ -1582,11 +1580,11 @@
1582 login_check_credentials();
1583 if( !g.perm.Read ){ login_needed(); return; }
1584 if( rid==0 ) fossil_redirect_home();
1585 if( g.perm.Admin ){
1586 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1587 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1588 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
1589 g.zTop, zUuid);
1590 }else{
1591 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1592 g.zTop, zUuid);
@@ -1768,20 +1766,20 @@
1768 login_check_credentials();
1769 if( !g.perm.Read ){ login_needed(); return; }
1770 if( rid==0 ) fossil_redirect_home();
1771 if( g.perm.Admin ){
1772 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1773 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1774 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1775 g.zTop, zUuid);
1776 }else{
1777 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1778 g.zTop, zUuid);
1779 }
1780 }
1781 if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1782 style_header(descOnly ? "Artifact Description" : "Artifact Content");
1783 zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
1784 if( g.perm.Setup ){
1785 @ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
1786 }else{
1787 @ <h2>Artifact %s(zUuid):</h2>
@@ -1884,11 +1882,11 @@
1884 if( !g.perm.RdTkt ){ login_needed(); return; }
1885 rid = name_to_rid_www("name");
1886 if( rid==0 ){ fossil_redirect_home(); }
1887 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1888 if( g.perm.Admin ){
1889 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1890 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1891 g.zTop, zUuid);
1892 }else{
1893 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1894 g.zTop, zUuid);
@@ -2029,11 +2027,11 @@
2029 cgi_set_parameter("src","info");
2030 ambiguous_page();
2031 return;
2032 }
2033 zName = blob_str(&uuid);
2034 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
2035 if( rid==0 ){
2036 style_header("Broken Link");
2037 @ <p>No such object: %h(zName)</p>
2038 style_footer();
2039 return;
2040
--- src/info.c
+++ src/info.c
@@ -535,20 +535,18 @@
535 timeline_utc(), timeline_utc(), rid, rid
536 );
537 sideBySide = !is_false(PD("sbs","1"));
538 if( db_step(&q1)==SQLITE_ROW ){
539 const char *zUuid = db_column_text(&q1, 0);
 
540 char *zEUser, *zEComment;
541 const char *zUser;
542 const char *zComment;
543 const char *zDate;
544 const char *zOrigDate;
545
546 style_header("Check-in [%S]", zUuid);
547 login_anonymous_available();
 
548 zEUser = db_text(0,
549 "SELECT value FROM tagxref"
550 " WHERE tagid=%d AND rid=%d AND tagtype>0",
551 TAG_USER, rid);
552 zEComment = db_text(0,
@@ -1582,11 +1580,11 @@
1580 login_check_credentials();
1581 if( !g.perm.Read ){ login_needed(); return; }
1582 if( rid==0 ) fossil_redirect_home();
1583 if( g.perm.Admin ){
1584 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1585 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
1586 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
1587 g.zTop, zUuid);
1588 }else{
1589 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1590 g.zTop, zUuid);
@@ -1768,20 +1766,20 @@
1766 login_check_credentials();
1767 if( !g.perm.Read ){ login_needed(); return; }
1768 if( rid==0 ) fossil_redirect_home();
1769 if( g.perm.Admin ){
1770 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1771 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
1772 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1773 g.zTop, zUuid);
1774 }else{
1775 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1776 g.zTop, zUuid);
1777 }
1778 }
1779 if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1780 style_header("%s", descOnly ? "Artifact Description" : "Artifact Content");
1781 zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
1782 if( g.perm.Setup ){
1783 @ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
1784 }else{
1785 @ <h2>Artifact %s(zUuid):</h2>
@@ -1884,11 +1882,11 @@
1882 if( !g.perm.RdTkt ){ login_needed(); return; }
1883 rid = name_to_rid_www("name");
1884 if( rid==0 ){ fossil_redirect_home(); }
1885 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1886 if( g.perm.Admin ){
1887 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
1888 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1889 g.zTop, zUuid);
1890 }else{
1891 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1892 g.zTop, zUuid);
@@ -2029,11 +2027,11 @@
2027 cgi_set_parameter("src","info");
2028 ambiguous_page();
2029 return;
2030 }
2031 zName = blob_str(&uuid);
2032 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
2033 if( rid==0 ){
2034 style_header("Broken Link");
2035 @ <p>No such object: %h(zName)</p>
2036 style_footer();
2037 return;
2038
+7 -7
--- src/json.c
+++ src/json.c
@@ -1665,11 +1665,11 @@
16651665
cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
16661666
char resetBlob){
16671667
Stmt q = empty_Stmt;
16681668
cson_value * pay = NULL;
16691669
assert( blob_size(pSql) > 0 );
1670
- db_prepare(&q, "%s", blob_str(pSql));
1670
+ db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
16711671
if(resetBlob){
16721672
blob_reset(pSql);
16731673
}
16741674
pay = json_stmt_to_array_of_obj(&q, pTgt);
16751675
db_finalize(&q);
@@ -1983,16 +1983,16 @@
19831983
cson_object_set(jo, "sqlite", jv2);
19841984
sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
19851985
sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
19861986
SETBUF(jo2, "version");
19871987
zDb = db_name("repository");
1988
- cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb)));
1989
- cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb)));
1990
- cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb)));
1991
- sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb));
1988
+ cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb)));
1989
+ cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb)));
1990
+ cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb)));
1991
+ sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb));
19921992
SETBUF(jo2, "encoding");
1993
- sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb));
1993
+ sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
19941994
cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
19951995
return jv;
19961996
#undef SETBUF
19971997
}
19981998
@@ -2016,11 +2016,11 @@
20162016
for( ; zPages->name; ++zPages, ++i ){
20172017
if(filterByMode){
20182018
if(g.isHTTP && zPages->runMode < 0) continue;
20192019
else if(zPages->runMode > 0) continue;
20202020
}
2021
- blob_appendf(pOut, zPages->name, -1);
2021
+ blob_append(pOut, zPages->name, -1);
20222022
if((zPages+1)->name){
20232023
blob_append(pOut, ", ",2);
20242024
}
20252025
}
20262026
return i;
20272027
--- src/json.c
+++ src/json.c
@@ -1665,11 +1665,11 @@
1665 cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1666 char resetBlob){
1667 Stmt q = empty_Stmt;
1668 cson_value * pay = NULL;
1669 assert( blob_size(pSql) > 0 );
1670 db_prepare(&q, "%s", blob_str(pSql));
1671 if(resetBlob){
1672 blob_reset(pSql);
1673 }
1674 pay = json_stmt_to_array_of_obj(&q, pTgt);
1675 db_finalize(&q);
@@ -1983,16 +1983,16 @@
1983 cson_object_set(jo, "sqlite", jv2);
1984 sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
1985 sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
1986 SETBUF(jo2, "version");
1987 zDb = db_name("repository");
1988 cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb)));
1989 cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb)));
1990 cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb)));
1991 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb));
1992 SETBUF(jo2, "encoding");
1993 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb));
1994 cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
1995 return jv;
1996 #undef SETBUF
1997 }
1998
@@ -2016,11 +2016,11 @@
2016 for( ; zPages->name; ++zPages, ++i ){
2017 if(filterByMode){
2018 if(g.isHTTP && zPages->runMode < 0) continue;
2019 else if(zPages->runMode > 0) continue;
2020 }
2021 blob_appendf(pOut, zPages->name, -1);
2022 if((zPages+1)->name){
2023 blob_append(pOut, ", ",2);
2024 }
2025 }
2026 return i;
2027
--- src/json.c
+++ src/json.c
@@ -1665,11 +1665,11 @@
1665 cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1666 char resetBlob){
1667 Stmt q = empty_Stmt;
1668 cson_value * pay = NULL;
1669 assert( blob_size(pSql) > 0 );
1670 db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
1671 if(resetBlob){
1672 blob_reset(pSql);
1673 }
1674 pay = json_stmt_to_array_of_obj(&q, pTgt);
1675 db_finalize(&q);
@@ -1983,16 +1983,16 @@
1983 cson_object_set(jo, "sqlite", jv2);
1984 sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
1985 sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
1986 SETBUF(jo2, "version");
1987 zDb = db_name("repository");
1988 cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb)));
1989 cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb)));
1990 cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb)));
1991 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb));
1992 SETBUF(jo2, "encoding");
1993 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
1994 cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
1995 return jv;
1996 #undef SETBUF
1997 }
1998
@@ -2016,11 +2016,11 @@
2016 for( ; zPages->name; ++zPages, ++i ){
2017 if(filterByMode){
2018 if(g.isHTTP && zPages->runMode < 0) continue;
2019 else if(zPages->runMode > 0) continue;
2020 }
2021 blob_append(pOut, zPages->name, -1);
2022 if((zPages+1)->name){
2023 blob_append(pOut, ", ",2);
2024 }
2025 }
2026 return i;
2027
--- src/json_config.c
+++ src/json_config.c
@@ -145,11 +145,11 @@
145145
for( i = 0; prop->name; ++prop ){
146146
if(prop->groupMask & confMask){
147147
if( i++ ){
148148
blob_append(&sql,",",1);
149149
}
150
- blob_appendf(&sql, "%Q", prop->name);
150
+ blob_append_sql(&sql, "%Q", prop->name);
151151
}
152152
}
153153
blob_append(&sql,") ", -1);
154154
}
155155
@@ -156,11 +156,11 @@
156156
157157
if( optSkinBackups ){
158158
blob_append(&sql, " OR name GLOB 'skin:*'", -1);
159159
}
160160
blob_append(&sql," ORDER BY name", -1);
161
- db_prepare(&q, blob_str(&sql));
161
+ db_prepare(&q, "%s", blob_sql_text(&sql));
162162
blob_reset(&sql);
163163
pay = cson_new_object();
164164
while( (SQLITE_ROW==db_step(&q)) ){
165165
cson_object_set(pay,
166166
db_column_text(&q,0),
167167
--- src/json_config.c
+++ src/json_config.c
@@ -145,11 +145,11 @@
145 for( i = 0; prop->name; ++prop ){
146 if(prop->groupMask & confMask){
147 if( i++ ){
148 blob_append(&sql,",",1);
149 }
150 blob_appendf(&sql, "%Q", prop->name);
151 }
152 }
153 blob_append(&sql,") ", -1);
154 }
155
@@ -156,11 +156,11 @@
156
157 if( optSkinBackups ){
158 blob_append(&sql, " OR name GLOB 'skin:*'", -1);
159 }
160 blob_append(&sql," ORDER BY name", -1);
161 db_prepare(&q, blob_str(&sql));
162 blob_reset(&sql);
163 pay = cson_new_object();
164 while( (SQLITE_ROW==db_step(&q)) ){
165 cson_object_set(pay,
166 db_column_text(&q,0),
167
--- src/json_config.c
+++ src/json_config.c
@@ -145,11 +145,11 @@
145 for( i = 0; prop->name; ++prop ){
146 if(prop->groupMask & confMask){
147 if( i++ ){
148 blob_append(&sql,",",1);
149 }
150 blob_append_sql(&sql, "%Q", prop->name);
151 }
152 }
153 blob_append(&sql,") ", -1);
154 }
155
@@ -156,11 +156,11 @@
156
157 if( optSkinBackups ){
158 blob_append(&sql, " OR name GLOB 'skin:*'", -1);
159 }
160 blob_append(&sql," ORDER BY name", -1);
161 db_prepare(&q, "%s", blob_sql_text(&sql));
162 blob_reset(&sql);
163 pay = cson_new_object();
164 while( (SQLITE_ROW==db_step(&q)) ){
165 cson_object_set(pay,
166 db_column_text(&q,0),
167
--- src/json_finfo.c
+++ src/json_finfo.c
@@ -62,11 +62,11 @@
6262
zBefore = json_find_option_cstr("before",NULL,"b");
6363
zAfter = json_find_option_cstr("after",NULL,"a");
6464
limit = json_find_option_int("limit",NULL,"n", -1);
6565
zCheckin = json_find_option_cstr("checkin",NULL,"ci");
6666
67
- blob_appendf(&sql,
67
+ blob_append_sql(&sql,
6868
/*0*/ "SELECT b.uuid,"
6969
/*1*/ " ci.uuid,"
7070
/*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
7171
/*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER),"
7272
/*4*/ " coalesce(event.euser, event.user),"
@@ -93,25 +93,24 @@
9393
json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
9494
"Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
9595
blob_reset(&sql);
9696
return NULL;
9797
}
98
- blob_appendf(&sql, " AND ci.uuid='%q'", zU);
98
+ blob_append_sql(&sql, " AND ci.uuid='%q'", zU);
9999
free(zU);
100100
}else{
101101
if( zAfter && *zAfter ){
102
- blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter);
102
+ blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter);
103103
sort = 1;
104104
}else if( zBefore && *zBefore ){
105
- blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore);
105
+ blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore);
106106
}
107107
}
108108
109
- blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
109
+ blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
110110
/*printf("SQL=\n%s\n",blob_str(&sql));*/
111
- db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
112
- SQL escapes*/);
111
+ db_prepare(&q, "%s", blob_sql_text(&sql));
113112
blob_reset(&sql);
114113
115114
pay = cson_new_object();
116115
cson_object_set(pay, "name", json_new_string(zFilename));
117116
if( limit > 0 ){
118117
--- src/json_finfo.c
+++ src/json_finfo.c
@@ -62,11 +62,11 @@
62 zBefore = json_find_option_cstr("before",NULL,"b");
63 zAfter = json_find_option_cstr("after",NULL,"a");
64 limit = json_find_option_int("limit",NULL,"n", -1);
65 zCheckin = json_find_option_cstr("checkin",NULL,"ci");
66
67 blob_appendf(&sql,
68 /*0*/ "SELECT b.uuid,"
69 /*1*/ " ci.uuid,"
70 /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
71 /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER),"
72 /*4*/ " coalesce(event.euser, event.user),"
@@ -93,25 +93,24 @@
93 json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
94 "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
95 blob_reset(&sql);
96 return NULL;
97 }
98 blob_appendf(&sql, " AND ci.uuid='%q'", zU);
99 free(zU);
100 }else{
101 if( zAfter && *zAfter ){
102 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter);
103 sort = 1;
104 }else if( zBefore && *zBefore ){
105 blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore);
106 }
107 }
108
109 blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
110 /*printf("SQL=\n%s\n",blob_str(&sql));*/
111 db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
112 SQL escapes*/);
113 blob_reset(&sql);
114
115 pay = cson_new_object();
116 cson_object_set(pay, "name", json_new_string(zFilename));
117 if( limit > 0 ){
118
--- src/json_finfo.c
+++ src/json_finfo.c
@@ -62,11 +62,11 @@
62 zBefore = json_find_option_cstr("before",NULL,"b");
63 zAfter = json_find_option_cstr("after",NULL,"a");
64 limit = json_find_option_int("limit",NULL,"n", -1);
65 zCheckin = json_find_option_cstr("checkin",NULL,"ci");
66
67 blob_append_sql(&sql,
68 /*0*/ "SELECT b.uuid,"
69 /*1*/ " ci.uuid,"
70 /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
71 /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER),"
72 /*4*/ " coalesce(event.euser, event.user),"
@@ -93,25 +93,24 @@
93 json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
94 "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
95 blob_reset(&sql);
96 return NULL;
97 }
98 blob_append_sql(&sql, " AND ci.uuid='%q'", zU);
99 free(zU);
100 }else{
101 if( zAfter && *zAfter ){
102 blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter);
103 sort = 1;
104 }else if( zBefore && *zBefore ){
105 blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore);
106 }
107 }
108
109 blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
110 /*printf("SQL=\n%s\n",blob_str(&sql));*/
111 db_prepare(&q, "%s", blob_sql_text(&sql));
 
112 blob_reset(&sql);
113
114 pay = cson_new_object();
115 cson_object_set(pay, "name", json_new_string(zFilename));
116 if( limit > 0 ){
117
--- src/json_query.c
+++ src/json_query.c
@@ -64,11 +64,11 @@
6464
return NULL;
6565
}
6666
6767
zFmt = json_find_option_cstr2("format",NULL,"f",3);
6868
if(!zFmt) zFmt = "o";
69
- db_prepare(&q,"%s", zSql);
69
+ db_prepare(&q,"%s", zSql/*safe-for-%s*/);
7070
if( 0 == sqlite3_column_count( q.pStmt ) ){
7171
json_set_err(FSL_JSON_E_USAGE,
7272
"Input query has no result columns. "
7373
"Only SELECT-like queries are supported.");
7474
db_finalize(&q);
7575
--- src/json_query.c
+++ src/json_query.c
@@ -64,11 +64,11 @@
64 return NULL;
65 }
66
67 zFmt = json_find_option_cstr2("format",NULL,"f",3);
68 if(!zFmt) zFmt = "o";
69 db_prepare(&q,"%s", zSql);
70 if( 0 == sqlite3_column_count( q.pStmt ) ){
71 json_set_err(FSL_JSON_E_USAGE,
72 "Input query has no result columns. "
73 "Only SELECT-like queries are supported.");
74 db_finalize(&q);
75
--- src/json_query.c
+++ src/json_query.c
@@ -64,11 +64,11 @@
64 return NULL;
65 }
66
67 zFmt = json_find_option_cstr2("format",NULL,"f",3);
68 if(!zFmt) zFmt = "o";
69 db_prepare(&q,"%s", zSql/*safe-for-%s*/);
70 if( 0 == sqlite3_column_count( q.pStmt ) ){
71 json_set_err(FSL_JSON_E_USAGE,
72 "Input query has no result columns. "
73 "Only SELECT-like queries are supported.");
74 db_finalize(&q);
75
--- src/json_report.c
+++ src/json_report.c
@@ -204,11 +204,11 @@
204204
205205
/* Copy over report's SQL...*/
206206
blob_append(&sql, db_column_text(&q,0), -1);
207207
zTitle = mprintf("%s", db_column_text(&q,1));
208208
db_finalize(&q);
209
- db_prepare(&q, "%s", blob_str(&sql));
209
+ db_prepare(&q, "%s", blob_sql_text(&sql));
210210
211211
/** Build the response... */
212212
pay = cson_new_object();
213213
214214
cson_object_set(pay, "report", json_new_int(nReport));
215215
--- src/json_report.c
+++ src/json_report.c
@@ -204,11 +204,11 @@
204
205 /* Copy over report's SQL...*/
206 blob_append(&sql, db_column_text(&q,0), -1);
207 zTitle = mprintf("%s", db_column_text(&q,1));
208 db_finalize(&q);
209 db_prepare(&q, "%s", blob_str(&sql));
210
211 /** Build the response... */
212 pay = cson_new_object();
213
214 cson_object_set(pay, "report", json_new_int(nReport));
215
--- src/json_report.c
+++ src/json_report.c
@@ -204,11 +204,11 @@
204
205 /* Copy over report's SQL...*/
206 blob_append(&sql, db_column_text(&q,0), -1);
207 zTitle = mprintf("%s", db_column_text(&q,1));
208 db_finalize(&q);
209 db_prepare(&q, "%s", blob_sql_text(&sql));
210
211 /** Build the response... */
212 pay = cson_new_object();
213
214 cson_object_set(pay, "report", json_new_int(nReport));
215
+2 -2
--- src/json_tag.c
+++ src/json_tag.c
@@ -301,11 +301,11 @@
301301
" SELECT rid FROM tagxref"
302302
" WHERE tagtype>0 AND tagid=%d"
303303
" )"
304304
" ORDER BY event.mtime DESC"
305305
"%s LIMIT %d",
306
- zSqlBase, zType, tagid,
306
+ zSqlBase /*safe-for-%s*/, zType, tagid,
307307
(limit>0)?"":"--", limit
308308
);
309309
listV = json_stmt_to_array_of_obj(&q, NULL);
310310
db_finalize(&q);
311311
}
@@ -442,11 +442,11 @@
442442
if(!fTicket){
443443
blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
444444
}
445445
blob_append(&sql,
446446
" ORDER BY tagname", -1);
447
- db_prepare(&q, blob_buffer(&sql));
447
+ db_prepare(&q, "%s", blob_sql_text(&sql));
448448
blob_reset(&sql);
449449
cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
450450
while( SQLITE_ROW == db_step(&q) ){
451451
const char *zName = db_column_text(&q, 0);
452452
if(NULL==arV){
453453
--- src/json_tag.c
+++ src/json_tag.c
@@ -301,11 +301,11 @@
301 " SELECT rid FROM tagxref"
302 " WHERE tagtype>0 AND tagid=%d"
303 " )"
304 " ORDER BY event.mtime DESC"
305 "%s LIMIT %d",
306 zSqlBase, zType, tagid,
307 (limit>0)?"":"--", limit
308 );
309 listV = json_stmt_to_array_of_obj(&q, NULL);
310 db_finalize(&q);
311 }
@@ -442,11 +442,11 @@
442 if(!fTicket){
443 blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
444 }
445 blob_append(&sql,
446 " ORDER BY tagname", -1);
447 db_prepare(&q, blob_buffer(&sql));
448 blob_reset(&sql);
449 cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
450 while( SQLITE_ROW == db_step(&q) ){
451 const char *zName = db_column_text(&q, 0);
452 if(NULL==arV){
453
--- src/json_tag.c
+++ src/json_tag.c
@@ -301,11 +301,11 @@
301 " SELECT rid FROM tagxref"
302 " WHERE tagtype>0 AND tagid=%d"
303 " )"
304 " ORDER BY event.mtime DESC"
305 "%s LIMIT %d",
306 zSqlBase /*safe-for-%s*/, zType, tagid,
307 (limit>0)?"":"--", limit
308 );
309 listV = json_stmt_to_array_of_obj(&q, NULL);
310 db_finalize(&q);
311 }
@@ -442,11 +442,11 @@
442 if(!fTicket){
443 blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
444 }
445 blob_append(&sql,
446 " ORDER BY tagname", -1);
447 db_prepare(&q, "%s", blob_sql_text(&sql));
448 blob_reset(&sql);
449 cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
450 while( SQLITE_ROW == db_step(&q) ){
451 const char *zName = db_column_text(&q, 0);
452 if(NULL==arV){
453
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -83,11 +83,11 @@
8383
@ tags TEXT,
8484
@ tagId INTEGER,
8585
@ brief TEXT
8686
@ )
8787
;
88
- db_multi_exec(zSql);
88
+ db_multi_exec("%s", zSql /*safe-for-%s*/);
8989
}
9090
9191
/*
9292
** Return a pointer to a constant string that forms the basis
9393
** for a timeline query for the JSON interface.
@@ -384,21 +384,21 @@
384384
" bgcolor as bgColor"
385385
" FROM event JOIN blob"
386386
" WHERE blob.rid=event.objid",
387387
-1);
388388
389
- blob_appendf(&sql,
389
+ blob_append_sql(&sql,
390390
" AND event.type='ci'"
391391
" AND blob.rid IN (SELECT rid FROM tagxref"
392392
" WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
393393
" ORDER BY event.mtime DESC",
394394
TAG_BRANCH);
395395
limit = json_timeline_limit(20);
396396
if(limit>0){
397
- blob_appendf(&sql," LIMIT %d ",limit);
397
+ blob_append_sql(&sql," LIMIT %d ",limit);
398398
}
399
- db_prepare(&q,"%s", blob_str(&sql));
399
+ db_prepare(&q,"%s", blob_sql_text(&sql));
400400
blob_reset(&sql);
401401
pay = json_stmt_to_array_of_obj(&q, NULL);
402402
db_finalize(&q);
403403
assert(NULL != pay);
404404
if(pay){
@@ -482,11 +482,11 @@
482482
#if 0
483483
/* only for testing! */
484484
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
485485
SET("timelineSql");
486486
#endif
487
- db_multi_exec(blob_buffer(&sql));
487
+ db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/);
488488
blob_reset(&sql);
489489
db_prepare(&q, "SELECT "
490490
" rid AS rid"
491491
" FROM json_timeline"
492492
" ORDER BY rowid");
@@ -547,11 +547,11 @@
547547
#if 0
548548
/* only for testing! */
549549
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550550
SET("timelineSql");
551551
#endif
552
- db_multi_exec(blob_buffer(&sql));
552
+ db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553553
blob_reset(&sql);
554554
db_prepare(&q, "SELECT"
555555
" uuid AS uuid,"
556556
" mtime AS timestamp,"
557557
#if 0
@@ -565,12 +565,11 @@
565565
" tags AS tags," /*FIXME: split this into
566566
a JSON array*/
567567
" tagId AS tagId,"
568568
#endif
569569
" FROM json_timeline"
570
- " ORDER BY rowid",
571
- -1);
570
+ " ORDER BY rowid");
572571
list = cson_new_array();
573572
json_stmt_to_array_of_obj(&q, list);
574573
cson_object_set(pay, "timeline", cson_array_value(list));
575574
goto ok;
576575
error:
@@ -607,11 +606,11 @@
607606
if(check){
608607
json_set_err(check, "Query initialization failed.");
609608
goto error;
610609
}
611610
612
- db_multi_exec(blob_buffer(&sql));
611
+ db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
613612
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
614613
json_set_err((cson_rc.AllocError==check) \
615614
? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
616615
"Object property insertion failed."); \
617616
goto error;\
@@ -638,12 +637,11 @@
638637
" user AS user,"
639638
" eventType AS eventType,"
640639
" comment AS comment,"
641640
" brief AS briefComment"
642641
" FROM json_timeline"
643
- " ORDER BY rowid",
644
- -1);
642
+ " ORDER BY rowid");
645643
listV = cson_value_new_array();
646644
list = cson_value_get_array(listV);
647645
tmp = listV;
648646
SET("timeline");
649647
while( (SQLITE_ROW == db_step(&q) )){
650648
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -83,11 +83,11 @@
83 @ tags TEXT,
84 @ tagId INTEGER,
85 @ brief TEXT
86 @ )
87 ;
88 db_multi_exec(zSql);
89 }
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
@@ -384,21 +384,21 @@
384 " bgcolor as bgColor"
385 " FROM event JOIN blob"
386 " WHERE blob.rid=event.objid",
387 -1);
388
389 blob_appendf(&sql,
390 " AND event.type='ci'"
391 " AND blob.rid IN (SELECT rid FROM tagxref"
392 " WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
393 " ORDER BY event.mtime DESC",
394 TAG_BRANCH);
395 limit = json_timeline_limit(20);
396 if(limit>0){
397 blob_appendf(&sql," LIMIT %d ",limit);
398 }
399 db_prepare(&q,"%s", blob_str(&sql));
400 blob_reset(&sql);
401 pay = json_stmt_to_array_of_obj(&q, NULL);
402 db_finalize(&q);
403 assert(NULL != pay);
404 if(pay){
@@ -482,11 +482,11 @@
482 #if 0
483 /* only for testing! */
484 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
485 SET("timelineSql");
486 #endif
487 db_multi_exec(blob_buffer(&sql));
488 blob_reset(&sql);
489 db_prepare(&q, "SELECT "
490 " rid AS rid"
491 " FROM json_timeline"
492 " ORDER BY rowid");
@@ -547,11 +547,11 @@
547 #if 0
548 /* only for testing! */
549 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550 SET("timelineSql");
551 #endif
552 db_multi_exec(blob_buffer(&sql));
553 blob_reset(&sql);
554 db_prepare(&q, "SELECT"
555 " uuid AS uuid,"
556 " mtime AS timestamp,"
557 #if 0
@@ -565,12 +565,11 @@
565 " tags AS tags," /*FIXME: split this into
566 a JSON array*/
567 " tagId AS tagId,"
568 #endif
569 " FROM json_timeline"
570 " ORDER BY rowid",
571 -1);
572 list = cson_new_array();
573 json_stmt_to_array_of_obj(&q, list);
574 cson_object_set(pay, "timeline", cson_array_value(list));
575 goto ok;
576 error:
@@ -607,11 +606,11 @@
607 if(check){
608 json_set_err(check, "Query initialization failed.");
609 goto error;
610 }
611
612 db_multi_exec(blob_buffer(&sql));
613 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
614 json_set_err((cson_rc.AllocError==check) \
615 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
616 "Object property insertion failed."); \
617 goto error;\
@@ -638,12 +637,11 @@
638 " user AS user,"
639 " eventType AS eventType,"
640 " comment AS comment,"
641 " brief AS briefComment"
642 " FROM json_timeline"
643 " ORDER BY rowid",
644 -1);
645 listV = cson_value_new_array();
646 list = cson_value_get_array(listV);
647 tmp = listV;
648 SET("timeline");
649 while( (SQLITE_ROW == db_step(&q) )){
650
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -83,11 +83,11 @@
83 @ tags TEXT,
84 @ tagId INTEGER,
85 @ brief TEXT
86 @ )
87 ;
88 db_multi_exec("%s", zSql /*safe-for-%s*/);
89 }
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
@@ -384,21 +384,21 @@
384 " bgcolor as bgColor"
385 " FROM event JOIN blob"
386 " WHERE blob.rid=event.objid",
387 -1);
388
389 blob_append_sql(&sql,
390 " AND event.type='ci'"
391 " AND blob.rid IN (SELECT rid FROM tagxref"
392 " WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
393 " ORDER BY event.mtime DESC",
394 TAG_BRANCH);
395 limit = json_timeline_limit(20);
396 if(limit>0){
397 blob_append_sql(&sql," LIMIT %d ",limit);
398 }
399 db_prepare(&q,"%s", blob_sql_text(&sql));
400 blob_reset(&sql);
401 pay = json_stmt_to_array_of_obj(&q, NULL);
402 db_finalize(&q);
403 assert(NULL != pay);
404 if(pay){
@@ -482,11 +482,11 @@
482 #if 0
483 /* only for testing! */
484 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
485 SET("timelineSql");
486 #endif
487 db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/);
488 blob_reset(&sql);
489 db_prepare(&q, "SELECT "
490 " rid AS rid"
491 " FROM json_timeline"
492 " ORDER BY rowid");
@@ -547,11 +547,11 @@
547 #if 0
548 /* only for testing! */
549 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550 SET("timelineSql");
551 #endif
552 db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553 blob_reset(&sql);
554 db_prepare(&q, "SELECT"
555 " uuid AS uuid,"
556 " mtime AS timestamp,"
557 #if 0
@@ -565,12 +565,11 @@
565 " tags AS tags," /*FIXME: split this into
566 a JSON array*/
567 " tagId AS tagId,"
568 #endif
569 " FROM json_timeline"
570 " ORDER BY rowid");
 
571 list = cson_new_array();
572 json_stmt_to_array_of_obj(&q, list);
573 cson_object_set(pay, "timeline", cson_array_value(list));
574 goto ok;
575 error:
@@ -607,11 +606,11 @@
606 if(check){
607 json_set_err(check, "Query initialization failed.");
608 goto error;
609 }
610
611 db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
612 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
613 json_set_err((cson_rc.AllocError==check) \
614 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
615 "Object property insertion failed."); \
616 goto error;\
@@ -638,12 +637,11 @@
637 " user AS user,"
638 " eventType AS eventType,"
639 " comment AS comment,"
640 " brief AS briefComment"
641 " FROM json_timeline"
642 " ORDER BY rowid");
 
643 listV = cson_value_new_array();
644 list = cson_value_get_array(listV);
645 tmp = listV;
646 SET("timeline");
647 while( (SQLITE_ROW == db_step(&q) )){
648
+9 -9
--- src/json_user.c
+++ src/json_user.c
@@ -286,11 +286,11 @@
286286
/* reminders: 1) does not allocate.
287287
2) we do this because changing a name
288288
invalidates any login token because the old name
289289
is part of the token hash.
290290
*/;
291
- blob_appendf(&sql, ", login=%Q", zNameNew);
291
+ blob_append_sql(&sql, ", login=%Q", zNameNew);
292292
++gotFields;
293293
}
294294
}
295295
296296
if( zCap && *zCap ){
@@ -298,11 +298,11 @@
298298
/* we "could" arguably silently ignore cap in this case. */
299299
json_set_err(FSL_JSON_E_DENIED,
300300
"Changing capabilities requires 'a' or 's' privileges.");
301301
goto error;
302302
}
303
- blob_appendf(&sql, ", cap=%Q", zCap);
303
+ blob_append_sql(&sql, ", cap=%Q", zCap);
304304
++gotFields;
305305
}
306306
307307
if( zPW && *zPW ){
308308
if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
@@ -314,24 +314,24 @@
314314
#define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
315315
#if !TRY_LOGIN_GROUP
316316
char * zPWHash = NULL;
317317
++gotFields;
318318
zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
319
- blob_appendf(&sql, ", pw=%Q", zPWHash);
319
+ blob_append_sql(&sql, ", pw=%Q", zPWHash);
320320
free(zPWHash);
321321
#else
322322
++gotFields;
323
- blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
323
+ blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
324324
"(SELECT value FROM config WHERE name='project-code')))",
325325
zPW, zNameNew ? zNameNew : zName);
326326
/* shared_secret() func is undefined? */
327327
#endif
328328
}
329329
}
330330
331331
if( zInfo ){
332
- blob_appendf(&sql, ", info=%Q", zInfo);
332
+ blob_append_sql(&sql, ", info=%Q", zInfo);
333333
++gotFields;
334334
}
335335
336336
if((g.perm.Admin || g.perm.Setup)
337337
&& forceLogout && cson_value_get_bool(forceLogout)){
@@ -344,26 +344,26 @@
344344
"Required user data are missing.");
345345
goto error;
346346
}
347347
assert(uid>0);
348348
#if !TRY_LOGIN_GROUP
349
- blob_appendf(&sql, " WHERE uid=%d", uid);
349
+ blob_append_sql(&sql, " WHERE uid=%d", uid);
350350
#else /* need name for login group support :/ */
351
- blob_appendf(&sql, " WHERE login=%Q", zName);
351
+ blob_append_sql(&sql, " WHERE login=%Q", zName);
352352
#endif
353353
#if 0
354354
puts(blob_str(&sql));
355355
cson_output_FILE( cson_object_value(pUser), stdout, NULL );
356356
#endif
357
- db_prepare(&q, "%s", blob_str(&sql));
357
+ db_prepare(&q, "%s", blob_sql_text(&sql));
358358
db_exec(&q);
359359
db_finalize(&q);
360360
#if TRY_LOGIN_GROUP
361361
if( zPW || cson_value_get_bool(forceLogout) ){
362362
Blob groupSql = empty_blob;
363363
char * zErr = NULL;
364
- blob_appendf(&groupSql,
364
+ blob_append_sql(&groupSql,
365365
"INSERT INTO user(login)"
366366
" SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
367367
zName, zName
368368
);
369369
blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
370370
--- src/json_user.c
+++ src/json_user.c
@@ -286,11 +286,11 @@
286 /* reminders: 1) does not allocate.
287 2) we do this because changing a name
288 invalidates any login token because the old name
289 is part of the token hash.
290 */;
291 blob_appendf(&sql, ", login=%Q", zNameNew);
292 ++gotFields;
293 }
294 }
295
296 if( zCap && *zCap ){
@@ -298,11 +298,11 @@
298 /* we "could" arguably silently ignore cap in this case. */
299 json_set_err(FSL_JSON_E_DENIED,
300 "Changing capabilities requires 'a' or 's' privileges.");
301 goto error;
302 }
303 blob_appendf(&sql, ", cap=%Q", zCap);
304 ++gotFields;
305 }
306
307 if( zPW && *zPW ){
308 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
@@ -314,24 +314,24 @@
314 #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
315 #if !TRY_LOGIN_GROUP
316 char * zPWHash = NULL;
317 ++gotFields;
318 zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
319 blob_appendf(&sql, ", pw=%Q", zPWHash);
320 free(zPWHash);
321 #else
322 ++gotFields;
323 blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
324 "(SELECT value FROM config WHERE name='project-code')))",
325 zPW, zNameNew ? zNameNew : zName);
326 /* shared_secret() func is undefined? */
327 #endif
328 }
329 }
330
331 if( zInfo ){
332 blob_appendf(&sql, ", info=%Q", zInfo);
333 ++gotFields;
334 }
335
336 if((g.perm.Admin || g.perm.Setup)
337 && forceLogout && cson_value_get_bool(forceLogout)){
@@ -344,26 +344,26 @@
344 "Required user data are missing.");
345 goto error;
346 }
347 assert(uid>0);
348 #if !TRY_LOGIN_GROUP
349 blob_appendf(&sql, " WHERE uid=%d", uid);
350 #else /* need name for login group support :/ */
351 blob_appendf(&sql, " WHERE login=%Q", zName);
352 #endif
353 #if 0
354 puts(blob_str(&sql));
355 cson_output_FILE( cson_object_value(pUser), stdout, NULL );
356 #endif
357 db_prepare(&q, "%s", blob_str(&sql));
358 db_exec(&q);
359 db_finalize(&q);
360 #if TRY_LOGIN_GROUP
361 if( zPW || cson_value_get_bool(forceLogout) ){
362 Blob groupSql = empty_blob;
363 char * zErr = NULL;
364 blob_appendf(&groupSql,
365 "INSERT INTO user(login)"
366 " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
367 zName, zName
368 );
369 blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
370
--- src/json_user.c
+++ src/json_user.c
@@ -286,11 +286,11 @@
286 /* reminders: 1) does not allocate.
287 2) we do this because changing a name
288 invalidates any login token because the old name
289 is part of the token hash.
290 */;
291 blob_append_sql(&sql, ", login=%Q", zNameNew);
292 ++gotFields;
293 }
294 }
295
296 if( zCap && *zCap ){
@@ -298,11 +298,11 @@
298 /* we "could" arguably silently ignore cap in this case. */
299 json_set_err(FSL_JSON_E_DENIED,
300 "Changing capabilities requires 'a' or 's' privileges.");
301 goto error;
302 }
303 blob_append_sql(&sql, ", cap=%Q", zCap);
304 ++gotFields;
305 }
306
307 if( zPW && *zPW ){
308 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
@@ -314,24 +314,24 @@
314 #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
315 #if !TRY_LOGIN_GROUP
316 char * zPWHash = NULL;
317 ++gotFields;
318 zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
319 blob_append_sql(&sql, ", pw=%Q", zPWHash);
320 free(zPWHash);
321 #else
322 ++gotFields;
323 blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
324 "(SELECT value FROM config WHERE name='project-code')))",
325 zPW, zNameNew ? zNameNew : zName);
326 /* shared_secret() func is undefined? */
327 #endif
328 }
329 }
330
331 if( zInfo ){
332 blob_append_sql(&sql, ", info=%Q", zInfo);
333 ++gotFields;
334 }
335
336 if((g.perm.Admin || g.perm.Setup)
337 && forceLogout && cson_value_get_bool(forceLogout)){
@@ -344,26 +344,26 @@
344 "Required user data are missing.");
345 goto error;
346 }
347 assert(uid>0);
348 #if !TRY_LOGIN_GROUP
349 blob_append_sql(&sql, " WHERE uid=%d", uid);
350 #else /* need name for login group support :/ */
351 blob_append_sql(&sql, " WHERE login=%Q", zName);
352 #endif
353 #if 0
354 puts(blob_str(&sql));
355 cson_output_FILE( cson_object_value(pUser), stdout, NULL );
356 #endif
357 db_prepare(&q, "%s", blob_sql_text(&sql));
358 db_exec(&q);
359 db_finalize(&q);
360 #if TRY_LOGIN_GROUP
361 if( zPW || cson_value_get_bool(forceLogout) ){
362 Blob groupSql = empty_blob;
363 char * zErr = NULL;
364 blob_append_sql(&groupSql,
365 "INSERT INTO user(login)"
366 " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
367 zName, zName
368 );
369 blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
370
+5 -6
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -444,22 +444,21 @@
444444
" substr(tagname,6) as name"
445445
" FROM tag WHERE tagname GLOB 'wiki-*'",
446446
-1);
447447
zGlob = json_find_option_cstr("glob",NULL,"g");
448448
if(zGlob && *zGlob){
449
- blob_appendf(&sql," AND name %s GLOB %Q",
450
- fInvert ? "NOT" : "", zGlob);
449
+ blob_append_sql(&sql," AND name %s GLOB %Q",
450
+ fInvert ? "NOT" : "", zGlob);
451451
}else{
452452
zGlob = json_find_option_cstr("like",NULL,"l");
453453
if(zGlob && *zGlob){
454
- blob_appendf(&sql," AND name %s LIKE %Q",
455
- fInvert ? "NOT" : "",
456
- zGlob);
454
+ blob_append_sql(&sql," AND name %s LIKE %Q",
455
+ fInvert ? "NOT" : "", zGlob);
457456
}
458457
}
459458
blob_append(&sql," ORDER BY lower(name)", -1);
460
- db_prepare(&q,"%s", blob_str(&sql));
459
+ db_prepare(&q,"%s", blob_sql_text(&sql));
461460
blob_reset(&sql);
462461
listV = cson_value_new_array();
463462
list = cson_value_get_array(listV);
464463
while( SQLITE_ROW == db_step(&q) ){
465464
cson_value * v;
466465
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -444,22 +444,21 @@
444 " substr(tagname,6) as name"
445 " FROM tag WHERE tagname GLOB 'wiki-*'",
446 -1);
447 zGlob = json_find_option_cstr("glob",NULL,"g");
448 if(zGlob && *zGlob){
449 blob_appendf(&sql," AND name %s GLOB %Q",
450 fInvert ? "NOT" : "", zGlob);
451 }else{
452 zGlob = json_find_option_cstr("like",NULL,"l");
453 if(zGlob && *zGlob){
454 blob_appendf(&sql," AND name %s LIKE %Q",
455 fInvert ? "NOT" : "",
456 zGlob);
457 }
458 }
459 blob_append(&sql," ORDER BY lower(name)", -1);
460 db_prepare(&q,"%s", blob_str(&sql));
461 blob_reset(&sql);
462 listV = cson_value_new_array();
463 list = cson_value_get_array(listV);
464 while( SQLITE_ROW == db_step(&q) ){
465 cson_value * v;
466
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -444,22 +444,21 @@
444 " substr(tagname,6) as name"
445 " FROM tag WHERE tagname GLOB 'wiki-*'",
446 -1);
447 zGlob = json_find_option_cstr("glob",NULL,"g");
448 if(zGlob && *zGlob){
449 blob_append_sql(&sql," AND name %s GLOB %Q",
450 fInvert ? "NOT" : "", zGlob);
451 }else{
452 zGlob = json_find_option_cstr("like",NULL,"l");
453 if(zGlob && *zGlob){
454 blob_append_sql(&sql," AND name %s LIKE %Q",
455 fInvert ? "NOT" : "", zGlob);
 
456 }
457 }
458 blob_append(&sql," ORDER BY lower(name)", -1);
459 db_prepare(&q,"%s", blob_sql_text(&sql));
460 blob_reset(&sql);
461 listV = cson_value_new_array();
462 list = cson_value_get_array(listV);
463 while( SQLITE_ROW == db_step(&q) ){
464 cson_value * v;
465
+3 -2
--- src/leaf.c
+++ src/leaf.c
@@ -39,11 +39,12 @@
3939
@ AND coalesce((SELECT value FROM tagxref
4040
@ WHERE tagid=%d AND rid=plink.pid), 'trunk')
4141
@ =coalesce((SELECT value FROM tagxref
4242
@ WHERE tagid=%d AND rid=plink.cid), 'trunk')
4343
;
44
- rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
44
+ rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/,
45
+ rid, TAG_BRANCH, TAG_BRANCH);
4546
return rc==0;
4647
}
4748
4849
/*
4950
** Count the number of primary non-branch children for the given check-in.
@@ -63,11 +64,11 @@
6364
@ AND coalesce((SELECT value FROM tagxref
6465
@ WHERE tagid=%d AND rid=plink.pid), 'trunk')
6566
@ =coalesce((SELECT value FROM tagxref
6667
@ WHERE tagid=%d AND rid=plink.cid), 'trunk')
6768
;
68
- db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
69
+ db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH);
6970
db_bind_int(&q, ":pid", pid);
7071
if( db_step(&q)==SQLITE_ROW ){
7172
nNonBranch = db_column_int(&q, 0);
7273
}
7374
db_reset(&q);
7475
--- src/leaf.c
+++ src/leaf.c
@@ -39,11 +39,12 @@
39 @ AND coalesce((SELECT value FROM tagxref
40 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
41 @ =coalesce((SELECT value FROM tagxref
42 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
43 ;
44 rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
 
45 return rc==0;
46 }
47
48 /*
49 ** Count the number of primary non-branch children for the given check-in.
@@ -63,11 +64,11 @@
63 @ AND coalesce((SELECT value FROM tagxref
64 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
65 @ =coalesce((SELECT value FROM tagxref
66 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
67 ;
68 db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
69 db_bind_int(&q, ":pid", pid);
70 if( db_step(&q)==SQLITE_ROW ){
71 nNonBranch = db_column_int(&q, 0);
72 }
73 db_reset(&q);
74
--- src/leaf.c
+++ src/leaf.c
@@ -39,11 +39,12 @@
39 @ AND coalesce((SELECT value FROM tagxref
40 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
41 @ =coalesce((SELECT value FROM tagxref
42 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
43 ;
44 rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/,
45 rid, TAG_BRANCH, TAG_BRANCH);
46 return rc==0;
47 }
48
49 /*
50 ** Count the number of primary non-branch children for the given check-in.
@@ -63,11 +64,11 @@
64 @ AND coalesce((SELECT value FROM tagxref
65 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
66 @ =coalesce((SELECT value FROM tagxref
67 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
68 ;
69 db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH);
70 db_bind_int(&q, ":pid", pid);
71 if( db_step(&q)==SQLITE_ROW ){
72 nNonBranch = db_column_int(&q, 0);
73 }
74 db_reset(&q);
75
+14 -17
--- src/login.c
+++ src/login.c
@@ -93,15 +93,12 @@
9393
"SELECT 'fossil-' || substr(value,1,16)"
9494
" FROM config"
9595
" WHERE name IN ('project-code','login-group-code')"
9696
" ORDER BY name /*sort*/"
9797
);
98
- if( zCookieName==0 ){
99
- zCookieName = mprintf("fossil-0123456789abcdef");
100
- }
10198
}
102
- return zCookieName;
99
+ return zCookieName ? zCookieName : "unknown";
103100
}
104101
105102
/*
106103
** Redirect to the page specified by the "g" query parameter.
107104
** Or if there is no "g" query parameter, redirect to the homepage.
@@ -403,15 +400,15 @@
403400
/* If a URI appears in the User-Agent, it is probably a bot */
404401
if( strncmp("http", zAgent+i,4)==0 ) return 0;
405402
}
406403
if( strncmp(zAgent, "Mozilla/", 8)==0 ){
407404
if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
408
- if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
409
- if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
410
- if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
411
- if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
412
- if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
405
+ if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
406
+ if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
407
+ if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
408
+ if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
409
+ if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
413410
return 0;
414411
}
415412
if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
416413
if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
417414
if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1302,11 +1299,11 @@
13021299
}else{
13031300
char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
13041301
int uid;
13051302
db_multi_exec(
13061303
"INSERT INTO user(login,pw,cap,info,mtime)"
1307
- "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
1304
+ "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
13081305
&login, zPw, &caps, &contact
13091306
);
13101307
free(zPw);
13111308
13121309
/* The user is registered, now just log him in. */
@@ -1477,17 +1474,17 @@
14771474
*pzErrMsg = 0; /* Default to no errors */
14781475
zSelf = db_name("repository");
14791476
14801477
/* Get the full pathname of the other repository */
14811478
file_canonical_name(zRepo, &fullName, 0);
1482
- zRepo = mprintf(blob_str(&fullName));
1479
+ zRepo = fossil_strdup(blob_str(&fullName));
14831480
blob_reset(&fullName);
14841481
14851482
/* Get the full pathname for our repository. Also the project code
14861483
** and project name for ourself. */
14871484
file_canonical_name(g.zRepositoryName, &fullName, 0);
1488
- zSelfRepo = mprintf(blob_str(&fullName));
1485
+ zSelfRepo = fossil_strdup(blob_str(&fullName));
14891486
blob_reset(&fullName);
14901487
zSelfProjCode = db_get("project-code", "unknown");
14911488
zSelfLabel = db_get("project-name", 0);
14921489
if( zSelfLabel==0 ){
14931490
zSelfLabel = zSelfProjCode;
@@ -1508,11 +1505,11 @@
15081505
zRepo, &pOther,
15091506
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
15101507
g.zVfsName
15111508
);
15121509
if( rc!=SQLITE_OK ){
1513
- *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
1510
+ *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
15141511
}else{
15151512
rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
15161513
}
15171514
sqlite3_close(pOther);
15181515
if( rc ) return;
@@ -1541,13 +1538,13 @@
15411538
*/
15421539
zSelfProjCode = abbreviated_project_code(zSelfProjCode);
15431540
zOtherProjCode = abbreviated_project_code(zOtherProjCode);
15441541
db_begin_transaction();
15451542
db_multi_exec(
1546
- "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
1547
- "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
1548
- "INSERT INTO %s.config(name,value) "
1543
+ "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
1544
+ "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
1545
+ "INSERT INTO \"%w\".config(name,value) "
15491546
" SELECT 'peer-name-%q', value FROM other.config"
15501547
" WHERE name='project-name';",
15511548
zSelf,
15521549
zSelf, zOtherProjCode, zRepo,
15531550
zSelf, zOtherProjCode
@@ -1558,11 +1555,11 @@
15581555
"INSERT OR IGNORE INTO other.config(name,value)"
15591556
" VALUES('login-group-code',lower(hex(randomblob(8))));",
15601557
zNewName
15611558
);
15621559
db_multi_exec(
1563
- "REPLACE INTO %s.config(name,value)"
1560
+ "REPLACE INTO \"%w\".config(name,value)"
15641561
" SELECT name, value FROM other.config"
15651562
" WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
15661563
zSelf
15671564
);
15681565
db_end_transaction(0);
15691566
--- src/login.c
+++ src/login.c
@@ -93,15 +93,12 @@
93 "SELECT 'fossil-' || substr(value,1,16)"
94 " FROM config"
95 " WHERE name IN ('project-code','login-group-code')"
96 " ORDER BY name /*sort*/"
97 );
98 if( zCookieName==0 ){
99 zCookieName = mprintf("fossil-0123456789abcdef");
100 }
101 }
102 return zCookieName;
103 }
104
105 /*
106 ** Redirect to the page specified by the "g" query parameter.
107 ** Or if there is no "g" query parameter, redirect to the homepage.
@@ -403,15 +400,15 @@
403 /* If a URI appears in the User-Agent, it is probably a bot */
404 if( strncmp("http", zAgent+i,4)==0 ) return 0;
405 }
406 if( strncmp(zAgent, "Mozilla/", 8)==0 ){
407 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
408 if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
409 if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
410 if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
411 if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
412 if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
413 return 0;
414 }
415 if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
416 if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
417 if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1302,11 +1299,11 @@
1302 }else{
1303 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
1304 int uid;
1305 db_multi_exec(
1306 "INSERT INTO user(login,pw,cap,info,mtime)"
1307 "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
1308 &login, zPw, &caps, &contact
1309 );
1310 free(zPw);
1311
1312 /* The user is registered, now just log him in. */
@@ -1477,17 +1474,17 @@
1477 *pzErrMsg = 0; /* Default to no errors */
1478 zSelf = db_name("repository");
1479
1480 /* Get the full pathname of the other repository */
1481 file_canonical_name(zRepo, &fullName, 0);
1482 zRepo = mprintf(blob_str(&fullName));
1483 blob_reset(&fullName);
1484
1485 /* Get the full pathname for our repository. Also the project code
1486 ** and project name for ourself. */
1487 file_canonical_name(g.zRepositoryName, &fullName, 0);
1488 zSelfRepo = mprintf(blob_str(&fullName));
1489 blob_reset(&fullName);
1490 zSelfProjCode = db_get("project-code", "unknown");
1491 zSelfLabel = db_get("project-name", 0);
1492 if( zSelfLabel==0 ){
1493 zSelfLabel = zSelfProjCode;
@@ -1508,11 +1505,11 @@
1508 zRepo, &pOther,
1509 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1510 g.zVfsName
1511 );
1512 if( rc!=SQLITE_OK ){
1513 *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
1514 }else{
1515 rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
1516 }
1517 sqlite3_close(pOther);
1518 if( rc ) return;
@@ -1541,13 +1538,13 @@
1541 */
1542 zSelfProjCode = abbreviated_project_code(zSelfProjCode);
1543 zOtherProjCode = abbreviated_project_code(zOtherProjCode);
1544 db_begin_transaction();
1545 db_multi_exec(
1546 "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
1547 "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
1548 "INSERT INTO %s.config(name,value) "
1549 " SELECT 'peer-name-%q', value FROM other.config"
1550 " WHERE name='project-name';",
1551 zSelf,
1552 zSelf, zOtherProjCode, zRepo,
1553 zSelf, zOtherProjCode
@@ -1558,11 +1555,11 @@
1558 "INSERT OR IGNORE INTO other.config(name,value)"
1559 " VALUES('login-group-code',lower(hex(randomblob(8))));",
1560 zNewName
1561 );
1562 db_multi_exec(
1563 "REPLACE INTO %s.config(name,value)"
1564 " SELECT name, value FROM other.config"
1565 " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
1566 zSelf
1567 );
1568 db_end_transaction(0);
1569
--- src/login.c
+++ src/login.c
@@ -93,15 +93,12 @@
93 "SELECT 'fossil-' || substr(value,1,16)"
94 " FROM config"
95 " WHERE name IN ('project-code','login-group-code')"
96 " ORDER BY name /*sort*/"
97 );
 
 
 
98 }
99 return zCookieName ? zCookieName : "unknown";
100 }
101
102 /*
103 ** Redirect to the page specified by the "g" query parameter.
104 ** Or if there is no "g" query parameter, redirect to the homepage.
@@ -403,15 +400,15 @@
400 /* If a URI appears in the User-Agent, it is probably a bot */
401 if( strncmp("http", zAgent+i,4)==0 ) return 0;
402 }
403 if( strncmp(zAgent, "Mozilla/", 8)==0 ){
404 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
405 if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
406 if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
407 if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
408 if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
409 if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
410 return 0;
411 }
412 if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
413 if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
414 if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1302,11 +1299,11 @@
1299 }else{
1300 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
1301 int uid;
1302 db_multi_exec(
1303 "INSERT INTO user(login,pw,cap,info,mtime)"
1304 "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
1305 &login, zPw, &caps, &contact
1306 );
1307 free(zPw);
1308
1309 /* The user is registered, now just log him in. */
@@ -1477,17 +1474,17 @@
1474 *pzErrMsg = 0; /* Default to no errors */
1475 zSelf = db_name("repository");
1476
1477 /* Get the full pathname of the other repository */
1478 file_canonical_name(zRepo, &fullName, 0);
1479 zRepo = fossil_strdup(blob_str(&fullName));
1480 blob_reset(&fullName);
1481
1482 /* Get the full pathname for our repository. Also the project code
1483 ** and project name for ourself. */
1484 file_canonical_name(g.zRepositoryName, &fullName, 0);
1485 zSelfRepo = fossil_strdup(blob_str(&fullName));
1486 blob_reset(&fullName);
1487 zSelfProjCode = db_get("project-code", "unknown");
1488 zSelfLabel = db_get("project-name", 0);
1489 if( zSelfLabel==0 ){
1490 zSelfLabel = zSelfProjCode;
@@ -1508,11 +1505,11 @@
1505 zRepo, &pOther,
1506 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1507 g.zVfsName
1508 );
1509 if( rc!=SQLITE_OK ){
1510 *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
1511 }else{
1512 rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
1513 }
1514 sqlite3_close(pOther);
1515 if( rc ) return;
@@ -1541,13 +1538,13 @@
1538 */
1539 zSelfProjCode = abbreviated_project_code(zSelfProjCode);
1540 zOtherProjCode = abbreviated_project_code(zOtherProjCode);
1541 db_begin_transaction();
1542 db_multi_exec(
1543 "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
1544 "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
1545 "INSERT INTO \"%w\".config(name,value) "
1546 " SELECT 'peer-name-%q', value FROM other.config"
1547 " WHERE name='project-name';",
1548 zSelf,
1549 zSelf, zOtherProjCode, zRepo,
1550 zSelf, zOtherProjCode
@@ -1558,11 +1555,11 @@
1555 "INSERT OR IGNORE INTO other.config(name,value)"
1556 " VALUES('login-group-code',lower(hex(randomblob(8))));",
1557 zNewName
1558 );
1559 db_multi_exec(
1560 "REPLACE INTO \"%w\".config(name,value)"
1561 " SELECT name, value FROM other.config"
1562 " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
1563 zSelf
1564 );
1565 db_end_transaction(0);
1566
+14 -17
--- src/login.c
+++ src/login.c
@@ -93,15 +93,12 @@
9393
"SELECT 'fossil-' || substr(value,1,16)"
9494
" FROM config"
9595
" WHERE name IN ('project-code','login-group-code')"
9696
" ORDER BY name /*sort*/"
9797
);
98
- if( zCookieName==0 ){
99
- zCookieName = mprintf("fossil-0123456789abcdef");
100
- }
10198
}
102
- return zCookieName;
99
+ return zCookieName ? zCookieName : "unknown";
103100
}
104101
105102
/*
106103
** Redirect to the page specified by the "g" query parameter.
107104
** Or if there is no "g" query parameter, redirect to the homepage.
@@ -403,15 +400,15 @@
403400
/* If a URI appears in the User-Agent, it is probably a bot */
404401
if( strncmp("http", zAgent+i,4)==0 ) return 0;
405402
}
406403
if( strncmp(zAgent, "Mozilla/", 8)==0 ){
407404
if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
408
- if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
409
- if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
410
- if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
411
- if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
412
- if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
405
+ if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
406
+ if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
407
+ if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
408
+ if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
409
+ if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
413410
return 0;
414411
}
415412
if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
416413
if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
417414
if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1302,11 +1299,11 @@
13021299
}else{
13031300
char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
13041301
int uid;
13051302
db_multi_exec(
13061303
"INSERT INTO user(login,pw,cap,info,mtime)"
1307
- "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
1304
+ "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
13081305
&login, zPw, &caps, &contact
13091306
);
13101307
free(zPw);
13111308
13121309
/* The user is registered, now just log him in. */
@@ -1477,17 +1474,17 @@
14771474
*pzErrMsg = 0; /* Default to no errors */
14781475
zSelf = db_name("repository");
14791476
14801477
/* Get the full pathname of the other repository */
14811478
file_canonical_name(zRepo, &fullName, 0);
1482
- zRepo = mprintf(blob_str(&fullName));
1479
+ zRepo = fossil_strdup(blob_str(&fullName));
14831480
blob_reset(&fullName);
14841481
14851482
/* Get the full pathname for our repository. Also the project code
14861483
** and project name for ourself. */
14871484
file_canonical_name(g.zRepositoryName, &fullName, 0);
1488
- zSelfRepo = mprintf(blob_str(&fullName));
1485
+ zSelfRepo = fossil_strdup(blob_str(&fullName));
14891486
blob_reset(&fullName);
14901487
zSelfProjCode = db_get("project-code", "unknown");
14911488
zSelfLabel = db_get("project-name", 0);
14921489
if( zSelfLabel==0 ){
14931490
zSelfLabel = zSelfProjCode;
@@ -1508,11 +1505,11 @@
15081505
zRepo, &pOther,
15091506
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
15101507
g.zVfsName
15111508
);
15121509
if( rc!=SQLITE_OK ){
1513
- *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
1510
+ *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
15141511
}else{
15151512
rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
15161513
}
15171514
sqlite3_close(pOther);
15181515
if( rc ) return;
@@ -1541,13 +1538,13 @@
15411538
*/
15421539
zSelfProjCode = abbreviated_project_code(zSelfProjCode);
15431540
zOtherProjCode = abbreviated_project_code(zOtherProjCode);
15441541
db_begin_transaction();
15451542
db_multi_exec(
1546
- "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
1547
- "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
1548
- "INSERT INTO %s.config(name,value) "
1543
+ "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
1544
+ "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
1545
+ "INSERT INTO \"%w\".config(name,value) "
15491546
" SELECT 'peer-name-%q', value FROM other.config"
15501547
" WHERE name='project-name';",
15511548
zSelf,
15521549
zSelf, zOtherProjCode, zRepo,
15531550
zSelf, zOtherProjCode
@@ -1558,11 +1555,11 @@
15581555
"INSERT OR IGNORE INTO other.config(name,value)"
15591556
" VALUES('login-group-code',lower(hex(randomblob(8))));",
15601557
zNewName
15611558
);
15621559
db_multi_exec(
1563
- "REPLACE INTO %s.config(name,value)"
1560
+ "REPLACE INTO \"%w\".config(name,value)"
15641561
" SELECT name, value FROM other.config"
15651562
" WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
15661563
zSelf
15671564
);
15681565
db_end_transaction(0);
15691566
--- src/login.c
+++ src/login.c
@@ -93,15 +93,12 @@
93 "SELECT 'fossil-' || substr(value,1,16)"
94 " FROM config"
95 " WHERE name IN ('project-code','login-group-code')"
96 " ORDER BY name /*sort*/"
97 );
98 if( zCookieName==0 ){
99 zCookieName = mprintf("fossil-0123456789abcdef");
100 }
101 }
102 return zCookieName;
103 }
104
105 /*
106 ** Redirect to the page specified by the "g" query parameter.
107 ** Or if there is no "g" query parameter, redirect to the homepage.
@@ -403,15 +400,15 @@
403 /* If a URI appears in the User-Agent, it is probably a bot */
404 if( strncmp("http", zAgent+i,4)==0 ) return 0;
405 }
406 if( strncmp(zAgent, "Mozilla/", 8)==0 ){
407 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
408 if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
409 if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
410 if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
411 if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
412 if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
413 return 0;
414 }
415 if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
416 if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
417 if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1302,11 +1299,11 @@
1302 }else{
1303 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
1304 int uid;
1305 db_multi_exec(
1306 "INSERT INTO user(login,pw,cap,info,mtime)"
1307 "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
1308 &login, zPw, &caps, &contact
1309 );
1310 free(zPw);
1311
1312 /* The user is registered, now just log him in. */
@@ -1477,17 +1474,17 @@
1477 *pzErrMsg = 0; /* Default to no errors */
1478 zSelf = db_name("repository");
1479
1480 /* Get the full pathname of the other repository */
1481 file_canonical_name(zRepo, &fullName, 0);
1482 zRepo = mprintf(blob_str(&fullName));
1483 blob_reset(&fullName);
1484
1485 /* Get the full pathname for our repository. Also the project code
1486 ** and project name for ourself. */
1487 file_canonical_name(g.zRepositoryName, &fullName, 0);
1488 zSelfRepo = mprintf(blob_str(&fullName));
1489 blob_reset(&fullName);
1490 zSelfProjCode = db_get("project-code", "unknown");
1491 zSelfLabel = db_get("project-name", 0);
1492 if( zSelfLabel==0 ){
1493 zSelfLabel = zSelfProjCode;
@@ -1508,11 +1505,11 @@
1508 zRepo, &pOther,
1509 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1510 g.zVfsName
1511 );
1512 if( rc!=SQLITE_OK ){
1513 *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
1514 }else{
1515 rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
1516 }
1517 sqlite3_close(pOther);
1518 if( rc ) return;
@@ -1541,13 +1538,13 @@
1541 */
1542 zSelfProjCode = abbreviated_project_code(zSelfProjCode);
1543 zOtherProjCode = abbreviated_project_code(zOtherProjCode);
1544 db_begin_transaction();
1545 db_multi_exec(
1546 "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
1547 "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
1548 "INSERT INTO %s.config(name,value) "
1549 " SELECT 'peer-name-%q', value FROM other.config"
1550 " WHERE name='project-name';",
1551 zSelf,
1552 zSelf, zOtherProjCode, zRepo,
1553 zSelf, zOtherProjCode
@@ -1558,11 +1555,11 @@
1558 "INSERT OR IGNORE INTO other.config(name,value)"
1559 " VALUES('login-group-code',lower(hex(randomblob(8))));",
1560 zNewName
1561 );
1562 db_multi_exec(
1563 "REPLACE INTO %s.config(name,value)"
1564 " SELECT name, value FROM other.config"
1565 " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
1566 zSelf
1567 );
1568 db_end_transaction(0);
1569
--- src/login.c
+++ src/login.c
@@ -93,15 +93,12 @@
93 "SELECT 'fossil-' || substr(value,1,16)"
94 " FROM config"
95 " WHERE name IN ('project-code','login-group-code')"
96 " ORDER BY name /*sort*/"
97 );
 
 
 
98 }
99 return zCookieName ? zCookieName : "unknown";
100 }
101
102 /*
103 ** Redirect to the page specified by the "g" query parameter.
104 ** Or if there is no "g" query parameter, redirect to the homepage.
@@ -403,15 +400,15 @@
400 /* If a URI appears in the User-Agent, it is probably a bot */
401 if( strncmp("http", zAgent+i,4)==0 ) return 0;
402 }
403 if( strncmp(zAgent, "Mozilla/", 8)==0 ){
404 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
405 if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
406 if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
407 if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
408 if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
409 if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
410 return 0;
411 }
412 if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
413 if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
414 if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1302,11 +1299,11 @@
1299 }else{
1300 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
1301 int uid;
1302 db_multi_exec(
1303 "INSERT INTO user(login,pw,cap,info,mtime)"
1304 "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
1305 &login, zPw, &caps, &contact
1306 );
1307 free(zPw);
1308
1309 /* The user is registered, now just log him in. */
@@ -1477,17 +1474,17 @@
1474 *pzErrMsg = 0; /* Default to no errors */
1475 zSelf = db_name("repository");
1476
1477 /* Get the full pathname of the other repository */
1478 file_canonical_name(zRepo, &fullName, 0);
1479 zRepo = fossil_strdup(blob_str(&fullName));
1480 blob_reset(&fullName);
1481
1482 /* Get the full pathname for our repository. Also the project code
1483 ** and project name for ourself. */
1484 file_canonical_name(g.zRepositoryName, &fullName, 0);
1485 zSelfRepo = fossil_strdup(blob_str(&fullName));
1486 blob_reset(&fullName);
1487 zSelfProjCode = db_get("project-code", "unknown");
1488 zSelfLabel = db_get("project-name", 0);
1489 if( zSelfLabel==0 ){
1490 zSelfLabel = zSelfProjCode;
@@ -1508,11 +1505,11 @@
1505 zRepo, &pOther,
1506 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1507 g.zVfsName
1508 );
1509 if( rc!=SQLITE_OK ){
1510 *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
1511 }else{
1512 rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
1513 }
1514 sqlite3_close(pOther);
1515 if( rc ) return;
@@ -1541,13 +1538,13 @@
1538 */
1539 zSelfProjCode = abbreviated_project_code(zSelfProjCode);
1540 zOtherProjCode = abbreviated_project_code(zOtherProjCode);
1541 db_begin_transaction();
1542 db_multi_exec(
1543 "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
1544 "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
1545 "INSERT INTO \"%w\".config(name,value) "
1546 " SELECT 'peer-name-%q', value FROM other.config"
1547 " WHERE name='project-name';",
1548 zSelf,
1549 zSelf, zOtherProjCode, zRepo,
1550 zSelf, zOtherProjCode
@@ -1558,11 +1555,11 @@
1555 "INSERT OR IGNORE INTO other.config(name,value)"
1556 " VALUES('login-group-code',lower(hex(randomblob(8))));",
1557 zNewName
1558 );
1559 db_multi_exec(
1560 "REPLACE INTO \"%w\".config(name,value)"
1561 " SELECT name, value FROM other.config"
1562 " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
1563 zSelf
1564 );
1565 db_end_transaction(0);
1566
+9 -8
--- src/main.c
+++ src/main.c
@@ -169,11 +169,11 @@
169169
int xlinkClusterOnly; /* Set when cloning. Only process clusters */
170170
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
171171
int *aCommitFile; /* Array of files to be committed */
172172
int markPrivate; /* All new artifacts are private if true */
173173
int clockSkewSeen; /* True if clocks on client and server out of sync */
174
- int wikiFlags; /* Wiki conversion flags applied to %w and %W */
174
+ int wikiFlags; /* Wiki conversion flags applied to %W */
175175
char isHTTP; /* True if server/CGI modes, else assume CLI. */
176176
char javascriptHyperlink; /* If true, set href= using script, not HTML */
177177
Blob httpHeader; /* Complete text of the HTTP request header */
178178
UrlData url; /* Information about current URL */
179179
const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -1694,13 +1694,13 @@
16941694
/* If the CGI program contains one or more lines of the form
16951695
**
16961696
** redirect: repository-filename http://hostname/path/%s
16971697
**
16981698
** then control jumps here. Search each repository for an artifact ID
1699
-** that matches the "name" CGI parameter and for the first match,
1700
-** redirect to the corresponding URL with the "name" CGI parameter
1701
-** inserted. Paint an error page if no match is found.
1699
+** or ticket ID that matches the "name" CGI parameter and for the
1700
+** first match, redirect to the corresponding URL with the "name" CGI
1701
+** parameter inserted. Paint an error page if no match is found.
17021702
**
17031703
** If there is a line of the form:
17041704
**
17051705
** redirect: * URL
17061706
**
@@ -1721,19 +1721,20 @@
17211721
if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
17221722
zNotFound = azRedirect[i*2+1];
17231723
continue;
17241724
}
17251725
db_open_repository(azRedirect[i*2]);
1726
- if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){
1727
- cgi_redirectf(azRedirect[i*2+1], zName);
1726
+ if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) ||
1727
+ db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
1728
+ cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName);
17281729
return;
17291730
}
17301731
db_close(1);
17311732
}
17321733
}
17331734
if( zNotFound ){
1734
- cgi_redirectf(zNotFound, zName);
1735
+ cgi_redirectf(zNotFound /*works-like:"%s"*/, zName);
17351736
}else{
17361737
@ <html>
17371738
@ <head><title>No Such Object</title></head>
17381739
@ <body>
17391740
@ <p>No such object: <b>%h(zName)</b></p>
@@ -2199,11 +2200,11 @@
21992200
}else{
22002201
zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser);
22012202
}
22022203
if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
22032204
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
2204
- }else{
2205
+ }else if( g.db ){
22052206
db_setup_server_and_project_codes(1);
22062207
}
22072208
db_close(1);
22082209
if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
22092210
fossil_fatal("unable to listen on TCP socket %d", iPort);
22102211
--- src/main.c
+++ src/main.c
@@ -169,11 +169,11 @@
169 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
170 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
171 int *aCommitFile; /* Array of files to be committed */
172 int markPrivate; /* All new artifacts are private if true */
173 int clockSkewSeen; /* True if clocks on client and server out of sync */
174 int wikiFlags; /* Wiki conversion flags applied to %w and %W */
175 char isHTTP; /* True if server/CGI modes, else assume CLI. */
176 char javascriptHyperlink; /* If true, set href= using script, not HTML */
177 Blob httpHeader; /* Complete text of the HTTP request header */
178 UrlData url; /* Information about current URL */
179 const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -1694,13 +1694,13 @@
1694 /* If the CGI program contains one or more lines of the form
1695 **
1696 ** redirect: repository-filename http://hostname/path/%s
1697 **
1698 ** then control jumps here. Search each repository for an artifact ID
1699 ** that matches the "name" CGI parameter and for the first match,
1700 ** redirect to the corresponding URL with the "name" CGI parameter
1701 ** inserted. Paint an error page if no match is found.
1702 **
1703 ** If there is a line of the form:
1704 **
1705 ** redirect: * URL
1706 **
@@ -1721,19 +1721,20 @@
1721 if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
1722 zNotFound = azRedirect[i*2+1];
1723 continue;
1724 }
1725 db_open_repository(azRedirect[i*2]);
1726 if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){
1727 cgi_redirectf(azRedirect[i*2+1], zName);
 
1728 return;
1729 }
1730 db_close(1);
1731 }
1732 }
1733 if( zNotFound ){
1734 cgi_redirectf(zNotFound, zName);
1735 }else{
1736 @ <html>
1737 @ <head><title>No Such Object</title></head>
1738 @ <body>
1739 @ <p>No such object: <b>%h(zName)</b></p>
@@ -2199,11 +2200,11 @@
2199 }else{
2200 zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser);
2201 }
2202 if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
2203 if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
2204 }else{
2205 db_setup_server_and_project_codes(1);
2206 }
2207 db_close(1);
2208 if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
2209 fossil_fatal("unable to listen on TCP socket %d", iPort);
2210
--- src/main.c
+++ src/main.c
@@ -169,11 +169,11 @@
169 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
170 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
171 int *aCommitFile; /* Array of files to be committed */
172 int markPrivate; /* All new artifacts are private if true */
173 int clockSkewSeen; /* True if clocks on client and server out of sync */
174 int wikiFlags; /* Wiki conversion flags applied to %W */
175 char isHTTP; /* True if server/CGI modes, else assume CLI. */
176 char javascriptHyperlink; /* If true, set href= using script, not HTML */
177 Blob httpHeader; /* Complete text of the HTTP request header */
178 UrlData url; /* Information about current URL */
179 const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -1694,13 +1694,13 @@
1694 /* If the CGI program contains one or more lines of the form
1695 **
1696 ** redirect: repository-filename http://hostname/path/%s
1697 **
1698 ** then control jumps here. Search each repository for an artifact ID
1699 ** or ticket ID that matches the "name" CGI parameter and for the
1700 ** first match, redirect to the corresponding URL with the "name" CGI
1701 ** parameter inserted. Paint an error page if no match is found.
1702 **
1703 ** If there is a line of the form:
1704 **
1705 ** redirect: * URL
1706 **
@@ -1721,19 +1721,20 @@
1721 if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
1722 zNotFound = azRedirect[i*2+1];
1723 continue;
1724 }
1725 db_open_repository(azRedirect[i*2]);
1726 if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) ||
1727 db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
1728 cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName);
1729 return;
1730 }
1731 db_close(1);
1732 }
1733 }
1734 if( zNotFound ){
1735 cgi_redirectf(zNotFound /*works-like:"%s"*/, zName);
1736 }else{
1737 @ <html>
1738 @ <head><title>No Such Object</title></head>
1739 @ <body>
1740 @ <p>No such object: <b>%h(zName)</b></p>
@@ -2199,11 +2200,11 @@
2200 }else{
2201 zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser);
2202 }
2203 if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
2204 if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
2205 }else if( g.db ){
2206 db_setup_server_and_project_codes(1);
2207 }
2208 db_close(1);
2209 if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
2210 fossil_fatal("unable to listen on TCP socket %d", iPort);
2211
+30 -2
--- src/main.mk
+++ src/main.mk
@@ -20,10 +20,11 @@
2020
$(SRCDIR)/bag.c \
2121
$(SRCDIR)/bisect.c \
2222
$(SRCDIR)/blob.c \
2323
$(SRCDIR)/branch.c \
2424
$(SRCDIR)/browse.c \
25
+ $(SRCDIR)/builtin.c \
2526
$(SRCDIR)/cache.c \
2627
$(SRCDIR)/captcha.c \
2728
$(SRCDIR)/cgi.c \
2829
$(SRCDIR)/checkin.c \
2930
$(SRCDIR)/checkout.c \
@@ -124,19 +125,23 @@
124125
$(SRCDIR)/wysiwyg.c \
125126
$(SRCDIR)/xfer.c \
126127
$(SRCDIR)/xfersetup.c \
127128
$(SRCDIR)/zip.c
128129
130
+EXTRA_FILES = \
131
+ $(SRCDIR)/diff.tcl
132
+
129133
TRANS_SRC = \
130134
$(OBJDIR)/add_.c \
131135
$(OBJDIR)/allrepo_.c \
132136
$(OBJDIR)/attach_.c \
133137
$(OBJDIR)/bag_.c \
134138
$(OBJDIR)/bisect_.c \
135139
$(OBJDIR)/blob_.c \
136140
$(OBJDIR)/branch_.c \
137141
$(OBJDIR)/browse_.c \
142
+ $(OBJDIR)/builtin_.c \
138143
$(OBJDIR)/cache_.c \
139144
$(OBJDIR)/captcha_.c \
140145
$(OBJDIR)/cgi_.c \
141146
$(OBJDIR)/checkin_.c \
142147
$(OBJDIR)/checkout_.c \
@@ -246,10 +251,11 @@
246251
$(OBJDIR)/bag.o \
247252
$(OBJDIR)/bisect.o \
248253
$(OBJDIR)/blob.o \
249254
$(OBJDIR)/branch.o \
250255
$(OBJDIR)/browse.o \
256
+ $(OBJDIR)/builtin.o \
251257
$(OBJDIR)/cache.o \
252258
$(OBJDIR)/captcha.o \
253259
$(OBJDIR)/cgi.o \
254260
$(OBJDIR)/checkin.o \
255261
$(OBJDIR)/checkout.o \
@@ -360,10 +366,13 @@
360366
361367
install: $(APPNAME)
362368
mkdir -p $(INSTALLDIR)
363369
mv $(APPNAME) $(INSTALLDIR)
364370
371
+codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
372
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
373
+
365374
$(OBJDIR):
366375
-mkdir $(OBJDIR)
367376
368377
$(OBJDIR)/translate: $(SRCDIR)/translate.c
369378
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -372,13 +381,19 @@
372381
$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c
373382
374383
$(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c
375384
$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
376385
386
+$(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c
387
+ $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c
388
+
377389
$(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
378390
$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
379391
392
+$(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
393
+ $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
394
+
380395
# WARNING. DANGER. Running the test suite modifies the repository the
381396
# build is done from, i.e. the checkout belongs to. Do not sync/push
382397
# the repository after running the tests.
383398
test: $(OBJDIR) $(APPNAME)
384399
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -430,11 +445,12 @@
430445
$(OBJDIR)/th_lang.o \
431446
$(OBJDIR)/th_tcl.o \
432447
$(OBJDIR)/cson_amalgamation.o
433448
434449
435
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
450
+$(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
451
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
436452
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
437453
438454
# This rule prevents make from using its default rules to try build
439455
# an executable named "manifest" out of the file named "manifest.c"
440456
#
@@ -445,19 +461,24 @@
445461
rm -rf $(OBJDIR)/* $(APPNAME)
446462
447463
448464
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
449465
$(OBJDIR)/mkindex $(TRANS_SRC) >$@
450
-$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
466
+
467
+$(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES)
468
+ $(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@
469
+
470
+$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
451471
$(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
452472
$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
453473
$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
454474
$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
455475
$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
456476
$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
457477
$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
458478
$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
479
+ $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
459480
$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
460481
$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
461482
$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
462483
$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
463484
$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -620,10 +641,17 @@
620641
621642
$(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
622643
$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
623644
624645
$(OBJDIR)/browse.h: $(OBJDIR)/headers
646
+$(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(OBJDIR)/translate
647
+ $(OBJDIR)/translate $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c
648
+
649
+$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
650
+ $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
651
+
652
+$(OBJDIR)/builtin.h: $(OBJDIR)/headers
625653
$(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate
626654
$(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
627655
628656
$(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
629657
$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c
630658
--- src/main.mk
+++ src/main.mk
@@ -20,10 +20,11 @@
20 $(SRCDIR)/bag.c \
21 $(SRCDIR)/bisect.c \
22 $(SRCDIR)/blob.c \
23 $(SRCDIR)/branch.c \
24 $(SRCDIR)/browse.c \
 
25 $(SRCDIR)/cache.c \
26 $(SRCDIR)/captcha.c \
27 $(SRCDIR)/cgi.c \
28 $(SRCDIR)/checkin.c \
29 $(SRCDIR)/checkout.c \
@@ -124,19 +125,23 @@
124 $(SRCDIR)/wysiwyg.c \
125 $(SRCDIR)/xfer.c \
126 $(SRCDIR)/xfersetup.c \
127 $(SRCDIR)/zip.c
128
 
 
 
129 TRANS_SRC = \
130 $(OBJDIR)/add_.c \
131 $(OBJDIR)/allrepo_.c \
132 $(OBJDIR)/attach_.c \
133 $(OBJDIR)/bag_.c \
134 $(OBJDIR)/bisect_.c \
135 $(OBJDIR)/blob_.c \
136 $(OBJDIR)/branch_.c \
137 $(OBJDIR)/browse_.c \
 
138 $(OBJDIR)/cache_.c \
139 $(OBJDIR)/captcha_.c \
140 $(OBJDIR)/cgi_.c \
141 $(OBJDIR)/checkin_.c \
142 $(OBJDIR)/checkout_.c \
@@ -246,10 +251,11 @@
246 $(OBJDIR)/bag.o \
247 $(OBJDIR)/bisect.o \
248 $(OBJDIR)/blob.o \
249 $(OBJDIR)/branch.o \
250 $(OBJDIR)/browse.o \
 
251 $(OBJDIR)/cache.o \
252 $(OBJDIR)/captcha.o \
253 $(OBJDIR)/cgi.o \
254 $(OBJDIR)/checkin.o \
255 $(OBJDIR)/checkout.o \
@@ -360,10 +366,13 @@
360
361 install: $(APPNAME)
362 mkdir -p $(INSTALLDIR)
363 mv $(APPNAME) $(INSTALLDIR)
364
 
 
 
365 $(OBJDIR):
366 -mkdir $(OBJDIR)
367
368 $(OBJDIR)/translate: $(SRCDIR)/translate.c
369 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -372,13 +381,19 @@
372 $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c
373
374 $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c
375 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
376
 
 
 
377 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
378 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
379
 
 
 
380 # WARNING. DANGER. Running the test suite modifies the repository the
381 # build is done from, i.e. the checkout belongs to. Do not sync/push
382 # the repository after running the tests.
383 test: $(OBJDIR) $(APPNAME)
384 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -430,11 +445,12 @@
430 $(OBJDIR)/th_lang.o \
431 $(OBJDIR)/th_tcl.o \
432 $(OBJDIR)/cson_amalgamation.o
433
434
435 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
 
436 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
437
438 # This rule prevents make from using its default rules to try build
439 # an executable named "manifest" out of the file named "manifest.c"
440 #
@@ -445,19 +461,24 @@
445 rm -rf $(OBJDIR)/* $(APPNAME)
446
447
448 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
449 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
450 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
 
 
 
 
451 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
452 $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
453 $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
454 $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
455 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
456 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
457 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
458 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
 
459 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
460 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
461 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
462 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
463 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -620,10 +641,17 @@
620
621 $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
622 $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
623
624 $(OBJDIR)/browse.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
625 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate
626 $(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
627
628 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
629 $(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c
630
--- src/main.mk
+++ src/main.mk
@@ -20,10 +20,11 @@
20 $(SRCDIR)/bag.c \
21 $(SRCDIR)/bisect.c \
22 $(SRCDIR)/blob.c \
23 $(SRCDIR)/branch.c \
24 $(SRCDIR)/browse.c \
25 $(SRCDIR)/builtin.c \
26 $(SRCDIR)/cache.c \
27 $(SRCDIR)/captcha.c \
28 $(SRCDIR)/cgi.c \
29 $(SRCDIR)/checkin.c \
30 $(SRCDIR)/checkout.c \
@@ -124,19 +125,23 @@
125 $(SRCDIR)/wysiwyg.c \
126 $(SRCDIR)/xfer.c \
127 $(SRCDIR)/xfersetup.c \
128 $(SRCDIR)/zip.c
129
130 EXTRA_FILES = \
131 $(SRCDIR)/diff.tcl
132
133 TRANS_SRC = \
134 $(OBJDIR)/add_.c \
135 $(OBJDIR)/allrepo_.c \
136 $(OBJDIR)/attach_.c \
137 $(OBJDIR)/bag_.c \
138 $(OBJDIR)/bisect_.c \
139 $(OBJDIR)/blob_.c \
140 $(OBJDIR)/branch_.c \
141 $(OBJDIR)/browse_.c \
142 $(OBJDIR)/builtin_.c \
143 $(OBJDIR)/cache_.c \
144 $(OBJDIR)/captcha_.c \
145 $(OBJDIR)/cgi_.c \
146 $(OBJDIR)/checkin_.c \
147 $(OBJDIR)/checkout_.c \
@@ -246,10 +251,11 @@
251 $(OBJDIR)/bag.o \
252 $(OBJDIR)/bisect.o \
253 $(OBJDIR)/blob.o \
254 $(OBJDIR)/branch.o \
255 $(OBJDIR)/browse.o \
256 $(OBJDIR)/builtin.o \
257 $(OBJDIR)/cache.o \
258 $(OBJDIR)/captcha.o \
259 $(OBJDIR)/cgi.o \
260 $(OBJDIR)/checkin.o \
261 $(OBJDIR)/checkout.o \
@@ -360,10 +366,13 @@
366
367 install: $(APPNAME)
368 mkdir -p $(INSTALLDIR)
369 mv $(APPNAME) $(INSTALLDIR)
370
371 codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
372 $(OBJDIR)/codecheck1 $(TRANS_SRC)
373
374 $(OBJDIR):
375 -mkdir $(OBJDIR)
376
377 $(OBJDIR)/translate: $(SRCDIR)/translate.c
378 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -372,13 +381,19 @@
381 $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c
382
383 $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c
384 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
385
386 $(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c
387 $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c
388
389 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
390 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
391
392 $(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
393 $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
394
395 # WARNING. DANGER. Running the test suite modifies the repository the
396 # build is done from, i.e. the checkout belongs to. Do not sync/push
397 # the repository after running the tests.
398 test: $(OBJDIR) $(APPNAME)
399 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -430,11 +445,12 @@
445 $(OBJDIR)/th_lang.o \
446 $(OBJDIR)/th_tcl.o \
447 $(OBJDIR)/cson_amalgamation.o
448
449
450 $(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
451 $(OBJDIR)/codecheck1 $(TRANS_SRC)
452 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
453
454 # This rule prevents make from using its default rules to try build
455 # an executable named "manifest" out of the file named "manifest.c"
456 #
@@ -445,19 +461,24 @@
461 rm -rf $(OBJDIR)/* $(APPNAME)
462
463
464 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
465 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
466
467 $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES)
468 $(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@
469
470 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
471 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
472 $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
473 $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
474 $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
475 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
476 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
477 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
478 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
479 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
480 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
481 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
482 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
483 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
484 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -620,10 +641,17 @@
641
642 $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
643 $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
644
645 $(OBJDIR)/browse.h: $(OBJDIR)/headers
646 $(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(OBJDIR)/translate
647 $(OBJDIR)/translate $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c
648
649 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
650 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
651
652 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
653 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate
654 $(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
655
656 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
657 $(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c
658
+140 -26
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -12,12 +12,15 @@
1212
# tclsh makemake.tcl
1313
#
1414
#############################################################################
1515
1616
# Basenames of all source files that get preprocessed using
17
-# "translate" and "makeheaders". To add new source files to the
17
+# "translate" and "makeheaders". To add new C-language source files to the
1818
# project, simply add the basename to this list and rerun this script.
19
+#
20
+# Set the separate extra_files variable further down for how to add non-C
21
+# files, such as string and BLOB resources.
1922
#
2023
set src {
2124
add
2225
allrepo
2326
attach
@@ -24,10 +27,11 @@
2427
bag
2528
bisect
2629
blob
2730
branch
2831
browse
32
+ builtin
2933
cache
3034
captcha
3135
cgi
3236
checkin
3337
checkout
@@ -128,10 +132,16 @@
128132
xfer
129133
xfersetup
130134
zip
131135
http_ssl
132136
}
137
+
138
+# Additional resource files that get built into the executable.
139
+#
140
+set extra_files {
141
+ diff.tcl
142
+}
133143
134144
# Options used to compile the included SQLite library.
135145
#
136146
set SQLITE_OPTIONS {
137147
-DNDEBUG=1
@@ -217,10 +227,15 @@
217227
}
218228
writeln -nonewline "SRC ="
219229
foreach s [lsort $src] {
220230
writeln -nonewline " \\\n \$(SRCDIR)/$s.c"
221231
}
232
+writeln "\n"
233
+writeln -nonewline "EXTRA_FILES ="
234
+foreach s [lsort $extra_files] {
235
+ writeln -nonewline " \\\n \$(SRCDIR)/$s"
236
+}
222237
writeln "\n"
223238
writeln -nonewline "TRANS_SRC ="
224239
foreach s [lsort $src] {
225240
writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c"
226241
}
@@ -241,10 +256,13 @@
241256
242257
install: $(APPNAME)
243258
mkdir -p $(INSTALLDIR)
244259
mv $(APPNAME) $(INSTALLDIR)
245260
261
+codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
262
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
263
+
246264
$(OBJDIR):
247265
-mkdir $(OBJDIR)
248266
249267
$(OBJDIR)/translate: $(SRCDIR)/translate.c
250268
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -253,13 +271,19 @@
253271
$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c
254272
255273
$(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c
256274
$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
257275
276
+$(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c
277
+ $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c
278
+
258279
$(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
259280
$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
260281
282
+$(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
283
+ $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
284
+
261285
# WARNING. DANGER. Running the test suite modifies the repository the
262286
# build is done from, i.e. the checkout belongs to. Do not sync/push
263287
# the repository after running the tests.
264288
test: $(OBJDIR) $(APPNAME)
265289
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -304,11 +328,12 @@
304328
$(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
305329
$(OBJDIR)/cson_amalgamation.o
306330
}]
307331
308332
writeln {
309
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
333
+$(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
334
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
310335
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
311336
312337
# This rule prevents make from using its default rules to try build
313338
# an executable named "manifest" out of the file named "manifest.c"
314339
#
@@ -329,18 +354,23 @@
329354
append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>"
330355
#append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>"
331356
append mhargs "\$(OBJDIR)/VERSION.h"
332357
set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs]
333358
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
334
-writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@"
335
-writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
359
+writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@\n"
360
+
361
+writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)"
362
+writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >$@\n"
363
+
364
+writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
336365
writeln "\t\$(OBJDIR)/makeheaders $mhargs"
337366
writeln "\ttouch \$(OBJDIR)/headers"
338367
writeln "\$(OBJDIR)/headers: Makefile"
339368
writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h"
340369
writeln "Makefile:"
341370
set extra_h(main) " \$(OBJDIR)/page_index.h "
371
+set extra_h(builtin) " \$(OBJDIR)/builtin_data.h "
342372
343373
foreach s [lsort $src] {
344374
writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
345375
writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
346376
writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
@@ -505,12 +535,12 @@
505535
#### The directories where the OpenSSL include and library files are located.
506536
# The recommended usage here is to use the Sysinternals junction tool
507537
# to create a hard link between an "openssl-1.x" sub-directory of the
508538
# Fossil source code directory and the target OpenSSL source directory.
509539
#
510
-OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
511
-OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
540
+OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
541
+OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
512542
513543
#### Either the directory where the Tcl library is installed or the Tcl
514544
# source code directory resides (depending on the value of the macro
515545
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
516546
# this directory must have "include" and "lib" sub-directories. If
@@ -726,10 +756,15 @@
726756
}
727757
writeln -nonewline "SRC ="
728758
foreach s [lsort $src] {
729759
writeln -nonewline " \\\n \$(SRCDIR)/$s.c"
730760
}
761
+writeln "\n"
762
+writeln -nonewline "EXTRA_FILES ="
763
+foreach s [lsort $extra_files] {
764
+ writeln -nonewline " \\\n \$(SRCDIR)/$s"
765
+}
731766
writeln "\n"
732767
writeln -nonewline "TRANS_SRC ="
733768
foreach s [lsort $src] {
734769
writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c"
735770
}
@@ -752,11 +787,13 @@
752787
#
753788
ifdef USE_WINDOWS
754789
TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
755790
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
756791
MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
757
-VERSION = $(subst /,\,$(OBJDIR)/version.exe)
792
+MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
793
+MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe)
794
+CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
758795
CAT = type
759796
CP = copy
760797
GREP = find
761798
MV = copy
762799
RM = del /Q
@@ -764,11 +801,13 @@
764801
RMDIR = rmdir /S /Q
765802
else
766803
TRANSLATE = $(OBJDIR)/translate.exe
767804
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
768805
MKINDEX = $(OBJDIR)/mkindex.exe
769
-VERSION = $(OBJDIR)/version.exe
806
+MKBUILTIN = $(OBJDIR)/mkbuiltin.exe
807
+MKVERSION = $(OBJDIR)/mkversion.exe
808
+CODECHECK1 = $(OBJDIR)/codecheck1.exe
770809
CAT = cat
771810
CP = cp
772811
GREP = grep
773812
MV = mv
774813
RM = rm -f
@@ -816,21 +855,27 @@
816855
$(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
817856
818857
$(MKINDEX): $(SRCDIR)/mkindex.c
819858
$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
820859
821
-$(VERSION): $(SRCDIR)/mkversion.c
822
- $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
860
+$(MKBUILTIN): $(SRCDIR)/mkbuiltin.c
861
+ $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c
862
+
863
+$(MKVERSION): $(SRCDIR)/mkversion.c
864
+ $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c
865
+
866
+$(CODECHECK1): $(SRCDIR)/codecheck1.c
867
+ $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
823868
824869
# WARNING. DANGER. Running the test suite modifies the repository the
825870
# build is done from, i.e. the checkout belongs to. Do not sync/push
826871
# the repository after running the tests.
827872
test: $(OBJDIR) $(APPNAME)
828873
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
829874
830
-$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
831
- $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
875
+$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
876
+ $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
832877
833878
# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
834879
# to 1. If it is set to 1, then there is no need to build or link
835880
# the sqlite3.o object. Instead, the system SQLite will be linked
836881
# using -lsqlite3.
@@ -886,11 +931,12 @@
886931
887932
ifdef FOSSIL_BUILD_SSL
888933
APPTARGETS += openssl
889934
endif
890935
891
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
936
+$(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
937
+ $(CODECHECK1) $(TRANS_SRC)
892938
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
893939
894940
# This rule prevents make from using its default rules to try build
895941
# an executable named "manifest" out of the file named "manifest.c"
896942
#
@@ -922,16 +968,24 @@
922968
append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h"
923969
append mhargs " \\\n\t\t\$(SRCDIR)/th.h"
924970
append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h"
925971
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)"
926972
writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n"
927
-writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h"
973
+
974
+writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)"
975
+writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >$@\n"
976
+
977
+writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h"
928978
writeln "\t\$(MAKEHEADERS) $mhargs"
929979
writeln "\techo Done >\$(OBJDIR)/headers\n"
930980
writeln "\$(OBJDIR)/headers: Makefile\n"
931981
writeln "Makefile:\n"
932982
set extra_h(main) " \$(OBJDIR)/page_index.h "
983
+set extra_h(builtin) " \$(OBJDIR)/builtin_data.h "
984
+
985
+writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)"
986
+writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$(OBJDIR)/builtin_data.h\n"
933987
934988
foreach s [lsort $src] {
935989
writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)"
936990
writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
937991
writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
@@ -1037,12 +1091,13 @@
10371091
10381092
APPNAME = $(OBJDIR)\fossil$(E)
10391093
10401094
all: $(APPNAME)
10411095
1042
-$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
1096
+$(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
10431097
cd $(OBJDIR)
1098
+ codecheck1$E $(SRC)
10441099
$(DMDIR)\bin\link @link
10451100
10461101
$(OBJDIR)\fossil.res: $B\win\fossil.rc
10471102
$(RC) $(RCFLAGS) -o$@ $**
10481103
@@ -1066,11 +1121,17 @@
10661121
$(BCC) -o$@ $**
10671122
10681123
mkindex$E: $(SRCDIR)\mkindex.c
10691124
$(BCC) -o$@ $**
10701125
1071
-version$E: $B\src\mkversion.c
1126
+mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
1127
+ $(BCC) -o$@ $**
1128
+
1129
+mkversion$E: $(SRCDIR)\mkversion.c
1130
+ $(BCC) -o$@ $**
1131
+
1132
+codecheck1$E: $(SRCDIR)\codecheck1.c
10721133
$(BCC) -o$@ $**
10731134
10741135
$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
10751136
$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
10761137
@@ -1084,22 +1145,25 @@
10841145
$(TCC) -o$@ -c $**
10851146
10861147
$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
10871148
cp $@ $@
10881149
1089
-VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
1150
+VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
10901151
+$** > $@
10911152
10921153
page_index.h: mkindex$E $(SRC)
10931154
+$** > $@
1155
+
1156
+builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
1157
+ +$** > $@
10941158
10951159
clean:
10961160
-del $(OBJDIR)\*.obj
10971161
-del *.obj *_.c *.h *.map
10981162
10991163
realclean:
1100
- -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
1164
+ -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E
11011165
11021166
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
11031167
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
11041168
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
11051169
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1122,11 +1186,11 @@
11221186
writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
11231187
writeln "${s}_.c : \$(SRCDIR)\\$s.c"
11241188
writeln "\t+translate\$E \$** > \$@\n"
11251189
}
11261190
1127
-writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E "
1191
+writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
11281192
foreach s [lsort $src] {
11291193
writeln -nonewline "${s}_.c:$s.h "
11301194
}
11311195
writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
11321196
writeln "\t@copy /Y nul: headers"
@@ -1174,10 +1238,13 @@
11741238
PERLDIR = C:\Perl\bin
11751239
PERL = perl.exe
11761240
11771241
# Uncomment to enable debug symbols
11781242
# DEBUG = 1
1243
+
1244
+# Uncomment to support Windows XP with Visual Studio 201x
1245
+# FOSSIL_ENABLE_WINXP = 1
11791246
11801247
# Uncomment to enable JSON API
11811248
# FOSSIL_ENABLE_JSON = 1
11821249
11831250
# Uncomment to enable miniz usage
@@ -1197,13 +1264,14 @@
11971264
11981265
# Uncomment to enable Tcl support
11991266
# FOSSIL_ENABLE_TCL = 1
12001267
12011268
!ifdef FOSSIL_ENABLE_SSL
1202
-SSLDIR = $(B)\compat\openssl-1.0.1i
1269
+SSLDIR = $(B)\compat\openssl-1.0.1j
12031270
SSLINCDIR = $(SSLDIR)\inc32
12041271
SSLLIBDIR = $(SSLDIR)\out32
1272
+SSLLFLAGS = /nologo /opt:ref /debug
12051273
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
12061274
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
12071275
!message Using 'x64' platform for OpenSSL...
12081276
SSLCONFIG = VC-WIN64A no-asm
12091277
SSLSETUP = ms\do_win64a.bat
@@ -1246,10 +1314,21 @@
12461314
INCL = $(INCL) /I$(TCLINCDIR)
12471315
!endif
12481316
12491317
CFLAGS = /nologo
12501318
LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
1319
+
1320
+!ifdef FOSSIL_ENABLE_WINXP
1321
+XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
1322
+CFLAGS = $(CFLAGS) $(XPCFLAGS)
1323
+!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1324
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1325
+!else
1326
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1327
+!endif
1328
+LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1329
+!endif
12511330
12521331
!ifdef DEBUG
12531332
CFLAGS = $(CFLAGS) /Zi /MTd /Od
12541333
LDFLAGS = $(LDFLAGS) /DEBUG
12551334
!else
@@ -1324,10 +1403,20 @@
13241403
writeln " \\"
13251404
writeln -nonewline " "
13261405
}
13271406
writeln -nonewline "${s}_.c"; incr i
13281407
}
1408
+writeln "\n"
1409
+writeln -nonewline "EXTRA_FILES = "
1410
+set i 0
1411
+foreach s [lsort $extra_files] {
1412
+ if {$i > 0} {
1413
+ writeln " \\"
1414
+ writeln -nonewline " "
1415
+ }
1416
+ writeln -nonewline "\$(SRCDIR)\\${s}"; incr i
1417
+}
13291418
writeln "\n"
13301419
set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation]
13311420
writeln -nonewline "OBJ = "
13321421
set i 0
13331422
foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1352,21 +1441,29 @@
13521441
13531442
all: $(OX) $(APPNAME)
13541443
13551444
zlib:
13561445
@echo Building zlib from "$(ZLIBDIR)"...
1446
+!ifdef FOSSIL_ENABLE_WINXP
1447
+ @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
1448
+!else
13571449
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
1450
+!endif
13581451
13591452
!ifdef FOSSIL_ENABLE_SSL
13601453
openssl:
13611454
@echo Building OpenSSL from "$(SSLDIR)"...
13621455
!if "$(PERLDIR)" != ""
13631456
@set PATH=$(PERLDIR);$(PATH)
13641457
!endif
13651458
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
13661459
@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1460
+!ifdef FOSSIL_ENABLE_WINXP
1461
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1462
+!else
13671463
@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
1464
+!endif
13681465
!endif
13691466
13701467
!ifndef FOSSIL_ENABLE_MINIZ
13711468
APPTARGETS = $(APPTARGETS) zlib
13721469
!endif
@@ -1375,12 +1472,13 @@
13751472
!ifdef FOSSIL_BUILD_SSL
13761473
APPTARGETS = $(APPTARGETS) openssl
13771474
!endif
13781475
!endif
13791476
1380
-$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
1477
+$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
13811478
cd $(OX)
1479
+ codecheck1$E $(SRC)
13821480
link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
13831481
13841482
$(OX)\linkopts: $B\win\Makefile.msc}
13851483
set redir {>}
13861484
foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1403,11 +1501,17 @@
14031501
$(BCC) $**
14041502
14051503
mkindex$E: $(SRCDIR)\mkindex.c
14061504
$(BCC) $**
14071505
1408
-mkversion$E: $B\src\mkversion.c
1506
+mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
1507
+ $(BCC) $**
1508
+
1509
+mkversion$E: $(SRCDIR)\mkversion.c
1510
+ $(BCC) $**
1511
+
1512
+codecheck1$E: $(SRCDIR)\codecheck1.c
14091513
$(BCC) $**
14101514
14111515
$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
14121516
$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
14131517
@@ -1432,10 +1536,13 @@
14321536
$(TCC) /Fo$@ /c $**
14331537
14341538
page_index.h: mkindex$E $(SRC)
14351539
$** > $@
14361540
1541
+builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
1542
+ $** > $@
1543
+
14371544
clean:
14381545
-del $(OX)\*.obj
14391546
-del *.obj
14401547
-del *_.c
14411548
-del *.h
@@ -1455,10 +1562,14 @@
14551562
-del mkindex$P
14561563
-del makeheaders$E
14571564
-del makeheaders$P
14581565
-del mkversion$E
14591566
-del mkversion$P
1567
+ -del codecheck1$E
1568
+ -del codecheck1$P
1569
+ -del mkbuiltin$E
1570
+ -del mkbuiltin$P
14601571
14611572
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
14621573
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
14631574
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
14641575
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1482,11 +1593,11 @@
14821593
}
14831594
14841595
writeln "fossil.res : \$B\\win\\fossil.rc"
14851596
writeln "\t\$(RCC) /fo \$@ \$**\n"
14861597
1487
-writeln "headers: makeheaders\$E page_index.h VERSION.h"
1598
+writeln "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h"
14881599
writeln -nonewline "\tmakeheaders\$E "
14891600
set i 0
14901601
foreach s [lsort $src] {
14911602
if {$i > 0} {
14921603
writeln " \\"
@@ -1592,11 +1703,11 @@
15921703
RC=$(PellesCDir)\bin\porc.exe
15931704
RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
15941705
15951706
# define the special utilities files, needed to generate
15961707
# the automatically generated source files
1597
-UTILS=translate.exe mkindex.exe makeheaders.exe
1708
+UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
15981709
UTILS_OBJ=$(UTILS:.exe=.obj)
15991710
UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
16001711
16011712
# define the SQLite files, which need special flags on compile
16021713
SQLITESRC=sqlite3.c
@@ -1631,11 +1742,11 @@
16311742
# main target file is the application
16321743
APPLICATION=fossil.exe
16331744
16341745
# define the standard make target
16351746
.PHONY: default
1636
-default: page_index.h headers $(APPLICATION)
1747
+default: page_index.h builtin_data.h headers $(APPLICATION)
16371748
16381749
# symbolic target to generate the source generate utils
16391750
.PHONY: utils
16401751
utils: $(UTILS)
16411752
@@ -1656,17 +1767,20 @@
16561767
translate.exe $< >$@
16571768
16581769
# generate the index source, containing all web references,..
16591770
page_index.h: $(TRANSLATEDSRC) mkindex.exe
16601771
mkindex.exe $(TRANSLATEDSRC) >$@
1772
+
1773
+builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
1774
+ mkbuiltin.exe $(EXTRA_FILES) >$@
16611775
16621776
# extracting version info from manifest
16631777
VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
16641778
version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@
16651779
16661780
# generate the simplified headers
1667
-headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
1781
+headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
16681782
makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
16691783
echo Done >$@
16701784
16711785
# compile C sources with relevant options
16721786
16731787
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -12,12 +12,15 @@
12 # tclsh makemake.tcl
13 #
14 #############################################################################
15
16 # Basenames of all source files that get preprocessed using
17 # "translate" and "makeheaders". To add new source files to the
18 # project, simply add the basename to this list and rerun this script.
 
 
 
19 #
20 set src {
21 add
22 allrepo
23 attach
@@ -24,10 +27,11 @@
24 bag
25 bisect
26 blob
27 branch
28 browse
 
29 cache
30 captcha
31 cgi
32 checkin
33 checkout
@@ -128,10 +132,16 @@
128 xfer
129 xfersetup
130 zip
131 http_ssl
132 }
 
 
 
 
 
 
133
134 # Options used to compile the included SQLite library.
135 #
136 set SQLITE_OPTIONS {
137 -DNDEBUG=1
@@ -217,10 +227,15 @@
217 }
218 writeln -nonewline "SRC ="
219 foreach s [lsort $src] {
220 writeln -nonewline " \\\n \$(SRCDIR)/$s.c"
221 }
 
 
 
 
 
222 writeln "\n"
223 writeln -nonewline "TRANS_SRC ="
224 foreach s [lsort $src] {
225 writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c"
226 }
@@ -241,10 +256,13 @@
241
242 install: $(APPNAME)
243 mkdir -p $(INSTALLDIR)
244 mv $(APPNAME) $(INSTALLDIR)
245
 
 
 
246 $(OBJDIR):
247 -mkdir $(OBJDIR)
248
249 $(OBJDIR)/translate: $(SRCDIR)/translate.c
250 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -253,13 +271,19 @@
253 $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c
254
255 $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c
256 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
257
 
 
 
258 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
259 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
260
 
 
 
261 # WARNING. DANGER. Running the test suite modifies the repository the
262 # build is done from, i.e. the checkout belongs to. Do not sync/push
263 # the repository after running the tests.
264 test: $(OBJDIR) $(APPNAME)
265 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -304,11 +328,12 @@
304 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
305 $(OBJDIR)/cson_amalgamation.o
306 }]
307
308 writeln {
309 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
 
310 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
311
312 # This rule prevents make from using its default rules to try build
313 # an executable named "manifest" out of the file named "manifest.c"
314 #
@@ -329,18 +354,23 @@
329 append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>"
330 #append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>"
331 append mhargs "\$(OBJDIR)/VERSION.h"
332 set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs]
333 writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
334 writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@"
335 writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
 
 
 
 
336 writeln "\t\$(OBJDIR)/makeheaders $mhargs"
337 writeln "\ttouch \$(OBJDIR)/headers"
338 writeln "\$(OBJDIR)/headers: Makefile"
339 writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h"
340 writeln "Makefile:"
341 set extra_h(main) " \$(OBJDIR)/page_index.h "
 
342
343 foreach s [lsort $src] {
344 writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
345 writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
346 writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
@@ -505,12 +535,12 @@
505 #### The directories where the OpenSSL include and library files are located.
506 # The recommended usage here is to use the Sysinternals junction tool
507 # to create a hard link between an "openssl-1.x" sub-directory of the
508 # Fossil source code directory and the target OpenSSL source directory.
509 #
510 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
511 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
512
513 #### Either the directory where the Tcl library is installed or the Tcl
514 # source code directory resides (depending on the value of the macro
515 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
516 # this directory must have "include" and "lib" sub-directories. If
@@ -726,10 +756,15 @@
726 }
727 writeln -nonewline "SRC ="
728 foreach s [lsort $src] {
729 writeln -nonewline " \\\n \$(SRCDIR)/$s.c"
730 }
 
 
 
 
 
731 writeln "\n"
732 writeln -nonewline "TRANS_SRC ="
733 foreach s [lsort $src] {
734 writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c"
735 }
@@ -752,11 +787,13 @@
752 #
753 ifdef USE_WINDOWS
754 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
755 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
756 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
757 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
 
 
758 CAT = type
759 CP = copy
760 GREP = find
761 MV = copy
762 RM = del /Q
@@ -764,11 +801,13 @@
764 RMDIR = rmdir /S /Q
765 else
766 TRANSLATE = $(OBJDIR)/translate.exe
767 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
768 MKINDEX = $(OBJDIR)/mkindex.exe
769 VERSION = $(OBJDIR)/version.exe
 
 
770 CAT = cat
771 CP = cp
772 GREP = grep
773 MV = mv
774 RM = rm -f
@@ -816,21 +855,27 @@
816 $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
817
818 $(MKINDEX): $(SRCDIR)/mkindex.c
819 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
820
821 $(VERSION): $(SRCDIR)/mkversion.c
822 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
 
 
 
 
 
 
823
824 # WARNING. DANGER. Running the test suite modifies the repository the
825 # build is done from, i.e. the checkout belongs to. Do not sync/push
826 # the repository after running the tests.
827 test: $(OBJDIR) $(APPNAME)
828 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
829
830 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
831 $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
832
833 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
834 # to 1. If it is set to 1, then there is no need to build or link
835 # the sqlite3.o object. Instead, the system SQLite will be linked
836 # using -lsqlite3.
@@ -886,11 +931,12 @@
886
887 ifdef FOSSIL_BUILD_SSL
888 APPTARGETS += openssl
889 endif
890
891 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
 
892 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
893
894 # This rule prevents make from using its default rules to try build
895 # an executable named "manifest" out of the file named "manifest.c"
896 #
@@ -922,16 +968,24 @@
922 append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h"
923 append mhargs " \\\n\t\t\$(SRCDIR)/th.h"
924 append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h"
925 writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)"
926 writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n"
927 writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h"
 
 
 
 
928 writeln "\t\$(MAKEHEADERS) $mhargs"
929 writeln "\techo Done >\$(OBJDIR)/headers\n"
930 writeln "\$(OBJDIR)/headers: Makefile\n"
931 writeln "Makefile:\n"
932 set extra_h(main) " \$(OBJDIR)/page_index.h "
 
 
 
 
933
934 foreach s [lsort $src] {
935 writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)"
936 writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
937 writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
@@ -1037,12 +1091,13 @@
1037
1038 APPNAME = $(OBJDIR)\fossil$(E)
1039
1040 all: $(APPNAME)
1041
1042 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
1043 cd $(OBJDIR)
 
1044 $(DMDIR)\bin\link @link
1045
1046 $(OBJDIR)\fossil.res: $B\win\fossil.rc
1047 $(RC) $(RCFLAGS) -o$@ $**
1048
@@ -1066,11 +1121,17 @@
1066 $(BCC) -o$@ $**
1067
1068 mkindex$E: $(SRCDIR)\mkindex.c
1069 $(BCC) -o$@ $**
1070
1071 version$E: $B\src\mkversion.c
 
 
 
 
 
 
1072 $(BCC) -o$@ $**
1073
1074 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
1075 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
1076
@@ -1084,22 +1145,25 @@
1084 $(TCC) -o$@ -c $**
1085
1086 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
1087 cp $@ $@
1088
1089 VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
1090 +$** > $@
1091
1092 page_index.h: mkindex$E $(SRC)
1093 +$** > $@
 
 
 
1094
1095 clean:
1096 -del $(OBJDIR)\*.obj
1097 -del *.obj *_.c *.h *.map
1098
1099 realclean:
1100 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
1101
1102 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1103 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1104 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1105 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1122,11 +1186,11 @@
1122 writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
1123 writeln "${s}_.c : \$(SRCDIR)\\$s.c"
1124 writeln "\t+translate\$E \$** > \$@\n"
1125 }
1126
1127 writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E "
1128 foreach s [lsort $src] {
1129 writeln -nonewline "${s}_.c:$s.h "
1130 }
1131 writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
1132 writeln "\t@copy /Y nul: headers"
@@ -1174,10 +1238,13 @@
1174 PERLDIR = C:\Perl\bin
1175 PERL = perl.exe
1176
1177 # Uncomment to enable debug symbols
1178 # DEBUG = 1
 
 
 
1179
1180 # Uncomment to enable JSON API
1181 # FOSSIL_ENABLE_JSON = 1
1182
1183 # Uncomment to enable miniz usage
@@ -1197,13 +1264,14 @@
1197
1198 # Uncomment to enable Tcl support
1199 # FOSSIL_ENABLE_TCL = 1
1200
1201 !ifdef FOSSIL_ENABLE_SSL
1202 SSLDIR = $(B)\compat\openssl-1.0.1i
1203 SSLINCDIR = $(SSLDIR)\inc32
1204 SSLLIBDIR = $(SSLDIR)\out32
 
1205 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1206 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1207 !message Using 'x64' platform for OpenSSL...
1208 SSLCONFIG = VC-WIN64A no-asm
1209 SSLSETUP = ms\do_win64a.bat
@@ -1246,10 +1314,21 @@
1246 INCL = $(INCL) /I$(TCLINCDIR)
1247 !endif
1248
1249 CFLAGS = /nologo
1250 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
 
 
 
 
 
 
 
 
 
 
 
1251
1252 !ifdef DEBUG
1253 CFLAGS = $(CFLAGS) /Zi /MTd /Od
1254 LDFLAGS = $(LDFLAGS) /DEBUG
1255 !else
@@ -1324,10 +1403,20 @@
1324 writeln " \\"
1325 writeln -nonewline " "
1326 }
1327 writeln -nonewline "${s}_.c"; incr i
1328 }
 
 
 
 
 
 
 
 
 
 
1329 writeln "\n"
1330 set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation]
1331 writeln -nonewline "OBJ = "
1332 set i 0
1333 foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1352,21 +1441,29 @@
1352
1353 all: $(OX) $(APPNAME)
1354
1355 zlib:
1356 @echo Building zlib from "$(ZLIBDIR)"...
 
 
 
1357 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
 
1358
1359 !ifdef FOSSIL_ENABLE_SSL
1360 openssl:
1361 @echo Building OpenSSL from "$(SSLDIR)"...
1362 !if "$(PERLDIR)" != ""
1363 @set PATH=$(PERLDIR);$(PATH)
1364 !endif
1365 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1366 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
 
 
 
1367 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
 
1368 !endif
1369
1370 !ifndef FOSSIL_ENABLE_MINIZ
1371 APPTARGETS = $(APPTARGETS) zlib
1372 !endif
@@ -1375,12 +1472,13 @@
1375 !ifdef FOSSIL_BUILD_SSL
1376 APPTARGETS = $(APPTARGETS) openssl
1377 !endif
1378 !endif
1379
1380 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
1381 cd $(OX)
 
1382 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
1383
1384 $(OX)\linkopts: $B\win\Makefile.msc}
1385 set redir {>}
1386 foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1403,11 +1501,17 @@
1403 $(BCC) $**
1404
1405 mkindex$E: $(SRCDIR)\mkindex.c
1406 $(BCC) $**
1407
1408 mkversion$E: $B\src\mkversion.c
 
 
 
 
 
 
1409 $(BCC) $**
1410
1411 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
1412 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
1413
@@ -1432,10 +1536,13 @@
1432 $(TCC) /Fo$@ /c $**
1433
1434 page_index.h: mkindex$E $(SRC)
1435 $** > $@
1436
 
 
 
1437 clean:
1438 -del $(OX)\*.obj
1439 -del *.obj
1440 -del *_.c
1441 -del *.h
@@ -1455,10 +1562,14 @@
1455 -del mkindex$P
1456 -del makeheaders$E
1457 -del makeheaders$P
1458 -del mkversion$E
1459 -del mkversion$P
 
 
 
 
1460
1461 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1462 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1463 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1464 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1482,11 +1593,11 @@
1482 }
1483
1484 writeln "fossil.res : \$B\\win\\fossil.rc"
1485 writeln "\t\$(RCC) /fo \$@ \$**\n"
1486
1487 writeln "headers: makeheaders\$E page_index.h VERSION.h"
1488 writeln -nonewline "\tmakeheaders\$E "
1489 set i 0
1490 foreach s [lsort $src] {
1491 if {$i > 0} {
1492 writeln " \\"
@@ -1592,11 +1703,11 @@
1592 RC=$(PellesCDir)\bin\porc.exe
1593 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
1594
1595 # define the special utilities files, needed to generate
1596 # the automatically generated source files
1597 UTILS=translate.exe mkindex.exe makeheaders.exe
1598 UTILS_OBJ=$(UTILS:.exe=.obj)
1599 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
1600
1601 # define the SQLite files, which need special flags on compile
1602 SQLITESRC=sqlite3.c
@@ -1631,11 +1742,11 @@
1631 # main target file is the application
1632 APPLICATION=fossil.exe
1633
1634 # define the standard make target
1635 .PHONY: default
1636 default: page_index.h headers $(APPLICATION)
1637
1638 # symbolic target to generate the source generate utils
1639 .PHONY: utils
1640 utils: $(UTILS)
1641
@@ -1656,17 +1767,20 @@
1656 translate.exe $< >$@
1657
1658 # generate the index source, containing all web references,..
1659 page_index.h: $(TRANSLATEDSRC) mkindex.exe
1660 mkindex.exe $(TRANSLATEDSRC) >$@
 
 
 
1661
1662 # extracting version info from manifest
1663 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
1664 version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@
1665
1666 # generate the simplified headers
1667 headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
1668 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
1669 echo Done >$@
1670
1671 # compile C sources with relevant options
1672
1673
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -12,12 +12,15 @@
12 # tclsh makemake.tcl
13 #
14 #############################################################################
15
16 # Basenames of all source files that get preprocessed using
17 # "translate" and "makeheaders". To add new C-language source files to the
18 # project, simply add the basename to this list and rerun this script.
19 #
20 # Set the separate extra_files variable further down for how to add non-C
21 # files, such as string and BLOB resources.
22 #
23 set src {
24 add
25 allrepo
26 attach
@@ -24,10 +27,11 @@
27 bag
28 bisect
29 blob
30 branch
31 browse
32 builtin
33 cache
34 captcha
35 cgi
36 checkin
37 checkout
@@ -128,10 +132,16 @@
132 xfer
133 xfersetup
134 zip
135 http_ssl
136 }
137
138 # Additional resource files that get built into the executable.
139 #
140 set extra_files {
141 diff.tcl
142 }
143
144 # Options used to compile the included SQLite library.
145 #
146 set SQLITE_OPTIONS {
147 -DNDEBUG=1
@@ -217,10 +227,15 @@
227 }
228 writeln -nonewline "SRC ="
229 foreach s [lsort $src] {
230 writeln -nonewline " \\\n \$(SRCDIR)/$s.c"
231 }
232 writeln "\n"
233 writeln -nonewline "EXTRA_FILES ="
234 foreach s [lsort $extra_files] {
235 writeln -nonewline " \\\n \$(SRCDIR)/$s"
236 }
237 writeln "\n"
238 writeln -nonewline "TRANS_SRC ="
239 foreach s [lsort $src] {
240 writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c"
241 }
@@ -241,10 +256,13 @@
256
257 install: $(APPNAME)
258 mkdir -p $(INSTALLDIR)
259 mv $(APPNAME) $(INSTALLDIR)
260
261 codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
262 $(OBJDIR)/codecheck1 $(TRANS_SRC)
263
264 $(OBJDIR):
265 -mkdir $(OBJDIR)
266
267 $(OBJDIR)/translate: $(SRCDIR)/translate.c
268 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -253,13 +271,19 @@
271 $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c
272
273 $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c
274 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
275
276 $(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c
277 $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c
278
279 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
280 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
281
282 $(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
283 $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
284
285 # WARNING. DANGER. Running the test suite modifies the repository the
286 # build is done from, i.e. the checkout belongs to. Do not sync/push
287 # the repository after running the tests.
288 test: $(OBJDIR) $(APPNAME)
289 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -304,11 +328,12 @@
328 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
329 $(OBJDIR)/cson_amalgamation.o
330 }]
331
332 writeln {
333 $(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
334 $(OBJDIR)/codecheck1 $(TRANS_SRC)
335 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
336
337 # This rule prevents make from using its default rules to try build
338 # an executable named "manifest" out of the file named "manifest.c"
339 #
@@ -329,18 +354,23 @@
354 append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>"
355 #append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>"
356 append mhargs "\$(OBJDIR)/VERSION.h"
357 set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs]
358 writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
359 writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@\n"
360
361 writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)"
362 writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >$@\n"
363
364 writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
365 writeln "\t\$(OBJDIR)/makeheaders $mhargs"
366 writeln "\ttouch \$(OBJDIR)/headers"
367 writeln "\$(OBJDIR)/headers: Makefile"
368 writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h"
369 writeln "Makefile:"
370 set extra_h(main) " \$(OBJDIR)/page_index.h "
371 set extra_h(builtin) " \$(OBJDIR)/builtin_data.h "
372
373 foreach s [lsort $src] {
374 writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
375 writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
376 writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
@@ -505,12 +535,12 @@
535 #### The directories where the OpenSSL include and library files are located.
536 # The recommended usage here is to use the Sysinternals junction tool
537 # to create a hard link between an "openssl-1.x" sub-directory of the
538 # Fossil source code directory and the target OpenSSL source directory.
539 #
540 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
541 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
542
543 #### Either the directory where the Tcl library is installed or the Tcl
544 # source code directory resides (depending on the value of the macro
545 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
546 # this directory must have "include" and "lib" sub-directories. If
@@ -726,10 +756,15 @@
756 }
757 writeln -nonewline "SRC ="
758 foreach s [lsort $src] {
759 writeln -nonewline " \\\n \$(SRCDIR)/$s.c"
760 }
761 writeln "\n"
762 writeln -nonewline "EXTRA_FILES ="
763 foreach s [lsort $extra_files] {
764 writeln -nonewline " \\\n \$(SRCDIR)/$s"
765 }
766 writeln "\n"
767 writeln -nonewline "TRANS_SRC ="
768 foreach s [lsort $src] {
769 writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c"
770 }
@@ -752,11 +787,13 @@
787 #
788 ifdef USE_WINDOWS
789 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
790 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
791 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
792 MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
793 MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe)
794 CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
795 CAT = type
796 CP = copy
797 GREP = find
798 MV = copy
799 RM = del /Q
@@ -764,11 +801,13 @@
801 RMDIR = rmdir /S /Q
802 else
803 TRANSLATE = $(OBJDIR)/translate.exe
804 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
805 MKINDEX = $(OBJDIR)/mkindex.exe
806 MKBUILTIN = $(OBJDIR)/mkbuiltin.exe
807 MKVERSION = $(OBJDIR)/mkversion.exe
808 CODECHECK1 = $(OBJDIR)/codecheck1.exe
809 CAT = cat
810 CP = cp
811 GREP = grep
812 MV = mv
813 RM = rm -f
@@ -816,21 +855,27 @@
855 $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
856
857 $(MKINDEX): $(SRCDIR)/mkindex.c
858 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
859
860 $(MKBUILTIN): $(SRCDIR)/mkbuiltin.c
861 $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c
862
863 $(MKVERSION): $(SRCDIR)/mkversion.c
864 $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c
865
866 $(CODECHECK1): $(SRCDIR)/codecheck1.c
867 $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
868
869 # WARNING. DANGER. Running the test suite modifies the repository the
870 # build is done from, i.e. the checkout belongs to. Do not sync/push
871 # the repository after running the tests.
872 test: $(OBJDIR) $(APPNAME)
873 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
874
875 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
876 $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
877
878 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
879 # to 1. If it is set to 1, then there is no need to build or link
880 # the sqlite3.o object. Instead, the system SQLite will be linked
881 # using -lsqlite3.
@@ -886,11 +931,12 @@
931
932 ifdef FOSSIL_BUILD_SSL
933 APPTARGETS += openssl
934 endif
935
936 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
937 $(CODECHECK1) $(TRANS_SRC)
938 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
939
940 # This rule prevents make from using its default rules to try build
941 # an executable named "manifest" out of the file named "manifest.c"
942 #
@@ -922,16 +968,24 @@
968 append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h"
969 append mhargs " \\\n\t\t\$(SRCDIR)/th.h"
970 append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h"
971 writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)"
972 writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n"
973
974 writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)"
975 writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >$@\n"
976
977 writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h"
978 writeln "\t\$(MAKEHEADERS) $mhargs"
979 writeln "\techo Done >\$(OBJDIR)/headers\n"
980 writeln "\$(OBJDIR)/headers: Makefile\n"
981 writeln "Makefile:\n"
982 set extra_h(main) " \$(OBJDIR)/page_index.h "
983 set extra_h(builtin) " \$(OBJDIR)/builtin_data.h "
984
985 writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)"
986 writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$(OBJDIR)/builtin_data.h\n"
987
988 foreach s [lsort $src] {
989 writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)"
990 writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n"
991 writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h"
@@ -1037,12 +1091,13 @@
1091
1092 APPNAME = $(OBJDIR)\fossil$(E)
1093
1094 all: $(APPNAME)
1095
1096 $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
1097 cd $(OBJDIR)
1098 codecheck1$E $(SRC)
1099 $(DMDIR)\bin\link @link
1100
1101 $(OBJDIR)\fossil.res: $B\win\fossil.rc
1102 $(RC) $(RCFLAGS) -o$@ $**
1103
@@ -1066,11 +1121,17 @@
1121 $(BCC) -o$@ $**
1122
1123 mkindex$E: $(SRCDIR)\mkindex.c
1124 $(BCC) -o$@ $**
1125
1126 mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
1127 $(BCC) -o$@ $**
1128
1129 mkversion$E: $(SRCDIR)\mkversion.c
1130 $(BCC) -o$@ $**
1131
1132 codecheck1$E: $(SRCDIR)\codecheck1.c
1133 $(BCC) -o$@ $**
1134
1135 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
1136 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
1137
@@ -1084,22 +1145,25 @@
1145 $(TCC) -o$@ -c $**
1146
1147 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
1148 cp $@ $@
1149
1150 VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
1151 +$** > $@
1152
1153 page_index.h: mkindex$E $(SRC)
1154 +$** > $@
1155
1156 builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
1157 +$** > $@
1158
1159 clean:
1160 -del $(OBJDIR)\*.obj
1161 -del *.obj *_.c *.h *.map
1162
1163 realclean:
1164 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E
1165
1166 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1167 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1168 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1169 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1122,11 +1186,11 @@
1186 writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
1187 writeln "${s}_.c : \$(SRCDIR)\\$s.c"
1188 writeln "\t+translate\$E \$** > \$@\n"
1189 }
1190
1191 writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
1192 foreach s [lsort $src] {
1193 writeln -nonewline "${s}_.c:$s.h "
1194 }
1195 writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
1196 writeln "\t@copy /Y nul: headers"
@@ -1174,10 +1238,13 @@
1238 PERLDIR = C:\Perl\bin
1239 PERL = perl.exe
1240
1241 # Uncomment to enable debug symbols
1242 # DEBUG = 1
1243
1244 # Uncomment to support Windows XP with Visual Studio 201x
1245 # FOSSIL_ENABLE_WINXP = 1
1246
1247 # Uncomment to enable JSON API
1248 # FOSSIL_ENABLE_JSON = 1
1249
1250 # Uncomment to enable miniz usage
@@ -1197,13 +1264,14 @@
1264
1265 # Uncomment to enable Tcl support
1266 # FOSSIL_ENABLE_TCL = 1
1267
1268 !ifdef FOSSIL_ENABLE_SSL
1269 SSLDIR = $(B)\compat\openssl-1.0.1j
1270 SSLINCDIR = $(SSLDIR)\inc32
1271 SSLLIBDIR = $(SSLDIR)\out32
1272 SSLLFLAGS = /nologo /opt:ref /debug
1273 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1274 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1275 !message Using 'x64' platform for OpenSSL...
1276 SSLCONFIG = VC-WIN64A no-asm
1277 SSLSETUP = ms\do_win64a.bat
@@ -1246,10 +1314,21 @@
1314 INCL = $(INCL) /I$(TCLINCDIR)
1315 !endif
1316
1317 CFLAGS = /nologo
1318 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
1319
1320 !ifdef FOSSIL_ENABLE_WINXP
1321 XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
1322 CFLAGS = $(CFLAGS) $(XPCFLAGS)
1323 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1324 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1325 !else
1326 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1327 !endif
1328 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1329 !endif
1330
1331 !ifdef DEBUG
1332 CFLAGS = $(CFLAGS) /Zi /MTd /Od
1333 LDFLAGS = $(LDFLAGS) /DEBUG
1334 !else
@@ -1324,10 +1403,20 @@
1403 writeln " \\"
1404 writeln -nonewline " "
1405 }
1406 writeln -nonewline "${s}_.c"; incr i
1407 }
1408 writeln "\n"
1409 writeln -nonewline "EXTRA_FILES = "
1410 set i 0
1411 foreach s [lsort $extra_files] {
1412 if {$i > 0} {
1413 writeln " \\"
1414 writeln -nonewline " "
1415 }
1416 writeln -nonewline "\$(SRCDIR)\\${s}"; incr i
1417 }
1418 writeln "\n"
1419 set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation]
1420 writeln -nonewline "OBJ = "
1421 set i 0
1422 foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1352,21 +1441,29 @@
1441
1442 all: $(OX) $(APPNAME)
1443
1444 zlib:
1445 @echo Building zlib from "$(ZLIBDIR)"...
1446 !ifdef FOSSIL_ENABLE_WINXP
1447 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
1448 !else
1449 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
1450 !endif
1451
1452 !ifdef FOSSIL_ENABLE_SSL
1453 openssl:
1454 @echo Building OpenSSL from "$(SSLDIR)"...
1455 !if "$(PERLDIR)" != ""
1456 @set PATH=$(PERLDIR);$(PATH)
1457 !endif
1458 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1459 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1460 !ifdef FOSSIL_ENABLE_WINXP
1461 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1462 !else
1463 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
1464 !endif
1465 !endif
1466
1467 !ifndef FOSSIL_ENABLE_MINIZ
1468 APPTARGETS = $(APPTARGETS) zlib
1469 !endif
@@ -1375,12 +1472,13 @@
1472 !ifdef FOSSIL_BUILD_SSL
1473 APPTARGETS = $(APPTARGETS) openssl
1474 !endif
1475 !endif
1476
1477 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
1478 cd $(OX)
1479 codecheck1$E $(SRC)
1480 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
1481
1482 $(OX)\linkopts: $B\win\Makefile.msc}
1483 set redir {>}
1484 foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1403,11 +1501,17 @@
1501 $(BCC) $**
1502
1503 mkindex$E: $(SRCDIR)\mkindex.c
1504 $(BCC) $**
1505
1506 mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
1507 $(BCC) $**
1508
1509 mkversion$E: $(SRCDIR)\mkversion.c
1510 $(BCC) $**
1511
1512 codecheck1$E: $(SRCDIR)\codecheck1.c
1513 $(BCC) $**
1514
1515 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
1516 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
1517
@@ -1432,10 +1536,13 @@
1536 $(TCC) /Fo$@ /c $**
1537
1538 page_index.h: mkindex$E $(SRC)
1539 $** > $@
1540
1541 builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
1542 $** > $@
1543
1544 clean:
1545 -del $(OX)\*.obj
1546 -del *.obj
1547 -del *_.c
1548 -del *.h
@@ -1455,10 +1562,14 @@
1562 -del mkindex$P
1563 -del makeheaders$E
1564 -del makeheaders$P
1565 -del mkversion$E
1566 -del mkversion$P
1567 -del codecheck1$E
1568 -del codecheck1$P
1569 -del mkbuiltin$E
1570 -del mkbuiltin$P
1571
1572 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1573 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1574 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1575 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1482,11 +1593,11 @@
1593 }
1594
1595 writeln "fossil.res : \$B\\win\\fossil.rc"
1596 writeln "\t\$(RCC) /fo \$@ \$**\n"
1597
1598 writeln "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h"
1599 writeln -nonewline "\tmakeheaders\$E "
1600 set i 0
1601 foreach s [lsort $src] {
1602 if {$i > 0} {
1603 writeln " \\"
@@ -1592,11 +1703,11 @@
1703 RC=$(PellesCDir)\bin\porc.exe
1704 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
1705
1706 # define the special utilities files, needed to generate
1707 # the automatically generated source files
1708 UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
1709 UTILS_OBJ=$(UTILS:.exe=.obj)
1710 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
1711
1712 # define the SQLite files, which need special flags on compile
1713 SQLITESRC=sqlite3.c
@@ -1631,11 +1742,11 @@
1742 # main target file is the application
1743 APPLICATION=fossil.exe
1744
1745 # define the standard make target
1746 .PHONY: default
1747 default: page_index.h builtin_data.h headers $(APPLICATION)
1748
1749 # symbolic target to generate the source generate utils
1750 .PHONY: utils
1751 utils: $(UTILS)
1752
@@ -1656,17 +1767,20 @@
1767 translate.exe $< >$@
1768
1769 # generate the index source, containing all web references,..
1770 page_index.h: $(TRANSLATEDSRC) mkindex.exe
1771 mkindex.exe $(TRANSLATEDSRC) >$@
1772
1773 builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
1774 mkbuiltin.exe $(EXTRA_FILES) >$@
1775
1776 # extracting version info from manifest
1777 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
1778 version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@
1779
1780 # generate the simplified headers
1781 headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
1782 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
1783 echo Done >$@
1784
1785 # compile C sources with relevant options
1786
1787
+26 -9
--- src/manifest.c
+++ src/manifest.c
@@ -47,10 +47,11 @@
4747
/*
4848
** Flags for use with manifest_crosslink().
4949
*/
5050
#define MC_NONE 0 /* default handling */
5151
#define MC_PERMIT_HOOKS 1 /* permit hooks to execute */
52
+#define MC_NO_ERRORS 2 /* do not issue errors for a bad parse */
5253
5354
/*
5455
** A single F-card within a manifest
5556
*/
5657
struct ManifestFile {
@@ -360,10 +361,11 @@
360361
char *z;
361362
int n;
362363
char *zUuid;
363364
int sz = 0;
364365
int isRepeat, hasSelfRefTag = 0;
366
+ Blob bUuid = BLOB_INITIALIZER;
365367
static Bag seen;
366368
const char *zErr = 0;
367369
368370
if( rid==0 ){
369371
isRepeat = 1;
@@ -378,13 +380,13 @@
378380
** if that is not the case for this artifact.
379381
*/
380382
if( !isRepeat ) g.parseCnt[0]++;
381383
z = blob_materialize(pContent);
382384
n = blob_size(pContent);
383
- if( n<=0 || z[n-1]!='\n' ){
385
+ if( pErr && (n<=0 || z[n-1]!='\n') ){
384386
blob_reset(pContent);
385
- blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
387
+ blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1);
386388
return 0;
387389
}
388390
389391
/* Strip off the PGP signature if there is one.
390392
*/
@@ -403,10 +405,15 @@
403405
if( verify_z_card(z, n)==2 ){
404406
blob_reset(pContent);
405407
blob_appendf(pErr, "incorrect Z-card cksum");
406408
return 0;
407409
}
410
+
411
+ /* Store the UUID (before modifying the blob) only for error
412
+ ** reporting purposes.
413
+ */
414
+ sha1sum_blob(pContent, &bUuid);
408415
409416
/* Allocate a Manifest object to hold the parsed control artifact.
410417
*/
411418
p = fossil_malloc( sizeof(*p) );
412419
memset(p, 0, sizeof(*p));
@@ -944,13 +951,18 @@
944951
if( !seenZ ) SYNTAX("missing Z-card on control");
945952
p->type = CFTYPE_CONTROL;
946953
}
947954
md5sum_init();
948955
if( !isRepeat ) g.parseCnt[p->type]++;
956
+ blob_reset(&bUuid);
949957
return p;
950958
951959
manifest_syntax_error:
960
+ if(bUuid.nUsed){
961
+ blob_appendf(pErr, "manifest [%.40s] ", blob_str(&bUuid));
962
+ blob_reset(&bUuid);
963
+ }
952964
if( zErr ){
953965
blob_appendf(pErr, "line %d: %s", lineNo, zErr);
954966
}else{
955967
blob_appendf(pErr, "unknown error on line %d", lineNo);
956968
}
@@ -1589,11 +1601,11 @@
15891601
once = 0;
15901602
zTitleExpr = db_get("ticket-title-expr", "title");
15911603
zStatusColumn = db_get("ticket-status-column", "status");
15921604
}
15931605
zTitle = db_text("unknown",
1594
- "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1606
+ "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
15951607
zTitleExpr, pManifest->zTicketUuid
15961608
);
15971609
if( !isNew ){
15981610
for(i=0; i<pManifest->nField; i++){
15991611
if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
@@ -1610,11 +1622,11 @@
16101622
}
16111623
blob_appendf(&brief, "%h ticket [%s|%S].",
16121624
zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
16131625
}else{
16141626
zNewStatus = db_text("unknown",
1615
- "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1627
+ "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
16161628
zStatusColumn, pManifest->zTicketUuid
16171629
);
16181630
blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
16191631
"%d other change%s",
16201632
pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
@@ -1733,23 +1745,29 @@
17331745
17341746
if( (p = manifest_cache_find(rid))!=0 ){
17351747
blob_reset(pContent);
17361748
}else if( (p = manifest_parse(pContent, rid, 0))==0 ){
17371749
assert( blob_is_reset(pContent) || pContent==0 );
1738
- fossil_error(1, "syntax error in manifest");
1750
+ if( (flags & MC_NO_ERRORS)==0 ){
1751
+ fossil_error(1, "syntax error in manifest [%s]",
1752
+ db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
1753
+ }
17391754
return 0;
17401755
}
17411756
if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
17421757
manifest_destroy(p);
17431758
assert( blob_is_reset(pContent) );
1744
- fossil_error(1, "no manifest");
1759
+ if( (flags & MC_NO_ERRORS)==0 ) fossil_error(1, "no manifest");
17451760
return 0;
17461761
}
17471762
if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
17481763
manifest_destroy(p);
17491764
assert( blob_is_reset(pContent) );
1750
- fossil_error(1, "cannot fetch baseline manifest");
1765
+ if( (flags & MC_NO_ERRORS)==0 ){
1766
+ fossil_error(1, "cannot fetch baseline for manifest [%s]",
1767
+ db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
1768
+ }
17511769
return 0;
17521770
}
17531771
db_begin_transaction();
17541772
if( p->type==CFTYPE_MANIFEST ){
17551773
if( permitHooks ){
@@ -1894,11 +1912,10 @@
18941912
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
18951913
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
18961914
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
18971915
p->rDate, rid, p->zUser, zComment,
18981916
TAG_BGCOLOR, rid,
1899
- TAG_BGCOLOR, rid,
19001917
TAG_USER, rid,
19011918
TAG_COMMENT, rid
19021919
);
19031920
fossil_free(zComment);
19041921
}
@@ -2026,11 +2043,11 @@
20262043
" Edit [%s|%S]:",
20272044
zTagUuid, zTagUuid);
20282045
branchMove = 0;
20292046
if( permitHooks && db_exists("SELECT 1 FROM event, blob"
20302047
" WHERE event.type='ci' AND event.objid=blob.rid"
2031
- " AND blob.uuid='%s'", zTagUuid) ){
2048
+ " AND blob.uuid=%Q", zTagUuid) ){
20322049
zScript = xfer_commit_code();
20332050
zUuid = zTagUuid;
20342051
}
20352052
}
20362053
zName = p->aTag[i].zName;
20372054
--- src/manifest.c
+++ src/manifest.c
@@ -47,10 +47,11 @@
47 /*
48 ** Flags for use with manifest_crosslink().
49 */
50 #define MC_NONE 0 /* default handling */
51 #define MC_PERMIT_HOOKS 1 /* permit hooks to execute */
 
52
53 /*
54 ** A single F-card within a manifest
55 */
56 struct ManifestFile {
@@ -360,10 +361,11 @@
360 char *z;
361 int n;
362 char *zUuid;
363 int sz = 0;
364 int isRepeat, hasSelfRefTag = 0;
 
365 static Bag seen;
366 const char *zErr = 0;
367
368 if( rid==0 ){
369 isRepeat = 1;
@@ -378,13 +380,13 @@
378 ** if that is not the case for this artifact.
379 */
380 if( !isRepeat ) g.parseCnt[0]++;
381 z = blob_materialize(pContent);
382 n = blob_size(pContent);
383 if( n<=0 || z[n-1]!='\n' ){
384 blob_reset(pContent);
385 blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
386 return 0;
387 }
388
389 /* Strip off the PGP signature if there is one.
390 */
@@ -403,10 +405,15 @@
403 if( verify_z_card(z, n)==2 ){
404 blob_reset(pContent);
405 blob_appendf(pErr, "incorrect Z-card cksum");
406 return 0;
407 }
 
 
 
 
 
408
409 /* Allocate a Manifest object to hold the parsed control artifact.
410 */
411 p = fossil_malloc( sizeof(*p) );
412 memset(p, 0, sizeof(*p));
@@ -944,13 +951,18 @@
944 if( !seenZ ) SYNTAX("missing Z-card on control");
945 p->type = CFTYPE_CONTROL;
946 }
947 md5sum_init();
948 if( !isRepeat ) g.parseCnt[p->type]++;
 
949 return p;
950
951 manifest_syntax_error:
 
 
 
 
952 if( zErr ){
953 blob_appendf(pErr, "line %d: %s", lineNo, zErr);
954 }else{
955 blob_appendf(pErr, "unknown error on line %d", lineNo);
956 }
@@ -1589,11 +1601,11 @@
1589 once = 0;
1590 zTitleExpr = db_get("ticket-title-expr", "title");
1591 zStatusColumn = db_get("ticket-status-column", "status");
1592 }
1593 zTitle = db_text("unknown",
1594 "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1595 zTitleExpr, pManifest->zTicketUuid
1596 );
1597 if( !isNew ){
1598 for(i=0; i<pManifest->nField; i++){
1599 if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
@@ -1610,11 +1622,11 @@
1610 }
1611 blob_appendf(&brief, "%h ticket [%s|%S].",
1612 zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
1613 }else{
1614 zNewStatus = db_text("unknown",
1615 "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1616 zStatusColumn, pManifest->zTicketUuid
1617 );
1618 blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
1619 "%d other change%s",
1620 pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
@@ -1733,23 +1745,29 @@
1733
1734 if( (p = manifest_cache_find(rid))!=0 ){
1735 blob_reset(pContent);
1736 }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
1737 assert( blob_is_reset(pContent) || pContent==0 );
1738 fossil_error(1, "syntax error in manifest");
 
 
 
1739 return 0;
1740 }
1741 if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
1742 manifest_destroy(p);
1743 assert( blob_is_reset(pContent) );
1744 fossil_error(1, "no manifest");
1745 return 0;
1746 }
1747 if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
1748 manifest_destroy(p);
1749 assert( blob_is_reset(pContent) );
1750 fossil_error(1, "cannot fetch baseline manifest");
 
 
 
1751 return 0;
1752 }
1753 db_begin_transaction();
1754 if( p->type==CFTYPE_MANIFEST ){
1755 if( permitHooks ){
@@ -1894,11 +1912,10 @@
1894 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
1895 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
1896 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
1897 p->rDate, rid, p->zUser, zComment,
1898 TAG_BGCOLOR, rid,
1899 TAG_BGCOLOR, rid,
1900 TAG_USER, rid,
1901 TAG_COMMENT, rid
1902 );
1903 fossil_free(zComment);
1904 }
@@ -2026,11 +2043,11 @@
2026 " Edit [%s|%S]:",
2027 zTagUuid, zTagUuid);
2028 branchMove = 0;
2029 if( permitHooks && db_exists("SELECT 1 FROM event, blob"
2030 " WHERE event.type='ci' AND event.objid=blob.rid"
2031 " AND blob.uuid='%s'", zTagUuid) ){
2032 zScript = xfer_commit_code();
2033 zUuid = zTagUuid;
2034 }
2035 }
2036 zName = p->aTag[i].zName;
2037
--- src/manifest.c
+++ src/manifest.c
@@ -47,10 +47,11 @@
47 /*
48 ** Flags for use with manifest_crosslink().
49 */
50 #define MC_NONE 0 /* default handling */
51 #define MC_PERMIT_HOOKS 1 /* permit hooks to execute */
52 #define MC_NO_ERRORS 2 /* do not issue errors for a bad parse */
53
54 /*
55 ** A single F-card within a manifest
56 */
57 struct ManifestFile {
@@ -360,10 +361,11 @@
361 char *z;
362 int n;
363 char *zUuid;
364 int sz = 0;
365 int isRepeat, hasSelfRefTag = 0;
366 Blob bUuid = BLOB_INITIALIZER;
367 static Bag seen;
368 const char *zErr = 0;
369
370 if( rid==0 ){
371 isRepeat = 1;
@@ -378,13 +380,13 @@
380 ** if that is not the case for this artifact.
381 */
382 if( !isRepeat ) g.parseCnt[0]++;
383 z = blob_materialize(pContent);
384 n = blob_size(pContent);
385 if( pErr && (n<=0 || z[n-1]!='\n') ){
386 blob_reset(pContent);
387 blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1);
388 return 0;
389 }
390
391 /* Strip off the PGP signature if there is one.
392 */
@@ -403,10 +405,15 @@
405 if( verify_z_card(z, n)==2 ){
406 blob_reset(pContent);
407 blob_appendf(pErr, "incorrect Z-card cksum");
408 return 0;
409 }
410
411 /* Store the UUID (before modifying the blob) only for error
412 ** reporting purposes.
413 */
414 sha1sum_blob(pContent, &bUuid);
415
416 /* Allocate a Manifest object to hold the parsed control artifact.
417 */
418 p = fossil_malloc( sizeof(*p) );
419 memset(p, 0, sizeof(*p));
@@ -944,13 +951,18 @@
951 if( !seenZ ) SYNTAX("missing Z-card on control");
952 p->type = CFTYPE_CONTROL;
953 }
954 md5sum_init();
955 if( !isRepeat ) g.parseCnt[p->type]++;
956 blob_reset(&bUuid);
957 return p;
958
959 manifest_syntax_error:
960 if(bUuid.nUsed){
961 blob_appendf(pErr, "manifest [%.40s] ", blob_str(&bUuid));
962 blob_reset(&bUuid);
963 }
964 if( zErr ){
965 blob_appendf(pErr, "line %d: %s", lineNo, zErr);
966 }else{
967 blob_appendf(pErr, "unknown error on line %d", lineNo);
968 }
@@ -1589,11 +1601,11 @@
1601 once = 0;
1602 zTitleExpr = db_get("ticket-title-expr", "title");
1603 zStatusColumn = db_get("ticket-status-column", "status");
1604 }
1605 zTitle = db_text("unknown",
1606 "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
1607 zTitleExpr, pManifest->zTicketUuid
1608 );
1609 if( !isNew ){
1610 for(i=0; i<pManifest->nField; i++){
1611 if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
@@ -1610,11 +1622,11 @@
1622 }
1623 blob_appendf(&brief, "%h ticket [%s|%S].",
1624 zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
1625 }else{
1626 zNewStatus = db_text("unknown",
1627 "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
1628 zStatusColumn, pManifest->zTicketUuid
1629 );
1630 blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
1631 "%d other change%s",
1632 pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
@@ -1733,23 +1745,29 @@
1745
1746 if( (p = manifest_cache_find(rid))!=0 ){
1747 blob_reset(pContent);
1748 }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
1749 assert( blob_is_reset(pContent) || pContent==0 );
1750 if( (flags & MC_NO_ERRORS)==0 ){
1751 fossil_error(1, "syntax error in manifest [%s]",
1752 db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
1753 }
1754 return 0;
1755 }
1756 if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
1757 manifest_destroy(p);
1758 assert( blob_is_reset(pContent) );
1759 if( (flags & MC_NO_ERRORS)==0 ) fossil_error(1, "no manifest");
1760 return 0;
1761 }
1762 if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
1763 manifest_destroy(p);
1764 assert( blob_is_reset(pContent) );
1765 if( (flags & MC_NO_ERRORS)==0 ){
1766 fossil_error(1, "cannot fetch baseline for manifest [%s]",
1767 db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
1768 }
1769 return 0;
1770 }
1771 db_begin_transaction();
1772 if( p->type==CFTYPE_MANIFEST ){
1773 if( permitHooks ){
@@ -1894,11 +1912,10 @@
1912 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
1913 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
1914 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
1915 p->rDate, rid, p->zUser, zComment,
1916 TAG_BGCOLOR, rid,
 
1917 TAG_USER, rid,
1918 TAG_COMMENT, rid
1919 );
1920 fossil_free(zComment);
1921 }
@@ -2026,11 +2043,11 @@
2043 " Edit [%s|%S]:",
2044 zTagUuid, zTagUuid);
2045 branchMove = 0;
2046 if( permitHooks && db_exists("SELECT 1 FROM event, blob"
2047 " WHERE event.type='ci' AND event.objid=blob.rid"
2048 " AND blob.uuid=%Q", zTagUuid) ){
2049 zScript = xfer_commit_code();
2050 zUuid = zTagUuid;
2051 }
2052 }
2053 zName = p->aTag[i].zName;
2054
+4 -4
--- src/merge3.c
+++ src/merge3.c
@@ -268,17 +268,17 @@
268268
nConflict++;
269269
while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
270270
sz++;
271271
}
272272
DEBUG( printf("CONFLICT %d\n", sz); )
273
- blob_appendf(pOut, mergeMarker[0]);
273
+ blob_append(pOut, mergeMarker[0], -1);
274274
i1 = output_one_side(pOut, pV1, aC1, i1, sz);
275
- blob_appendf(pOut, mergeMarker[1]);
275
+ blob_append(pOut, mergeMarker[1], -1);
276276
blob_copy_lines(pOut, pPivot, sz);
277
- blob_appendf(pOut, mergeMarker[2]);
277
+ blob_append(pOut, mergeMarker[2], -1);
278278
i2 = output_one_side(pOut, pV2, aC2, i2, sz);
279
- blob_appendf(pOut, mergeMarker[3]);
279
+ blob_append(pOut, mergeMarker[3], -1);
280280
}
281281
282282
/* If we are finished with an edit triple, advance to the next
283283
** triple.
284284
*/
285285
286286
ADDED src/mkbuiltin.c
--- src/merge3.c
+++ src/merge3.c
@@ -268,17 +268,17 @@
268 nConflict++;
269 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
270 sz++;
271 }
272 DEBUG( printf("CONFLICT %d\n", sz); )
273 blob_appendf(pOut, mergeMarker[0]);
274 i1 = output_one_side(pOut, pV1, aC1, i1, sz);
275 blob_appendf(pOut, mergeMarker[1]);
276 blob_copy_lines(pOut, pPivot, sz);
277 blob_appendf(pOut, mergeMarker[2]);
278 i2 = output_one_side(pOut, pV2, aC2, i2, sz);
279 blob_appendf(pOut, mergeMarker[3]);
280 }
281
282 /* If we are finished with an edit triple, advance to the next
283 ** triple.
284 */
285
286 DDED src/mkbuiltin.c
--- src/merge3.c
+++ src/merge3.c
@@ -268,17 +268,17 @@
268 nConflict++;
269 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
270 sz++;
271 }
272 DEBUG( printf("CONFLICT %d\n", sz); )
273 blob_append(pOut, mergeMarker[0], -1);
274 i1 = output_one_side(pOut, pV1, aC1, i1, sz);
275 blob_append(pOut, mergeMarker[1], -1);
276 blob_copy_lines(pOut, pPivot, sz);
277 blob_append(pOut, mergeMarker[2], -1);
278 i2 = output_one_side(pOut, pV2, aC2, i2, sz);
279 blob_append(pOut, mergeMarker[3], -1);
280 }
281
282 /* If we are finished with an edit triple, advance to the next
283 ** triple.
284 */
285
286 DDED src/mkbuiltin.c
--- a/src/mkbuiltin.c
+++ b/src/mkbuiltin.c
@@ -0,0 +1,61 @@
1
+/*
2
+** Con = argc-1/*
3
+ /*
4
+** Con = argc-1/*
5
+** Const/*
6
+** Copyright (st/*
7
+** Copyright (c) 2014 D. Richard Hipp
8
+**
9
+** This program is free software; you can redistribute it and/or
10
+** modify it under the terms of the Simplif Copvoid *a, const v*)a;
11
+ Resource *pB = esource*)b;
12
+ return strcmp(pA->zName, pB->zName) nRes = argc - 1;
13
+ aRes = malloc( nRes*sizeof(aRes[0]) );
14
+ if( aRes==0t (c) 2014 D. Richard Hip/return 1;
15
+ }
16
+aRes[ireturn nErr;
17
+}
18
+const char *zTail;
19
+ int nSlash = 0;
20
+ zTail = z;
21
+ while( z && z[0] ){
22
+ if( z[0]=='/' || z[0]=='\\' ){
23
+ nSlash++;
24
+ if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1];
25
+ }
26
+ z++;
27
+ }zTail);
28
+ for(j=Tail;/*
29
+** Con = argc-1/*
30
+** Const/*
31
+** Copyright (st/*
32
+** Copyright (c) 20gc-1/*
33
+** Const** Const/*
34
+** Copyright (st/*
35
+** Copyright (c) 2014 D. Richard Hipp
36
+**
37
+** This program is free software; you can redistribute it and/or
38
+** modify it under the terms of the Simplif Copvoid *a, const v*)a;
39
+ Resource *pB = esource*)b;
40
+ return strcmp(pA->zName, pB->zName) nRes = argc - 1;
41
+ aRes = malloc( nRes*sizeof(aRes[0]) );
42
+ if( aRes==0t (c) 2014 D. Richard Hip/return 1;
43
+ }
44
+aRes[ireturn nErr;
45
+}
46
+const char *zTail;
47
+ int nSlash = 0;
48
+ zTail = z;
49
+ while( z && z[0] ){
50
+ if( z[0]=='/' || z[0]=='\\' ){
51
+ nSlash++;
52
+ if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1];
53
+ }
54
+ z++;
55
+ }zTail);
56
+ for(j=Tail;/*
57
+** Con = argc-1/*
58
+** Const/*
59
+** Copyright (st/*
60
+** Copyright (c) 20gc-1/*
61
+** Const
--- a/src/mkbuiltin.c
+++ b/src/mkbuiltin.c
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/mkbuiltin.c
+++ b/src/mkbuiltin.c
@@ -0,0 +1,61 @@
1 /*
2 ** Con = argc-1/*
3 /*
4 ** Con = argc-1/*
5 ** Const/*
6 ** Copyright (st/*
7 ** Copyright (c) 2014 D. Richard Hipp
8 **
9 ** This program is free software; you can redistribute it and/or
10 ** modify it under the terms of the Simplif Copvoid *a, const v*)a;
11 Resource *pB = esource*)b;
12 return strcmp(pA->zName, pB->zName) nRes = argc - 1;
13 aRes = malloc( nRes*sizeof(aRes[0]) );
14 if( aRes==0t (c) 2014 D. Richard Hip/return 1;
15 }
16 aRes[ireturn nErr;
17 }
18 const char *zTail;
19 int nSlash = 0;
20 zTail = z;
21 while( z && z[0] ){
22 if( z[0]=='/' || z[0]=='\\' ){
23 nSlash++;
24 if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1];
25 }
26 z++;
27 }zTail);
28 for(j=Tail;/*
29 ** Con = argc-1/*
30 ** Const/*
31 ** Copyright (st/*
32 ** Copyright (c) 20gc-1/*
33 ** Const** Const/*
34 ** Copyright (st/*
35 ** Copyright (c) 2014 D. Richard Hipp
36 **
37 ** This program is free software; you can redistribute it and/or
38 ** modify it under the terms of the Simplif Copvoid *a, const v*)a;
39 Resource *pB = esource*)b;
40 return strcmp(pA->zName, pB->zName) nRes = argc - 1;
41 aRes = malloc( nRes*sizeof(aRes[0]) );
42 if( aRes==0t (c) 2014 D. Richard Hip/return 1;
43 }
44 aRes[ireturn nErr;
45 }
46 const char *zTail;
47 int nSlash = 0;
48 zTail = z;
49 while( z && z[0] ){
50 if( z[0]=='/' || z[0]=='\\' ){
51 nSlash++;
52 if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1];
53 }
54 z++;
55 }zTail);
56 for(j=Tail;/*
57 ** Con = argc-1/*
58 ** Const/*
59 ** Copyright (st/*
60 ** Copyright (c) 20gc-1/*
61 ** Const
+3 -3
--- src/moderate.c
+++ src/moderate.c
@@ -73,11 +73,11 @@
7373
"tagxref", "srcid",
7474
"tagxref", "rid",
7575
};
7676
int i;
7777
for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
78
- if( db_exists("SELECT 1 FROM %s WHERE %s=%d",
78
+ if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d",
7979
aTabField[i], aTabField[i+1], rid) ) return 1;
8080
}
8181
return 0;
8282
}
8383
@@ -152,15 +152,15 @@
152152
if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
153153
style_header("Pending Moderation Requests");
154154
@ <h2>All Pending Moderation Requests</h2>
155155
if( moderation_table_exists() ){
156156
blob_init(&sql, timeline_query_for_www(), -1);
157
- blob_appendf(&sql,
157
+ blob_append_sql(&sql,
158158
" AND event.objid IN (SELECT objid FROM modreq)"
159159
" ORDER BY event.mtime DESC"
160160
);
161
- db_prepare(&q, blob_str(&sql));
161
+ db_prepare(&q, "%s", blob_sql_text(&sql));
162162
www_print_timeline(&q, 0, 0, 0, 0);
163163
db_finalize(&q);
164164
}
165165
style_footer();
166166
}
167167
--- src/moderate.c
+++ src/moderate.c
@@ -73,11 +73,11 @@
73 "tagxref", "srcid",
74 "tagxref", "rid",
75 };
76 int i;
77 for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
78 if( db_exists("SELECT 1 FROM %s WHERE %s=%d",
79 aTabField[i], aTabField[i+1], rid) ) return 1;
80 }
81 return 0;
82 }
83
@@ -152,15 +152,15 @@
152 if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
153 style_header("Pending Moderation Requests");
154 @ <h2>All Pending Moderation Requests</h2>
155 if( moderation_table_exists() ){
156 blob_init(&sql, timeline_query_for_www(), -1);
157 blob_appendf(&sql,
158 " AND event.objid IN (SELECT objid FROM modreq)"
159 " ORDER BY event.mtime DESC"
160 );
161 db_prepare(&q, blob_str(&sql));
162 www_print_timeline(&q, 0, 0, 0, 0);
163 db_finalize(&q);
164 }
165 style_footer();
166 }
167
--- src/moderate.c
+++ src/moderate.c
@@ -73,11 +73,11 @@
73 "tagxref", "srcid",
74 "tagxref", "rid",
75 };
76 int i;
77 for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
78 if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d",
79 aTabField[i], aTabField[i+1], rid) ) return 1;
80 }
81 return 0;
82 }
83
@@ -152,15 +152,15 @@
152 if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
153 style_header("Pending Moderation Requests");
154 @ <h2>All Pending Moderation Requests</h2>
155 if( moderation_table_exists() ){
156 blob_init(&sql, timeline_query_for_www(), -1);
157 blob_append_sql(&sql,
158 " AND event.objid IN (SELECT objid FROM modreq)"
159 " ORDER BY event.mtime DESC"
160 );
161 db_prepare(&q, "%s", blob_sql_text(&sql));
162 www_print_timeline(&q, 0, 0, 0, 0);
163 db_finalize(&q);
164 }
165 style_footer();
166 }
167
+4 -4
--- src/name.c
+++ src/name.c
@@ -216,16 +216,16 @@
216216
char zUuid[UUID_SIZE+1];
217217
memcpy(zUuid, zTag, nTag+1);
218218
canonical16(zUuid, nTag);
219219
rid = 0;
220220
if( zType[0]=='*' ){
221
- db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid);
221
+ db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid);
222222
}else{
223223
db_prepare(&q,
224224
"SELECT blob.rid"
225225
" FROM blob, event"
226
- " WHERE blob.uuid GLOB '%s*'"
226
+ " WHERE blob.uuid GLOB '%q*'"
227227
" AND event.objid=blob.rid"
228228
" AND event.type GLOB '%q'",
229229
zUuid, zType
230230
);
231231
}
@@ -259,11 +259,11 @@
259259
}else{
260260
rid = db_int(0,
261261
"SELECT event.objid"
262262
" FROM event"
263263
" WHERE event.objid=%s"
264
- " AND event.type GLOB '%q'", zTag, zType);
264
+ " AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType);
265265
}
266266
}
267267
}
268268
return rid;
269269
}
@@ -554,11 +554,11 @@
554554
"SELECT tagname"
555555
" FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
556556
" WHERE tagxref.rid=%d"
557557
" AND tag.tagid IN (5,6,7,9)"
558558
" ORDER BY 1",
559
- rid, rid
559
+ rid
560560
);
561561
cnt = 0;
562562
while( db_step(&q)==SQLITE_ROW ){
563563
const char *zPrefix = cnt++ ? ", " : "raw-tags: ";
564564
fossil_print("%s%s", zPrefix, db_column_text(&q,0));
565565
--- src/name.c
+++ src/name.c
@@ -216,16 +216,16 @@
216 char zUuid[UUID_SIZE+1];
217 memcpy(zUuid, zTag, nTag+1);
218 canonical16(zUuid, nTag);
219 rid = 0;
220 if( zType[0]=='*' ){
221 db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid);
222 }else{
223 db_prepare(&q,
224 "SELECT blob.rid"
225 " FROM blob, event"
226 " WHERE blob.uuid GLOB '%s*'"
227 " AND event.objid=blob.rid"
228 " AND event.type GLOB '%q'",
229 zUuid, zType
230 );
231 }
@@ -259,11 +259,11 @@
259 }else{
260 rid = db_int(0,
261 "SELECT event.objid"
262 " FROM event"
263 " WHERE event.objid=%s"
264 " AND event.type GLOB '%q'", zTag, zType);
265 }
266 }
267 }
268 return rid;
269 }
@@ -554,11 +554,11 @@
554 "SELECT tagname"
555 " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
556 " WHERE tagxref.rid=%d"
557 " AND tag.tagid IN (5,6,7,9)"
558 " ORDER BY 1",
559 rid, rid
560 );
561 cnt = 0;
562 while( db_step(&q)==SQLITE_ROW ){
563 const char *zPrefix = cnt++ ? ", " : "raw-tags: ";
564 fossil_print("%s%s", zPrefix, db_column_text(&q,0));
565
--- src/name.c
+++ src/name.c
@@ -216,16 +216,16 @@
216 char zUuid[UUID_SIZE+1];
217 memcpy(zUuid, zTag, nTag+1);
218 canonical16(zUuid, nTag);
219 rid = 0;
220 if( zType[0]=='*' ){
221 db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid);
222 }else{
223 db_prepare(&q,
224 "SELECT blob.rid"
225 " FROM blob, event"
226 " WHERE blob.uuid GLOB '%q*'"
227 " AND event.objid=blob.rid"
228 " AND event.type GLOB '%q'",
229 zUuid, zType
230 );
231 }
@@ -259,11 +259,11 @@
259 }else{
260 rid = db_int(0,
261 "SELECT event.objid"
262 " FROM event"
263 " WHERE event.objid=%s"
264 " AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType);
265 }
266 }
267 }
268 return rid;
269 }
@@ -554,11 +554,11 @@
554 "SELECT tagname"
555 " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
556 " WHERE tagxref.rid=%d"
557 " AND tag.tagid IN (5,6,7,9)"
558 " ORDER BY 1",
559 rid
560 );
561 cnt = 0;
562 while( db_step(&q)==SQLITE_ROW ){
563 const char *zPrefix = cnt++ ? ", " : "raw-tags: ";
564 fossil_print("%s%s", zPrefix, db_column_text(&q,0));
565
+10 -10
--- src/path.c
+++ src/path.c
@@ -112,11 +112,11 @@
112112
** Compute the shortest path from iFrom to iTo
113113
**
114114
** If directOnly is true, then use only the "primary" links from parent to
115115
** child. In other words, ignore merges.
116116
**
117
-** Return a pointer to the beginning of the path (the iFrom node).
117
+** Return a pointer to the beginning of the path (the iFrom node).
118118
** Elements of the path can be traversed by following the PathNode.u.pTo
119119
** pointer chain.
120120
**
121121
** Return NULL if no path is found.
122122
*/
@@ -135,25 +135,25 @@
135135
if( iTo==iFrom ){
136136
path.pEnd = path.pStart;
137137
return path.pStart;
138138
}
139139
if( oneWayOnly && directOnly ){
140
- db_prepare(&s,
140
+ db_prepare(&s,
141141
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
142142
);
143143
}else if( oneWayOnly ){
144
- db_prepare(&s,
144
+ db_prepare(&s,
145145
"SELECT cid, 1 FROM plink WHERE pid=:pid "
146146
);
147147
}else if( directOnly ){
148
- db_prepare(&s,
148
+ db_prepare(&s,
149149
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
150150
"UNION ALL "
151151
"SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
152152
);
153153
}else{
154
- db_prepare(&s,
154
+ db_prepare(&s,
155155
"SELECT cid, 1 FROM plink WHERE pid=:pid "
156156
"UNION ALL "
157157
"SELECT pid, 0 FROM plink WHERE cid=:pid"
158158
);
159159
}
@@ -230,11 +230,11 @@
230230
" WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
231231
p->rid, p->rid);
232232
fossil_print("%4d: %5d %s", n, p->rid, z);
233233
fossil_free(z);
234234
if( p->u.pTo ){
235
- fossil_print(" is a %s of\n",
235
+ fossil_print(" is a %s of\n",
236236
p->u.pTo->fromIsParent ? "parent" : "child");
237237
}else{
238238
fossil_print("\n");
239239
}
240240
}
@@ -353,11 +353,11 @@
353353
/*
354354
** Compute all file name changes that occur going from checkin iFrom
355355
** to checkin iTo.
356356
**
357357
** The number of name changes is written into *pnChng. For each name
358
-** change, two integers are allocated for *piChng. The first is the
358
+** change, two integers are allocated for *piChng. The first is the
359359
** filename.fnid for the original name as seen in check-in iFrom and
360360
** the second is for new name as it is used in check-in iTo.
361361
**
362362
** Space to hold *piChng is obtained from fossil_malloc() and should
363363
** be released by the caller.
@@ -516,11 +516,11 @@
516516
g.argc -= 2;
517517
}
518518
}
519519
520520
/* Query to extract all rename operations */
521
-static const char zRenameQuery[] =
521
+static const char zRenameQuery[] =
522522
@ SELECT
523523
@ datetime(event.mtime),
524524
@ F.name AS old_name,
525525
@ T.name AS new_name,
526526
@ blob.uuid
@@ -531,11 +531,11 @@
531531
@ AND event.objid=mlink.mid
532532
@ AND event.type='ci'
533533
@ AND blob.rid=mlink.mid
534534
@ ORDER BY 1 DESC, 2;
535535
;
536
-
536
+
537537
/*
538538
** WEBPAGE: test-rename-list
539539
**
540540
** Print a list of all file rename operations throughout history.
541541
** This page is intended for for testing purposes only and may change
@@ -551,11 +551,11 @@
551551
@ <table border="1" width="100%%">
552552
@ <tr><th>Date &amp; Time</th>
553553
@ <th>Old Name</th>
554554
@ <th>New Name</th>
555555
@ <th>Check-in</th></tr>
556
- db_prepare(&q, zRenameQuery);
556
+ db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/);
557557
while( db_step(&q)==SQLITE_ROW ){
558558
const char *zDate = db_column_text(&q, 0);
559559
const char *zOld = db_column_text(&q, 1);
560560
const char *zNew = db_column_text(&q, 2);
561561
const char *zUuid = db_column_text(&q, 3);
562562
--- src/path.c
+++ src/path.c
@@ -112,11 +112,11 @@
112 ** Compute the shortest path from iFrom to iTo
113 **
114 ** If directOnly is true, then use only the "primary" links from parent to
115 ** child. In other words, ignore merges.
116 **
117 ** Return a pointer to the beginning of the path (the iFrom node).
118 ** Elements of the path can be traversed by following the PathNode.u.pTo
119 ** pointer chain.
120 **
121 ** Return NULL if no path is found.
122 */
@@ -135,25 +135,25 @@
135 if( iTo==iFrom ){
136 path.pEnd = path.pStart;
137 return path.pStart;
138 }
139 if( oneWayOnly && directOnly ){
140 db_prepare(&s,
141 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
142 );
143 }else if( oneWayOnly ){
144 db_prepare(&s,
145 "SELECT cid, 1 FROM plink WHERE pid=:pid "
146 );
147 }else if( directOnly ){
148 db_prepare(&s,
149 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
150 "UNION ALL "
151 "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
152 );
153 }else{
154 db_prepare(&s,
155 "SELECT cid, 1 FROM plink WHERE pid=:pid "
156 "UNION ALL "
157 "SELECT pid, 0 FROM plink WHERE cid=:pid"
158 );
159 }
@@ -230,11 +230,11 @@
230 " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
231 p->rid, p->rid);
232 fossil_print("%4d: %5d %s", n, p->rid, z);
233 fossil_free(z);
234 if( p->u.pTo ){
235 fossil_print(" is a %s of\n",
236 p->u.pTo->fromIsParent ? "parent" : "child");
237 }else{
238 fossil_print("\n");
239 }
240 }
@@ -353,11 +353,11 @@
353 /*
354 ** Compute all file name changes that occur going from checkin iFrom
355 ** to checkin iTo.
356 **
357 ** The number of name changes is written into *pnChng. For each name
358 ** change, two integers are allocated for *piChng. The first is the
359 ** filename.fnid for the original name as seen in check-in iFrom and
360 ** the second is for new name as it is used in check-in iTo.
361 **
362 ** Space to hold *piChng is obtained from fossil_malloc() and should
363 ** be released by the caller.
@@ -516,11 +516,11 @@
516 g.argc -= 2;
517 }
518 }
519
520 /* Query to extract all rename operations */
521 static const char zRenameQuery[] =
522 @ SELECT
523 @ datetime(event.mtime),
524 @ F.name AS old_name,
525 @ T.name AS new_name,
526 @ blob.uuid
@@ -531,11 +531,11 @@
531 @ AND event.objid=mlink.mid
532 @ AND event.type='ci'
533 @ AND blob.rid=mlink.mid
534 @ ORDER BY 1 DESC, 2;
535 ;
536
537 /*
538 ** WEBPAGE: test-rename-list
539 **
540 ** Print a list of all file rename operations throughout history.
541 ** This page is intended for for testing purposes only and may change
@@ -551,11 +551,11 @@
551 @ <table border="1" width="100%%">
552 @ <tr><th>Date &amp; Time</th>
553 @ <th>Old Name</th>
554 @ <th>New Name</th>
555 @ <th>Check-in</th></tr>
556 db_prepare(&q, zRenameQuery);
557 while( db_step(&q)==SQLITE_ROW ){
558 const char *zDate = db_column_text(&q, 0);
559 const char *zOld = db_column_text(&q, 1);
560 const char *zNew = db_column_text(&q, 2);
561 const char *zUuid = db_column_text(&q, 3);
562
--- src/path.c
+++ src/path.c
@@ -112,11 +112,11 @@
112 ** Compute the shortest path from iFrom to iTo
113 **
114 ** If directOnly is true, then use only the "primary" links from parent to
115 ** child. In other words, ignore merges.
116 **
117 ** Return a pointer to the beginning of the path (the iFrom node).
118 ** Elements of the path can be traversed by following the PathNode.u.pTo
119 ** pointer chain.
120 **
121 ** Return NULL if no path is found.
122 */
@@ -135,25 +135,25 @@
135 if( iTo==iFrom ){
136 path.pEnd = path.pStart;
137 return path.pStart;
138 }
139 if( oneWayOnly && directOnly ){
140 db_prepare(&s,
141 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
142 );
143 }else if( oneWayOnly ){
144 db_prepare(&s,
145 "SELECT cid, 1 FROM plink WHERE pid=:pid "
146 );
147 }else if( directOnly ){
148 db_prepare(&s,
149 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
150 "UNION ALL "
151 "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
152 );
153 }else{
154 db_prepare(&s,
155 "SELECT cid, 1 FROM plink WHERE pid=:pid "
156 "UNION ALL "
157 "SELECT pid, 0 FROM plink WHERE cid=:pid"
158 );
159 }
@@ -230,11 +230,11 @@
230 " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
231 p->rid, p->rid);
232 fossil_print("%4d: %5d %s", n, p->rid, z);
233 fossil_free(z);
234 if( p->u.pTo ){
235 fossil_print(" is a %s of\n",
236 p->u.pTo->fromIsParent ? "parent" : "child");
237 }else{
238 fossil_print("\n");
239 }
240 }
@@ -353,11 +353,11 @@
353 /*
354 ** Compute all file name changes that occur going from checkin iFrom
355 ** to checkin iTo.
356 **
357 ** The number of name changes is written into *pnChng. For each name
358 ** change, two integers are allocated for *piChng. The first is the
359 ** filename.fnid for the original name as seen in check-in iFrom and
360 ** the second is for new name as it is used in check-in iTo.
361 **
362 ** Space to hold *piChng is obtained from fossil_malloc() and should
363 ** be released by the caller.
@@ -516,11 +516,11 @@
516 g.argc -= 2;
517 }
518 }
519
520 /* Query to extract all rename operations */
521 static const char zRenameQuery[] =
522 @ SELECT
523 @ datetime(event.mtime),
524 @ F.name AS old_name,
525 @ T.name AS new_name,
526 @ blob.uuid
@@ -531,11 +531,11 @@
531 @ AND event.objid=mlink.mid
532 @ AND event.type='ci'
533 @ AND blob.rid=mlink.mid
534 @ ORDER BY 1 DESC, 2;
535 ;
536
537 /*
538 ** WEBPAGE: test-rename-list
539 **
540 ** Print a list of all file rename operations throughout history.
541 ** This page is intended for for testing purposes only and may change
@@ -551,11 +551,11 @@
551 @ <table border="1" width="100%%">
552 @ <tr><th>Date &amp; Time</th>
553 @ <th>Old Name</th>
554 @ <th>New Name</th>
555 @ <th>Check-in</th></tr>
556 db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/);
557 while( db_step(&q)==SQLITE_ROW ){
558 const char *zDate = db_column_text(&q, 0);
559 const char *zOld = db_column_text(&q, 1);
560 const char *zNew = db_column_text(&q, 2);
561 const char *zUuid = db_column_text(&q, 3);
562
+18 -14
--- src/printf.c
+++ src/printf.c
@@ -44,19 +44,20 @@
4444
#define etBLOB 11 /* Blob objects. %b */
4545
#define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */
4646
#define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */
4747
#define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
4848
NULL pointers replaced by SQL NULL. %Q */
49
-#define etPOINTER 15 /* The %p conversion */
50
-#define etHTMLIZE 16 /* Make text safe for HTML */
51
-#define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */
52
-#define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */
53
-#define etFOSSILIZE 19 /* The fossil header encoding format. */
54
-#define etPATH 20 /* Path type */
55
-#define etWIKISTR 21 /* Timeline comment text rendered from a char*: %w */
49
+#define etSQLESCAPE3 15 /* Double '"' characters within an indentifier. %w */
50
+#define etPOINTER 16 /* The %p conversion */
51
+#define etHTMLIZE 17 /* Make text safe for HTML */
52
+#define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */
53
+#define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */
54
+#define etFOSSILIZE 20 /* The fossil header encoding format. */
55
+#define etPATH 21 /* Path type */
56
+#define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
5657
#define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
57
-#define etROOT 24 /* String value of g.zTop: % */
58
+#define etROOT 24 /* String value of g.zTop: %R */
5859
5960
6061
/*
6162
** An "etByte" is an 8-bit unsigned value.
6263
*/
@@ -96,15 +97,16 @@
9697
{ 'z', 0, 6, etDYNSTRING, 0, 0 },
9798
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
9899
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
99100
{ 'b', 0, 2, etBLOB, 0, 0 },
100101
{ 'B', 0, 2, etBLOBSQL, 0, 0 },
101
- { 'w', 0, 2, etWIKISTR, 0, 0 },
102
+ { 'W', 0, 2, etWIKISTR, 0, 0 },
102103
{ 'h', 0, 4, etHTMLIZE, 0, 0 },
103104
{ 'R', 0, 0, etROOT, 0, 0 },
104105
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
105106
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
107
+ { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
106108
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
107109
{ 'S', 0, 4, etSTRINGID, 0, 0 },
108110
{ 'c', 0, 0, etCHARX, 0, 0 },
109111
{ 'o', 8, 0, etRADIX, 0, 2 },
110112
{ 'u', 10, 0, etRADIX, 0, 0 },
@@ -661,35 +663,37 @@
661663
length = j;
662664
assert( length==n+cnt+2 );
663665
break;
664666
}
665667
case etSQLESCAPE:
666
- case etSQLESCAPE2: {
668
+ case etSQLESCAPE2:
669
+ case etSQLESCAPE3: {
667670
int i, j, n, ch, isnull;
668671
int needQuote;
669672
int limit = flag_alternateform ? va_arg(ap,int) : -1;
673
+ char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */
670674
char *escarg = va_arg(ap,char*);
671675
isnull = escarg==0;
672676
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
673677
if( limit<0 ) limit = strlen(escarg);
674678
for(i=n=0; i<limit; i++){
675
- if( escarg[i]=='\'' ) n++;
679
+ if( escarg[i]==q ) n++;
676680
}
677681
needQuote = !isnull && xtype==etSQLESCAPE2;
678682
n += i + 1 + needQuote*2;
679683
if( n>etBUFSIZE ){
680684
bufpt = zExtra = fossil_malloc( n );
681685
}else{
682686
bufpt = buf;
683687
}
684688
j = 0;
685
- if( needQuote ) bufpt[j++] = '\'';
689
+ if( needQuote ) bufpt[j++] = q;
686690
for(i=0; i<limit; i++){
687691
bufpt[j++] = ch = escarg[i];
688
- if( ch=='\'' ) bufpt[j++] = ch;
692
+ if( ch==q ) bufpt[j++] = ch;
689693
}
690
- if( needQuote ) bufpt[j++] = '\'';
694
+ if( needQuote ) bufpt[j++] = q;
691695
bufpt[j] = 0;
692696
length = j;
693697
if( precision>=0 && precision<length ) length = precision;
694698
break;
695699
}
696700
--- src/printf.c
+++ src/printf.c
@@ -44,19 +44,20 @@
44 #define etBLOB 11 /* Blob objects. %b */
45 #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */
46 #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */
47 #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
48 NULL pointers replaced by SQL NULL. %Q */
49 #define etPOINTER 15 /* The %p conversion */
50 #define etHTMLIZE 16 /* Make text safe for HTML */
51 #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */
52 #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */
53 #define etFOSSILIZE 19 /* The fossil header encoding format. */
54 #define etPATH 20 /* Path type */
55 #define etWIKISTR 21 /* Timeline comment text rendered from a char*: %w */
 
56 #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
57 #define etROOT 24 /* String value of g.zTop: % */
58
59
60 /*
61 ** An "etByte" is an 8-bit unsigned value.
62 */
@@ -96,15 +97,16 @@
96 { 'z', 0, 6, etDYNSTRING, 0, 0 },
97 { 'q', 0, 4, etSQLESCAPE, 0, 0 },
98 { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
99 { 'b', 0, 2, etBLOB, 0, 0 },
100 { 'B', 0, 2, etBLOBSQL, 0, 0 },
101 { 'w', 0, 2, etWIKISTR, 0, 0 },
102 { 'h', 0, 4, etHTMLIZE, 0, 0 },
103 { 'R', 0, 0, etROOT, 0, 0 },
104 { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
105 { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
 
106 { 'F', 0, 4, etFOSSILIZE, 0, 0 },
107 { 'S', 0, 4, etSTRINGID, 0, 0 },
108 { 'c', 0, 0, etCHARX, 0, 0 },
109 { 'o', 8, 0, etRADIX, 0, 2 },
110 { 'u', 10, 0, etRADIX, 0, 0 },
@@ -661,35 +663,37 @@
661 length = j;
662 assert( length==n+cnt+2 );
663 break;
664 }
665 case etSQLESCAPE:
666 case etSQLESCAPE2: {
 
667 int i, j, n, ch, isnull;
668 int needQuote;
669 int limit = flag_alternateform ? va_arg(ap,int) : -1;
 
670 char *escarg = va_arg(ap,char*);
671 isnull = escarg==0;
672 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
673 if( limit<0 ) limit = strlen(escarg);
674 for(i=n=0; i<limit; i++){
675 if( escarg[i]=='\'' ) n++;
676 }
677 needQuote = !isnull && xtype==etSQLESCAPE2;
678 n += i + 1 + needQuote*2;
679 if( n>etBUFSIZE ){
680 bufpt = zExtra = fossil_malloc( n );
681 }else{
682 bufpt = buf;
683 }
684 j = 0;
685 if( needQuote ) bufpt[j++] = '\'';
686 for(i=0; i<limit; i++){
687 bufpt[j++] = ch = escarg[i];
688 if( ch=='\'' ) bufpt[j++] = ch;
689 }
690 if( needQuote ) bufpt[j++] = '\'';
691 bufpt[j] = 0;
692 length = j;
693 if( precision>=0 && precision<length ) length = precision;
694 break;
695 }
696
--- src/printf.c
+++ src/printf.c
@@ -44,19 +44,20 @@
44 #define etBLOB 11 /* Blob objects. %b */
45 #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */
46 #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */
47 #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
48 NULL pointers replaced by SQL NULL. %Q */
49 #define etSQLESCAPE3 15 /* Double '"' characters within an indentifier. %w */
50 #define etPOINTER 16 /* The %p conversion */
51 #define etHTMLIZE 17 /* Make text safe for HTML */
52 #define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */
53 #define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */
54 #define etFOSSILIZE 20 /* The fossil header encoding format. */
55 #define etPATH 21 /* Path type */
56 #define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
57 #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
58 #define etROOT 24 /* String value of g.zTop: %R */
59
60
61 /*
62 ** An "etByte" is an 8-bit unsigned value.
63 */
@@ -96,15 +97,16 @@
97 { 'z', 0, 6, etDYNSTRING, 0, 0 },
98 { 'q', 0, 4, etSQLESCAPE, 0, 0 },
99 { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
100 { 'b', 0, 2, etBLOB, 0, 0 },
101 { 'B', 0, 2, etBLOBSQL, 0, 0 },
102 { 'W', 0, 2, etWIKISTR, 0, 0 },
103 { 'h', 0, 4, etHTMLIZE, 0, 0 },
104 { 'R', 0, 0, etROOT, 0, 0 },
105 { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
106 { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
107 { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
108 { 'F', 0, 4, etFOSSILIZE, 0, 0 },
109 { 'S', 0, 4, etSTRINGID, 0, 0 },
110 { 'c', 0, 0, etCHARX, 0, 0 },
111 { 'o', 8, 0, etRADIX, 0, 2 },
112 { 'u', 10, 0, etRADIX, 0, 0 },
@@ -661,35 +663,37 @@
663 length = j;
664 assert( length==n+cnt+2 );
665 break;
666 }
667 case etSQLESCAPE:
668 case etSQLESCAPE2:
669 case etSQLESCAPE3: {
670 int i, j, n, ch, isnull;
671 int needQuote;
672 int limit = flag_alternateform ? va_arg(ap,int) : -1;
673 char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */
674 char *escarg = va_arg(ap,char*);
675 isnull = escarg==0;
676 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
677 if( limit<0 ) limit = strlen(escarg);
678 for(i=n=0; i<limit; i++){
679 if( escarg[i]==q ) n++;
680 }
681 needQuote = !isnull && xtype==etSQLESCAPE2;
682 n += i + 1 + needQuote*2;
683 if( n>etBUFSIZE ){
684 bufpt = zExtra = fossil_malloc( n );
685 }else{
686 bufpt = buf;
687 }
688 j = 0;
689 if( needQuote ) bufpt[j++] = q;
690 for(i=0; i<limit; i++){
691 bufpt[j++] = ch = escarg[i];
692 if( ch==q ) bufpt[j++] = ch;
693 }
694 if( needQuote ) bufpt[j++] = q;
695 bufpt[j] = 0;
696 length = j;
697 if( precision>=0 && precision<length ) length = precision;
698 break;
699 }
700
+9 -8
--- src/rebuild.c
+++ src/rebuild.c
@@ -81,12 +81,12 @@
8181
@ );
8282
;
8383
8484
static void rebuild_update_schema(void){
8585
int rc;
86
- db_multi_exec(zSchemaUpdates1);
87
- db_multi_exec(zSchemaUpdates2);
86
+ db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/);
87
+ db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/);
8888
8989
rc = db_exists("SELECT 1 FROM sqlite_master"
9090
" WHERE name='user' AND sql GLOB '* mtime *'");
9191
if( rc==0 ){
9292
db_multi_exec(
@@ -135,11 +135,11 @@
135135
if( rc==0 ){
136136
db_multi_exec(
137137
"CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
138138
"DROP TABLE reportfmt;"
139139
);
140
- db_multi_exec(zSchemaUpdates2);
140
+ db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/);
141141
db_multi_exec(
142142
"INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
143143
" SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
144144
"INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
145145
" SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
@@ -254,11 +254,12 @@
254254
/* We are doing "fossil rebuild" */
255255
manifest_crosslink(rid, pUse, MC_NONE);
256256
}else{
257257
/* We are doing "fossil deconstruct" */
258258
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
259
- char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
259
+ char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/,
260
+ zUuid, zUuid+prefixLength);
260261
blob_write_to_file(pUse,zFile);
261262
free(zFile);
262263
free(zUuid);
263264
blob_reset(pUse);
264265
}
@@ -355,11 +356,11 @@
355356
);
356357
if( zTable==0 ) break;
357358
db_multi_exec("DROP TABLE %Q", zTable);
358359
free(zTable);
359360
}
360
- db_multi_exec(zRepositorySchema2);
361
+ db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
361362
ticket_create_table(0);
362363
shun_artifacts();
363364
364365
db_multi_exec(
365366
"INSERT INTO unclustered"
@@ -587,13 +588,13 @@
587588
db_begin_transaction();
588589
ttyOutput = 1;
589590
errCnt = rebuild_db(randomizeFlag, 1, doClustering);
590591
reconstruct_private_table();
591592
db_multi_exec(
592
- "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());"
593
- "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());"
594
- "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());",
593
+ "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
594
+ "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
595
+ "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());",
595596
CONTENT_SCHEMA, AUX_SCHEMA, get_version()
596597
);
597598
if( errCnt && !forceFlag ){
598599
fossil_print(
599600
"%d errors. Rolling back changes. Use --force to force a commit.\n",
600601
--- src/rebuild.c
+++ src/rebuild.c
@@ -81,12 +81,12 @@
81 @ );
82 ;
83
84 static void rebuild_update_schema(void){
85 int rc;
86 db_multi_exec(zSchemaUpdates1);
87 db_multi_exec(zSchemaUpdates2);
88
89 rc = db_exists("SELECT 1 FROM sqlite_master"
90 " WHERE name='user' AND sql GLOB '* mtime *'");
91 if( rc==0 ){
92 db_multi_exec(
@@ -135,11 +135,11 @@
135 if( rc==0 ){
136 db_multi_exec(
137 "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
138 "DROP TABLE reportfmt;"
139 );
140 db_multi_exec(zSchemaUpdates2);
141 db_multi_exec(
142 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
143 " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
144 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
145 " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
@@ -254,11 +254,12 @@
254 /* We are doing "fossil rebuild" */
255 manifest_crosslink(rid, pUse, MC_NONE);
256 }else{
257 /* We are doing "fossil deconstruct" */
258 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
259 char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
 
260 blob_write_to_file(pUse,zFile);
261 free(zFile);
262 free(zUuid);
263 blob_reset(pUse);
264 }
@@ -355,11 +356,11 @@
355 );
356 if( zTable==0 ) break;
357 db_multi_exec("DROP TABLE %Q", zTable);
358 free(zTable);
359 }
360 db_multi_exec(zRepositorySchema2);
361 ticket_create_table(0);
362 shun_artifacts();
363
364 db_multi_exec(
365 "INSERT INTO unclustered"
@@ -587,13 +588,13 @@
587 db_begin_transaction();
588 ttyOutput = 1;
589 errCnt = rebuild_db(randomizeFlag, 1, doClustering);
590 reconstruct_private_table();
591 db_multi_exec(
592 "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());"
593 "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());"
594 "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());",
595 CONTENT_SCHEMA, AUX_SCHEMA, get_version()
596 );
597 if( errCnt && !forceFlag ){
598 fossil_print(
599 "%d errors. Rolling back changes. Use --force to force a commit.\n",
600
--- src/rebuild.c
+++ src/rebuild.c
@@ -81,12 +81,12 @@
81 @ );
82 ;
83
84 static void rebuild_update_schema(void){
85 int rc;
86 db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/);
87 db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/);
88
89 rc = db_exists("SELECT 1 FROM sqlite_master"
90 " WHERE name='user' AND sql GLOB '* mtime *'");
91 if( rc==0 ){
92 db_multi_exec(
@@ -135,11 +135,11 @@
135 if( rc==0 ){
136 db_multi_exec(
137 "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
138 "DROP TABLE reportfmt;"
139 );
140 db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/);
141 db_multi_exec(
142 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
143 " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
144 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
145 " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
@@ -254,11 +254,12 @@
254 /* We are doing "fossil rebuild" */
255 manifest_crosslink(rid, pUse, MC_NONE);
256 }else{
257 /* We are doing "fossil deconstruct" */
258 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
259 char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/,
260 zUuid, zUuid+prefixLength);
261 blob_write_to_file(pUse,zFile);
262 free(zFile);
263 free(zUuid);
264 blob_reset(pUse);
265 }
@@ -355,11 +356,11 @@
356 );
357 if( zTable==0 ) break;
358 db_multi_exec("DROP TABLE %Q", zTable);
359 free(zTable);
360 }
361 db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
362 ticket_create_table(0);
363 shun_artifacts();
364
365 db_multi_exec(
366 "INSERT INTO unclustered"
@@ -587,13 +588,13 @@
588 db_begin_transaction();
589 ttyOutput = 1;
590 errCnt = rebuild_db(randomizeFlag, 1, doClustering);
591 reconstruct_private_table();
592 db_multi_exec(
593 "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
594 "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
595 "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());",
596 CONTENT_SCHEMA, AUX_SCHEMA, get_version()
597 );
598 if( errCnt && !forceFlag ){
599 fossil_print(
600 "%d errors. Rolling back changes. Use --force to force a commit.\n",
601
+5 -7
--- src/report.c
+++ src/report.c
@@ -436,11 +436,11 @@
436436
if( zOwner==0 ) zOwner = g.zLogin;
437437
style_submenu_element("Cancel", "Cancel", "reportlist");
438438
if( rn>0 ){
439439
style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
440440
}
441
- style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
441
+ style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format");
442442
if( zErr ){
443443
@ <blockquote class="reportError">%h(zErr)</blockquote>
444444
}
445445
@ <form action="rptedit" method="post"><div>
446446
@ <input type="hidden" name="rn" value="%d(rn)" />
@@ -1070,11 +1070,11 @@
10701070
}
10711071
if( g.perm.NewTkt ){
10721072
style_submenu_element("New Ticket", "Create a new ticket",
10731073
"%s/tktnew", g.zTop);
10741074
}
1075
- style_header(zTitle);
1075
+ style_header("%s", zTitle);
10761076
output_color_key(zClrKey, 1,
10771077
"border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
10781078
@ <table border="1" cellpadding="2" cellspacing="0" class="report"
10791079
@ id="reportTable">
10801080
sState.rn = rn;
@@ -1112,21 +1112,19 @@
11121112
** show all reports, which can be used for ticket show.
11131113
** Output is written to stdout as tab delimited table
11141114
*/
11151115
void rpt_list_reports(void){
11161116
Stmt q;
1117
- const char aRptOutFrmt[] = "%s\t%s\n";
1118
-
11191117
fossil_print("Available reports:\n");
1120
- fossil_print(aRptOutFrmt,"report number","report title");
1121
- fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
1118
+ fossil_print("%s\t%s\n","report number","report title");
1119
+ fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle);
11221120
db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
11231121
while( db_step(&q)==SQLITE_ROW ){
11241122
const char *zRn = db_column_text(&q, 0);
11251123
const char *zTitle = db_column_text(&q, 1);
11261124
1127
- fossil_print(aRptOutFrmt,zRn,zTitle);
1125
+ fossil_print("%s\t%s\n",zRn,zTitle);
11281126
}
11291127
db_finalize(&q);
11301128
}
11311129
11321130
/*
11331131
--- src/report.c
+++ src/report.c
@@ -436,11 +436,11 @@
436 if( zOwner==0 ) zOwner = g.zLogin;
437 style_submenu_element("Cancel", "Cancel", "reportlist");
438 if( rn>0 ){
439 style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
440 }
441 style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
442 if( zErr ){
443 @ <blockquote class="reportError">%h(zErr)</blockquote>
444 }
445 @ <form action="rptedit" method="post"><div>
446 @ <input type="hidden" name="rn" value="%d(rn)" />
@@ -1070,11 +1070,11 @@
1070 }
1071 if( g.perm.NewTkt ){
1072 style_submenu_element("New Ticket", "Create a new ticket",
1073 "%s/tktnew", g.zTop);
1074 }
1075 style_header(zTitle);
1076 output_color_key(zClrKey, 1,
1077 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1078 @ <table border="1" cellpadding="2" cellspacing="0" class="report"
1079 @ id="reportTable">
1080 sState.rn = rn;
@@ -1112,21 +1112,19 @@
1112 ** show all reports, which can be used for ticket show.
1113 ** Output is written to stdout as tab delimited table
1114 */
1115 void rpt_list_reports(void){
1116 Stmt q;
1117 const char aRptOutFrmt[] = "%s\t%s\n";
1118
1119 fossil_print("Available reports:\n");
1120 fossil_print(aRptOutFrmt,"report number","report title");
1121 fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
1122 db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
1123 while( db_step(&q)==SQLITE_ROW ){
1124 const char *zRn = db_column_text(&q, 0);
1125 const char *zTitle = db_column_text(&q, 1);
1126
1127 fossil_print(aRptOutFrmt,zRn,zTitle);
1128 }
1129 db_finalize(&q);
1130 }
1131
1132 /*
1133
--- src/report.c
+++ src/report.c
@@ -436,11 +436,11 @@
436 if( zOwner==0 ) zOwner = g.zLogin;
437 style_submenu_element("Cancel", "Cancel", "reportlist");
438 if( rn>0 ){
439 style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
440 }
441 style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format");
442 if( zErr ){
443 @ <blockquote class="reportError">%h(zErr)</blockquote>
444 }
445 @ <form action="rptedit" method="post"><div>
446 @ <input type="hidden" name="rn" value="%d(rn)" />
@@ -1070,11 +1070,11 @@
1070 }
1071 if( g.perm.NewTkt ){
1072 style_submenu_element("New Ticket", "Create a new ticket",
1073 "%s/tktnew", g.zTop);
1074 }
1075 style_header("%s", zTitle);
1076 output_color_key(zClrKey, 1,
1077 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1078 @ <table border="1" cellpadding="2" cellspacing="0" class="report"
1079 @ id="reportTable">
1080 sState.rn = rn;
@@ -1112,21 +1112,19 @@
1112 ** show all reports, which can be used for ticket show.
1113 ** Output is written to stdout as tab delimited table
1114 */
1115 void rpt_list_reports(void){
1116 Stmt q;
 
 
1117 fossil_print("Available reports:\n");
1118 fossil_print("%s\t%s\n","report number","report title");
1119 fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle);
1120 db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
1121 while( db_step(&q)==SQLITE_ROW ){
1122 const char *zRn = db_column_text(&q, 0);
1123 const char *zTitle = db_column_text(&q, 1);
1124
1125 fossil_print("%s\t%s\n",zRn,zTitle);
1126 }
1127 db_finalize(&q);
1128 }
1129
1130 /*
1131
+10 -10
--- src/rss.c
+++ src/rss.c
@@ -76,11 +76,11 @@
7676
7777
if( zType[0]!='a' ){
7878
if( zType[0]=='c' && !g.perm.Read ) zType = "x";
7979
if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
8080
if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
81
- blob_appendf(&bSQL, " AND event.type=%Q", zType);
81
+ blob_append_sql(&bSQL, " AND event.type=%Q", zType);
8282
}else{
8383
if( !g.perm.Read ){
8484
if( g.perm.RdTkt && g.perm.RdWiki ){
8585
blob_append(&bSQL, " AND event.type!='ci'", -1);
8686
}else if( g.perm.RdTkt ){
@@ -122,18 +122,18 @@
122122
}else{
123123
nTagId = 0;
124124
}
125125
126126
if( nTagId==-1 ){
127
- blob_appendf(&bSQL, " AND 0");
127
+ blob_append_sql(&bSQL, " AND 0");
128128
}else if( nTagId!=0 ){
129
- blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
129
+ blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
130130
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
131131
}
132132
133133
if( zFilename ){
134
- blob_appendf(&bSQL,
134
+ blob_append_sql(&bSQL,
135135
" AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
136136
zFilename, filename_collation()
137137
);
138138
}
139139
@@ -160,11 +160,11 @@
160160
@ <link>%s(g.zBaseURL)</link>
161161
@ <description>%h(zProjectDescr)</description>
162162
@ <pubDate>%s(zPubDate)</pubDate>
163163
@ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
164164
free(zPubDate);
165
- db_prepare(&q, blob_str(&bSQL));
165
+ db_prepare(&q, "%s", blob_sql_text(&bSQL));
166166
blob_reset( &bSQL );
167167
while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
168168
const char *zId = db_column_text(&q, 1);
169169
const char *zCom = db_column_text(&q, 3);
170170
const char *zAuthor = db_column_text(&q, 4);
@@ -280,11 +280,11 @@
280280
281281
blob_zero(&bSQL);
282282
blob_append( &bSQL, zSQL1, -1 );
283283
284284
if( zType[0]!='a' ){
285
- blob_appendf(&bSQL, " AND event.type=%Q", zType);
285
+ blob_append_sql(&bSQL, " AND event.type=%Q", zType);
286286
}
287287
288288
if( zTicketUuid ){
289289
nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
290290
zTicketUuid);
@@ -306,18 +306,18 @@
306306
}else{
307307
nTagId = 0;
308308
}
309309
310310
if( nTagId==-1 ){
311
- blob_appendf(&bSQL, " AND 0");
311
+ blob_append_sql(&bSQL, " AND 0");
312312
}else if( nTagId!=0 ){
313
- blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
313
+ blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
314314
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
315315
}
316316
317317
if( zFilename ){
318
- blob_appendf(&bSQL,
318
+ blob_append_sql(&bSQL,
319319
" AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
320320
zFilename, filename_collation()
321321
);
322322
}
323323
@@ -343,11 +343,11 @@
343343
fossil_print("<description>%h</description>\n", zProjectDescr);
344344
fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
345345
fossil_print("<generator>Fossil version %s %s</generator>\n",
346346
MANIFEST_VERSION, MANIFEST_DATE);
347347
free(zPubDate);
348
- db_prepare(&q, blob_str(&bSQL));
348
+ db_prepare(&q, "%s", blob_sql_text(&bSQL));
349349
blob_reset( &bSQL );
350350
while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
351351
const char *zId = db_column_text(&q, 1);
352352
const char *zCom = db_column_text(&q, 3);
353353
const char *zAuthor = db_column_text(&q, 4);
354354
--- src/rss.c
+++ src/rss.c
@@ -76,11 +76,11 @@
76
77 if( zType[0]!='a' ){
78 if( zType[0]=='c' && !g.perm.Read ) zType = "x";
79 if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
80 if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
81 blob_appendf(&bSQL, " AND event.type=%Q", zType);
82 }else{
83 if( !g.perm.Read ){
84 if( g.perm.RdTkt && g.perm.RdWiki ){
85 blob_append(&bSQL, " AND event.type!='ci'", -1);
86 }else if( g.perm.RdTkt ){
@@ -122,18 +122,18 @@
122 }else{
123 nTagId = 0;
124 }
125
126 if( nTagId==-1 ){
127 blob_appendf(&bSQL, " AND 0");
128 }else if( nTagId!=0 ){
129 blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
130 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
131 }
132
133 if( zFilename ){
134 blob_appendf(&bSQL,
135 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
136 zFilename, filename_collation()
137 );
138 }
139
@@ -160,11 +160,11 @@
160 @ <link>%s(g.zBaseURL)</link>
161 @ <description>%h(zProjectDescr)</description>
162 @ <pubDate>%s(zPubDate)</pubDate>
163 @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
164 free(zPubDate);
165 db_prepare(&q, blob_str(&bSQL));
166 blob_reset( &bSQL );
167 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
168 const char *zId = db_column_text(&q, 1);
169 const char *zCom = db_column_text(&q, 3);
170 const char *zAuthor = db_column_text(&q, 4);
@@ -280,11 +280,11 @@
280
281 blob_zero(&bSQL);
282 blob_append( &bSQL, zSQL1, -1 );
283
284 if( zType[0]!='a' ){
285 blob_appendf(&bSQL, " AND event.type=%Q", zType);
286 }
287
288 if( zTicketUuid ){
289 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
290 zTicketUuid);
@@ -306,18 +306,18 @@
306 }else{
307 nTagId = 0;
308 }
309
310 if( nTagId==-1 ){
311 blob_appendf(&bSQL, " AND 0");
312 }else if( nTagId!=0 ){
313 blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
314 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
315 }
316
317 if( zFilename ){
318 blob_appendf(&bSQL,
319 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
320 zFilename, filename_collation()
321 );
322 }
323
@@ -343,11 +343,11 @@
343 fossil_print("<description>%h</description>\n", zProjectDescr);
344 fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
345 fossil_print("<generator>Fossil version %s %s</generator>\n",
346 MANIFEST_VERSION, MANIFEST_DATE);
347 free(zPubDate);
348 db_prepare(&q, blob_str(&bSQL));
349 blob_reset( &bSQL );
350 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
351 const char *zId = db_column_text(&q, 1);
352 const char *zCom = db_column_text(&q, 3);
353 const char *zAuthor = db_column_text(&q, 4);
354
--- src/rss.c
+++ src/rss.c
@@ -76,11 +76,11 @@
76
77 if( zType[0]!='a' ){
78 if( zType[0]=='c' && !g.perm.Read ) zType = "x";
79 if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
80 if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
81 blob_append_sql(&bSQL, " AND event.type=%Q", zType);
82 }else{
83 if( !g.perm.Read ){
84 if( g.perm.RdTkt && g.perm.RdWiki ){
85 blob_append(&bSQL, " AND event.type!='ci'", -1);
86 }else if( g.perm.RdTkt ){
@@ -122,18 +122,18 @@
122 }else{
123 nTagId = 0;
124 }
125
126 if( nTagId==-1 ){
127 blob_append_sql(&bSQL, " AND 0");
128 }else if( nTagId!=0 ){
129 blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
130 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
131 }
132
133 if( zFilename ){
134 blob_append_sql(&bSQL,
135 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
136 zFilename, filename_collation()
137 );
138 }
139
@@ -160,11 +160,11 @@
160 @ <link>%s(g.zBaseURL)</link>
161 @ <description>%h(zProjectDescr)</description>
162 @ <pubDate>%s(zPubDate)</pubDate>
163 @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
164 free(zPubDate);
165 db_prepare(&q, "%s", blob_sql_text(&bSQL));
166 blob_reset( &bSQL );
167 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
168 const char *zId = db_column_text(&q, 1);
169 const char *zCom = db_column_text(&q, 3);
170 const char *zAuthor = db_column_text(&q, 4);
@@ -280,11 +280,11 @@
280
281 blob_zero(&bSQL);
282 blob_append( &bSQL, zSQL1, -1 );
283
284 if( zType[0]!='a' ){
285 blob_append_sql(&bSQL, " AND event.type=%Q", zType);
286 }
287
288 if( zTicketUuid ){
289 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
290 zTicketUuid);
@@ -306,18 +306,18 @@
306 }else{
307 nTagId = 0;
308 }
309
310 if( nTagId==-1 ){
311 blob_append_sql(&bSQL, " AND 0");
312 }else if( nTagId!=0 ){
313 blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
314 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
315 }
316
317 if( zFilename ){
318 blob_append_sql(&bSQL,
319 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
320 zFilename, filename_collation()
321 );
322 }
323
@@ -343,11 +343,11 @@
343 fossil_print("<description>%h</description>\n", zProjectDescr);
344 fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
345 fossil_print("<generator>Fossil version %s %s</generator>\n",
346 MANIFEST_VERSION, MANIFEST_DATE);
347 free(zPubDate);
348 db_prepare(&q, "%s", blob_sql_text(&bSQL));
349 blob_reset( &bSQL );
350 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
351 const char *zId = db_column_text(&q, 1);
352 const char *zCom = db_column_text(&q, 3);
353 const char *zAuthor = db_column_text(&q, 4);
354
+2 -2
--- src/search.c
+++ src/search.c
@@ -231,13 +231,13 @@
231231
iBest = db_int(0, "SELECT max(x) FROM srch");
232232
blob_append(&sql,
233233
"SELECT rid, uuid, date, comment, 0, 0 FROM srch "
234234
"WHERE 1 ", -1);
235235
if(!fAll){
236
- blob_appendf(&sql,"AND x>%d ", iBest/3);
236
+ blob_append_sql(&sql,"AND x>%d ", iBest/3);
237237
}
238238
blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
239
- db_prepare(&q, blob_str(&sql));
239
+ db_prepare(&q, "%s", blob_sql_text(&sql));
240240
blob_reset(&sql);
241241
print_timeline(&q, nLimit, width, 0);
242242
db_finalize(&q);
243243
}
244244
--- src/search.c
+++ src/search.c
@@ -231,13 +231,13 @@
231 iBest = db_int(0, "SELECT max(x) FROM srch");
232 blob_append(&sql,
233 "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
234 "WHERE 1 ", -1);
235 if(!fAll){
236 blob_appendf(&sql,"AND x>%d ", iBest/3);
237 }
238 blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
239 db_prepare(&q, blob_str(&sql));
240 blob_reset(&sql);
241 print_timeline(&q, nLimit, width, 0);
242 db_finalize(&q);
243 }
244
--- src/search.c
+++ src/search.c
@@ -231,13 +231,13 @@
231 iBest = db_int(0, "SELECT max(x) FROM srch");
232 blob_append(&sql,
233 "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
234 "WHERE 1 ", -1);
235 if(!fAll){
236 blob_append_sql(&sql,"AND x>%d ", iBest/3);
237 }
238 blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
239 db_prepare(&q, "%s", blob_sql_text(&sql));
240 blob_reset(&sql);
241 print_timeline(&q, nLimit, width, 0);
242 db_finalize(&q);
243 }
244
+12 -4
--- src/setup.c
+++ src/setup.c
@@ -375,11 +375,11 @@
375375
return;
376376
}
377377
login_verify_csrf_secret();
378378
db_multi_exec(
379379
"REPLACE INTO user(uid,login,info,pw,cap,mtime) "
380
- "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())",
380
+ "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
381381
uid, P("login"), P("info"), zPw, zCap
382382
);
383383
if( atoi(PD("all","0"))>0 ){
384384
Blob sql;
385385
char *zErr = 0;
@@ -477,11 +477,11 @@
477477
478478
/* Begin generating the page
479479
*/
480480
style_submenu_element("Cancel", "Cancel", "setup_ulist");
481481
if( uid ){
482
- style_header(mprintf("Edit User %h", zLogin));
482
+ style_header("Edit User %h", zLogin);
483483
}else{
484484
style_header("Add A New User");
485485
}
486486
@ <div class="ueditCapBox">
487487
@ <form action="%s(g.zPath)" method="post"><div>
@@ -1075,10 +1075,14 @@
10751075
@ every historical check-in, which can use a lot of CPU and bandwidth
10761076
@ even for relatively small projects.</p>
10771077
@
10781078
@ <p>Additional parameters that control this behavior:</p>
10791079
@ <blockquote>
1080
+ onoff_attribute("Enable hyperlinks for humans (as deduced from the UserAgent "
1081
+ " HTTP header string)",
1082
+ "auto-hyperlink-ishuman", "ahis", 0, 0);
1083
+ @ <br>
10801084
onoff_attribute("Require mouse movement before enabling hyperlinks",
10811085
"auto-hyperlink-mouseover", "ahmo", 0, 0);
10821086
@ <br>
10831087
entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5,
10841088
"auto-hyperlink-delay", "ah-delay", "10", 0);
@@ -1157,11 +1161,11 @@
11571161
login_check_credentials();
11581162
if( !g.perm.Setup ){
11591163
login_needed();
11601164
}
11611165
file_canonical_name(g.zRepositoryName, &fullName, 0);
1162
- zSelfRepo = mprintf(blob_str(&fullName));
1166
+ zSelfRepo = fossil_strdup(blob_str(&fullName));
11631167
blob_reset(&fullName);
11641168
if( P("join")!=0 ){
11651169
login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
11661170
}else if( P("leave") ){
11671171
login_group_leave(&zErrMsg);
@@ -1331,11 +1335,15 @@
13311335
login_needed();
13321336
}
13331337
13341338
(void) aCmdHelp; /* NOTE: Silence compiler warning. */
13351339
style_header("Settings");
1336
- db_open_local(0);
1340
+ if(!g.repositoryOpen){
1341
+ /* Provide read-only access to versioned settings,
1342
+ but only if no repo file was explicitly provided. */
1343
+ db_open_local(0);
1344
+ }
13371345
db_begin_transaction();
13381346
@ <p>This page provides a simple interface to the "fossil setting" command.
13391347
@ See the "fossil help setting" output below for further information on
13401348
@ the meaning of each setting.</p><hr />
13411349
@ <form action="%s(g.zTop)/setup_settings" method="post"><div>
13421350
--- src/setup.c
+++ src/setup.c
@@ -375,11 +375,11 @@
375 return;
376 }
377 login_verify_csrf_secret();
378 db_multi_exec(
379 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
380 "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())",
381 uid, P("login"), P("info"), zPw, zCap
382 );
383 if( atoi(PD("all","0"))>0 ){
384 Blob sql;
385 char *zErr = 0;
@@ -477,11 +477,11 @@
477
478 /* Begin generating the page
479 */
480 style_submenu_element("Cancel", "Cancel", "setup_ulist");
481 if( uid ){
482 style_header(mprintf("Edit User %h", zLogin));
483 }else{
484 style_header("Add A New User");
485 }
486 @ <div class="ueditCapBox">
487 @ <form action="%s(g.zPath)" method="post"><div>
@@ -1075,10 +1075,14 @@
1075 @ every historical check-in, which can use a lot of CPU and bandwidth
1076 @ even for relatively small projects.</p>
1077 @
1078 @ <p>Additional parameters that control this behavior:</p>
1079 @ <blockquote>
 
 
 
 
1080 onoff_attribute("Require mouse movement before enabling hyperlinks",
1081 "auto-hyperlink-mouseover", "ahmo", 0, 0);
1082 @ <br>
1083 entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5,
1084 "auto-hyperlink-delay", "ah-delay", "10", 0);
@@ -1157,11 +1161,11 @@
1157 login_check_credentials();
1158 if( !g.perm.Setup ){
1159 login_needed();
1160 }
1161 file_canonical_name(g.zRepositoryName, &fullName, 0);
1162 zSelfRepo = mprintf(blob_str(&fullName));
1163 blob_reset(&fullName);
1164 if( P("join")!=0 ){
1165 login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
1166 }else if( P("leave") ){
1167 login_group_leave(&zErrMsg);
@@ -1331,11 +1335,15 @@
1331 login_needed();
1332 }
1333
1334 (void) aCmdHelp; /* NOTE: Silence compiler warning. */
1335 style_header("Settings");
1336 db_open_local(0);
 
 
 
 
1337 db_begin_transaction();
1338 @ <p>This page provides a simple interface to the "fossil setting" command.
1339 @ See the "fossil help setting" output below for further information on
1340 @ the meaning of each setting.</p><hr />
1341 @ <form action="%s(g.zTop)/setup_settings" method="post"><div>
1342
--- src/setup.c
+++ src/setup.c
@@ -375,11 +375,11 @@
375 return;
376 }
377 login_verify_csrf_secret();
378 db_multi_exec(
379 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
380 "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
381 uid, P("login"), P("info"), zPw, zCap
382 );
383 if( atoi(PD("all","0"))>0 ){
384 Blob sql;
385 char *zErr = 0;
@@ -477,11 +477,11 @@
477
478 /* Begin generating the page
479 */
480 style_submenu_element("Cancel", "Cancel", "setup_ulist");
481 if( uid ){
482 style_header("Edit User %h", zLogin);
483 }else{
484 style_header("Add A New User");
485 }
486 @ <div class="ueditCapBox">
487 @ <form action="%s(g.zPath)" method="post"><div>
@@ -1075,10 +1075,14 @@
1075 @ every historical check-in, which can use a lot of CPU and bandwidth
1076 @ even for relatively small projects.</p>
1077 @
1078 @ <p>Additional parameters that control this behavior:</p>
1079 @ <blockquote>
1080 onoff_attribute("Enable hyperlinks for humans (as deduced from the UserAgent "
1081 " HTTP header string)",
1082 "auto-hyperlink-ishuman", "ahis", 0, 0);
1083 @ <br>
1084 onoff_attribute("Require mouse movement before enabling hyperlinks",
1085 "auto-hyperlink-mouseover", "ahmo", 0, 0);
1086 @ <br>
1087 entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5,
1088 "auto-hyperlink-delay", "ah-delay", "10", 0);
@@ -1157,11 +1161,11 @@
1161 login_check_credentials();
1162 if( !g.perm.Setup ){
1163 login_needed();
1164 }
1165 file_canonical_name(g.zRepositoryName, &fullName, 0);
1166 zSelfRepo = fossil_strdup(blob_str(&fullName));
1167 blob_reset(&fullName);
1168 if( P("join")!=0 ){
1169 login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
1170 }else if( P("leave") ){
1171 login_group_leave(&zErrMsg);
@@ -1331,11 +1335,15 @@
1335 login_needed();
1336 }
1337
1338 (void) aCmdHelp; /* NOTE: Silence compiler warning. */
1339 style_header("Settings");
1340 if(!g.repositoryOpen){
1341 /* Provide read-only access to versioned settings,
1342 but only if no repo file was explicitly provided. */
1343 db_open_local(0);
1344 }
1345 db_begin_transaction();
1346 @ <p>This page provides a simple interface to the "fossil setting" command.
1347 @ See the "fossil help setting" output below for further information on
1348 @ the meaning of each setting.</p><hr />
1349 @ <form action="%s(g.zTop)/setup_settings" method="post"><div>
1350
+13 -1
--- src/shell.c
+++ src/shell.c
@@ -880,11 +880,11 @@
880880
for(i=0; i<nArg; i++){
881881
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
882882
}
883883
fprintf(p->out,"%s",p->newline);
884884
}
885
- if( azArg>0 ){
885
+ if( nArg>0 ){
886886
for(i=0; i<nArg; i++){
887887
output_csv(p, azArg[i], i<nArg-1);
888888
}
889889
fprintf(p->out,"%s",p->newline);
890890
}
@@ -1350,10 +1350,21 @@
13501350
}
13511351
}
13521352
sqlite3_finalize(pExplain);
13531353
sqlite3_free(zEQP);
13541354
}
1355
+
1356
+#if USE_SYSTEM_SQLITE+0==1
1357
+ /* Output TESTCTRL_EXPLAIN text of requested */
1358
+ if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){
1359
+ const char *zExplain = 0;
1360
+ sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1361
+ if( zExplain && zExplain[0] ){
1362
+ fprintf(pArg->out, "%s", zExplain);
1363
+ }
1364
+ }
1365
+#endif
13551366
13561367
/* If the shell is currently in ".explain" mode, gather the extra
13571368
** data required to add indents to the output.*/
13581369
if( pArg && pArg->mode==MODE_Explain ){
13591370
explain_data_prepare(pArg, pStmt);
@@ -3723,10 +3734,11 @@
37233734
}
37243735
}
37253736
if( nSql ){
37263737
if( !_all_whitespace(zSql) ){
37273738
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3739
+ errCnt++;
37283740
}
37293741
free(zSql);
37303742
}
37313743
free(zLine);
37323744
return errCnt>0;
37333745
--- src/shell.c
+++ src/shell.c
@@ -880,11 +880,11 @@
880 for(i=0; i<nArg; i++){
881 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
882 }
883 fprintf(p->out,"%s",p->newline);
884 }
885 if( azArg>0 ){
886 for(i=0; i<nArg; i++){
887 output_csv(p, azArg[i], i<nArg-1);
888 }
889 fprintf(p->out,"%s",p->newline);
890 }
@@ -1350,10 +1350,21 @@
1350 }
1351 }
1352 sqlite3_finalize(pExplain);
1353 sqlite3_free(zEQP);
1354 }
 
 
 
 
 
 
 
 
 
 
 
1355
1356 /* If the shell is currently in ".explain" mode, gather the extra
1357 ** data required to add indents to the output.*/
1358 if( pArg && pArg->mode==MODE_Explain ){
1359 explain_data_prepare(pArg, pStmt);
@@ -3723,10 +3734,11 @@
3723 }
3724 }
3725 if( nSql ){
3726 if( !_all_whitespace(zSql) ){
3727 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
 
3728 }
3729 free(zSql);
3730 }
3731 free(zLine);
3732 return errCnt>0;
3733
--- src/shell.c
+++ src/shell.c
@@ -880,11 +880,11 @@
880 for(i=0; i<nArg; i++){
881 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
882 }
883 fprintf(p->out,"%s",p->newline);
884 }
885 if( nArg>0 ){
886 for(i=0; i<nArg; i++){
887 output_csv(p, azArg[i], i<nArg-1);
888 }
889 fprintf(p->out,"%s",p->newline);
890 }
@@ -1350,10 +1350,21 @@
1350 }
1351 }
1352 sqlite3_finalize(pExplain);
1353 sqlite3_free(zEQP);
1354 }
1355
1356 #if USE_SYSTEM_SQLITE+0==1
1357 /* Output TESTCTRL_EXPLAIN text of requested */
1358 if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){
1359 const char *zExplain = 0;
1360 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1361 if( zExplain && zExplain[0] ){
1362 fprintf(pArg->out, "%s", zExplain);
1363 }
1364 }
1365 #endif
1366
1367 /* If the shell is currently in ".explain" mode, gather the extra
1368 ** data required to add indents to the output.*/
1369 if( pArg && pArg->mode==MODE_Explain ){
1370 explain_data_prepare(pArg, pStmt);
@@ -3723,10 +3734,11 @@
3734 }
3735 }
3736 if( nSql ){
3737 if( !_all_whitespace(zSql) ){
3738 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3739 errCnt++;
3740 }
3741 free(zSql);
3742 }
3743 free(zLine);
3744 return errCnt>0;
3745
+9 -9
--- src/shun.c
+++ src/shun.c
@@ -43,12 +43,11 @@
4343
int cnt = 0;
4444
const char *zUuid = P("uuid");
4545
const char *zShun = P("shun");
4646
const char *zAccept = P("accept");
4747
const char *zRcvid = P("rcvid");
48
- int nRcvid;
49
- int nUuid;
48
+ int nRcvid = 0;
5049
int numRows = 3;
5150
char *zCanonical = 0;
5251
5352
login_check_credentials();
5453
if( !g.perm.Admin ){
@@ -79,11 +78,11 @@
7978
i++;
8079
}
8180
zCanonical[j+1] = zCanonical[j] = 0;
8281
p = zCanonical;
8382
while( *p ){
84
- nUuid = strlen(p);
83
+ int nUuid = strlen(p);
8584
if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
8685
@ <p class="generalError">Error: Bad artifact IDs.</p>
8786
fossil_free(zCanonical);
8887
zCanonical = 0;
8988
break;
@@ -98,12 +97,12 @@
9897
if( zUuid && P("sub") ){
9998
const char *p = zUuid;
10099
int allExist = 1;
101100
login_verify_csrf_secret();
102101
while( *p ){
103
- db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p);
104
- if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){
102
+ db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
103
+ if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
105104
allExist = 0;
106105
}
107106
p += UUID_SIZE+1;
108107
}
109108
if( allExist ){
@@ -128,11 +127,11 @@
128127
int rid, tagid;
129128
login_verify_csrf_secret();
130129
while( *p ){
131130
db_multi_exec(
132131
"INSERT OR IGNORE INTO shun(uuid,mtime)"
133
- " VALUES('%s', now())", p);
132
+ " VALUES(%Q, now())", p);
134133
db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
135134
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
136135
if( rid ){
137136
db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
138137
}
@@ -152,11 +151,12 @@
152151
@ They will be removed from the repository the next time the repository
153152
@ is rebuilt using the <b>fossil rebuild</b> command-line</p>
154153
}
155154
if( zRcvid ){
156155
nRcvid = atoi(zRcvid);
157
- numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid);
156
+ numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d",
157
+ nRcvid);
158158
}
159159
@ <p>A shunned artifact will not be pushed nor accepted in a pull and the
160160
@ artifact content will be purged from the repository the next time the
161161
@ repository is rebuilt. A list of shunned artifacts can be seen at the
162162
@ bottom of this page.</p>
@@ -183,11 +183,11 @@
183183
login_insert_csrf_secret();
184184
@ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
185185
if( zShun ){
186186
if( strlen(zShun) ){
187187
@ %h(zShun)
188
- }else if( zRcvid ){
188
+ }else if( nRcvid ){
189189
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
190190
while( db_step(&q)==SQLITE_ROW ){
191191
@ %s(db_column_text(&q, 0))
192192
}
193193
db_finalize(&q);
@@ -210,11 +210,11 @@
210210
login_insert_csrf_secret();
211211
@ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
212212
if( zAccept ){
213213
if( strlen(zAccept) ){
214214
@ %h(zAccept)
215
- }else if( zRcvid ){
215
+ }else if( nRcvid ){
216216
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
217217
while( db_step(&q)==SQLITE_ROW ){
218218
@ %s(db_column_text(&q, 0))
219219
}
220220
db_finalize(&q);
221221
--- src/shun.c
+++ src/shun.c
@@ -43,12 +43,11 @@
43 int cnt = 0;
44 const char *zUuid = P("uuid");
45 const char *zShun = P("shun");
46 const char *zAccept = P("accept");
47 const char *zRcvid = P("rcvid");
48 int nRcvid;
49 int nUuid;
50 int numRows = 3;
51 char *zCanonical = 0;
52
53 login_check_credentials();
54 if( !g.perm.Admin ){
@@ -79,11 +78,11 @@
79 i++;
80 }
81 zCanonical[j+1] = zCanonical[j] = 0;
82 p = zCanonical;
83 while( *p ){
84 nUuid = strlen(p);
85 if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
86 @ <p class="generalError">Error: Bad artifact IDs.</p>
87 fossil_free(zCanonical);
88 zCanonical = 0;
89 break;
@@ -98,12 +97,12 @@
98 if( zUuid && P("sub") ){
99 const char *p = zUuid;
100 int allExist = 1;
101 login_verify_csrf_secret();
102 while( *p ){
103 db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p);
104 if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){
105 allExist = 0;
106 }
107 p += UUID_SIZE+1;
108 }
109 if( allExist ){
@@ -128,11 +127,11 @@
128 int rid, tagid;
129 login_verify_csrf_secret();
130 while( *p ){
131 db_multi_exec(
132 "INSERT OR IGNORE INTO shun(uuid,mtime)"
133 " VALUES('%s', now())", p);
134 db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
135 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
136 if( rid ){
137 db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
138 }
@@ -152,11 +151,12 @@
152 @ They will be removed from the repository the next time the repository
153 @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
154 }
155 if( zRcvid ){
156 nRcvid = atoi(zRcvid);
157 numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid);
 
158 }
159 @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
160 @ artifact content will be purged from the repository the next time the
161 @ repository is rebuilt. A list of shunned artifacts can be seen at the
162 @ bottom of this page.</p>
@@ -183,11 +183,11 @@
183 login_insert_csrf_secret();
184 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
185 if( zShun ){
186 if( strlen(zShun) ){
187 @ %h(zShun)
188 }else if( zRcvid ){
189 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
190 while( db_step(&q)==SQLITE_ROW ){
191 @ %s(db_column_text(&q, 0))
192 }
193 db_finalize(&q);
@@ -210,11 +210,11 @@
210 login_insert_csrf_secret();
211 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
212 if( zAccept ){
213 if( strlen(zAccept) ){
214 @ %h(zAccept)
215 }else if( zRcvid ){
216 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
217 while( db_step(&q)==SQLITE_ROW ){
218 @ %s(db_column_text(&q, 0))
219 }
220 db_finalize(&q);
221
--- src/shun.c
+++ src/shun.c
@@ -43,12 +43,11 @@
43 int cnt = 0;
44 const char *zUuid = P("uuid");
45 const char *zShun = P("shun");
46 const char *zAccept = P("accept");
47 const char *zRcvid = P("rcvid");
48 int nRcvid = 0;
 
49 int numRows = 3;
50 char *zCanonical = 0;
51
52 login_check_credentials();
53 if( !g.perm.Admin ){
@@ -79,11 +78,11 @@
78 i++;
79 }
80 zCanonical[j+1] = zCanonical[j] = 0;
81 p = zCanonical;
82 while( *p ){
83 int nUuid = strlen(p);
84 if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
85 @ <p class="generalError">Error: Bad artifact IDs.</p>
86 fossil_free(zCanonical);
87 zCanonical = 0;
88 break;
@@ -98,12 +97,12 @@
97 if( zUuid && P("sub") ){
98 const char *p = zUuid;
99 int allExist = 1;
100 login_verify_csrf_secret();
101 while( *p ){
102 db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
103 if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
104 allExist = 0;
105 }
106 p += UUID_SIZE+1;
107 }
108 if( allExist ){
@@ -128,11 +127,11 @@
127 int rid, tagid;
128 login_verify_csrf_secret();
129 while( *p ){
130 db_multi_exec(
131 "INSERT OR IGNORE INTO shun(uuid,mtime)"
132 " VALUES(%Q, now())", p);
133 db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
134 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
135 if( rid ){
136 db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
137 }
@@ -152,11 +151,12 @@
151 @ They will be removed from the repository the next time the repository
152 @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
153 }
154 if( zRcvid ){
155 nRcvid = atoi(zRcvid);
156 numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d",
157 nRcvid);
158 }
159 @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
160 @ artifact content will be purged from the repository the next time the
161 @ repository is rebuilt. A list of shunned artifacts can be seen at the
162 @ bottom of this page.</p>
@@ -183,11 +183,11 @@
183 login_insert_csrf_secret();
184 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
185 if( zShun ){
186 if( strlen(zShun) ){
187 @ %h(zShun)
188 }else if( nRcvid ){
189 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
190 while( db_step(&q)==SQLITE_ROW ){
191 @ %s(db_column_text(&q, 0))
192 }
193 db_finalize(&q);
@@ -210,11 +210,11 @@
210 login_insert_csrf_secret();
211 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
212 if( zAccept ){
213 if( strlen(zAccept) ){
214 @ %h(zAccept)
215 }else if( nRcvid ){
216 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
217 while( db_step(&q)==SQLITE_ROW ){
218 @ %s(db_column_text(&q, 0))
219 }
220 db_finalize(&q);
221
+2 -2
--- src/skins.c
+++ src/skins.c
@@ -1392,18 +1392,18 @@
13921392
seen = 0;
13931393
for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
13941394
if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
13951395
seen = 1;
13961396
zCurrent = aBuiltinSkin[i].zValue;
1397
- db_multi_exec("%s", zCurrent);
1397
+ db_multi_exec("%s", zCurrent/*safe-for-%s*/);
13981398
break;
13991399
}
14001400
}
14011401
if( !seen ){
14021402
zName = skinVarName(z,0);
14031403
zCurrent = db_get(zName, 0);
1404
- db_multi_exec("%s", zCurrent);
1404
+ db_multi_exec("%s", zCurrent/*safe-for-%s*/);
14051405
}
14061406
}
14071407
14081408
style_header("Skins");
14091409
if( zErr ){
14101410
--- src/skins.c
+++ src/skins.c
@@ -1392,18 +1392,18 @@
1392 seen = 0;
1393 for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
1394 if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
1395 seen = 1;
1396 zCurrent = aBuiltinSkin[i].zValue;
1397 db_multi_exec("%s", zCurrent);
1398 break;
1399 }
1400 }
1401 if( !seen ){
1402 zName = skinVarName(z,0);
1403 zCurrent = db_get(zName, 0);
1404 db_multi_exec("%s", zCurrent);
1405 }
1406 }
1407
1408 style_header("Skins");
1409 if( zErr ){
1410
--- src/skins.c
+++ src/skins.c
@@ -1392,18 +1392,18 @@
1392 seen = 0;
1393 for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
1394 if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
1395 seen = 1;
1396 zCurrent = aBuiltinSkin[i].zValue;
1397 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
1398 break;
1399 }
1400 }
1401 if( !seen ){
1402 zName = skinVarName(z,0);
1403 zCurrent = db_get(zName, 0);
1404 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
1405 }
1406 }
1407
1408 style_header("Skins");
1409 if( zErr ){
1410
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -148,11 +148,15 @@
148148
extern int sqlite3_shell(int, char**);
149149
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
150150
db_close(1);
151151
sqlite3_shutdown();
152152
sqlite3_shell(g.argc-1, g.argv+1);
153
+ sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
153154
g.db = 0;
155
+ g.zMainDbType = 0;
156
+ g.repositoryOpen = 0;
157
+ g.localOpen = 0;
154158
}
155159
156160
/*
157161
** This routine is called by the patched sqlite3 command-line shell in order
158162
** to load the name and database connection for the open Fossil database.
159163
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -148,11 +148,15 @@
148 extern int sqlite3_shell(int, char**);
149 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
150 db_close(1);
151 sqlite3_shutdown();
152 sqlite3_shell(g.argc-1, g.argv+1);
 
153 g.db = 0;
 
 
 
154 }
155
156 /*
157 ** This routine is called by the patched sqlite3 command-line shell in order
158 ** to load the name and database connection for the open Fossil database.
159
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -148,11 +148,15 @@
148 extern int sqlite3_shell(int, char**);
149 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
150 db_close(1);
151 sqlite3_shutdown();
152 sqlite3_shell(g.argc-1, g.argv+1);
153 sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
154 g.db = 0;
155 g.zMainDbType = 0;
156 g.repositoryOpen = 0;
157 g.localOpen = 0;
158 }
159
160 /*
161 ** This routine is called by the patched sqlite3 command-line shell in order
162 ** to load the name and database connection for the open Fossil database.
163
+315 -232
--- 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.8.7. By combining all the individual C code files into this
3
+** version 3.8.7.1. 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.
@@ -229,13 +229,13 @@
229229
**
230230
** See also: [sqlite3_libversion()],
231231
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232232
** [sqlite_version()] and [sqlite_source_id()].
233233
*/
234
-#define SQLITE_VERSION "3.8.7"
234
+#define SQLITE_VERSION "3.8.7.1"
235235
#define SQLITE_VERSION_NUMBER 3008007
236
-#define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d"
236
+#define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52"
237237
238238
/*
239239
** CAPI3REF: Run-Time Library Version Numbers
240240
** KEYWORDS: sqlite3_version, sqlite3_sourceid
241241
**
@@ -7944,11 +7944,11 @@
79447944
** A macro to hint to the compiler that a function should not be
79457945
** inlined.
79467946
*/
79477947
#if defined(__GNUC__)
79487948
# define SQLITE_NOINLINE __attribute__((noinline))
7949
-#elif defined(_MSC_VER)
7949
+#elif defined(_MSC_VER) && _MSC_VER>=1310
79507950
# define SQLITE_NOINLINE __declspec(noinline)
79517951
#else
79527952
# define SQLITE_NOINLINE
79537953
#endif
79547954
@@ -11322,10 +11322,11 @@
1132211322
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
1132311323
int nSample; /* Number of elements in aSample[] */
1132411324
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
1132511325
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
1132611326
IndexSample *aSample; /* Samples of the left-most key */
11327
+ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this table */
1132711328
#endif
1132811329
};
1132911330
1133011331
/*
1133111332
** Allowed values for Index.idxType
@@ -12186,11 +12187,10 @@
1218612187
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
1218712188
#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
1218812189
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
1218912190
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
1219012191
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
12191
-#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
1219212192
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
1219312193
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
1219412194
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
1219512195
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
1219612196
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
@@ -13320,14 +13320,13 @@
1332013320
# define sqlite3MemdebugSetType(X,Y) /* no-op */
1332113321
# define sqlite3MemdebugHasType(X,Y) 1
1332213322
# define sqlite3MemdebugNoType(X,Y) 1
1332313323
#endif
1332413324
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
13325
-#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
13325
+#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
1332613326
#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
1332713327
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
13328
-#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
1332913328
1333013329
/*
1333113330
** Threading interface
1333213331
*/
1333313332
#if SQLITE_MAX_WORKER_THREADS>0
@@ -14095,21 +14094,19 @@
1409514094
#ifdef SQLITE_DEBUG
1409614095
u8 seekOp; /* Most recent seek operation on this cursor */
1409714096
#endif
1409814097
i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
1409914098
u8 nullRow; /* True if pointing to a row with no data */
14100
- u8 rowidIsValid; /* True if lastRowid is valid */
1410114099
u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
1410214100
Bool isEphemeral:1; /* True for an ephemeral table */
1410314101
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
1410414102
Bool isTable:1; /* True if a table requiring integer keys */
1410514103
Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
1410614104
Pgno pgnoRoot; /* Root page of the open btree cursor */
1410714105
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
1410814106
i64 seqCount; /* Sequence counter */
1410914107
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
14110
- i64 lastRowid; /* Rowid being deleted by OP_Delete */
1411114108
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
1411214109
1411314110
/* Cached information about the header for the data record that the
1411414111
** cursor is currently pointing to. Only valid if cacheStatus matches
1411514112
** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -14122,10 +14119,11 @@
1412214119
u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
1412314120
u32 payloadSize; /* Total number of bytes in the record */
1412414121
u32 szRow; /* Byte available in aRow */
1412514122
u32 iHdrOffset; /* Offset to next unparsed byte of the header */
1412614123
const u8 *aRow; /* Data for the current row, if all on one page */
14124
+ u32 *aOffset; /* Pointer to aType[nField] */
1412714125
u32 aType[1]; /* Type values for all entries in the record */
1412814126
/* 2*nField extra array elements allocated for aType[], beyond the one
1412914127
** static element declared in the structure. nField total array slots for
1413014128
** aType[] and nField+1 array slots for aOffset[] */
1413114129
};
@@ -14198,11 +14196,11 @@
1419814196
int n; /* Number of characters in string value, excluding '\0' */
1419914197
char *z; /* String or BLOB value */
1420014198
/* ShallowCopy only needs to copy the information above */
1420114199
char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
1420214200
int szMalloc; /* Size of the zMalloc allocation */
14203
- int iPadding1; /* Padding for 8-byte alignment */
14201
+ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
1420414202
sqlite3 *db; /* The associated database connection */
1420514203
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
1420614204
#ifdef SQLITE_DEBUG
1420714205
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
1420814206
void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
@@ -14406,10 +14404,11 @@
1440614404
** Function prototypes
1440714405
*/
1440814406
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
1440914407
void sqliteVdbePopStack(Vdbe*,int);
1441014408
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
14409
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
1441114410
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
1441214411
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
1441314412
#endif
1441414413
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
1441514414
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
@@ -17130,11 +17129,11 @@
1713017129
** allocation p. Also return true if p==NULL.
1713117130
**
1713217131
** This routine is designed for use within an assert() statement, to
1713317132
** verify the type of an allocation. For example:
1713417133
**
17135
-** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
17134
+** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
1713617135
*/
1713717136
SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
1713817137
int rc = 1;
1713917138
if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
1714017139
struct MemBlockHdr *pHdr;
@@ -17152,11 +17151,11 @@
1715217151
** allocation p. Also return true if p==NULL.
1715317152
**
1715417153
** This routine is designed for use within an assert() statement, to
1715517154
** verify the type of an allocation. For example:
1715617155
**
17157
-** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
17156
+** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
1715817157
*/
1715917158
SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
1716017159
int rc = 1;
1716117160
if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
1716217161
struct MemBlockHdr *pHdr;
@@ -20364,39 +20363,41 @@
2036420363
** Return the size of a memory allocation previously obtained from
2036520364
** sqlite3Malloc() or sqlite3_malloc().
2036620365
*/
2036720366
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
2036820367
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20369
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
2037020368
return sqlite3GlobalConfig.m.xSize(p);
2037120369
}
2037220370
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
2037320371
if( db==0 ){
20372
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20373
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
2037420374
return sqlite3MallocSize(p);
2037520375
}else{
2037620376
assert( sqlite3_mutex_held(db->mutex) );
2037720377
if( isLookaside(db, p) ){
2037820378
return db->lookaside.sz;
2037920379
}else{
20380
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20381
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20382
- assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20380
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20381
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
2038320382
return sqlite3GlobalConfig.m.xSize(p);
2038420383
}
2038520384
}
2038620385
}
2038720386
SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
20387
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20388
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
2038820389
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
2038920390
}
2039020391
2039120392
/*
2039220393
** Free memory previously obtained from sqlite3Malloc().
2039320394
*/
2039420395
SQLITE_API void sqlite3_free(void *p){
2039520396
if( p==0 ) return; /* IMP: R-49053-54554 */
20396
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
2039720397
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20398
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
2039820399
if( sqlite3GlobalConfig.bMemstat ){
2039920400
sqlite3_mutex_enter(mem0.mutex);
2040020401
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
2040120402
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
2040220403
sqlite3GlobalConfig.m.xFree(p);
@@ -20436,12 +20437,12 @@
2043620437
db->lookaside.pFree = pBuf;
2043720438
db->lookaside.nOut--;
2043820439
return;
2043920440
}
2044020441
}
20441
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20442
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20442
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20443
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
2044320444
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
2044420445
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
2044520446
sqlite3_free(p);
2044620447
}
2044720448
@@ -20449,10 +20450,12 @@
2044920450
** Change the size of an existing memory allocation
2045020451
*/
2045120452
SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
2045220453
int nOld, nNew, nDiff;
2045320454
void *pNew;
20455
+ assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20456
+ assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
2045420457
if( pOld==0 ){
2045520458
return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
2045620459
}
2045720460
if( nBytes==0 ){
2045820461
sqlite3_free(pOld); /* IMP: R-26507-47431 */
@@ -20475,12 +20478,10 @@
2047520478
nDiff = nNew - nOld;
2047620479
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
2047720480
mem0.alarmThreshold-nDiff ){
2047820481
sqlite3MallocAlarm(nDiff);
2047920482
}
20480
- assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20481
- assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
2048220483
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
2048320484
if( pNew==0 && mem0.alarmCallback ){
2048420485
sqlite3MallocAlarm((int)nBytes);
2048520486
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
2048620487
}
@@ -20589,12 +20590,12 @@
2058920590
#endif
2059020591
p = sqlite3Malloc(n);
2059120592
if( !p && db ){
2059220593
db->mallocFailed = 1;
2059320594
}
20594
- sqlite3MemdebugSetType(p, MEMTYPE_DB |
20595
- ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20595
+ sqlite3MemdebugSetType(p,
20596
+ (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
2059620597
return p;
2059720598
}
2059820599
2059920600
/*
2060020601
** Resize the block of memory pointed to by p to n bytes. If the
@@ -20616,19 +20617,18 @@
2061620617
if( pNew ){
2061720618
memcpy(pNew, p, db->lookaside.sz);
2061820619
sqlite3DbFree(db, p);
2061920620
}
2062020621
}else{
20621
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20622
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20622
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20623
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
2062320624
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
2062420625
pNew = sqlite3_realloc64(p, n);
2062520626
if( !pNew ){
20626
- sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
2062720627
db->mallocFailed = 1;
2062820628
}
20629
- sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
20629
+ sqlite3MemdebugSetType(pNew,
2063020630
(db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
2063120631
}
2063220632
}
2063320633
return pNew;
2063420634
}
@@ -20754,15 +20754,11 @@
2075420754
** HAVE_STRCHRNUL. If that routine is not available, this module
2075520755
** will supply its own. The built-in version is slower than
2075620756
** the glibc version so the glibc version is definitely preferred.
2075720757
*/
2075820758
#if !defined(HAVE_STRCHRNUL)
20759
-# if defined(linux)
20760
-# define HAVE_STRCHRNUL 1
20761
-# else
20762
-# define HAVE_STRCHRNUL 0
20763
-# endif
20759
+# define HAVE_STRCHRNUL 0
2076420760
#endif
2076520761
2076620762
2076720763
/*
2076820764
** Conversion types fall into various categories as defined by the
@@ -22091,18 +22087,18 @@
2209122087
#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
2209222088
/******************************** End Unix Pthreads *************************/
2209322089
2209422090
2209522091
/********************************* Win32 Threads ****************************/
22096
-#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
22092
+#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
2209722093
2209822094
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
2209922095
#include <process.h>
2210022096
2210122097
/* A running thread */
2210222098
struct SQLiteThread {
22103
- uintptr_t tid; /* The thread handle */
22099
+ void *tid; /* The thread handle */
2210422100
unsigned id; /* The thread identifier */
2210522101
void *(*xTask)(void*); /* The routine to run as a thread */
2210622102
void *pIn; /* Argument to xTask */
2210722103
void *pResult; /* Result of xTask */
2210822104
};
@@ -22146,11 +22142,11 @@
2214622142
if( sqlite3GlobalConfig.bCoreMutex==0 ){
2214722143
memset(p, 0, sizeof(*p));
2214822144
}else{
2214922145
p->xTask = xTask;
2215022146
p->pIn = pIn;
22151
- p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
22147
+ p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
2215222148
if( p->tid==0 ){
2215322149
memset(p, 0, sizeof(*p));
2215422150
}
2215522151
}
2215622152
if( p->xTask==0 ){
@@ -22184,11 +22180,11 @@
2218422180
if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
2218522181
sqlite3_free(p);
2218622182
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
2218722183
}
2218822184
22189
-#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
22185
+#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
2219022186
/******************************** End Win32 Threads *************************/
2219122187
2219222188
2219322189
/********************************* Single-Threaded **************************/
2219422190
#ifndef SQLITE_THREADS_IMPLEMENTED
@@ -33487,11 +33483,15 @@
3348733483
#endif
3348833484
3348933485
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
3349033486
DWORD))aSyscall[63].pCurrent)
3349133487
33488
+#if !SQLITE_OS_WINCE
3349233489
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
33490
+#else
33491
+ { "WaitForSingleObjectEx", (SYSCALL)0, 0 },
33492
+#endif
3349333493
3349433494
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
3349533495
BOOL))aSyscall[64].pCurrent)
3349633496
3349733497
#if SQLITE_OS_WINRT
@@ -33830,11 +33830,12 @@
3383033830
#else
3383133831
osSleep(milliseconds);
3383233832
#endif
3383333833
}
3383433834
33835
-#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
33835
+#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
33836
+ SQLITE_THREADSAFE>0
3383633837
SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
3383733838
DWORD rc;
3383833839
while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
3383933840
TRUE))==WAIT_IO_COMPLETION ){}
3384033841
return rc;
@@ -39855,11 +39856,11 @@
3985539856
assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
3985639857
assert( pCache->n90pct == pCache->nMax*9/10 );
3985739858
if( createFlag==1 && (
3985839859
nPinned>=pGroup->mxPinned
3985939860
|| nPinned>=pCache->n90pct
39860
- || pcache1UnderMemoryPressure(pCache)
39861
+ || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
3986139862
)){
3986239863
return 0;
3986339864
}
3986439865
3986539866
if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
@@ -42799,10 +42800,18 @@
4279942800
}else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
4280042801
if( pPager->journalOff==0 ){
4280142802
rc = SQLITE_OK;
4280242803
}else{
4280342804
rc = sqlite3OsTruncate(pPager->jfd, 0);
42805
+ if( rc==SQLITE_OK && pPager->fullSync ){
42806
+ /* Make sure the new file size is written into the inode right away.
42807
+ ** Otherwise the journal might resurrect following a power loss and
42808
+ ** cause the last transaction to roll back. See
42809
+ ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
42810
+ */
42811
+ rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
42812
+ }
4280442813
}
4280542814
pPager->journalOff = 0;
4280642815
}else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
4280742816
|| (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
4280842817
){
@@ -44476,17 +44485,19 @@
4447644485
if( !pNew ) rc = SQLITE_NOMEM;
4447744486
}
4447844487
4447944488
if( rc==SQLITE_OK ){
4448044489
pager_reset(pPager);
44481
- sqlite3PageFree(pPager->pTmpSpace);
44482
- pPager->pTmpSpace = pNew;
4448344490
rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
4448444491
}
4448544492
if( rc==SQLITE_OK ){
44493
+ sqlite3PageFree(pPager->pTmpSpace);
44494
+ pPager->pTmpSpace = pNew;
4448644495
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
4448744496
pPager->pageSize = pageSize;
44497
+ }else{
44498
+ sqlite3PageFree(pNew);
4448844499
}
4448944500
}
4449044501
4449144502
*pPageSize = pPager->pageSize;
4449244503
if( rc==SQLITE_OK ){
@@ -51649,11 +51660,11 @@
5164951660
int nRef; /* Number of references to this structure */
5165051661
BtShared *pNext; /* Next on a list of sharable BtShared structs */
5165151662
BtLock *pLock; /* List of locks held on this shared-btree struct */
5165251663
Btree *pWriter; /* Btree with currently open write transaction */
5165351664
#endif
51654
- u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
51665
+ u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
5165551666
};
5165651667
5165751668
/*
5165851669
** Allowed values for BtShared.btsFlags
5165951670
*/
@@ -52947,11 +52958,11 @@
5294752958
**
5294852959
** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
5294952960
** back to where it ought to be if this routine returns true.
5295052961
*/
5295152962
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
52952
- return pCur && pCur->eState!=CURSOR_VALID;
52963
+ return pCur->eState!=CURSOR_VALID;
5295352964
}
5295452965
5295552966
/*
5295652967
** This routine restores a cursor back to its original position after it
5295752968
** has been moved by some outside activity (such as a btree rebalance or
@@ -54279,11 +54290,12 @@
5427954290
#endif
5428054291
}
5428154292
5428254293
/*
5428354294
** Make sure pBt->pTmpSpace points to an allocation of
54284
-** MX_CELL_SIZE(pBt) bytes.
54295
+** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
54296
+** pointer.
5428554297
*/
5428654298
static void allocateTempSpace(BtShared *pBt){
5428754299
if( !pBt->pTmpSpace ){
5428854300
pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
5428954301
@@ -54294,21 +54306,32 @@
5429454306
** can mean that fillInCell() only initializes the first 2 or 3
5429554307
** bytes of pTmpSpace, but that the first 4 bytes are copied from
5429654308
** it into a database page. This is not actually a problem, but it
5429754309
** does cause a valgrind error when the 1 or 2 bytes of unitialized
5429854310
** data is passed to system call write(). So to avoid this error,
54299
- ** zero the first 4 bytes of temp space here. */
54300
- if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);
54311
+ ** zero the first 4 bytes of temp space here.
54312
+ **
54313
+ ** Also: Provide four bytes of initialized space before the
54314
+ ** beginning of pTmpSpace as an area available to prepend the
54315
+ ** left-child pointer to the beginning of a cell.
54316
+ */
54317
+ if( pBt->pTmpSpace ){
54318
+ memset(pBt->pTmpSpace, 0, 8);
54319
+ pBt->pTmpSpace += 4;
54320
+ }
5430154321
}
5430254322
}
5430354323
5430454324
/*
5430554325
** Free the pBt->pTmpSpace allocation
5430654326
*/
5430754327
static void freeTempSpace(BtShared *pBt){
54308
- sqlite3PageFree( pBt->pTmpSpace);
54309
- pBt->pTmpSpace = 0;
54328
+ if( pBt->pTmpSpace ){
54329
+ pBt->pTmpSpace -= 4;
54330
+ sqlite3PageFree(pBt->pTmpSpace);
54331
+ pBt->pTmpSpace = 0;
54332
+ }
5431054333
}
5431154334
5431254335
/*
5431354336
** Close an open database and invalidate all cursors.
5431454337
*/
@@ -58016,15 +58039,10 @@
5801658039
** pTemp is not null. Regardless of pTemp, allocate a new entry
5801758040
** in pPage->apOvfl[] and make it point to the cell content (either
5801858041
** in pTemp or the original pCell) and also record its index.
5801958042
** Allocating a new entry in pPage->aCell[] implies that
5802058043
** pPage->nOverflow is incremented.
58021
-**
58022
-** If nSkip is non-zero, then do not copy the first nSkip bytes of the
58023
-** cell. The caller will overwrite them after this function returns. If
58024
-** nSkip is non-zero, then pCell may not point to an invalid memory location
58025
-** (but pCell+nSkip is always valid).
5802658044
*/
5802758045
static void insertCell(
5802858046
MemPage *pPage, /* Page into which we are copying */
5802958047
int i, /* New cell becomes the i-th cell of the page */
5803058048
u8 *pCell, /* Content of the new cell */
@@ -58037,11 +58055,10 @@
5803758055
int j; /* Loop counter */
5803858056
int end; /* First byte past the last cell pointer in data[] */
5803958057
int ins; /* Index in data[] where new cell pointer is inserted */
5804058058
int cellOffset; /* Address of first cell pointer in data[] */
5804158059
u8 *data; /* The content of the whole page */
58042
- int nSkip = (iChild ? 4 : 0);
5804358060
5804458061
if( *pRC ) return;
5804558062
5804658063
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
5804758064
assert( MX_CELL(pPage->pBt)<=10921 );
@@ -58055,11 +58072,11 @@
5805558072
** might be less than 8 (leaf-size + pointer) on the interior node. Hence
5805658073
** the term after the || in the following assert(). */
5805758074
assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
5805858075
if( pPage->nOverflow || sz+2>pPage->nFree ){
5805958076
if( pTemp ){
58060
- memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
58077
+ memcpy(pTemp, pCell, sz);
5806158078
pCell = pTemp;
5806258079
}
5806358080
if( iChild ){
5806458081
put4byte(pCell, iChild);
5806558082
}
@@ -58084,11 +58101,11 @@
5808458101
** if it returns success */
5808558102
assert( idx >= end+2 );
5808658103
assert( idx+sz <= (int)pPage->pBt->usableSize );
5808758104
pPage->nCell++;
5808858105
pPage->nFree -= (u16)(2 + sz);
58089
- memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
58106
+ memcpy(&data[idx], pCell, sz);
5809058107
if( iChild ){
5809158108
put4byte(&data[idx], iChild);
5809258109
}
5809358110
memmove(&data[ins+2], &data[ins], end-ins);
5809458111
put2byte(&data[ins], idx);
@@ -61630,11 +61647,14 @@
6163061647
/* If MEM_Dyn is set then Mem.xDel!=0.
6163161648
** Mem.xDel is might not be initialized if MEM_Dyn is clear.
6163261649
*/
6163361650
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
6163461651
61635
- /* MEM_Dyn may only be set if Mem.szMalloc==0 */
61652
+ /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we
61653
+ ** ensure that if Mem.szMalloc>0 then it is safe to do
61654
+ ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
61655
+ ** That saves a few cycles in inner loops. */
6163661656
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
6163761657
6163861658
/* Cannot be both MEM_Int and MEM_Real at the same time */
6163961659
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
6164061660
@@ -61739,11 +61759,11 @@
6173961759
}else{
6174061760
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
6174161761
}
6174261762
}
6174361763
61744
- if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
61764
+ if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
6174561765
memcpy(pMem->zMalloc, pMem->z, pMem->n);
6174661766
}
6174761767
if( (pMem->flags&MEM_Dyn)!=0 ){
6174861768
assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
6174961769
pMem->xDel((void *)(pMem->z));
@@ -61766,11 +61786,12 @@
6176661786
**
6176761787
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
6176861788
** if unable to complete the resizing.
6176961789
*/
6177061790
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
61771
- assert( szNew>=0 );
61791
+ assert( szNew>0 );
61792
+ assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
6177261793
if( pMem->szMalloc<szNew ){
6177361794
return sqlite3VdbeMemGrow(pMem, szNew, 0);
6177461795
}
6177561796
assert( (pMem->flags & MEM_Dyn)==0 );
6177661797
pMem->z = pMem->zMalloc;
@@ -62490,11 +62511,14 @@
6249062511
nAlloc += (enc==SQLITE_UTF8?1:2);
6249162512
}
6249262513
if( nByte>iLimit ){
6249362514
return SQLITE_TOOBIG;
6249462515
}
62495
- if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){
62516
+ testcase( nAlloc==0 );
62517
+ testcase( nAlloc==31 );
62518
+ testcase( nAlloc==32 );
62519
+ if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
6249662520
return SQLITE_NOMEM;
6249762521
}
6249862522
memcpy(pMem->z, z, nAlloc);
6249962523
}else if( xDel==SQLITE_DYNAMIC ){
6250062524
sqlite3VdbeMemRelease(pMem);
@@ -62593,11 +62617,11 @@
6259362617
/*
6259462618
** The pVal argument is known to be a value other than NULL.
6259562619
** Convert it into a string with encoding enc and return a pointer
6259662620
** to a zero-terminated version of that string.
6259762621
*/
62598
-SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
62622
+static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
6259962623
assert( pVal!=0 );
6260062624
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
6260162625
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
6260262626
assert( (pVal->flags & MEM_RowSet)==0 );
6260362627
assert( (pVal->flags & (MEM_Null))==0 );
@@ -64913,11 +64937,11 @@
6491364937
** the call above. */
6491464938
}else if( pCx->pCursor ){
6491564939
sqlite3BtreeCloseCursor(pCx->pCursor);
6491664940
}
6491764941
#ifndef SQLITE_OMIT_VIRTUALTABLE
64918
- if( pCx->pVtabCursor ){
64942
+ else if( pCx->pVtabCursor ){
6491964943
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
6492064944
const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
6492164945
p->inVtabMethod = 1;
6492264946
pModule->xClose(pVtabCursor);
6492364947
p->inVtabMethod = 0;
@@ -64956,13 +64980,14 @@
6495664980
static void closeAllCursors(Vdbe *p){
6495764981
if( p->pFrame ){
6495864982
VdbeFrame *pFrame;
6495964983
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
6496064984
sqlite3VdbeFrameRestore(pFrame);
64985
+ p->pFrame = 0;
64986
+ p->nFrame = 0;
6496164987
}
64962
- p->pFrame = 0;
64963
- p->nFrame = 0;
64988
+ assert( p->nFrame==0 );
6496464989
6496564990
if( p->apCsr ){
6496664991
int i;
6496764992
for(i=0; i<p->nCursor; i++){
6496864993
VdbeCursor *pC = p->apCsr[i];
@@ -64980,11 +65005,11 @@
6498065005
p->pDelFrame = pDel->pParent;
6498165006
sqlite3VdbeFrameDelete(pDel);
6498265007
}
6498365008
6498465009
/* Delete any auxdata allocations made by the VM */
64985
- sqlite3VdbeDeleteAuxData(p, -1, 0);
65010
+ if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
6498665011
assert( p->pAuxData==0 );
6498765012
}
6498865013
6498965014
/*
6499065015
** Clean up the VM after a single run.
@@ -65886,13 +65911,11 @@
6588665911
#endif
6588765912
assert( p->deferredMoveto );
6588865913
assert( p->isTable );
6588965914
rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
6589065915
if( rc ) return rc;
65891
- p->lastRowid = p->movetoTarget;
6589265916
if( res!=0 ) return SQLITE_CORRUPT_BKPT;
65893
- p->rowidIsValid = 1;
6589465917
#ifdef SQLITE_TEST
6589565918
sqlite3_search_count++;
6589665919
#endif
6589765920
p->deferredMoveto = 0;
6589865921
p->cacheStatus = CACHE_STALE;
@@ -65913,10 +65936,21 @@
6591365936
rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
6591465937
p->cacheStatus = CACHE_STALE;
6591565938
if( isDifferentRow ) p->nullRow = 1;
6591665939
return rc;
6591765940
}
65941
+
65942
+/*
65943
+** Check to ensure that the cursor is valid. Restore the cursor
65944
+** if need be. Return any I/O error from the restore operation.
65945
+*/
65946
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
65947
+ if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65948
+ return handleMovedCursor(p);
65949
+ }
65950
+ return SQLITE_OK;
65951
+}
6591865952
6591965953
/*
6592065954
** Make sure the cursor p is ready to read or write the row to which it
6592165955
** was last positioned. Return an error code if an OOM fault or I/O error
6592265956
** prevents us from positioning the cursor to its correct position.
@@ -65931,11 +65965,11 @@
6593165965
*/
6593265966
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
6593365967
if( p->deferredMoveto ){
6593465968
return handleDeferredMoveto(p);
6593565969
}
65936
- if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65970
+ if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
6593765971
return handleMovedCursor(p);
6593865972
}
6593965973
return SQLITE_OK;
6594065974
}
6594165975
@@ -69095,10 +69129,11 @@
6909569129
if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
6909669130
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
6909769131
memset(pCx, 0, sizeof(VdbeCursor));
6909869132
pCx->iDb = iDb;
6909969133
pCx->nField = nField;
69134
+ pCx->aOffset = &pCx->aType[nField];
6910069135
if( isBtreeCursor ){
6910169136
pCx->pCursor = (BtCursor*)
6910269137
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
6910369138
sqlite3BtreeCursorZero(pCx->pCursor);
6910469139
}
@@ -70528,11 +70563,11 @@
7052870563
ctx.pFunc = pOp->p4.pFunc;
7052970564
ctx.iOp = pc;
7053070565
ctx.pVdbe = p;
7053170566
MemSetTypeFlag(ctx.pOut, MEM_Null);
7053270567
ctx.fErrorOrAux = 0;
70533
- assert( db->lastRowid==lastRowid );
70568
+ db->lastRowid = lastRowid;
7053470569
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
7053570570
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
7053670571
7053770572
/* If the function returned an error, throw an exception */
7053870573
if( ctx.fErrorOrAux ){
@@ -71246,11 +71281,11 @@
7124671281
memAboutToChange(p, pDest);
7124771282
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
7124871283
pC = p->apCsr[pOp->p1];
7124971284
assert( pC!=0 );
7125071285
assert( p2<pC->nField );
71251
- aOffset = pC->aType + pC->nField;
71286
+ aOffset = pC->aOffset;
7125271287
#ifndef SQLITE_OMIT_VIRTUALTABLE
7125371288
assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
7125471289
#endif
7125571290
pCrsr = pC->pCursor;
7125671291
assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
@@ -71257,11 +71292,11 @@
7125771292
assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
7125871293
7125971294
/* If the cursor cache is stale, bring it up-to-date */
7126071295
rc = sqlite3VdbeCursorMoveto(pC);
7126171296
if( rc ) goto abort_due_to_error;
71262
- if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
71297
+ if( pC->cacheStatus!=p->cacheCtr ){
7126371298
if( pC->nullRow ){
7126471299
if( pCrsr==0 ){
7126571300
assert( pC->pseudoTableReg>0 );
7126671301
pReg = &aMem[pC->pseudoTableReg];
7126771302
assert( pReg->flags & MEM_Blob );
@@ -71302,18 +71337,10 @@
7130271337
}
7130371338
pC->cacheStatus = p->cacheCtr;
7130471339
pC->iHdrOffset = getVarint32(pC->aRow, offset);
7130571340
pC->nHdrParsed = 0;
7130671341
aOffset[0] = offset;
71307
- if( avail<offset ){
71308
- /* pC->aRow does not have to hold the entire row, but it does at least
71309
- ** need to cover the header of the record. If pC->aRow does not contain
71310
- ** the complete header, then set it to zero, forcing the header to be
71311
- ** dynamically allocated. */
71312
- pC->aRow = 0;
71313
- pC->szRow = 0;
71314
- }
7131571342
7131671343
/* Make sure a corrupt database has not given us an oversize header.
7131771344
** Do this now to avoid an oversize memory allocation.
7131871345
**
7131971346
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -71324,19 +71351,36 @@
7132471351
*/
7132571352
if( offset > 98307 || offset > pC->payloadSize ){
7132671353
rc = SQLITE_CORRUPT_BKPT;
7132771354
goto op_column_error;
7132871355
}
71356
+
71357
+ if( avail<offset ){
71358
+ /* pC->aRow does not have to hold the entire row, but it does at least
71359
+ ** need to cover the header of the record. If pC->aRow does not contain
71360
+ ** the complete header, then set it to zero, forcing the header to be
71361
+ ** dynamically allocated. */
71362
+ pC->aRow = 0;
71363
+ pC->szRow = 0;
71364
+ }
71365
+
71366
+ /* The following goto is an optimization. It can be omitted and
71367
+ ** everything will still work. But OP_Column is measurably faster
71368
+ ** by skipping the subsequent conditional, which is always true.
71369
+ */
71370
+ assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
71371
+ goto op_column_read_header;
7132971372
}
7133071373
7133171374
/* Make sure at least the first p2+1 entries of the header have been
7133271375
** parsed and valid information is in aOffset[] and pC->aType[].
7133371376
*/
7133471377
if( pC->nHdrParsed<=p2 ){
7133571378
/* If there is more header available for parsing in the record, try
7133671379
** to extract additional fields up through the p2+1-th field
7133771380
*/
71381
+ op_column_read_header:
7133871382
if( pC->iHdrOffset<aOffset[0] ){
7133971383
/* Make sure zData points to enough of the record to cover the header. */
7134071384
if( pC->aRow==0 ){
7134171385
memset(&sMem, 0, sizeof(sMem));
7134271386
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
@@ -71377,19 +71421,20 @@
7137771421
if( pC->aRow==0 ){
7137871422
sqlite3VdbeMemRelease(&sMem);
7137971423
sMem.flags = MEM_Null;
7138071424
}
7138171425
71382
- /* If we have read more header data than was contained in the header,
71383
- ** or if the end of the last field appears to be past the end of the
71384
- ** record, or if the end of the last field appears to be before the end
71385
- ** of the record (when all fields present), then we must be dealing
71386
- ** with a corrupt database.
71426
+ /* The record is corrupt if any of the following are true:
71427
+ ** (1) the bytes of the header extend past the declared header size
71428
+ ** (zHdr>zEndHdr)
71429
+ ** (2) the entire header was used but not all data was used
71430
+ ** (zHdr==zEndHdr && offset!=pC->payloadSize)
71431
+ ** (3) the end of the data extends beyond the end of the record.
71432
+ ** (offset > pC->payloadSize)
7138771433
*/
71388
- if( (zHdr > zEndHdr)
71434
+ if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
7138971435
|| (offset > pC->payloadSize)
71390
- || (zHdr==zEndHdr && offset!=pC->payloadSize)
7139171436
){
7139271437
rc = SQLITE_CORRUPT_BKPT;
7139371438
goto op_column_error;
7139471439
}
7139571440
}
@@ -71400,11 +71445,11 @@
7140071445
*/
7140171446
if( pC->nHdrParsed<=p2 ){
7140271447
if( pOp->p4type==P4_MEM ){
7140371448
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
7140471449
}else{
71405
- MemSetTypeFlag(pDest, MEM_Null);
71450
+ sqlite3VdbeMemSetNull(pDest);
7140671451
}
7140771452
goto op_column_out;
7140871453
}
7140971454
}
7141071455
@@ -71576,11 +71621,11 @@
7157671621
** out how much space is required for the new record.
7157771622
*/
7157871623
pRec = pLast;
7157971624
do{
7158071625
assert( memIsValid(pRec) );
71581
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
71626
+ pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
7158271627
len = sqlite3VdbeSerialTypeLen(serial_type);
7158371628
if( pRec->flags & MEM_Zero ){
7158471629
if( nData ){
7158571630
sqlite3VdbeMemExpandBlob(pRec);
7158671631
}else{
@@ -71625,11 +71670,11 @@
7162571670
i = putVarint32(zNewRecord, nHdr);
7162671671
j = nHdr;
7162771672
assert( pData0<=pLast );
7162871673
pRec = pData0;
7162971674
do{
71630
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
71675
+ serial_type = pRec->uTemp;
7163171676
i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
7163271677
j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
7163371678
}while( (++pRec)<=pLast );
7163471679
assert( i==nHdr );
7163571680
assert( j==nByte );
@@ -72524,11 +72569,10 @@
7252472569
pIn3 = &aMem[pOp->p3];
7252572570
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
7252672571
applyNumericAffinity(pIn3, 0);
7252772572
}
7252872573
iKey = sqlite3VdbeIntValue(pIn3);
72529
- pC->rowidIsValid = 0;
7253072574
7253172575
/* If the P3 value could not be converted into an integer without
7253272576
** loss of information, then special processing is required... */
7253372577
if( (pIn3->flags & MEM_Int)==0 ){
7253472578
if( (pIn3->flags & MEM_Real)==0 ){
@@ -72560,17 +72604,14 @@
7256072604
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
7256172605
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
7256272606
}
7256372607
}
7256472608
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
72609
+ pC->movetoTarget = iKey; /* Used by OP_Delete */
7256572610
if( rc!=SQLITE_OK ){
7256672611
goto abort_due_to_error;
7256772612
}
72568
- if( res==0 ){
72569
- pC->rowidIsValid = 1;
72570
- pC->lastRowid = iKey;
72571
- }
7257272613
}else{
7257372614
nField = pOp->p4.i;
7257472615
assert( pOp->p4type==P4_INT32 );
7257572616
assert( nField>0 );
7257672617
r.pKeyInfo = pC->pKeyInfo;
@@ -72596,11 +72637,10 @@
7259672637
ExpandBlob(r.aMem);
7259772638
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
7259872639
if( rc!=SQLITE_OK ){
7259972640
goto abort_due_to_error;
7260072641
}
72601
- pC->rowidIsValid = 0;
7260272642
}
7260372643
pC->deferredMoveto = 0;
7260472644
pC->cacheStatus = CACHE_STALE;
7260572645
#ifdef SQLITE_TEST
7260672646
sqlite3_search_count++;
@@ -72608,21 +72648,19 @@
7260872648
if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
7260972649
if( res<0 || (res==0 && oc==OP_SeekGT) ){
7261072650
res = 0;
7261172651
rc = sqlite3BtreeNext(pC->pCursor, &res);
7261272652
if( rc!=SQLITE_OK ) goto abort_due_to_error;
72613
- pC->rowidIsValid = 0;
7261472653
}else{
7261572654
res = 0;
7261672655
}
7261772656
}else{
7261872657
assert( oc==OP_SeekLT || oc==OP_SeekLE );
7261972658
if( res>0 || (res==0 && oc==OP_SeekLT) ){
7262072659
res = 0;
7262172660
rc = sqlite3BtreePrevious(pC->pCursor, &res);
7262272661
if( rc!=SQLITE_OK ) goto abort_due_to_error;
72623
- pC->rowidIsValid = 0;
7262472662
}else{
7262572663
/* res might be negative because the table is empty. Check to
7262672664
** see if this is the case.
7262772665
*/
7262872666
res = sqlite3BtreeEof(pC->pCursor);
@@ -72655,11 +72693,10 @@
7265572693
assert( pC->pCursor!=0 );
7265672694
assert( pC->isTable );
7265772695
pC->nullRow = 0;
7265872696
pIn2 = &aMem[pOp->p2];
7265972697
pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
72660
- pC->rowidIsValid = 0;
7266172698
pC->deferredMoveto = 1;
7266272699
break;
7266372700
}
7266472701
7266572702
@@ -72841,19 +72878,17 @@
7284172878
pCrsr = pC->pCursor;
7284272879
assert( pCrsr!=0 );
7284372880
res = 0;
7284472881
iKey = pIn3->u.i;
7284572882
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
72846
- pC->lastRowid = pIn3->u.i;
72847
- pC->rowidIsValid = res==0 ?1:0;
72883
+ pC->movetoTarget = iKey; /* Used by OP_Delete */
7284872884
pC->nullRow = 0;
7284972885
pC->cacheStatus = CACHE_STALE;
7285072886
pC->deferredMoveto = 0;
7285172887
VdbeBranchTaken(res!=0,2);
7285272888
if( res!=0 ){
7285372889
pc = pOp->p2 - 1;
72854
- assert( pC->rowidIsValid==0 );
7285572890
}
7285672891
pC->seekResult = res;
7285772892
break;
7285872893
}
7285972894
@@ -72997,11 +73032,10 @@
7299773032
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
7299873033
goto abort_due_to_error;
7299973034
}
7300073035
assert( v>0 ); /* EV: R-40812-03570 */
7300173036
}
73002
- pC->rowidIsValid = 0;
7300373037
pC->deferredMoveto = 0;
7300473038
pC->cacheStatus = CACHE_STALE;
7300573039
}
7300673040
pOut->u.i = v;
7300773041
break;
@@ -73102,11 +73136,10 @@
7310273136
}
7310373137
rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
7310473138
pData->z, pData->n, nZero,
7310573139
(pOp->p5 & OPFLAG_APPEND)!=0, seekResult
7310673140
);
73107
- pC->rowidIsValid = 0;
7310873141
pC->deferredMoveto = 0;
7310973142
pC->cacheStatus = CACHE_STALE;
7311073143
7311173144
/* Invoke the update-hook if required. */
7311273145
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -73139,37 +73172,36 @@
7313973172
** pointing to. The update hook will be invoked, if it exists.
7314073173
** If P4 is not NULL then the P1 cursor must have been positioned
7314173174
** using OP_NotFound prior to invoking this opcode.
7314273175
*/
7314373176
case OP_Delete: {
73144
- i64 iKey;
7314573177
VdbeCursor *pC;
7314673178
7314773179
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
7314873180
pC = p->apCsr[pOp->p1];
7314973181
assert( pC!=0 );
7315073182
assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
73151
- iKey = pC->lastRowid; /* Only used for the update hook */
73152
-
73153
- /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
73154
- ** OP_Column on the same table without any intervening operations that
73155
- ** might move or invalidate the cursor. Hence cursor pC is always pointing
73156
- ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
73157
- ** below is always a no-op and cannot fail. We will run it anyhow, though,
73158
- ** to guard against future changes to the code generator.
73159
- **/
7316073183
assert( pC->deferredMoveto==0 );
73161
- rc = sqlite3VdbeCursorMoveto(pC);
73162
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
7316373184
73185
+#ifdef SQLITE_DEBUG
73186
+ /* The seek operation that positioned the cursor prior to OP_Delete will
73187
+ ** have also set the pC->movetoTarget field to the rowid of the row that
73188
+ ** is being deleted */
73189
+ if( pOp->p4.z && pC->isTable ){
73190
+ i64 iKey = 0;
73191
+ sqlite3BtreeKeySize(pC->pCursor, &iKey);
73192
+ assert( pC->movetoTarget==iKey );
73193
+ }
73194
+#endif
73195
+
7316473196
rc = sqlite3BtreeDelete(pC->pCursor);
7316573197
pC->cacheStatus = CACHE_STALE;
7316673198
7316773199
/* Invoke the update-hook if required. */
7316873200
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
7316973201
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
73170
- db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
73202
+ db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
7317173203
assert( pC->iDb>=0 );
7317273204
}
7317373205
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
7317473206
break;
7317573207
}
@@ -73218,23 +73250,32 @@
7321873250
pc = pOp->p2-1;
7321973251
}
7322073252
break;
7322173253
};
7322273254
73223
-/* Opcode: SorterData P1 P2 * * *
73255
+/* Opcode: SorterData P1 P2 P3 * *
7322473256
** Synopsis: r[P2]=data
7322573257
**
7322673258
** Write into register P2 the current sorter data for sorter cursor P1.
73259
+** Then clear the column header cache on cursor P3.
73260
+**
73261
+** This opcode is normally use to move a record out of the sorter and into
73262
+** a register that is the source for a pseudo-table cursor created using
73263
+** OpenPseudo. That pseudo-table cursor is the one that is identified by
73264
+** parameter P3. Clearing the P3 column cache as part of this opcode saves
73265
+** us from having to issue a separate NullRow instruction to clear that cache.
7322773266
*/
7322873267
case OP_SorterData: {
7322973268
VdbeCursor *pC;
7323073269
7323173270
pOut = &aMem[pOp->p2];
7323273271
pC = p->apCsr[pOp->p1];
7323373272
assert( isSorter(pC) );
7323473273
rc = sqlite3VdbeSorterRowkey(pC, pOut);
7323573274
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
73275
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73276
+ p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
7323673277
break;
7323773278
}
7323873279
7323973280
/* Opcode: RowData P1 P2 * * *
7324073281
** Synopsis: r[P2]=data
@@ -73277,20 +73318,24 @@
7327773318
assert( pC!=0 );
7327873319
assert( pC->nullRow==0 );
7327973320
assert( pC->pseudoTableReg==0 );
7328073321
assert( pC->pCursor!=0 );
7328173322
pCrsr = pC->pCursor;
73282
- assert( sqlite3BtreeCursorIsValid(pCrsr) );
7328373323
7328473324
/* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
7328573325
** OP_Rewind/Op_Next with no intervening instructions that might invalidate
73286
- ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
73287
- ** a no-op and can never fail. But we leave it in place as a safety.
73326
+ ** the cursor. If this where not the case, on of the following assert()s
73327
+ ** would fail. Should this ever change (because of changes in the code
73328
+ ** generator) then the fix would be to insert a call to
73329
+ ** sqlite3VdbeCursorMoveto().
7328873330
*/
7328973331
assert( pC->deferredMoveto==0 );
73332
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
73333
+#if 0 /* Not required due to the previous to assert() statements */
7329073334
rc = sqlite3VdbeCursorMoveto(pC);
73291
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73335
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
73336
+#endif
7329273337
7329373338
if( pC->isTable==0 ){
7329473339
assert( !pC->isTable );
7329573340
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
7329673341
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -73303,11 +73348,12 @@
7330373348
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
7330473349
if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
7330573350
goto too_big;
7330673351
}
7330773352
}
73308
- if( sqlite3VdbeMemClearAndResize(pOut, n) ){
73353
+ testcase( n==0 );
73354
+ if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
7330973355
goto no_mem;
7331073356
}
7331173357
pOut->n = n;
7331273358
MemSetTypeFlag(pOut, MEM_Blob);
7331373359
if( pC->isTable==0 ){
@@ -73354,18 +73400,14 @@
7335473400
rc = pModule->xRowid(pC->pVtabCursor, &v);
7335573401
sqlite3VtabImportErrmsg(p, pVtab);
7335673402
#endif /* SQLITE_OMIT_VIRTUALTABLE */
7335773403
}else{
7335873404
assert( pC->pCursor!=0 );
73359
- rc = sqlite3VdbeCursorMoveto(pC);
73405
+ rc = sqlite3VdbeCursorRestore(pC);
7336073406
if( rc ) goto abort_due_to_error;
73361
- if( pC->rowidIsValid ){
73362
- v = pC->lastRowid;
73363
- }else{
73364
- rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73365
- assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
73366
- }
73407
+ rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73408
+ assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
7336773409
}
7336873410
pOut->u.i = v;
7336973411
break;
7337073412
}
7337173413
@@ -73380,11 +73422,10 @@
7338073422
7338173423
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
7338273424
pC = p->apCsr[pOp->p1];
7338373425
assert( pC!=0 );
7338473426
pC->nullRow = 1;
73385
- pC->rowidIsValid = 0;
7338673427
pC->cacheStatus = CACHE_STALE;
7338773428
if( pC->pCursor ){
7338873429
sqlite3BtreeClearCursor(pC->pCursor);
7338973430
}
7339073431
break;
@@ -73414,11 +73455,10 @@
7341473455
res = 0;
7341573456
assert( pCrsr!=0 );
7341673457
rc = sqlite3BtreeLast(pCrsr, &res);
7341773458
pC->nullRow = (u8)res;
7341873459
pC->deferredMoveto = 0;
73419
- pC->rowidIsValid = 0;
7342073460
pC->cacheStatus = CACHE_STALE;
7342173461
#ifdef SQLITE_DEBUG
7342273462
pC->seekOp = OP_Last;
7342373463
#endif
7342473464
if( pOp->p2>0 ){
@@ -73481,11 +73521,10 @@
7348173521
pCrsr = pC->pCursor;
7348273522
assert( pCrsr );
7348373523
rc = sqlite3BtreeFirst(pCrsr, &res);
7348473524
pC->deferredMoveto = 0;
7348573525
pC->cacheStatus = CACHE_STALE;
73486
- pC->rowidIsValid = 0;
7348773526
}
7348873527
pC->nullRow = (u8)res;
7348973528
assert( pOp->p2>0 && pOp->p2<p->nOp );
7349073529
VdbeBranchTaken(res!=0,2);
7349173530
if( res ){
@@ -73607,11 +73646,10 @@
7360773646
sqlite3_search_count++;
7360873647
#endif
7360973648
}else{
7361073649
pC->nullRow = 1;
7361173650
}
73612
- pC->rowidIsValid = 0;
7361373651
goto check_for_interrupt;
7361473652
}
7361573653
7361673654
/* Opcode: IdxInsert P1 P2 P3 * P5
7361773655
** Synopsis: key=r[P2]
@@ -73723,14 +73761,20 @@
7372373761
pC = p->apCsr[pOp->p1];
7372473762
assert( pC!=0 );
7372573763
pCrsr = pC->pCursor;
7372673764
assert( pCrsr!=0 );
7372773765
pOut->flags = MEM_Null;
73728
- rc = sqlite3VdbeCursorMoveto(pC);
73729
- if( NEVER(rc) ) goto abort_due_to_error;
73766
+ assert( pC->isTable==0 );
7373073767
assert( pC->deferredMoveto==0 );
73731
- assert( pC->isTable==0 );
73768
+
73769
+ /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
73770
+ ** out from under the cursor. That will never happend for an IdxRowid
73771
+ ** opcode, hence the NEVER() arround the check of the return value.
73772
+ */
73773
+ rc = sqlite3VdbeCursorRestore(pC);
73774
+ if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73775
+
7373273776
if( !pC->nullRow ){
7373373777
rowid = 0; /* Not needed. Only used to silence a warning. */
7373473778
rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
7373573779
if( rc!=SQLITE_OK ){
7373673780
goto abort_due_to_error;
@@ -78187,11 +78231,11 @@
7818778231
if( rc==SQLITE_OK ){
7818878232
#if SQLITE_MAX_WORKER_THREADS
7818978233
assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
7819078234
if( pSorter->bUseThreads ){
7819178235
int iTask;
78192
- PmaReader *pReadr;
78236
+ PmaReader *pReadr = 0;
7819378237
SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
7819478238
rc = vdbeSortAllocUnpacked(pLast);
7819578239
if( rc==SQLITE_OK ){
7819678240
pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
7819778241
pSorter->pReader = pReadr;
@@ -87168,29 +87212,27 @@
8716887212
tRowcnt v;
8716987213
8717087214
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
8717187215
if( z==0 ) z = "";
8717287216
#else
87173
- if( NEVER(z==0) ) z = "";
87217
+ assert( z!=0 );
8717487218
#endif
8717587219
for(i=0; *z && i<nOut; i++){
8717687220
v = 0;
8717787221
while( (c=z[0])>='0' && c<='9' ){
8717887222
v = v*10 + c - '0';
8717987223
z++;
8718087224
}
8718187225
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87182
- if( aOut ){
87183
- aOut[i] = v;
87184
- }else
87226
+ if( aOut ) aOut[i] = v;
87227
+ if( aLog ) aLog[i] = sqlite3LogEst(v);
8718587228
#else
8718687229
assert( aOut==0 );
8718787230
UNUSED_PARAMETER(aOut);
87231
+ assert( aLog!=0 );
87232
+ aLog[i] = sqlite3LogEst(v);
8718887233
#endif
87189
- {
87190
- aLog[i] = sqlite3LogEst(v);
87191
- }
8719287234
if( *z==' ' ) z++;
8719387235
}
8719487236
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
8719587237
assert( pIndex!=0 );
8719687238
#else
@@ -87247,12 +87289,21 @@
8724787289
pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
8724887290
}
8724987291
z = argv[2];
8725087292
8725187293
if( pIndex ){
87294
+ int nCol = pIndex->nKeyCol+1;
87295
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87296
+ tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
87297
+ sizeof(tRowcnt) * nCol
87298
+ );
87299
+ if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
87300
+#else
87301
+ tRowcnt * const aiRowEst = 0;
87302
+#endif
8725287303
pIndex->bUnordered = 0;
87253
- decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
87304
+ decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
8725487305
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
8725587306
}else{
8725687307
Index fakeIdx;
8725787308
fakeIdx.szIdxRow = pTable->szTabRow;
8725887309
#ifdef SQLITE_ENABLE_COSTMULT
@@ -87307,29 +87358,42 @@
8730787358
** unique. */
8730887359
nCol = pIdx->nSampleCol-1;
8730987360
pIdx->aAvgEq[nCol] = 1;
8731087361
}
8731187362
for(iCol=0; iCol<nCol; iCol++){
87363
+ int nSample = pIdx->nSample;
8731287364
int i; /* Used to iterate through samples */
8731387365
tRowcnt sumEq = 0; /* Sum of the nEq values */
87314
- tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
8731587366
tRowcnt avgEq = 0;
87316
- tRowcnt nDLt = pFinal->anDLt[iCol];
87367
+ tRowcnt nRow; /* Number of rows in index */
87368
+ i64 nSum100 = 0; /* Number of terms contributing to sumEq */
87369
+ i64 nDist100; /* Number of distinct values in index */
87370
+
87371
+ if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
87372
+ nRow = pFinal->anLt[iCol];
87373
+ nDist100 = (i64)100 * pFinal->anDLt[iCol];
87374
+ nSample--;
87375
+ }else{
87376
+ nRow = pIdx->aiRowEst[0];
87377
+ nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
87378
+ }
8731787379
8731887380
/* Set nSum to the number of distinct (iCol+1) field prefixes that
87319
- ** occur in the stat4 table for this index before pFinal. Set
87320
- ** sumEq to the sum of the nEq values for column iCol for the same
87321
- ** set (adding the value only once where there exist duplicate
87322
- ** prefixes). */
87323
- for(i=0; i<(pIdx->nSample-1); i++){
87324
- if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
87381
+ ** occur in the stat4 table for this index. Set sumEq to the sum of
87382
+ ** the nEq values for column iCol for the same set (adding the value
87383
+ ** only once where there exist duplicate prefixes). */
87384
+ for(i=0; i<nSample; i++){
87385
+ if( i==(pIdx->nSample-1)
87386
+ || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
87387
+ ){
8732587388
sumEq += aSample[i].anEq[iCol];
87326
- nSum++;
87389
+ nSum100 += 100;
8732787390
}
8732887391
}
87329
- if( nDLt>nSum ){
87330
- avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
87392
+
87393
+ if( nDist100>nSum100 ){
87394
+ avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
8733187395
}
8733287396
if( avgEq==0 ) avgEq = 1;
8733387397
pIdx->aAvgEq[iCol] = avgEq;
8733487398
}
8733587399
}
@@ -87576,10 +87640,15 @@
8757687640
if( rc==SQLITE_OK ){
8757787641
int lookasideEnabled = db->lookaside.bEnabled;
8757887642
db->lookaside.bEnabled = 0;
8757987643
rc = loadStat4(db, sInfo.zDatabase);
8758087644
db->lookaside.bEnabled = lookasideEnabled;
87645
+ }
87646
+ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
87647
+ Index *pIdx = sqliteHashData(i);
87648
+ sqlite3_free(pIdx->aiRowEst);
87649
+ pIdx->aiRowEst = 0;
8758187650
}
8758287651
#endif
8758387652
8758487653
if( rc==SQLITE_NOMEM ){
8758587654
db->mallocFailed = 1;
@@ -88870,10 +88939,13 @@
8887088939
#endif
8887188940
if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
8887288941
sqlite3ExprDelete(db, p->pPartIdxWhere);
8887388942
sqlite3DbFree(db, p->zColAff);
8887488943
if( p->isResized ) sqlite3DbFree(db, p->azColl);
88944
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
88945
+ sqlite3_free(p->aiRowEst);
88946
+#endif
8887588947
sqlite3DbFree(db, p);
8887688948
}
8887788949
8887888950
/*
8887988951
** For the index called zIdxName which is found in the database iDb,
@@ -91179,11 +91251,11 @@
9117991251
pIndex->nKeyCol); VdbeCoverage(v);
9118091252
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
9118191253
}else{
9118291254
addr2 = sqlite3VdbeCurrentAddr(v);
9118391255
}
91184
- sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
91256
+ sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
9118591257
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
9118691258
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
9118791259
sqlite3ReleaseTempReg(pParse, regRecord);
9118891260
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
9118991261
sqlite3VdbeJumpHere(v, addr1);
@@ -93687,11 +93759,11 @@
9368793759
if( okOnePass ){
9368893760
/* Just one row. Hence the top-of-loop is a no-op */
9368993761
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
9369093762
assert( !IsVirtual(pTab) );
9369193763
if( aToOpen[iDataCur-iTabCur] ){
93692
- assert( pPk!=0 );
93764
+ assert( pPk!=0 || pTab->pSelect!=0 );
9369393765
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
9369493766
VdbeCoverage(v);
9369593767
}
9369693768
}else if( pPk ){
9369793769
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
@@ -105122,11 +105194,10 @@
105122105194
int regRow;
105123105195
int regRowid;
105124105196
int nKey;
105125105197
int iSortTab; /* Sorter cursor to read from */
105126105198
int nSortData; /* Trailing values to read from sorter */
105127
- u8 p5; /* p5 parameter for 1st OP_Column */
105128105199
int i;
105129105200
int bSeq; /* True if sorter record includes seq. no. */
105130105201
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
105131105202
struct ExprList_item *aOutEx = p->pEList->a;
105132105203
#endif
@@ -105156,23 +105227,20 @@
105156105227
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
105157105228
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
105158105229
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
105159105230
VdbeCoverage(v);
105160105231
codeOffset(v, p->iOffset, addrContinue);
105161
- sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
105162
- p5 = OPFLAG_CLEARCACHE;
105232
+ sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
105163105233
bSeq = 0;
105164105234
}else{
105165105235
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
105166105236
codeOffset(v, p->iOffset, addrContinue);
105167105237
iSortTab = iTab;
105168
- p5 = 0;
105169105238
bSeq = 1;
105170105239
}
105171105240
for(i=0; i<nSortData; i++){
105172105241
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
105173
- if( i==0 ) sqlite3VdbeChangeP5(v, p5);
105174105242
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
105175105243
}
105176105244
switch( eDest ){
105177105245
case SRT_Table:
105178105246
case SRT_EphemTab: {
@@ -109097,16 +109165,15 @@
109097109165
** from the previous row currently stored in a0, a1, a2...
109098109166
*/
109099109167
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
109100109168
sqlite3ExprCacheClear(pParse);
109101109169
if( groupBySort ){
109102
- sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
109170
+ sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
109103109171
}
109104109172
for(j=0; j<pGroupBy->nExpr; j++){
109105109173
if( groupBySort ){
109106109174
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
109107
- if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
109108109175
}else{
109109109176
sAggInfo.directMode = 1;
109110109177
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
109111109178
}
109112109179
}
@@ -111216,12 +111283,12 @@
111216111283
0, 0);
111217111284
}
111218111285
111219111286
/* Top of the update loop */
111220111287
if( okOnePass ){
111221
- if( aToOpen[iDataCur-iBaseCur] ){
111222
- assert( pPk!=0 );
111288
+ if( aToOpen[iDataCur-iBaseCur] && !isView ){
111289
+ assert( pPk );
111223111290
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
111224111291
VdbeCoverageNeverTaken(v);
111225111292
}
111226111293
labelContinue = labelBreak;
111227111294
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
@@ -112450,10 +112517,11 @@
112450112517
}
112451112518
sqlite3DbFree(db, pVTable);
112452112519
}else if( ALWAYS(pVTable->pVtab) ){
112453112520
/* Justification of ALWAYS(): A correct vtab constructor must allocate
112454112521
** the sqlite3_vtab object if successful. */
112522
+ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
112455112523
pVTable->pVtab->pModule = pMod->pModule;
112456112524
pVTable->nRef = 1;
112457112525
if( sCtx.pTab ){
112458112526
const char *zFormat = "vtable constructor did not declare schema: %s";
112459112527
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
@@ -115700,21 +115768,28 @@
115700115768
** have been requested when testing key $P in whereEqualScanEst(). */
115701115769
whereKeyStats(pParse, p, pRec, 0, a);
115702115770
iLower = a[0];
115703115771
iUpper = a[0] + a[1];
115704115772
}
115773
+
115774
+ assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115775
+ assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115776
+ assert( p->aSortOrder!=0 );
115777
+ if( p->aSortOrder[nEq] ){
115778
+ /* The roles of pLower and pUpper are swapped for a DESC index */
115779
+ SWAP(WhereTerm*, pLower, pUpper);
115780
+ }
115705115781
115706115782
/* If possible, improve on the iLower estimate using ($P:$L). */
115707115783
if( pLower ){
115708115784
int bOk; /* True if value is extracted from pExpr */
115709115785
Expr *pExpr = pLower->pExpr->pRight;
115710
- assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115711115786
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115712115787
if( rc==SQLITE_OK && bOk ){
115713115788
tRowcnt iNew;
115714115789
whereKeyStats(pParse, p, pRec, 0, a);
115715
- iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
115790
+ iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115716115791
if( iNew>iLower ) iLower = iNew;
115717115792
nOut--;
115718115793
pLower = 0;
115719115794
}
115720115795
}
@@ -115721,16 +115796,15 @@
115721115796
115722115797
/* If possible, improve on the iUpper estimate using ($P:$U). */
115723115798
if( pUpper ){
115724115799
int bOk; /* True if value is extracted from pExpr */
115725115800
Expr *pExpr = pUpper->pExpr->pRight;
115726
- assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115727115801
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115728115802
if( rc==SQLITE_OK && bOk ){
115729115803
tRowcnt iNew;
115730115804
whereKeyStats(pParse, p, pRec, 1, a);
115731
- iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
115805
+ iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115732115806
if( iNew<iUpper ) iUpper = iNew;
115733115807
nOut--;
115734115808
pUpper = 0;
115735115809
}
115736115810
}
@@ -116225,65 +116299,52 @@
116225116299
sqlite3StrAccumAppend(pStr, "?", 1);
116226116300
}
116227116301
116228116302
/*
116229116303
** Argument pLevel describes a strategy for scanning table pTab. This
116230
-** function returns a pointer to a string buffer containing a description
116231
-** of the subset of table rows scanned by the strategy in the form of an
116232
-** SQL expression. Or, if all rows are scanned, NULL is returned.
116304
+** function appends text to pStr that describes the subset of table
116305
+** rows scanned by the strategy in the form of an SQL expression.
116233116306
**
116234116307
** For example, if the query:
116235116308
**
116236116309
** SELECT * FROM t1 WHERE a=1 AND b>2;
116237116310
**
116238116311
** is run and there is an index on (a, b), then this function returns a
116239116312
** string similar to:
116240116313
**
116241116314
** "a=? AND b>?"
116242
-**
116243
-** The returned pointer points to memory obtained from sqlite3DbMalloc().
116244
-** It is the responsibility of the caller to free the buffer when it is
116245
-** no longer required.
116246116315
*/
116247
-static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
116316
+static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
116248116317
Index *pIndex = pLoop->u.btree.pIndex;
116249116318
u16 nEq = pLoop->u.btree.nEq;
116250116319
u16 nSkip = pLoop->u.btree.nSkip;
116251116320
int i, j;
116252116321
Column *aCol = pTab->aCol;
116253116322
i16 *aiColumn = pIndex->aiColumn;
116254
- StrAccum txt;
116255
-
116256
- if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
116257
- return 0;
116258
- }
116259
- sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
116260
- txt.db = db;
116261
- sqlite3StrAccumAppend(&txt, " (", 2);
116323
+
116324
+ if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
116325
+ sqlite3StrAccumAppend(pStr, " (", 2);
116262116326
for(i=0; i<nEq; i++){
116263116327
char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
116264116328
if( i>=nSkip ){
116265
- explainAppendTerm(&txt, i, z, "=");
116329
+ explainAppendTerm(pStr, i, z, "=");
116266116330
}else{
116267
- if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
116268
- sqlite3StrAccumAppend(&txt, "ANY(", 4);
116269
- sqlite3StrAccumAppendAll(&txt, z);
116270
- sqlite3StrAccumAppend(&txt, ")", 1);
116331
+ if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
116332
+ sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
116271116333
}
116272116334
}
116273116335
116274116336
j = i;
116275116337
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
116276116338
char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116277
- explainAppendTerm(&txt, i++, z, ">");
116339
+ explainAppendTerm(pStr, i++, z, ">");
116278116340
}
116279116341
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
116280116342
char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116281
- explainAppendTerm(&txt, i, z, "<");
116343
+ explainAppendTerm(pStr, i, z, "<");
116282116344
}
116283
- sqlite3StrAccumAppend(&txt, ")", 1);
116284
- return sqlite3StrAccumFinish(&txt);
116345
+ sqlite3StrAccumAppend(pStr, ")", 1);
116285116346
}
116286116347
116287116348
/*
116288116349
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
116289116350
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
@@ -116303,72 +116364,90 @@
116303116364
#endif
116304116365
{
116305116366
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
116306116367
Vdbe *v = pParse->pVdbe; /* VM being constructed */
116307116368
sqlite3 *db = pParse->db; /* Database handle */
116308
- char *zMsg; /* Text to add to EQP output */
116309116369
int iId = pParse->iSelectId; /* Select id (left-most output column) */
116310116370
int isSearch; /* True for a SEARCH. False for SCAN. */
116311116371
WhereLoop *pLoop; /* The controlling WhereLoop object */
116312116372
u32 flags; /* Flags that describe this loop */
116373
+ char *zMsg; /* Text to add to EQP output */
116374
+ StrAccum str; /* EQP output string */
116375
+ char zBuf[100]; /* Initial space for EQP output string */
116313116376
116314116377
pLoop = pLevel->pWLoop;
116315116378
flags = pLoop->wsFlags;
116316116379
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
116317116380
116318116381
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
116319116382
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
116320116383
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
116321116384
116322
- zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
116385
+ sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
116386
+ str.db = db;
116387
+ sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
116323116388
if( pItem->pSelect ){
116324
- zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
116389
+ sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
116325116390
}else{
116326
- zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
116391
+ sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
116327116392
}
116328116393
116329116394
if( pItem->zAlias ){
116330
- zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
116331
- }
116332
- if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
116333
- && ALWAYS(pLoop->u.btree.pIndex!=0)
116334
- ){
116335
- const char *zFmt;
116336
- Index *pIdx = pLoop->u.btree.pIndex;
116337
- char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
116395
+ sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
116396
+ }
116397
+ if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
116398
+ const char *zFmt = 0;
116399
+ Index *pIdx;
116400
+
116401
+ assert( pLoop->u.btree.pIndex!=0 );
116402
+ pIdx = pLoop->u.btree.pIndex;
116338116403
assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
116339116404
if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
116340
- zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";
116405
+ if( isSearch ){
116406
+ zFmt = "PRIMARY KEY";
116407
+ }
116341116408
}else if( flags & WHERE_AUTO_INDEX ){
116342
- zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
116409
+ zFmt = "AUTOMATIC COVERING INDEX";
116343116410
}else if( flags & WHERE_IDX_ONLY ){
116344
- zFmt = "%s USING COVERING INDEX %s%s";
116411
+ zFmt = "COVERING INDEX %s";
116345116412
}else{
116346
- zFmt = "%s USING INDEX %s%s";
116413
+ zFmt = "INDEX %s";
116347116414
}
116348
- zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
116349
- sqlite3DbFree(db, zWhere);
116415
+ if( zFmt ){
116416
+ sqlite3StrAccumAppend(&str, " USING ", 7);
116417
+ sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
116418
+ explainIndexRange(&str, pLoop, pItem->pTab);
116419
+ }
116350116420
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
116351
- zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
116352
-
116421
+ const char *zRange;
116353116422
if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
116354
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
116423
+ zRange = "(rowid=?)";
116355116424
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
116356
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
116425
+ zRange = "(rowid>? AND rowid<?)";
116357116426
}else if( flags&WHERE_BTM_LIMIT ){
116358
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
116359
- }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
116360
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
116427
+ zRange = "(rowid>?)";
116428
+ }else{
116429
+ assert( flags&WHERE_TOP_LIMIT);
116430
+ zRange = "(rowid<?)";
116361116431
}
116432
+ sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
116433
+ sqlite3StrAccumAppendAll(&str, zRange);
116362116434
}
116363116435
#ifndef SQLITE_OMIT_VIRTUALTABLE
116364116436
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
116365
- zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
116437
+ sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
116366116438
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
116367116439
}
116368116440
#endif
116369
- zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
116441
+#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
116442
+ if( pLoop->nOut>=10 ){
116443
+ sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
116444
+ }else{
116445
+ sqlite3StrAccumAppend(&str, " (~1 row)", 9);
116446
+ }
116447
+#endif
116448
+ zMsg = sqlite3StrAccumFinish(&str);
116370116449
sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
116371116450
}
116372116451
}
116373116452
#else
116374116453
# define explainOneScan(u,v,w,x,y,z)
@@ -117633,11 +117712,11 @@
117633117712
if( ppPrev==0 ){
117634117713
/* There already exists a WhereLoop on the list that is better
117635117714
** than pTemplate, so just ignore pTemplate */
117636117715
#if WHERETRACE_ENABLED /* 0x8 */
117637117716
if( sqlite3WhereTrace & 0x8 ){
117638
- sqlite3DebugPrintf("ins-noop: ");
117717
+ sqlite3DebugPrintf(" skip: ");
117639117718
whereLoopPrint(pTemplate, pBuilder->pWC);
117640117719
}
117641117720
#endif
117642117721
return SQLITE_OK;
117643117722
}else{
@@ -117649,14 +117728,14 @@
117649117728
** WhereLoop and insert it.
117650117729
*/
117651117730
#if WHERETRACE_ENABLED /* 0x8 */
117652117731
if( sqlite3WhereTrace & 0x8 ){
117653117732
if( p!=0 ){
117654
- sqlite3DebugPrintf("ins-del: ");
117733
+ sqlite3DebugPrintf("replace: ");
117655117734
whereLoopPrint(p, pBuilder->pWC);
117656117735
}
117657
- sqlite3DebugPrintf("ins-new: ");
117736
+ sqlite3DebugPrintf(" add: ");
117658117737
whereLoopPrint(pTemplate, pBuilder->pWC);
117659117738
}
117660117739
#endif
117661117740
if( p==0 ){
117662117741
/* Allocate a new WhereLoop to add to the end of the list */
@@ -117676,11 +117755,11 @@
117676117755
pToDel = *ppTail;
117677117756
if( pToDel==0 ) break;
117678117757
*ppTail = pToDel->pNextLoop;
117679117758
#if WHERETRACE_ENABLED /* 0x8 */
117680117759
if( sqlite3WhereTrace & 0x8 ){
117681
- sqlite3DebugPrintf("ins-del: ");
117760
+ sqlite3DebugPrintf(" delete: ");
117682117761
whereLoopPrint(pToDel, pBuilder->pWC);
117683117762
}
117684117763
#endif
117685117764
whereLoopDelete(db, pToDel);
117686117765
}
@@ -118843,11 +118922,11 @@
118843118922
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
118844118923
}
118845118924
isMatch = 1;
118846118925
break;
118847118926
}
118848
- if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
118927
+ if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
118849118928
/* Make sure the sort order is compatible in an ORDER BY clause.
118850118929
** Sort order is irrelevant for a GROUP BY clause. */
118851118930
if( revSet ){
118852118931
if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
118853118932
}else{
@@ -119308,16 +119387,19 @@
119308119387
pWInfo->revMask = pFrom->revLoop;
119309119388
}
119310119389
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
119311119390
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
119312119391
){
119313
- Bitmask notUsed = 0;
119392
+ Bitmask revMask = 0;
119314119393
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
119315
- pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
119394
+ pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
119316119395
);
119317119396
assert( pWInfo->sorted==0 );
119318
- pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);
119397
+ if( nOrder==pWInfo->pOrderBy->nExpr ){
119398
+ pWInfo->sorted = 1;
119399
+ pWInfo->revMask = revMask;
119400
+ }
119319119401
}
119320119402
}
119321119403
119322119404
119323119405
pWInfo->nRowOut = pFrom->nRow;
@@ -132620,10 +132702,11 @@
132620132702
assert( iIdx==nVal );
132621132703
132622132704
/* In case the cursor has been used before, clear it now. */
132623132705
sqlite3_finalize(pCsr->pStmt);
132624132706
sqlite3_free(pCsr->aDoclist);
132707
+ sqlite3_free(pCsr->aMatchinfo);
132625132708
sqlite3Fts3ExprFree(pCsr->pExpr);
132626132709
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
132627132710
132628132711
/* Set the lower and upper bounds on docids to return */
132629132712
pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -133930,11 +134013,11 @@
133930134013
if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
133931134014
iMax = a[i].iDocid;
133932134015
bMaxSet = 1;
133933134016
}
133934134017
}
133935
- assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
134018
+ assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
133936134019
assert( rc!=SQLITE_OK || bMaxSet );
133937134020
133938134021
/* Keep advancing iterators until they all point to the same document */
133939134022
for(i=0; i<p->nToken; i++){
133940134023
while( rc==SQLITE_OK && bEof==0
@@ -136047,11 +136130,11 @@
136047136130
int i = 0;
136048136131
136049136132
/* Set variable i to the maximum number of bytes of input to tokenize. */
136050136133
for(i=0; i<n; i++){
136051136134
if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
136052
- if( z[i]=='*' || z[i]=='"' ) break;
136135
+ if( z[i]=='"' ) break;
136053136136
}
136054136137
136055136138
*pnConsumed = i;
136056136139
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
136057136140
if( rc==SQLITE_OK ){
136058136141
--- 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.8.7. 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.
@@ -229,13 +229,13 @@
229 **
230 ** See also: [sqlite3_libversion()],
231 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232 ** [sqlite_version()] and [sqlite_source_id()].
233 */
234 #define SQLITE_VERSION "3.8.7"
235 #define SQLITE_VERSION_NUMBER 3008007
236 #define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d"
237
238 /*
239 ** CAPI3REF: Run-Time Library Version Numbers
240 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
241 **
@@ -7944,11 +7944,11 @@
7944 ** A macro to hint to the compiler that a function should not be
7945 ** inlined.
7946 */
7947 #if defined(__GNUC__)
7948 # define SQLITE_NOINLINE __attribute__((noinline))
7949 #elif defined(_MSC_VER)
7950 # define SQLITE_NOINLINE __declspec(noinline)
7951 #else
7952 # define SQLITE_NOINLINE
7953 #endif
7954
@@ -11322,10 +11322,11 @@
11322 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
11323 int nSample; /* Number of elements in aSample[] */
11324 int nSampleCol; /* Size of IndexSample.anEq[] and so on */
11325 tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
11326 IndexSample *aSample; /* Samples of the left-most key */
 
11327 #endif
11328 };
11329
11330 /*
11331 ** Allowed values for Index.idxType
@@ -12186,11 +12187,10 @@
12186 #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
12187 #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
12188 #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
12189 #define OPFLAG_APPEND 0x08 /* This is likely to be an append */
12190 #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
12191 #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
12192 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
12193 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
12194 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
12195 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
12196 #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
@@ -13320,14 +13320,13 @@
13320 # define sqlite3MemdebugSetType(X,Y) /* no-op */
13321 # define sqlite3MemdebugHasType(X,Y) 1
13322 # define sqlite3MemdebugNoType(X,Y) 1
13323 #endif
13324 #define MEMTYPE_HEAP 0x01 /* General heap allocations */
13325 #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
13326 #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
13327 #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
13328 #define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
13329
13330 /*
13331 ** Threading interface
13332 */
13333 #if SQLITE_MAX_WORKER_THREADS>0
@@ -14095,21 +14094,19 @@
14095 #ifdef SQLITE_DEBUG
14096 u8 seekOp; /* Most recent seek operation on this cursor */
14097 #endif
14098 i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
14099 u8 nullRow; /* True if pointing to a row with no data */
14100 u8 rowidIsValid; /* True if lastRowid is valid */
14101 u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
14102 Bool isEphemeral:1; /* True for an ephemeral table */
14103 Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
14104 Bool isTable:1; /* True if a table requiring integer keys */
14105 Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
14106 Pgno pgnoRoot; /* Root page of the open btree cursor */
14107 sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
14108 i64 seqCount; /* Sequence counter */
14109 i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
14110 i64 lastRowid; /* Rowid being deleted by OP_Delete */
14111 VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
14112
14113 /* Cached information about the header for the data record that the
14114 ** cursor is currently pointing to. Only valid if cacheStatus matches
14115 ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -14122,10 +14119,11 @@
14122 u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
14123 u32 payloadSize; /* Total number of bytes in the record */
14124 u32 szRow; /* Byte available in aRow */
14125 u32 iHdrOffset; /* Offset to next unparsed byte of the header */
14126 const u8 *aRow; /* Data for the current row, if all on one page */
 
14127 u32 aType[1]; /* Type values for all entries in the record */
14128 /* 2*nField extra array elements allocated for aType[], beyond the one
14129 ** static element declared in the structure. nField total array slots for
14130 ** aType[] and nField+1 array slots for aOffset[] */
14131 };
@@ -14198,11 +14196,11 @@
14198 int n; /* Number of characters in string value, excluding '\0' */
14199 char *z; /* String or BLOB value */
14200 /* ShallowCopy only needs to copy the information above */
14201 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
14202 int szMalloc; /* Size of the zMalloc allocation */
14203 int iPadding1; /* Padding for 8-byte alignment */
14204 sqlite3 *db; /* The associated database connection */
14205 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
14206 #ifdef SQLITE_DEBUG
14207 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
14208 void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
@@ -14406,10 +14404,11 @@
14406 ** Function prototypes
14407 */
14408 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
14409 void sqliteVdbePopStack(Vdbe*,int);
14410 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
 
14411 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
14412 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
14413 #endif
14414 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
14415 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
@@ -17130,11 +17129,11 @@
17130 ** allocation p. Also return true if p==NULL.
17131 **
17132 ** This routine is designed for use within an assert() statement, to
17133 ** verify the type of an allocation. For example:
17134 **
17135 ** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
17136 */
17137 SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
17138 int rc = 1;
17139 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17140 struct MemBlockHdr *pHdr;
@@ -17152,11 +17151,11 @@
17152 ** allocation p. Also return true if p==NULL.
17153 **
17154 ** This routine is designed for use within an assert() statement, to
17155 ** verify the type of an allocation. For example:
17156 **
17157 ** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
17158 */
17159 SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
17160 int rc = 1;
17161 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17162 struct MemBlockHdr *pHdr;
@@ -20364,39 +20363,41 @@
20364 ** Return the size of a memory allocation previously obtained from
20365 ** sqlite3Malloc() or sqlite3_malloc().
20366 */
20367 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
20368 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20369 assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
20370 return sqlite3GlobalConfig.m.xSize(p);
20371 }
20372 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
20373 if( db==0 ){
 
 
20374 return sqlite3MallocSize(p);
20375 }else{
20376 assert( sqlite3_mutex_held(db->mutex) );
20377 if( isLookaside(db, p) ){
20378 return db->lookaside.sz;
20379 }else{
20380 assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20381 assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20382 assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20383 return sqlite3GlobalConfig.m.xSize(p);
20384 }
20385 }
20386 }
20387 SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
 
 
20388 return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
20389 }
20390
20391 /*
20392 ** Free memory previously obtained from sqlite3Malloc().
20393 */
20394 SQLITE_API void sqlite3_free(void *p){
20395 if( p==0 ) return; /* IMP: R-49053-54554 */
20396 assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
20397 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
 
20398 if( sqlite3GlobalConfig.bMemstat ){
20399 sqlite3_mutex_enter(mem0.mutex);
20400 sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
20401 sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
20402 sqlite3GlobalConfig.m.xFree(p);
@@ -20436,12 +20437,12 @@
20436 db->lookaside.pFree = pBuf;
20437 db->lookaside.nOut--;
20438 return;
20439 }
20440 }
20441 assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20442 assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20443 assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20444 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20445 sqlite3_free(p);
20446 }
20447
@@ -20449,10 +20450,12 @@
20449 ** Change the size of an existing memory allocation
20450 */
20451 SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
20452 int nOld, nNew, nDiff;
20453 void *pNew;
 
 
20454 if( pOld==0 ){
20455 return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
20456 }
20457 if( nBytes==0 ){
20458 sqlite3_free(pOld); /* IMP: R-26507-47431 */
@@ -20475,12 +20478,10 @@
20475 nDiff = nNew - nOld;
20476 if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
20477 mem0.alarmThreshold-nDiff ){
20478 sqlite3MallocAlarm(nDiff);
20479 }
20480 assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20481 assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
20482 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20483 if( pNew==0 && mem0.alarmCallback ){
20484 sqlite3MallocAlarm((int)nBytes);
20485 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20486 }
@@ -20589,12 +20590,12 @@
20589 #endif
20590 p = sqlite3Malloc(n);
20591 if( !p && db ){
20592 db->mallocFailed = 1;
20593 }
20594 sqlite3MemdebugSetType(p, MEMTYPE_DB |
20595 ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20596 return p;
20597 }
20598
20599 /*
20600 ** Resize the block of memory pointed to by p to n bytes. If the
@@ -20616,19 +20617,18 @@
20616 if( pNew ){
20617 memcpy(pNew, p, db->lookaside.sz);
20618 sqlite3DbFree(db, p);
20619 }
20620 }else{
20621 assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20622 assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20623 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20624 pNew = sqlite3_realloc64(p, n);
20625 if( !pNew ){
20626 sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
20627 db->mallocFailed = 1;
20628 }
20629 sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
20630 (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20631 }
20632 }
20633 return pNew;
20634 }
@@ -20754,15 +20754,11 @@
20754 ** HAVE_STRCHRNUL. If that routine is not available, this module
20755 ** will supply its own. The built-in version is slower than
20756 ** the glibc version so the glibc version is definitely preferred.
20757 */
20758 #if !defined(HAVE_STRCHRNUL)
20759 # if defined(linux)
20760 # define HAVE_STRCHRNUL 1
20761 # else
20762 # define HAVE_STRCHRNUL 0
20763 # endif
20764 #endif
20765
20766
20767 /*
20768 ** Conversion types fall into various categories as defined by the
@@ -22091,18 +22087,18 @@
22091 #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
22092 /******************************** End Unix Pthreads *************************/
22093
22094
22095 /********************************* Win32 Threads ****************************/
22096 #if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
22097
22098 #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
22099 #include <process.h>
22100
22101 /* A running thread */
22102 struct SQLiteThread {
22103 uintptr_t tid; /* The thread handle */
22104 unsigned id; /* The thread identifier */
22105 void *(*xTask)(void*); /* The routine to run as a thread */
22106 void *pIn; /* Argument to xTask */
22107 void *pResult; /* Result of xTask */
22108 };
@@ -22146,11 +22142,11 @@
22146 if( sqlite3GlobalConfig.bCoreMutex==0 ){
22147 memset(p, 0, sizeof(*p));
22148 }else{
22149 p->xTask = xTask;
22150 p->pIn = pIn;
22151 p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
22152 if( p->tid==0 ){
22153 memset(p, 0, sizeof(*p));
22154 }
22155 }
22156 if( p->xTask==0 ){
@@ -22184,11 +22180,11 @@
22184 if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
22185 sqlite3_free(p);
22186 return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
22187 }
22188
22189 #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
22190 /******************************** End Win32 Threads *************************/
22191
22192
22193 /********************************* Single-Threaded **************************/
22194 #ifndef SQLITE_THREADS_IMPLEMENTED
@@ -33487,11 +33483,15 @@
33487 #endif
33488
33489 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
33490 DWORD))aSyscall[63].pCurrent)
33491
 
33492 { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
 
 
 
33493
33494 #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
33495 BOOL))aSyscall[64].pCurrent)
33496
33497 #if SQLITE_OS_WINRT
@@ -33830,11 +33830,12 @@
33830 #else
33831 osSleep(milliseconds);
33832 #endif
33833 }
33834
33835 #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
 
33836 SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
33837 DWORD rc;
33838 while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
33839 TRUE))==WAIT_IO_COMPLETION ){}
33840 return rc;
@@ -39855,11 +39856,11 @@
39855 assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
39856 assert( pCache->n90pct == pCache->nMax*9/10 );
39857 if( createFlag==1 && (
39858 nPinned>=pGroup->mxPinned
39859 || nPinned>=pCache->n90pct
39860 || pcache1UnderMemoryPressure(pCache)
39861 )){
39862 return 0;
39863 }
39864
39865 if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
@@ -42799,10 +42800,18 @@
42799 }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
42800 if( pPager->journalOff==0 ){
42801 rc = SQLITE_OK;
42802 }else{
42803 rc = sqlite3OsTruncate(pPager->jfd, 0);
 
 
 
 
 
 
 
 
42804 }
42805 pPager->journalOff = 0;
42806 }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
42807 || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
42808 ){
@@ -44476,17 +44485,19 @@
44476 if( !pNew ) rc = SQLITE_NOMEM;
44477 }
44478
44479 if( rc==SQLITE_OK ){
44480 pager_reset(pPager);
44481 sqlite3PageFree(pPager->pTmpSpace);
44482 pPager->pTmpSpace = pNew;
44483 rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
44484 }
44485 if( rc==SQLITE_OK ){
 
 
44486 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
44487 pPager->pageSize = pageSize;
 
 
44488 }
44489 }
44490
44491 *pPageSize = pPager->pageSize;
44492 if( rc==SQLITE_OK ){
@@ -51649,11 +51660,11 @@
51649 int nRef; /* Number of references to this structure */
51650 BtShared *pNext; /* Next on a list of sharable BtShared structs */
51651 BtLock *pLock; /* List of locks held on this shared-btree struct */
51652 Btree *pWriter; /* Btree with currently open write transaction */
51653 #endif
51654 u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
51655 };
51656
51657 /*
51658 ** Allowed values for BtShared.btsFlags
51659 */
@@ -52947,11 +52958,11 @@
52947 **
52948 ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
52949 ** back to where it ought to be if this routine returns true.
52950 */
52951 SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
52952 return pCur && pCur->eState!=CURSOR_VALID;
52953 }
52954
52955 /*
52956 ** This routine restores a cursor back to its original position after it
52957 ** has been moved by some outside activity (such as a btree rebalance or
@@ -54279,11 +54290,12 @@
54279 #endif
54280 }
54281
54282 /*
54283 ** Make sure pBt->pTmpSpace points to an allocation of
54284 ** MX_CELL_SIZE(pBt) bytes.
 
54285 */
54286 static void allocateTempSpace(BtShared *pBt){
54287 if( !pBt->pTmpSpace ){
54288 pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
54289
@@ -54294,21 +54306,32 @@
54294 ** can mean that fillInCell() only initializes the first 2 or 3
54295 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
54296 ** it into a database page. This is not actually a problem, but it
54297 ** does cause a valgrind error when the 1 or 2 bytes of unitialized
54298 ** data is passed to system call write(). So to avoid this error,
54299 ** zero the first 4 bytes of temp space here. */
54300 if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);
 
 
 
 
 
 
 
 
54301 }
54302 }
54303
54304 /*
54305 ** Free the pBt->pTmpSpace allocation
54306 */
54307 static void freeTempSpace(BtShared *pBt){
54308 sqlite3PageFree( pBt->pTmpSpace);
54309 pBt->pTmpSpace = 0;
 
 
 
54310 }
54311
54312 /*
54313 ** Close an open database and invalidate all cursors.
54314 */
@@ -58016,15 +58039,10 @@
58016 ** pTemp is not null. Regardless of pTemp, allocate a new entry
58017 ** in pPage->apOvfl[] and make it point to the cell content (either
58018 ** in pTemp or the original pCell) and also record its index.
58019 ** Allocating a new entry in pPage->aCell[] implies that
58020 ** pPage->nOverflow is incremented.
58021 **
58022 ** If nSkip is non-zero, then do not copy the first nSkip bytes of the
58023 ** cell. The caller will overwrite them after this function returns. If
58024 ** nSkip is non-zero, then pCell may not point to an invalid memory location
58025 ** (but pCell+nSkip is always valid).
58026 */
58027 static void insertCell(
58028 MemPage *pPage, /* Page into which we are copying */
58029 int i, /* New cell becomes the i-th cell of the page */
58030 u8 *pCell, /* Content of the new cell */
@@ -58037,11 +58055,10 @@
58037 int j; /* Loop counter */
58038 int end; /* First byte past the last cell pointer in data[] */
58039 int ins; /* Index in data[] where new cell pointer is inserted */
58040 int cellOffset; /* Address of first cell pointer in data[] */
58041 u8 *data; /* The content of the whole page */
58042 int nSkip = (iChild ? 4 : 0);
58043
58044 if( *pRC ) return;
58045
58046 assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
58047 assert( MX_CELL(pPage->pBt)<=10921 );
@@ -58055,11 +58072,11 @@
58055 ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
58056 ** the term after the || in the following assert(). */
58057 assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
58058 if( pPage->nOverflow || sz+2>pPage->nFree ){
58059 if( pTemp ){
58060 memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
58061 pCell = pTemp;
58062 }
58063 if( iChild ){
58064 put4byte(pCell, iChild);
58065 }
@@ -58084,11 +58101,11 @@
58084 ** if it returns success */
58085 assert( idx >= end+2 );
58086 assert( idx+sz <= (int)pPage->pBt->usableSize );
58087 pPage->nCell++;
58088 pPage->nFree -= (u16)(2 + sz);
58089 memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
58090 if( iChild ){
58091 put4byte(&data[idx], iChild);
58092 }
58093 memmove(&data[ins+2], &data[ins], end-ins);
58094 put2byte(&data[ins], idx);
@@ -61630,11 +61647,14 @@
61630 /* If MEM_Dyn is set then Mem.xDel!=0.
61631 ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
61632 */
61633 assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
61634
61635 /* MEM_Dyn may only be set if Mem.szMalloc==0 */
 
 
 
61636 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
61637
61638 /* Cannot be both MEM_Int and MEM_Real at the same time */
61639 assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
61640
@@ -61739,11 +61759,11 @@
61739 }else{
61740 pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
61741 }
61742 }
61743
61744 if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
61745 memcpy(pMem->zMalloc, pMem->z, pMem->n);
61746 }
61747 if( (pMem->flags&MEM_Dyn)!=0 ){
61748 assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
61749 pMem->xDel((void *)(pMem->z));
@@ -61766,11 +61786,12 @@
61766 **
61767 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
61768 ** if unable to complete the resizing.
61769 */
61770 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
61771 assert( szNew>=0 );
 
61772 if( pMem->szMalloc<szNew ){
61773 return sqlite3VdbeMemGrow(pMem, szNew, 0);
61774 }
61775 assert( (pMem->flags & MEM_Dyn)==0 );
61776 pMem->z = pMem->zMalloc;
@@ -62490,11 +62511,14 @@
62490 nAlloc += (enc==SQLITE_UTF8?1:2);
62491 }
62492 if( nByte>iLimit ){
62493 return SQLITE_TOOBIG;
62494 }
62495 if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){
 
 
 
62496 return SQLITE_NOMEM;
62497 }
62498 memcpy(pMem->z, z, nAlloc);
62499 }else if( xDel==SQLITE_DYNAMIC ){
62500 sqlite3VdbeMemRelease(pMem);
@@ -62593,11 +62617,11 @@
62593 /*
62594 ** The pVal argument is known to be a value other than NULL.
62595 ** Convert it into a string with encoding enc and return a pointer
62596 ** to a zero-terminated version of that string.
62597 */
62598 SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
62599 assert( pVal!=0 );
62600 assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
62601 assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
62602 assert( (pVal->flags & MEM_RowSet)==0 );
62603 assert( (pVal->flags & (MEM_Null))==0 );
@@ -64913,11 +64937,11 @@
64913 ** the call above. */
64914 }else if( pCx->pCursor ){
64915 sqlite3BtreeCloseCursor(pCx->pCursor);
64916 }
64917 #ifndef SQLITE_OMIT_VIRTUALTABLE
64918 if( pCx->pVtabCursor ){
64919 sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
64920 const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
64921 p->inVtabMethod = 1;
64922 pModule->xClose(pVtabCursor);
64923 p->inVtabMethod = 0;
@@ -64956,13 +64980,14 @@
64956 static void closeAllCursors(Vdbe *p){
64957 if( p->pFrame ){
64958 VdbeFrame *pFrame;
64959 for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
64960 sqlite3VdbeFrameRestore(pFrame);
 
 
64961 }
64962 p->pFrame = 0;
64963 p->nFrame = 0;
64964
64965 if( p->apCsr ){
64966 int i;
64967 for(i=0; i<p->nCursor; i++){
64968 VdbeCursor *pC = p->apCsr[i];
@@ -64980,11 +65005,11 @@
64980 p->pDelFrame = pDel->pParent;
64981 sqlite3VdbeFrameDelete(pDel);
64982 }
64983
64984 /* Delete any auxdata allocations made by the VM */
64985 sqlite3VdbeDeleteAuxData(p, -1, 0);
64986 assert( p->pAuxData==0 );
64987 }
64988
64989 /*
64990 ** Clean up the VM after a single run.
@@ -65886,13 +65911,11 @@
65886 #endif
65887 assert( p->deferredMoveto );
65888 assert( p->isTable );
65889 rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
65890 if( rc ) return rc;
65891 p->lastRowid = p->movetoTarget;
65892 if( res!=0 ) return SQLITE_CORRUPT_BKPT;
65893 p->rowidIsValid = 1;
65894 #ifdef SQLITE_TEST
65895 sqlite3_search_count++;
65896 #endif
65897 p->deferredMoveto = 0;
65898 p->cacheStatus = CACHE_STALE;
@@ -65913,10 +65936,21 @@
65913 rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
65914 p->cacheStatus = CACHE_STALE;
65915 if( isDifferentRow ) p->nullRow = 1;
65916 return rc;
65917 }
 
 
 
 
 
 
 
 
 
 
 
65918
65919 /*
65920 ** Make sure the cursor p is ready to read or write the row to which it
65921 ** was last positioned. Return an error code if an OOM fault or I/O error
65922 ** prevents us from positioning the cursor to its correct position.
@@ -65931,11 +65965,11 @@
65931 */
65932 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
65933 if( p->deferredMoveto ){
65934 return handleDeferredMoveto(p);
65935 }
65936 if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65937 return handleMovedCursor(p);
65938 }
65939 return SQLITE_OK;
65940 }
65941
@@ -69095,10 +69129,11 @@
69095 if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
69096 p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
69097 memset(pCx, 0, sizeof(VdbeCursor));
69098 pCx->iDb = iDb;
69099 pCx->nField = nField;
 
69100 if( isBtreeCursor ){
69101 pCx->pCursor = (BtCursor*)
69102 &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
69103 sqlite3BtreeCursorZero(pCx->pCursor);
69104 }
@@ -70528,11 +70563,11 @@
70528 ctx.pFunc = pOp->p4.pFunc;
70529 ctx.iOp = pc;
70530 ctx.pVdbe = p;
70531 MemSetTypeFlag(ctx.pOut, MEM_Null);
70532 ctx.fErrorOrAux = 0;
70533 assert( db->lastRowid==lastRowid );
70534 (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
70535 lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
70536
70537 /* If the function returned an error, throw an exception */
70538 if( ctx.fErrorOrAux ){
@@ -71246,11 +71281,11 @@
71246 memAboutToChange(p, pDest);
71247 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
71248 pC = p->apCsr[pOp->p1];
71249 assert( pC!=0 );
71250 assert( p2<pC->nField );
71251 aOffset = pC->aType + pC->nField;
71252 #ifndef SQLITE_OMIT_VIRTUALTABLE
71253 assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
71254 #endif
71255 pCrsr = pC->pCursor;
71256 assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
@@ -71257,11 +71292,11 @@
71257 assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
71258
71259 /* If the cursor cache is stale, bring it up-to-date */
71260 rc = sqlite3VdbeCursorMoveto(pC);
71261 if( rc ) goto abort_due_to_error;
71262 if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
71263 if( pC->nullRow ){
71264 if( pCrsr==0 ){
71265 assert( pC->pseudoTableReg>0 );
71266 pReg = &aMem[pC->pseudoTableReg];
71267 assert( pReg->flags & MEM_Blob );
@@ -71302,18 +71337,10 @@
71302 }
71303 pC->cacheStatus = p->cacheCtr;
71304 pC->iHdrOffset = getVarint32(pC->aRow, offset);
71305 pC->nHdrParsed = 0;
71306 aOffset[0] = offset;
71307 if( avail<offset ){
71308 /* pC->aRow does not have to hold the entire row, but it does at least
71309 ** need to cover the header of the record. If pC->aRow does not contain
71310 ** the complete header, then set it to zero, forcing the header to be
71311 ** dynamically allocated. */
71312 pC->aRow = 0;
71313 pC->szRow = 0;
71314 }
71315
71316 /* Make sure a corrupt database has not given us an oversize header.
71317 ** Do this now to avoid an oversize memory allocation.
71318 **
71319 ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -71324,19 +71351,36 @@
71324 */
71325 if( offset > 98307 || offset > pC->payloadSize ){
71326 rc = SQLITE_CORRUPT_BKPT;
71327 goto op_column_error;
71328 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71329 }
71330
71331 /* Make sure at least the first p2+1 entries of the header have been
71332 ** parsed and valid information is in aOffset[] and pC->aType[].
71333 */
71334 if( pC->nHdrParsed<=p2 ){
71335 /* If there is more header available for parsing in the record, try
71336 ** to extract additional fields up through the p2+1-th field
71337 */
 
71338 if( pC->iHdrOffset<aOffset[0] ){
71339 /* Make sure zData points to enough of the record to cover the header. */
71340 if( pC->aRow==0 ){
71341 memset(&sMem, 0, sizeof(sMem));
71342 rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
@@ -71377,19 +71421,20 @@
71377 if( pC->aRow==0 ){
71378 sqlite3VdbeMemRelease(&sMem);
71379 sMem.flags = MEM_Null;
71380 }
71381
71382 /* If we have read more header data than was contained in the header,
71383 ** or if the end of the last field appears to be past the end of the
71384 ** record, or if the end of the last field appears to be before the end
71385 ** of the record (when all fields present), then we must be dealing
71386 ** with a corrupt database.
 
 
71387 */
71388 if( (zHdr > zEndHdr)
71389 || (offset > pC->payloadSize)
71390 || (zHdr==zEndHdr && offset!=pC->payloadSize)
71391 ){
71392 rc = SQLITE_CORRUPT_BKPT;
71393 goto op_column_error;
71394 }
71395 }
@@ -71400,11 +71445,11 @@
71400 */
71401 if( pC->nHdrParsed<=p2 ){
71402 if( pOp->p4type==P4_MEM ){
71403 sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
71404 }else{
71405 MemSetTypeFlag(pDest, MEM_Null);
71406 }
71407 goto op_column_out;
71408 }
71409 }
71410
@@ -71576,11 +71621,11 @@
71576 ** out how much space is required for the new record.
71577 */
71578 pRec = pLast;
71579 do{
71580 assert( memIsValid(pRec) );
71581 serial_type = sqlite3VdbeSerialType(pRec, file_format);
71582 len = sqlite3VdbeSerialTypeLen(serial_type);
71583 if( pRec->flags & MEM_Zero ){
71584 if( nData ){
71585 sqlite3VdbeMemExpandBlob(pRec);
71586 }else{
@@ -71625,11 +71670,11 @@
71625 i = putVarint32(zNewRecord, nHdr);
71626 j = nHdr;
71627 assert( pData0<=pLast );
71628 pRec = pData0;
71629 do{
71630 serial_type = sqlite3VdbeSerialType(pRec, file_format);
71631 i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
71632 j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
71633 }while( (++pRec)<=pLast );
71634 assert( i==nHdr );
71635 assert( j==nByte );
@@ -72524,11 +72569,10 @@
72524 pIn3 = &aMem[pOp->p3];
72525 if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
72526 applyNumericAffinity(pIn3, 0);
72527 }
72528 iKey = sqlite3VdbeIntValue(pIn3);
72529 pC->rowidIsValid = 0;
72530
72531 /* If the P3 value could not be converted into an integer without
72532 ** loss of information, then special processing is required... */
72533 if( (pIn3->flags & MEM_Int)==0 ){
72534 if( (pIn3->flags & MEM_Real)==0 ){
@@ -72560,17 +72604,14 @@
72560 assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
72561 if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
72562 }
72563 }
72564 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
 
72565 if( rc!=SQLITE_OK ){
72566 goto abort_due_to_error;
72567 }
72568 if( res==0 ){
72569 pC->rowidIsValid = 1;
72570 pC->lastRowid = iKey;
72571 }
72572 }else{
72573 nField = pOp->p4.i;
72574 assert( pOp->p4type==P4_INT32 );
72575 assert( nField>0 );
72576 r.pKeyInfo = pC->pKeyInfo;
@@ -72596,11 +72637,10 @@
72596 ExpandBlob(r.aMem);
72597 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
72598 if( rc!=SQLITE_OK ){
72599 goto abort_due_to_error;
72600 }
72601 pC->rowidIsValid = 0;
72602 }
72603 pC->deferredMoveto = 0;
72604 pC->cacheStatus = CACHE_STALE;
72605 #ifdef SQLITE_TEST
72606 sqlite3_search_count++;
@@ -72608,21 +72648,19 @@
72608 if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
72609 if( res<0 || (res==0 && oc==OP_SeekGT) ){
72610 res = 0;
72611 rc = sqlite3BtreeNext(pC->pCursor, &res);
72612 if( rc!=SQLITE_OK ) goto abort_due_to_error;
72613 pC->rowidIsValid = 0;
72614 }else{
72615 res = 0;
72616 }
72617 }else{
72618 assert( oc==OP_SeekLT || oc==OP_SeekLE );
72619 if( res>0 || (res==0 && oc==OP_SeekLT) ){
72620 res = 0;
72621 rc = sqlite3BtreePrevious(pC->pCursor, &res);
72622 if( rc!=SQLITE_OK ) goto abort_due_to_error;
72623 pC->rowidIsValid = 0;
72624 }else{
72625 /* res might be negative because the table is empty. Check to
72626 ** see if this is the case.
72627 */
72628 res = sqlite3BtreeEof(pC->pCursor);
@@ -72655,11 +72693,10 @@
72655 assert( pC->pCursor!=0 );
72656 assert( pC->isTable );
72657 pC->nullRow = 0;
72658 pIn2 = &aMem[pOp->p2];
72659 pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
72660 pC->rowidIsValid = 0;
72661 pC->deferredMoveto = 1;
72662 break;
72663 }
72664
72665
@@ -72841,19 +72878,17 @@
72841 pCrsr = pC->pCursor;
72842 assert( pCrsr!=0 );
72843 res = 0;
72844 iKey = pIn3->u.i;
72845 rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
72846 pC->lastRowid = pIn3->u.i;
72847 pC->rowidIsValid = res==0 ?1:0;
72848 pC->nullRow = 0;
72849 pC->cacheStatus = CACHE_STALE;
72850 pC->deferredMoveto = 0;
72851 VdbeBranchTaken(res!=0,2);
72852 if( res!=0 ){
72853 pc = pOp->p2 - 1;
72854 assert( pC->rowidIsValid==0 );
72855 }
72856 pC->seekResult = res;
72857 break;
72858 }
72859
@@ -72997,11 +73032,10 @@
72997 rc = SQLITE_FULL; /* IMP: R-38219-53002 */
72998 goto abort_due_to_error;
72999 }
73000 assert( v>0 ); /* EV: R-40812-03570 */
73001 }
73002 pC->rowidIsValid = 0;
73003 pC->deferredMoveto = 0;
73004 pC->cacheStatus = CACHE_STALE;
73005 }
73006 pOut->u.i = v;
73007 break;
@@ -73102,11 +73136,10 @@
73102 }
73103 rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
73104 pData->z, pData->n, nZero,
73105 (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
73106 );
73107 pC->rowidIsValid = 0;
73108 pC->deferredMoveto = 0;
73109 pC->cacheStatus = CACHE_STALE;
73110
73111 /* Invoke the update-hook if required. */
73112 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -73139,37 +73172,36 @@
73139 ** pointing to. The update hook will be invoked, if it exists.
73140 ** If P4 is not NULL then the P1 cursor must have been positioned
73141 ** using OP_NotFound prior to invoking this opcode.
73142 */
73143 case OP_Delete: {
73144 i64 iKey;
73145 VdbeCursor *pC;
73146
73147 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73148 pC = p->apCsr[pOp->p1];
73149 assert( pC!=0 );
73150 assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
73151 iKey = pC->lastRowid; /* Only used for the update hook */
73152
73153 /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
73154 ** OP_Column on the same table without any intervening operations that
73155 ** might move or invalidate the cursor. Hence cursor pC is always pointing
73156 ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
73157 ** below is always a no-op and cannot fail. We will run it anyhow, though,
73158 ** to guard against future changes to the code generator.
73159 **/
73160 assert( pC->deferredMoveto==0 );
73161 rc = sqlite3VdbeCursorMoveto(pC);
73162 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73163
 
 
 
 
 
 
 
 
 
 
 
73164 rc = sqlite3BtreeDelete(pC->pCursor);
73165 pC->cacheStatus = CACHE_STALE;
73166
73167 /* Invoke the update-hook if required. */
73168 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
73169 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
73170 db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
73171 assert( pC->iDb>=0 );
73172 }
73173 if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
73174 break;
73175 }
@@ -73218,23 +73250,32 @@
73218 pc = pOp->p2-1;
73219 }
73220 break;
73221 };
73222
73223 /* Opcode: SorterData P1 P2 * * *
73224 ** Synopsis: r[P2]=data
73225 **
73226 ** Write into register P2 the current sorter data for sorter cursor P1.
 
 
 
 
 
 
 
73227 */
73228 case OP_SorterData: {
73229 VdbeCursor *pC;
73230
73231 pOut = &aMem[pOp->p2];
73232 pC = p->apCsr[pOp->p1];
73233 assert( isSorter(pC) );
73234 rc = sqlite3VdbeSorterRowkey(pC, pOut);
73235 assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
 
 
73236 break;
73237 }
73238
73239 /* Opcode: RowData P1 P2 * * *
73240 ** Synopsis: r[P2]=data
@@ -73277,20 +73318,24 @@
73277 assert( pC!=0 );
73278 assert( pC->nullRow==0 );
73279 assert( pC->pseudoTableReg==0 );
73280 assert( pC->pCursor!=0 );
73281 pCrsr = pC->pCursor;
73282 assert( sqlite3BtreeCursorIsValid(pCrsr) );
73283
73284 /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
73285 ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
73286 ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
73287 ** a no-op and can never fail. But we leave it in place as a safety.
 
 
73288 */
73289 assert( pC->deferredMoveto==0 );
 
 
73290 rc = sqlite3VdbeCursorMoveto(pC);
73291 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
 
73292
73293 if( pC->isTable==0 ){
73294 assert( !pC->isTable );
73295 VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
73296 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -73303,11 +73348,12 @@
73303 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
73304 if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
73305 goto too_big;
73306 }
73307 }
73308 if( sqlite3VdbeMemClearAndResize(pOut, n) ){
 
73309 goto no_mem;
73310 }
73311 pOut->n = n;
73312 MemSetTypeFlag(pOut, MEM_Blob);
73313 if( pC->isTable==0 ){
@@ -73354,18 +73400,14 @@
73354 rc = pModule->xRowid(pC->pVtabCursor, &v);
73355 sqlite3VtabImportErrmsg(p, pVtab);
73356 #endif /* SQLITE_OMIT_VIRTUALTABLE */
73357 }else{
73358 assert( pC->pCursor!=0 );
73359 rc = sqlite3VdbeCursorMoveto(pC);
73360 if( rc ) goto abort_due_to_error;
73361 if( pC->rowidIsValid ){
73362 v = pC->lastRowid;
73363 }else{
73364 rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73365 assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
73366 }
73367 }
73368 pOut->u.i = v;
73369 break;
73370 }
73371
@@ -73380,11 +73422,10 @@
73380
73381 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73382 pC = p->apCsr[pOp->p1];
73383 assert( pC!=0 );
73384 pC->nullRow = 1;
73385 pC->rowidIsValid = 0;
73386 pC->cacheStatus = CACHE_STALE;
73387 if( pC->pCursor ){
73388 sqlite3BtreeClearCursor(pC->pCursor);
73389 }
73390 break;
@@ -73414,11 +73455,10 @@
73414 res = 0;
73415 assert( pCrsr!=0 );
73416 rc = sqlite3BtreeLast(pCrsr, &res);
73417 pC->nullRow = (u8)res;
73418 pC->deferredMoveto = 0;
73419 pC->rowidIsValid = 0;
73420 pC->cacheStatus = CACHE_STALE;
73421 #ifdef SQLITE_DEBUG
73422 pC->seekOp = OP_Last;
73423 #endif
73424 if( pOp->p2>0 ){
@@ -73481,11 +73521,10 @@
73481 pCrsr = pC->pCursor;
73482 assert( pCrsr );
73483 rc = sqlite3BtreeFirst(pCrsr, &res);
73484 pC->deferredMoveto = 0;
73485 pC->cacheStatus = CACHE_STALE;
73486 pC->rowidIsValid = 0;
73487 }
73488 pC->nullRow = (u8)res;
73489 assert( pOp->p2>0 && pOp->p2<p->nOp );
73490 VdbeBranchTaken(res!=0,2);
73491 if( res ){
@@ -73607,11 +73646,10 @@
73607 sqlite3_search_count++;
73608 #endif
73609 }else{
73610 pC->nullRow = 1;
73611 }
73612 pC->rowidIsValid = 0;
73613 goto check_for_interrupt;
73614 }
73615
73616 /* Opcode: IdxInsert P1 P2 P3 * P5
73617 ** Synopsis: key=r[P2]
@@ -73723,14 +73761,20 @@
73723 pC = p->apCsr[pOp->p1];
73724 assert( pC!=0 );
73725 pCrsr = pC->pCursor;
73726 assert( pCrsr!=0 );
73727 pOut->flags = MEM_Null;
73728 rc = sqlite3VdbeCursorMoveto(pC);
73729 if( NEVER(rc) ) goto abort_due_to_error;
73730 assert( pC->deferredMoveto==0 );
73731 assert( pC->isTable==0 );
 
 
 
 
 
 
 
73732 if( !pC->nullRow ){
73733 rowid = 0; /* Not needed. Only used to silence a warning. */
73734 rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
73735 if( rc!=SQLITE_OK ){
73736 goto abort_due_to_error;
@@ -78187,11 +78231,11 @@
78187 if( rc==SQLITE_OK ){
78188 #if SQLITE_MAX_WORKER_THREADS
78189 assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
78190 if( pSorter->bUseThreads ){
78191 int iTask;
78192 PmaReader *pReadr;
78193 SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
78194 rc = vdbeSortAllocUnpacked(pLast);
78195 if( rc==SQLITE_OK ){
78196 pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
78197 pSorter->pReader = pReadr;
@@ -87168,29 +87212,27 @@
87168 tRowcnt v;
87169
87170 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87171 if( z==0 ) z = "";
87172 #else
87173 if( NEVER(z==0) ) z = "";
87174 #endif
87175 for(i=0; *z && i<nOut; i++){
87176 v = 0;
87177 while( (c=z[0])>='0' && c<='9' ){
87178 v = v*10 + c - '0';
87179 z++;
87180 }
87181 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87182 if( aOut ){
87183 aOut[i] = v;
87184 }else
87185 #else
87186 assert( aOut==0 );
87187 UNUSED_PARAMETER(aOut);
 
 
87188 #endif
87189 {
87190 aLog[i] = sqlite3LogEst(v);
87191 }
87192 if( *z==' ' ) z++;
87193 }
87194 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4
87195 assert( pIndex!=0 );
87196 #else
@@ -87247,12 +87289,21 @@
87247 pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
87248 }
87249 z = argv[2];
87250
87251 if( pIndex ){
 
 
 
 
 
 
 
 
 
87252 pIndex->bUnordered = 0;
87253 decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
87254 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
87255 }else{
87256 Index fakeIdx;
87257 fakeIdx.szIdxRow = pTable->szTabRow;
87258 #ifdef SQLITE_ENABLE_COSTMULT
@@ -87307,29 +87358,42 @@
87307 ** unique. */
87308 nCol = pIdx->nSampleCol-1;
87309 pIdx->aAvgEq[nCol] = 1;
87310 }
87311 for(iCol=0; iCol<nCol; iCol++){
 
87312 int i; /* Used to iterate through samples */
87313 tRowcnt sumEq = 0; /* Sum of the nEq values */
87314 tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
87315 tRowcnt avgEq = 0;
87316 tRowcnt nDLt = pFinal->anDLt[iCol];
 
 
 
 
 
 
 
 
 
 
 
87317
87318 /* Set nSum to the number of distinct (iCol+1) field prefixes that
87319 ** occur in the stat4 table for this index before pFinal. Set
87320 ** sumEq to the sum of the nEq values for column iCol for the same
87321 ** set (adding the value only once where there exist duplicate
87322 ** prefixes). */
87323 for(i=0; i<(pIdx->nSample-1); i++){
87324 if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
 
87325 sumEq += aSample[i].anEq[iCol];
87326 nSum++;
87327 }
87328 }
87329 if( nDLt>nSum ){
87330 avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
 
87331 }
87332 if( avgEq==0 ) avgEq = 1;
87333 pIdx->aAvgEq[iCol] = avgEq;
87334 }
87335 }
@@ -87576,10 +87640,15 @@
87576 if( rc==SQLITE_OK ){
87577 int lookasideEnabled = db->lookaside.bEnabled;
87578 db->lookaside.bEnabled = 0;
87579 rc = loadStat4(db, sInfo.zDatabase);
87580 db->lookaside.bEnabled = lookasideEnabled;
 
 
 
 
 
87581 }
87582 #endif
87583
87584 if( rc==SQLITE_NOMEM ){
87585 db->mallocFailed = 1;
@@ -88870,10 +88939,13 @@
88870 #endif
88871 if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
88872 sqlite3ExprDelete(db, p->pPartIdxWhere);
88873 sqlite3DbFree(db, p->zColAff);
88874 if( p->isResized ) sqlite3DbFree(db, p->azColl);
 
 
 
88875 sqlite3DbFree(db, p);
88876 }
88877
88878 /*
88879 ** For the index called zIdxName which is found in the database iDb,
@@ -91179,11 +91251,11 @@
91179 pIndex->nKeyCol); VdbeCoverage(v);
91180 sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
91181 }else{
91182 addr2 = sqlite3VdbeCurrentAddr(v);
91183 }
91184 sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
91185 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
91186 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
91187 sqlite3ReleaseTempReg(pParse, regRecord);
91188 sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
91189 sqlite3VdbeJumpHere(v, addr1);
@@ -93687,11 +93759,11 @@
93687 if( okOnePass ){
93688 /* Just one row. Hence the top-of-loop is a no-op */
93689 assert( nKey==nPk ); /* OP_Found will use an unpacked key */
93690 assert( !IsVirtual(pTab) );
93691 if( aToOpen[iDataCur-iTabCur] ){
93692 assert( pPk!=0 );
93693 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
93694 VdbeCoverage(v);
93695 }
93696 }else if( pPk ){
93697 addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
@@ -105122,11 +105194,10 @@
105122 int regRow;
105123 int regRowid;
105124 int nKey;
105125 int iSortTab; /* Sorter cursor to read from */
105126 int nSortData; /* Trailing values to read from sorter */
105127 u8 p5; /* p5 parameter for 1st OP_Column */
105128 int i;
105129 int bSeq; /* True if sorter record includes seq. no. */
105130 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
105131 struct ExprList_item *aOutEx = p->pEList->a;
105132 #endif
@@ -105156,23 +105227,20 @@
105156 sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
105157 if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
105158 addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
105159 VdbeCoverage(v);
105160 codeOffset(v, p->iOffset, addrContinue);
105161 sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
105162 p5 = OPFLAG_CLEARCACHE;
105163 bSeq = 0;
105164 }else{
105165 addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
105166 codeOffset(v, p->iOffset, addrContinue);
105167 iSortTab = iTab;
105168 p5 = 0;
105169 bSeq = 1;
105170 }
105171 for(i=0; i<nSortData; i++){
105172 sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
105173 if( i==0 ) sqlite3VdbeChangeP5(v, p5);
105174 VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
105175 }
105176 switch( eDest ){
105177 case SRT_Table:
105178 case SRT_EphemTab: {
@@ -109097,16 +109165,15 @@
109097 ** from the previous row currently stored in a0, a1, a2...
109098 */
109099 addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
109100 sqlite3ExprCacheClear(pParse);
109101 if( groupBySort ){
109102 sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
109103 }
109104 for(j=0; j<pGroupBy->nExpr; j++){
109105 if( groupBySort ){
109106 sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
109107 if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
109108 }else{
109109 sAggInfo.directMode = 1;
109110 sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
109111 }
109112 }
@@ -111216,12 +111283,12 @@
111216 0, 0);
111217 }
111218
111219 /* Top of the update loop */
111220 if( okOnePass ){
111221 if( aToOpen[iDataCur-iBaseCur] ){
111222 assert( pPk!=0 );
111223 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
111224 VdbeCoverageNeverTaken(v);
111225 }
111226 labelContinue = labelBreak;
111227 sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
@@ -112450,10 +112517,11 @@
112450 }
112451 sqlite3DbFree(db, pVTable);
112452 }else if( ALWAYS(pVTable->pVtab) ){
112453 /* Justification of ALWAYS(): A correct vtab constructor must allocate
112454 ** the sqlite3_vtab object if successful. */
 
112455 pVTable->pVtab->pModule = pMod->pModule;
112456 pVTable->nRef = 1;
112457 if( sCtx.pTab ){
112458 const char *zFormat = "vtable constructor did not declare schema: %s";
112459 *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
@@ -115700,21 +115768,28 @@
115700 ** have been requested when testing key $P in whereEqualScanEst(). */
115701 whereKeyStats(pParse, p, pRec, 0, a);
115702 iLower = a[0];
115703 iUpper = a[0] + a[1];
115704 }
 
 
 
 
 
 
 
 
115705
115706 /* If possible, improve on the iLower estimate using ($P:$L). */
115707 if( pLower ){
115708 int bOk; /* True if value is extracted from pExpr */
115709 Expr *pExpr = pLower->pExpr->pRight;
115710 assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115711 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115712 if( rc==SQLITE_OK && bOk ){
115713 tRowcnt iNew;
115714 whereKeyStats(pParse, p, pRec, 0, a);
115715 iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
115716 if( iNew>iLower ) iLower = iNew;
115717 nOut--;
115718 pLower = 0;
115719 }
115720 }
@@ -115721,16 +115796,15 @@
115721
115722 /* If possible, improve on the iUpper estimate using ($P:$U). */
115723 if( pUpper ){
115724 int bOk; /* True if value is extracted from pExpr */
115725 Expr *pExpr = pUpper->pExpr->pRight;
115726 assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115727 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115728 if( rc==SQLITE_OK && bOk ){
115729 tRowcnt iNew;
115730 whereKeyStats(pParse, p, pRec, 1, a);
115731 iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
115732 if( iNew<iUpper ) iUpper = iNew;
115733 nOut--;
115734 pUpper = 0;
115735 }
115736 }
@@ -116225,65 +116299,52 @@
116225 sqlite3StrAccumAppend(pStr, "?", 1);
116226 }
116227
116228 /*
116229 ** Argument pLevel describes a strategy for scanning table pTab. This
116230 ** function returns a pointer to a string buffer containing a description
116231 ** of the subset of table rows scanned by the strategy in the form of an
116232 ** SQL expression. Or, if all rows are scanned, NULL is returned.
116233 **
116234 ** For example, if the query:
116235 **
116236 ** SELECT * FROM t1 WHERE a=1 AND b>2;
116237 **
116238 ** is run and there is an index on (a, b), then this function returns a
116239 ** string similar to:
116240 **
116241 ** "a=? AND b>?"
116242 **
116243 ** The returned pointer points to memory obtained from sqlite3DbMalloc().
116244 ** It is the responsibility of the caller to free the buffer when it is
116245 ** no longer required.
116246 */
116247 static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
116248 Index *pIndex = pLoop->u.btree.pIndex;
116249 u16 nEq = pLoop->u.btree.nEq;
116250 u16 nSkip = pLoop->u.btree.nSkip;
116251 int i, j;
116252 Column *aCol = pTab->aCol;
116253 i16 *aiColumn = pIndex->aiColumn;
116254 StrAccum txt;
116255
116256 if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
116257 return 0;
116258 }
116259 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
116260 txt.db = db;
116261 sqlite3StrAccumAppend(&txt, " (", 2);
116262 for(i=0; i<nEq; i++){
116263 char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
116264 if( i>=nSkip ){
116265 explainAppendTerm(&txt, i, z, "=");
116266 }else{
116267 if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
116268 sqlite3StrAccumAppend(&txt, "ANY(", 4);
116269 sqlite3StrAccumAppendAll(&txt, z);
116270 sqlite3StrAccumAppend(&txt, ")", 1);
116271 }
116272 }
116273
116274 j = i;
116275 if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
116276 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116277 explainAppendTerm(&txt, i++, z, ">");
116278 }
116279 if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
116280 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116281 explainAppendTerm(&txt, i, z, "<");
116282 }
116283 sqlite3StrAccumAppend(&txt, ")", 1);
116284 return sqlite3StrAccumFinish(&txt);
116285 }
116286
116287 /*
116288 ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
116289 ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
@@ -116303,72 +116364,90 @@
116303 #endif
116304 {
116305 struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
116306 Vdbe *v = pParse->pVdbe; /* VM being constructed */
116307 sqlite3 *db = pParse->db; /* Database handle */
116308 char *zMsg; /* Text to add to EQP output */
116309 int iId = pParse->iSelectId; /* Select id (left-most output column) */
116310 int isSearch; /* True for a SEARCH. False for SCAN. */
116311 WhereLoop *pLoop; /* The controlling WhereLoop object */
116312 u32 flags; /* Flags that describe this loop */
 
 
 
116313
116314 pLoop = pLevel->pWLoop;
116315 flags = pLoop->wsFlags;
116316 if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
116317
116318 isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
116319 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
116320 || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
116321
116322 zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
 
 
116323 if( pItem->pSelect ){
116324 zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
116325 }else{
116326 zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
116327 }
116328
116329 if( pItem->zAlias ){
116330 zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
116331 }
116332 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
116333 && ALWAYS(pLoop->u.btree.pIndex!=0)
116334 ){
116335 const char *zFmt;
116336 Index *pIdx = pLoop->u.btree.pIndex;
116337 char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
116338 assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
116339 if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
116340 zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";
 
 
116341 }else if( flags & WHERE_AUTO_INDEX ){
116342 zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
116343 }else if( flags & WHERE_IDX_ONLY ){
116344 zFmt = "%s USING COVERING INDEX %s%s";
116345 }else{
116346 zFmt = "%s USING INDEX %s%s";
116347 }
116348 zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
116349 sqlite3DbFree(db, zWhere);
 
 
 
116350 }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
116351 zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
116352
116353 if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
116354 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
116355 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
116356 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
116357 }else if( flags&WHERE_BTM_LIMIT ){
116358 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
116359 }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
116360 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
 
116361 }
 
 
116362 }
116363 #ifndef SQLITE_OMIT_VIRTUALTABLE
116364 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
116365 zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
116366 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
116367 }
116368 #endif
116369 zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
 
 
 
 
 
 
 
116370 sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
116371 }
116372 }
116373 #else
116374 # define explainOneScan(u,v,w,x,y,z)
@@ -117633,11 +117712,11 @@
117633 if( ppPrev==0 ){
117634 /* There already exists a WhereLoop on the list that is better
117635 ** than pTemplate, so just ignore pTemplate */
117636 #if WHERETRACE_ENABLED /* 0x8 */
117637 if( sqlite3WhereTrace & 0x8 ){
117638 sqlite3DebugPrintf("ins-noop: ");
117639 whereLoopPrint(pTemplate, pBuilder->pWC);
117640 }
117641 #endif
117642 return SQLITE_OK;
117643 }else{
@@ -117649,14 +117728,14 @@
117649 ** WhereLoop and insert it.
117650 */
117651 #if WHERETRACE_ENABLED /* 0x8 */
117652 if( sqlite3WhereTrace & 0x8 ){
117653 if( p!=0 ){
117654 sqlite3DebugPrintf("ins-del: ");
117655 whereLoopPrint(p, pBuilder->pWC);
117656 }
117657 sqlite3DebugPrintf("ins-new: ");
117658 whereLoopPrint(pTemplate, pBuilder->pWC);
117659 }
117660 #endif
117661 if( p==0 ){
117662 /* Allocate a new WhereLoop to add to the end of the list */
@@ -117676,11 +117755,11 @@
117676 pToDel = *ppTail;
117677 if( pToDel==0 ) break;
117678 *ppTail = pToDel->pNextLoop;
117679 #if WHERETRACE_ENABLED /* 0x8 */
117680 if( sqlite3WhereTrace & 0x8 ){
117681 sqlite3DebugPrintf("ins-del: ");
117682 whereLoopPrint(pToDel, pBuilder->pWC);
117683 }
117684 #endif
117685 whereLoopDelete(db, pToDel);
117686 }
@@ -118843,11 +118922,11 @@
118843 if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
118844 }
118845 isMatch = 1;
118846 break;
118847 }
118848 if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
118849 /* Make sure the sort order is compatible in an ORDER BY clause.
118850 ** Sort order is irrelevant for a GROUP BY clause. */
118851 if( revSet ){
118852 if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
118853 }else{
@@ -119308,16 +119387,19 @@
119308 pWInfo->revMask = pFrom->revLoop;
119309 }
119310 if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
119311 && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
119312 ){
119313 Bitmask notUsed = 0;
119314 int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
119315 pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
119316 );
119317 assert( pWInfo->sorted==0 );
119318 pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);
 
 
 
119319 }
119320 }
119321
119322
119323 pWInfo->nRowOut = pFrom->nRow;
@@ -132620,10 +132702,11 @@
132620 assert( iIdx==nVal );
132621
132622 /* In case the cursor has been used before, clear it now. */
132623 sqlite3_finalize(pCsr->pStmt);
132624 sqlite3_free(pCsr->aDoclist);
 
132625 sqlite3Fts3ExprFree(pCsr->pExpr);
132626 memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
132627
132628 /* Set the lower and upper bounds on docids to return */
132629 pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -133930,11 +134013,11 @@
133930 if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
133931 iMax = a[i].iDocid;
133932 bMaxSet = 1;
133933 }
133934 }
133935 assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
133936 assert( rc!=SQLITE_OK || bMaxSet );
133937
133938 /* Keep advancing iterators until they all point to the same document */
133939 for(i=0; i<p->nToken; i++){
133940 while( rc==SQLITE_OK && bEof==0
@@ -136047,11 +136130,11 @@
136047 int i = 0;
136048
136049 /* Set variable i to the maximum number of bytes of input to tokenize. */
136050 for(i=0; i<n; i++){
136051 if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
136052 if( z[i]=='*' || z[i]=='"' ) break;
136053 }
136054
136055 *pnConsumed = i;
136056 rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
136057 if( rc==SQLITE_OK ){
136058
--- 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.8.7.1. 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.
@@ -229,13 +229,13 @@
229 **
230 ** See also: [sqlite3_libversion()],
231 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232 ** [sqlite_version()] and [sqlite_source_id()].
233 */
234 #define SQLITE_VERSION "3.8.7.1"
235 #define SQLITE_VERSION_NUMBER 3008007
236 #define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52"
237
238 /*
239 ** CAPI3REF: Run-Time Library Version Numbers
240 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
241 **
@@ -7944,11 +7944,11 @@
7944 ** A macro to hint to the compiler that a function should not be
7945 ** inlined.
7946 */
7947 #if defined(__GNUC__)
7948 # define SQLITE_NOINLINE __attribute__((noinline))
7949 #elif defined(_MSC_VER) && _MSC_VER>=1310
7950 # define SQLITE_NOINLINE __declspec(noinline)
7951 #else
7952 # define SQLITE_NOINLINE
7953 #endif
7954
@@ -11322,10 +11322,11 @@
11322 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
11323 int nSample; /* Number of elements in aSample[] */
11324 int nSampleCol; /* Size of IndexSample.anEq[] and so on */
11325 tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
11326 IndexSample *aSample; /* Samples of the left-most key */
11327 tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this table */
11328 #endif
11329 };
11330
11331 /*
11332 ** Allowed values for Index.idxType
@@ -12186,11 +12187,10 @@
12187 #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
12188 #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
12189 #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
12190 #define OPFLAG_APPEND 0x08 /* This is likely to be an append */
12191 #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
 
12192 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
12193 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
12194 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
12195 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
12196 #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
@@ -13320,14 +13320,13 @@
13320 # define sqlite3MemdebugSetType(X,Y) /* no-op */
13321 # define sqlite3MemdebugHasType(X,Y) 1
13322 # define sqlite3MemdebugNoType(X,Y) 1
13323 #endif
13324 #define MEMTYPE_HEAP 0x01 /* General heap allocations */
13325 #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
13326 #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
13327 #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
 
13328
13329 /*
13330 ** Threading interface
13331 */
13332 #if SQLITE_MAX_WORKER_THREADS>0
@@ -14095,21 +14094,19 @@
14094 #ifdef SQLITE_DEBUG
14095 u8 seekOp; /* Most recent seek operation on this cursor */
14096 #endif
14097 i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
14098 u8 nullRow; /* True if pointing to a row with no data */
 
14099 u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
14100 Bool isEphemeral:1; /* True for an ephemeral table */
14101 Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
14102 Bool isTable:1; /* True if a table requiring integer keys */
14103 Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
14104 Pgno pgnoRoot; /* Root page of the open btree cursor */
14105 sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
14106 i64 seqCount; /* Sequence counter */
14107 i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
 
14108 VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
14109
14110 /* Cached information about the header for the data record that the
14111 ** cursor is currently pointing to. Only valid if cacheStatus matches
14112 ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -14122,10 +14119,11 @@
14119 u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
14120 u32 payloadSize; /* Total number of bytes in the record */
14121 u32 szRow; /* Byte available in aRow */
14122 u32 iHdrOffset; /* Offset to next unparsed byte of the header */
14123 const u8 *aRow; /* Data for the current row, if all on one page */
14124 u32 *aOffset; /* Pointer to aType[nField] */
14125 u32 aType[1]; /* Type values for all entries in the record */
14126 /* 2*nField extra array elements allocated for aType[], beyond the one
14127 ** static element declared in the structure. nField total array slots for
14128 ** aType[] and nField+1 array slots for aOffset[] */
14129 };
@@ -14198,11 +14196,11 @@
14196 int n; /* Number of characters in string value, excluding '\0' */
14197 char *z; /* String or BLOB value */
14198 /* ShallowCopy only needs to copy the information above */
14199 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
14200 int szMalloc; /* Size of the zMalloc allocation */
14201 u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
14202 sqlite3 *db; /* The associated database connection */
14203 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
14204 #ifdef SQLITE_DEBUG
14205 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
14206 void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
@@ -14406,10 +14404,11 @@
14404 ** Function prototypes
14405 */
14406 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
14407 void sqliteVdbePopStack(Vdbe*,int);
14408 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
14409 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
14410 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
14411 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
14412 #endif
14413 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
14414 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
@@ -17130,11 +17129,11 @@
17129 ** allocation p. Also return true if p==NULL.
17130 **
17131 ** This routine is designed for use within an assert() statement, to
17132 ** verify the type of an allocation. For example:
17133 **
17134 ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
17135 */
17136 SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
17137 int rc = 1;
17138 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17139 struct MemBlockHdr *pHdr;
@@ -17152,11 +17151,11 @@
17151 ** allocation p. Also return true if p==NULL.
17152 **
17153 ** This routine is designed for use within an assert() statement, to
17154 ** verify the type of an allocation. For example:
17155 **
17156 ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
17157 */
17158 SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
17159 int rc = 1;
17160 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17161 struct MemBlockHdr *pHdr;
@@ -20364,39 +20363,41 @@
20363 ** Return the size of a memory allocation previously obtained from
20364 ** sqlite3Malloc() or sqlite3_malloc().
20365 */
20366 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
20367 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
 
20368 return sqlite3GlobalConfig.m.xSize(p);
20369 }
20370 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
20371 if( db==0 ){
20372 assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20373 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20374 return sqlite3MallocSize(p);
20375 }else{
20376 assert( sqlite3_mutex_held(db->mutex) );
20377 if( isLookaside(db, p) ){
20378 return db->lookaside.sz;
20379 }else{
20380 assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20381 assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
 
20382 return sqlite3GlobalConfig.m.xSize(p);
20383 }
20384 }
20385 }
20386 SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
20387 assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20388 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20389 return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
20390 }
20391
20392 /*
20393 ** Free memory previously obtained from sqlite3Malloc().
20394 */
20395 SQLITE_API void sqlite3_free(void *p){
20396 if( p==0 ) return; /* IMP: R-49053-54554 */
 
20397 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20398 assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20399 if( sqlite3GlobalConfig.bMemstat ){
20400 sqlite3_mutex_enter(mem0.mutex);
20401 sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
20402 sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
20403 sqlite3GlobalConfig.m.xFree(p);
@@ -20436,12 +20437,12 @@
20437 db->lookaside.pFree = pBuf;
20438 db->lookaside.nOut--;
20439 return;
20440 }
20441 }
20442 assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20443 assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20444 assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20445 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20446 sqlite3_free(p);
20447 }
20448
@@ -20449,10 +20450,12 @@
20450 ** Change the size of an existing memory allocation
20451 */
20452 SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
20453 int nOld, nNew, nDiff;
20454 void *pNew;
20455 assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20456 assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
20457 if( pOld==0 ){
20458 return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
20459 }
20460 if( nBytes==0 ){
20461 sqlite3_free(pOld); /* IMP: R-26507-47431 */
@@ -20475,12 +20478,10 @@
20478 nDiff = nNew - nOld;
20479 if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
20480 mem0.alarmThreshold-nDiff ){
20481 sqlite3MallocAlarm(nDiff);
20482 }
 
 
20483 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20484 if( pNew==0 && mem0.alarmCallback ){
20485 sqlite3MallocAlarm((int)nBytes);
20486 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20487 }
@@ -20589,12 +20590,12 @@
20590 #endif
20591 p = sqlite3Malloc(n);
20592 if( !p && db ){
20593 db->mallocFailed = 1;
20594 }
20595 sqlite3MemdebugSetType(p,
20596 (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
20597 return p;
20598 }
20599
20600 /*
20601 ** Resize the block of memory pointed to by p to n bytes. If the
@@ -20616,19 +20617,18 @@
20617 if( pNew ){
20618 memcpy(pNew, p, db->lookaside.sz);
20619 sqlite3DbFree(db, p);
20620 }
20621 }else{
20622 assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20623 assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20624 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20625 pNew = sqlite3_realloc64(p, n);
20626 if( !pNew ){
 
20627 db->mallocFailed = 1;
20628 }
20629 sqlite3MemdebugSetType(pNew,
20630 (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20631 }
20632 }
20633 return pNew;
20634 }
@@ -20754,15 +20754,11 @@
20754 ** HAVE_STRCHRNUL. If that routine is not available, this module
20755 ** will supply its own. The built-in version is slower than
20756 ** the glibc version so the glibc version is definitely preferred.
20757 */
20758 #if !defined(HAVE_STRCHRNUL)
20759 # define HAVE_STRCHRNUL 0
 
 
 
 
20760 #endif
20761
20762
20763 /*
20764 ** Conversion types fall into various categories as defined by the
@@ -22091,18 +22087,18 @@
22087 #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
22088 /******************************** End Unix Pthreads *************************/
22089
22090
22091 /********************************* Win32 Threads ****************************/
22092 #if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
22093
22094 #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
22095 #include <process.h>
22096
22097 /* A running thread */
22098 struct SQLiteThread {
22099 void *tid; /* The thread handle */
22100 unsigned id; /* The thread identifier */
22101 void *(*xTask)(void*); /* The routine to run as a thread */
22102 void *pIn; /* Argument to xTask */
22103 void *pResult; /* Result of xTask */
22104 };
@@ -22146,11 +22142,11 @@
22142 if( sqlite3GlobalConfig.bCoreMutex==0 ){
22143 memset(p, 0, sizeof(*p));
22144 }else{
22145 p->xTask = xTask;
22146 p->pIn = pIn;
22147 p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
22148 if( p->tid==0 ){
22149 memset(p, 0, sizeof(*p));
22150 }
22151 }
22152 if( p->xTask==0 ){
@@ -22184,11 +22180,11 @@
22180 if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
22181 sqlite3_free(p);
22182 return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
22183 }
22184
22185 #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
22186 /******************************** End Win32 Threads *************************/
22187
22188
22189 /********************************* Single-Threaded **************************/
22190 #ifndef SQLITE_THREADS_IMPLEMENTED
@@ -33487,11 +33483,15 @@
33483 #endif
33484
33485 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
33486 DWORD))aSyscall[63].pCurrent)
33487
33488 #if !SQLITE_OS_WINCE
33489 { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
33490 #else
33491 { "WaitForSingleObjectEx", (SYSCALL)0, 0 },
33492 #endif
33493
33494 #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
33495 BOOL))aSyscall[64].pCurrent)
33496
33497 #if SQLITE_OS_WINRT
@@ -33830,11 +33830,12 @@
33830 #else
33831 osSleep(milliseconds);
33832 #endif
33833 }
33834
33835 #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
33836 SQLITE_THREADSAFE>0
33837 SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
33838 DWORD rc;
33839 while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
33840 TRUE))==WAIT_IO_COMPLETION ){}
33841 return rc;
@@ -39855,11 +39856,11 @@
39856 assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
39857 assert( pCache->n90pct == pCache->nMax*9/10 );
39858 if( createFlag==1 && (
39859 nPinned>=pGroup->mxPinned
39860 || nPinned>=pCache->n90pct
39861 || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
39862 )){
39863 return 0;
39864 }
39865
39866 if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
@@ -42799,10 +42800,18 @@
42800 }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
42801 if( pPager->journalOff==0 ){
42802 rc = SQLITE_OK;
42803 }else{
42804 rc = sqlite3OsTruncate(pPager->jfd, 0);
42805 if( rc==SQLITE_OK && pPager->fullSync ){
42806 /* Make sure the new file size is written into the inode right away.
42807 ** Otherwise the journal might resurrect following a power loss and
42808 ** cause the last transaction to roll back. See
42809 ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
42810 */
42811 rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
42812 }
42813 }
42814 pPager->journalOff = 0;
42815 }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
42816 || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
42817 ){
@@ -44476,17 +44485,19 @@
44485 if( !pNew ) rc = SQLITE_NOMEM;
44486 }
44487
44488 if( rc==SQLITE_OK ){
44489 pager_reset(pPager);
 
 
44490 rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
44491 }
44492 if( rc==SQLITE_OK ){
44493 sqlite3PageFree(pPager->pTmpSpace);
44494 pPager->pTmpSpace = pNew;
44495 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
44496 pPager->pageSize = pageSize;
44497 }else{
44498 sqlite3PageFree(pNew);
44499 }
44500 }
44501
44502 *pPageSize = pPager->pageSize;
44503 if( rc==SQLITE_OK ){
@@ -51649,11 +51660,11 @@
51660 int nRef; /* Number of references to this structure */
51661 BtShared *pNext; /* Next on a list of sharable BtShared structs */
51662 BtLock *pLock; /* List of locks held on this shared-btree struct */
51663 Btree *pWriter; /* Btree with currently open write transaction */
51664 #endif
51665 u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
51666 };
51667
51668 /*
51669 ** Allowed values for BtShared.btsFlags
51670 */
@@ -52947,11 +52958,11 @@
52958 **
52959 ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
52960 ** back to where it ought to be if this routine returns true.
52961 */
52962 SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
52963 return pCur->eState!=CURSOR_VALID;
52964 }
52965
52966 /*
52967 ** This routine restores a cursor back to its original position after it
52968 ** has been moved by some outside activity (such as a btree rebalance or
@@ -54279,11 +54290,12 @@
54290 #endif
54291 }
54292
54293 /*
54294 ** Make sure pBt->pTmpSpace points to an allocation of
54295 ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
54296 ** pointer.
54297 */
54298 static void allocateTempSpace(BtShared *pBt){
54299 if( !pBt->pTmpSpace ){
54300 pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
54301
@@ -54294,21 +54306,32 @@
54306 ** can mean that fillInCell() only initializes the first 2 or 3
54307 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
54308 ** it into a database page. This is not actually a problem, but it
54309 ** does cause a valgrind error when the 1 or 2 bytes of unitialized
54310 ** data is passed to system call write(). So to avoid this error,
54311 ** zero the first 4 bytes of temp space here.
54312 **
54313 ** Also: Provide four bytes of initialized space before the
54314 ** beginning of pTmpSpace as an area available to prepend the
54315 ** left-child pointer to the beginning of a cell.
54316 */
54317 if( pBt->pTmpSpace ){
54318 memset(pBt->pTmpSpace, 0, 8);
54319 pBt->pTmpSpace += 4;
54320 }
54321 }
54322 }
54323
54324 /*
54325 ** Free the pBt->pTmpSpace allocation
54326 */
54327 static void freeTempSpace(BtShared *pBt){
54328 if( pBt->pTmpSpace ){
54329 pBt->pTmpSpace -= 4;
54330 sqlite3PageFree(pBt->pTmpSpace);
54331 pBt->pTmpSpace = 0;
54332 }
54333 }
54334
54335 /*
54336 ** Close an open database and invalidate all cursors.
54337 */
@@ -58016,15 +58039,10 @@
58039 ** pTemp is not null. Regardless of pTemp, allocate a new entry
58040 ** in pPage->apOvfl[] and make it point to the cell content (either
58041 ** in pTemp or the original pCell) and also record its index.
58042 ** Allocating a new entry in pPage->aCell[] implies that
58043 ** pPage->nOverflow is incremented.
 
 
 
 
 
58044 */
58045 static void insertCell(
58046 MemPage *pPage, /* Page into which we are copying */
58047 int i, /* New cell becomes the i-th cell of the page */
58048 u8 *pCell, /* Content of the new cell */
@@ -58037,11 +58055,10 @@
58055 int j; /* Loop counter */
58056 int end; /* First byte past the last cell pointer in data[] */
58057 int ins; /* Index in data[] where new cell pointer is inserted */
58058 int cellOffset; /* Address of first cell pointer in data[] */
58059 u8 *data; /* The content of the whole page */
 
58060
58061 if( *pRC ) return;
58062
58063 assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
58064 assert( MX_CELL(pPage->pBt)<=10921 );
@@ -58055,11 +58072,11 @@
58072 ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
58073 ** the term after the || in the following assert(). */
58074 assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
58075 if( pPage->nOverflow || sz+2>pPage->nFree ){
58076 if( pTemp ){
58077 memcpy(pTemp, pCell, sz);
58078 pCell = pTemp;
58079 }
58080 if( iChild ){
58081 put4byte(pCell, iChild);
58082 }
@@ -58084,11 +58101,11 @@
58101 ** if it returns success */
58102 assert( idx >= end+2 );
58103 assert( idx+sz <= (int)pPage->pBt->usableSize );
58104 pPage->nCell++;
58105 pPage->nFree -= (u16)(2 + sz);
58106 memcpy(&data[idx], pCell, sz);
58107 if( iChild ){
58108 put4byte(&data[idx], iChild);
58109 }
58110 memmove(&data[ins+2], &data[ins], end-ins);
58111 put2byte(&data[ins], idx);
@@ -61630,11 +61647,14 @@
61647 /* If MEM_Dyn is set then Mem.xDel!=0.
61648 ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
61649 */
61650 assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
61651
61652 /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we
61653 ** ensure that if Mem.szMalloc>0 then it is safe to do
61654 ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
61655 ** That saves a few cycles in inner loops. */
61656 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
61657
61658 /* Cannot be both MEM_Int and MEM_Real at the same time */
61659 assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
61660
@@ -61739,11 +61759,11 @@
61759 }else{
61760 pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
61761 }
61762 }
61763
61764 if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
61765 memcpy(pMem->zMalloc, pMem->z, pMem->n);
61766 }
61767 if( (pMem->flags&MEM_Dyn)!=0 ){
61768 assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
61769 pMem->xDel((void *)(pMem->z));
@@ -61766,11 +61786,12 @@
61786 **
61787 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
61788 ** if unable to complete the resizing.
61789 */
61790 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
61791 assert( szNew>0 );
61792 assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
61793 if( pMem->szMalloc<szNew ){
61794 return sqlite3VdbeMemGrow(pMem, szNew, 0);
61795 }
61796 assert( (pMem->flags & MEM_Dyn)==0 );
61797 pMem->z = pMem->zMalloc;
@@ -62490,11 +62511,14 @@
62511 nAlloc += (enc==SQLITE_UTF8?1:2);
62512 }
62513 if( nByte>iLimit ){
62514 return SQLITE_TOOBIG;
62515 }
62516 testcase( nAlloc==0 );
62517 testcase( nAlloc==31 );
62518 testcase( nAlloc==32 );
62519 if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
62520 return SQLITE_NOMEM;
62521 }
62522 memcpy(pMem->z, z, nAlloc);
62523 }else if( xDel==SQLITE_DYNAMIC ){
62524 sqlite3VdbeMemRelease(pMem);
@@ -62593,11 +62617,11 @@
62617 /*
62618 ** The pVal argument is known to be a value other than NULL.
62619 ** Convert it into a string with encoding enc and return a pointer
62620 ** to a zero-terminated version of that string.
62621 */
62622 static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
62623 assert( pVal!=0 );
62624 assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
62625 assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
62626 assert( (pVal->flags & MEM_RowSet)==0 );
62627 assert( (pVal->flags & (MEM_Null))==0 );
@@ -64913,11 +64937,11 @@
64937 ** the call above. */
64938 }else if( pCx->pCursor ){
64939 sqlite3BtreeCloseCursor(pCx->pCursor);
64940 }
64941 #ifndef SQLITE_OMIT_VIRTUALTABLE
64942 else if( pCx->pVtabCursor ){
64943 sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
64944 const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
64945 p->inVtabMethod = 1;
64946 pModule->xClose(pVtabCursor);
64947 p->inVtabMethod = 0;
@@ -64956,13 +64980,14 @@
64980 static void closeAllCursors(Vdbe *p){
64981 if( p->pFrame ){
64982 VdbeFrame *pFrame;
64983 for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
64984 sqlite3VdbeFrameRestore(pFrame);
64985 p->pFrame = 0;
64986 p->nFrame = 0;
64987 }
64988 assert( p->nFrame==0 );
 
64989
64990 if( p->apCsr ){
64991 int i;
64992 for(i=0; i<p->nCursor; i++){
64993 VdbeCursor *pC = p->apCsr[i];
@@ -64980,11 +65005,11 @@
65005 p->pDelFrame = pDel->pParent;
65006 sqlite3VdbeFrameDelete(pDel);
65007 }
65008
65009 /* Delete any auxdata allocations made by the VM */
65010 if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
65011 assert( p->pAuxData==0 );
65012 }
65013
65014 /*
65015 ** Clean up the VM after a single run.
@@ -65886,13 +65911,11 @@
65911 #endif
65912 assert( p->deferredMoveto );
65913 assert( p->isTable );
65914 rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
65915 if( rc ) return rc;
 
65916 if( res!=0 ) return SQLITE_CORRUPT_BKPT;
 
65917 #ifdef SQLITE_TEST
65918 sqlite3_search_count++;
65919 #endif
65920 p->deferredMoveto = 0;
65921 p->cacheStatus = CACHE_STALE;
@@ -65913,10 +65936,21 @@
65936 rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
65937 p->cacheStatus = CACHE_STALE;
65938 if( isDifferentRow ) p->nullRow = 1;
65939 return rc;
65940 }
65941
65942 /*
65943 ** Check to ensure that the cursor is valid. Restore the cursor
65944 ** if need be. Return any I/O error from the restore operation.
65945 */
65946 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
65947 if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65948 return handleMovedCursor(p);
65949 }
65950 return SQLITE_OK;
65951 }
65952
65953 /*
65954 ** Make sure the cursor p is ready to read or write the row to which it
65955 ** was last positioned. Return an error code if an OOM fault or I/O error
65956 ** prevents us from positioning the cursor to its correct position.
@@ -65931,11 +65965,11 @@
65965 */
65966 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
65967 if( p->deferredMoveto ){
65968 return handleDeferredMoveto(p);
65969 }
65970 if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
65971 return handleMovedCursor(p);
65972 }
65973 return SQLITE_OK;
65974 }
65975
@@ -69095,10 +69129,11 @@
69129 if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
69130 p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
69131 memset(pCx, 0, sizeof(VdbeCursor));
69132 pCx->iDb = iDb;
69133 pCx->nField = nField;
69134 pCx->aOffset = &pCx->aType[nField];
69135 if( isBtreeCursor ){
69136 pCx->pCursor = (BtCursor*)
69137 &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
69138 sqlite3BtreeCursorZero(pCx->pCursor);
69139 }
@@ -70528,11 +70563,11 @@
70563 ctx.pFunc = pOp->p4.pFunc;
70564 ctx.iOp = pc;
70565 ctx.pVdbe = p;
70566 MemSetTypeFlag(ctx.pOut, MEM_Null);
70567 ctx.fErrorOrAux = 0;
70568 db->lastRowid = lastRowid;
70569 (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
70570 lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
70571
70572 /* If the function returned an error, throw an exception */
70573 if( ctx.fErrorOrAux ){
@@ -71246,11 +71281,11 @@
71281 memAboutToChange(p, pDest);
71282 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
71283 pC = p->apCsr[pOp->p1];
71284 assert( pC!=0 );
71285 assert( p2<pC->nField );
71286 aOffset = pC->aOffset;
71287 #ifndef SQLITE_OMIT_VIRTUALTABLE
71288 assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
71289 #endif
71290 pCrsr = pC->pCursor;
71291 assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
@@ -71257,11 +71292,11 @@
71292 assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
71293
71294 /* If the cursor cache is stale, bring it up-to-date */
71295 rc = sqlite3VdbeCursorMoveto(pC);
71296 if( rc ) goto abort_due_to_error;
71297 if( pC->cacheStatus!=p->cacheCtr ){
71298 if( pC->nullRow ){
71299 if( pCrsr==0 ){
71300 assert( pC->pseudoTableReg>0 );
71301 pReg = &aMem[pC->pseudoTableReg];
71302 assert( pReg->flags & MEM_Blob );
@@ -71302,18 +71337,10 @@
71337 }
71338 pC->cacheStatus = p->cacheCtr;
71339 pC->iHdrOffset = getVarint32(pC->aRow, offset);
71340 pC->nHdrParsed = 0;
71341 aOffset[0] = offset;
 
 
 
 
 
 
 
 
71342
71343 /* Make sure a corrupt database has not given us an oversize header.
71344 ** Do this now to avoid an oversize memory allocation.
71345 **
71346 ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -71324,19 +71351,36 @@
71351 */
71352 if( offset > 98307 || offset > pC->payloadSize ){
71353 rc = SQLITE_CORRUPT_BKPT;
71354 goto op_column_error;
71355 }
71356
71357 if( avail<offset ){
71358 /* pC->aRow does not have to hold the entire row, but it does at least
71359 ** need to cover the header of the record. If pC->aRow does not contain
71360 ** the complete header, then set it to zero, forcing the header to be
71361 ** dynamically allocated. */
71362 pC->aRow = 0;
71363 pC->szRow = 0;
71364 }
71365
71366 /* The following goto is an optimization. It can be omitted and
71367 ** everything will still work. But OP_Column is measurably faster
71368 ** by skipping the subsequent conditional, which is always true.
71369 */
71370 assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
71371 goto op_column_read_header;
71372 }
71373
71374 /* Make sure at least the first p2+1 entries of the header have been
71375 ** parsed and valid information is in aOffset[] and pC->aType[].
71376 */
71377 if( pC->nHdrParsed<=p2 ){
71378 /* If there is more header available for parsing in the record, try
71379 ** to extract additional fields up through the p2+1-th field
71380 */
71381 op_column_read_header:
71382 if( pC->iHdrOffset<aOffset[0] ){
71383 /* Make sure zData points to enough of the record to cover the header. */
71384 if( pC->aRow==0 ){
71385 memset(&sMem, 0, sizeof(sMem));
71386 rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
@@ -71377,19 +71421,20 @@
71421 if( pC->aRow==0 ){
71422 sqlite3VdbeMemRelease(&sMem);
71423 sMem.flags = MEM_Null;
71424 }
71425
71426 /* The record is corrupt if any of the following are true:
71427 ** (1) the bytes of the header extend past the declared header size
71428 ** (zHdr>zEndHdr)
71429 ** (2) the entire header was used but not all data was used
71430 ** (zHdr==zEndHdr && offset!=pC->payloadSize)
71431 ** (3) the end of the data extends beyond the end of the record.
71432 ** (offset > pC->payloadSize)
71433 */
71434 if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
71435 || (offset > pC->payloadSize)
 
71436 ){
71437 rc = SQLITE_CORRUPT_BKPT;
71438 goto op_column_error;
71439 }
71440 }
@@ -71400,11 +71445,11 @@
71445 */
71446 if( pC->nHdrParsed<=p2 ){
71447 if( pOp->p4type==P4_MEM ){
71448 sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
71449 }else{
71450 sqlite3VdbeMemSetNull(pDest);
71451 }
71452 goto op_column_out;
71453 }
71454 }
71455
@@ -71576,11 +71621,11 @@
71621 ** out how much space is required for the new record.
71622 */
71623 pRec = pLast;
71624 do{
71625 assert( memIsValid(pRec) );
71626 pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
71627 len = sqlite3VdbeSerialTypeLen(serial_type);
71628 if( pRec->flags & MEM_Zero ){
71629 if( nData ){
71630 sqlite3VdbeMemExpandBlob(pRec);
71631 }else{
@@ -71625,11 +71670,11 @@
71670 i = putVarint32(zNewRecord, nHdr);
71671 j = nHdr;
71672 assert( pData0<=pLast );
71673 pRec = pData0;
71674 do{
71675 serial_type = pRec->uTemp;
71676 i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
71677 j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
71678 }while( (++pRec)<=pLast );
71679 assert( i==nHdr );
71680 assert( j==nByte );
@@ -72524,11 +72569,10 @@
72569 pIn3 = &aMem[pOp->p3];
72570 if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
72571 applyNumericAffinity(pIn3, 0);
72572 }
72573 iKey = sqlite3VdbeIntValue(pIn3);
 
72574
72575 /* If the P3 value could not be converted into an integer without
72576 ** loss of information, then special processing is required... */
72577 if( (pIn3->flags & MEM_Int)==0 ){
72578 if( (pIn3->flags & MEM_Real)==0 ){
@@ -72560,17 +72604,14 @@
72604 assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
72605 if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
72606 }
72607 }
72608 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
72609 pC->movetoTarget = iKey; /* Used by OP_Delete */
72610 if( rc!=SQLITE_OK ){
72611 goto abort_due_to_error;
72612 }
 
 
 
 
72613 }else{
72614 nField = pOp->p4.i;
72615 assert( pOp->p4type==P4_INT32 );
72616 assert( nField>0 );
72617 r.pKeyInfo = pC->pKeyInfo;
@@ -72596,11 +72637,10 @@
72637 ExpandBlob(r.aMem);
72638 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
72639 if( rc!=SQLITE_OK ){
72640 goto abort_due_to_error;
72641 }
 
72642 }
72643 pC->deferredMoveto = 0;
72644 pC->cacheStatus = CACHE_STALE;
72645 #ifdef SQLITE_TEST
72646 sqlite3_search_count++;
@@ -72608,21 +72648,19 @@
72648 if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
72649 if( res<0 || (res==0 && oc==OP_SeekGT) ){
72650 res = 0;
72651 rc = sqlite3BtreeNext(pC->pCursor, &res);
72652 if( rc!=SQLITE_OK ) goto abort_due_to_error;
 
72653 }else{
72654 res = 0;
72655 }
72656 }else{
72657 assert( oc==OP_SeekLT || oc==OP_SeekLE );
72658 if( res>0 || (res==0 && oc==OP_SeekLT) ){
72659 res = 0;
72660 rc = sqlite3BtreePrevious(pC->pCursor, &res);
72661 if( rc!=SQLITE_OK ) goto abort_due_to_error;
 
72662 }else{
72663 /* res might be negative because the table is empty. Check to
72664 ** see if this is the case.
72665 */
72666 res = sqlite3BtreeEof(pC->pCursor);
@@ -72655,11 +72693,10 @@
72693 assert( pC->pCursor!=0 );
72694 assert( pC->isTable );
72695 pC->nullRow = 0;
72696 pIn2 = &aMem[pOp->p2];
72697 pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
 
72698 pC->deferredMoveto = 1;
72699 break;
72700 }
72701
72702
@@ -72841,19 +72878,17 @@
72878 pCrsr = pC->pCursor;
72879 assert( pCrsr!=0 );
72880 res = 0;
72881 iKey = pIn3->u.i;
72882 rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
72883 pC->movetoTarget = iKey; /* Used by OP_Delete */
 
72884 pC->nullRow = 0;
72885 pC->cacheStatus = CACHE_STALE;
72886 pC->deferredMoveto = 0;
72887 VdbeBranchTaken(res!=0,2);
72888 if( res!=0 ){
72889 pc = pOp->p2 - 1;
 
72890 }
72891 pC->seekResult = res;
72892 break;
72893 }
72894
@@ -72997,11 +73032,10 @@
73032 rc = SQLITE_FULL; /* IMP: R-38219-53002 */
73033 goto abort_due_to_error;
73034 }
73035 assert( v>0 ); /* EV: R-40812-03570 */
73036 }
 
73037 pC->deferredMoveto = 0;
73038 pC->cacheStatus = CACHE_STALE;
73039 }
73040 pOut->u.i = v;
73041 break;
@@ -73102,11 +73136,10 @@
73136 }
73137 rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
73138 pData->z, pData->n, nZero,
73139 (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
73140 );
 
73141 pC->deferredMoveto = 0;
73142 pC->cacheStatus = CACHE_STALE;
73143
73144 /* Invoke the update-hook if required. */
73145 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -73139,37 +73172,36 @@
73172 ** pointing to. The update hook will be invoked, if it exists.
73173 ** If P4 is not NULL then the P1 cursor must have been positioned
73174 ** using OP_NotFound prior to invoking this opcode.
73175 */
73176 case OP_Delete: {
 
73177 VdbeCursor *pC;
73178
73179 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73180 pC = p->apCsr[pOp->p1];
73181 assert( pC!=0 );
73182 assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
 
 
 
 
 
 
 
 
 
73183 assert( pC->deferredMoveto==0 );
 
 
73184
73185 #ifdef SQLITE_DEBUG
73186 /* The seek operation that positioned the cursor prior to OP_Delete will
73187 ** have also set the pC->movetoTarget field to the rowid of the row that
73188 ** is being deleted */
73189 if( pOp->p4.z && pC->isTable ){
73190 i64 iKey = 0;
73191 sqlite3BtreeKeySize(pC->pCursor, &iKey);
73192 assert( pC->movetoTarget==iKey );
73193 }
73194 #endif
73195
73196 rc = sqlite3BtreeDelete(pC->pCursor);
73197 pC->cacheStatus = CACHE_STALE;
73198
73199 /* Invoke the update-hook if required. */
73200 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
73201 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
73202 db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
73203 assert( pC->iDb>=0 );
73204 }
73205 if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
73206 break;
73207 }
@@ -73218,23 +73250,32 @@
73250 pc = pOp->p2-1;
73251 }
73252 break;
73253 };
73254
73255 /* Opcode: SorterData P1 P2 P3 * *
73256 ** Synopsis: r[P2]=data
73257 **
73258 ** Write into register P2 the current sorter data for sorter cursor P1.
73259 ** Then clear the column header cache on cursor P3.
73260 **
73261 ** This opcode is normally use to move a record out of the sorter and into
73262 ** a register that is the source for a pseudo-table cursor created using
73263 ** OpenPseudo. That pseudo-table cursor is the one that is identified by
73264 ** parameter P3. Clearing the P3 column cache as part of this opcode saves
73265 ** us from having to issue a separate NullRow instruction to clear that cache.
73266 */
73267 case OP_SorterData: {
73268 VdbeCursor *pC;
73269
73270 pOut = &aMem[pOp->p2];
73271 pC = p->apCsr[pOp->p1];
73272 assert( isSorter(pC) );
73273 rc = sqlite3VdbeSorterRowkey(pC, pOut);
73274 assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
73275 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73276 p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
73277 break;
73278 }
73279
73280 /* Opcode: RowData P1 P2 * * *
73281 ** Synopsis: r[P2]=data
@@ -73277,20 +73318,24 @@
73318 assert( pC!=0 );
73319 assert( pC->nullRow==0 );
73320 assert( pC->pseudoTableReg==0 );
73321 assert( pC->pCursor!=0 );
73322 pCrsr = pC->pCursor;
 
73323
73324 /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
73325 ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
73326 ** the cursor. If this where not the case, on of the following assert()s
73327 ** would fail. Should this ever change (because of changes in the code
73328 ** generator) then the fix would be to insert a call to
73329 ** sqlite3VdbeCursorMoveto().
73330 */
73331 assert( pC->deferredMoveto==0 );
73332 assert( sqlite3BtreeCursorIsValid(pCrsr) );
73333 #if 0 /* Not required due to the previous to assert() statements */
73334 rc = sqlite3VdbeCursorMoveto(pC);
73335 if( rc!=SQLITE_OK ) goto abort_due_to_error;
73336 #endif
73337
73338 if( pC->isTable==0 ){
73339 assert( !pC->isTable );
73340 VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
73341 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -73303,11 +73348,12 @@
73348 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
73349 if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
73350 goto too_big;
73351 }
73352 }
73353 testcase( n==0 );
73354 if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
73355 goto no_mem;
73356 }
73357 pOut->n = n;
73358 MemSetTypeFlag(pOut, MEM_Blob);
73359 if( pC->isTable==0 ){
@@ -73354,18 +73400,14 @@
73400 rc = pModule->xRowid(pC->pVtabCursor, &v);
73401 sqlite3VtabImportErrmsg(p, pVtab);
73402 #endif /* SQLITE_OMIT_VIRTUALTABLE */
73403 }else{
73404 assert( pC->pCursor!=0 );
73405 rc = sqlite3VdbeCursorRestore(pC);
73406 if( rc ) goto abort_due_to_error;
73407 rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73408 assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
 
 
 
 
73409 }
73410 pOut->u.i = v;
73411 break;
73412 }
73413
@@ -73380,11 +73422,10 @@
73422
73423 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73424 pC = p->apCsr[pOp->p1];
73425 assert( pC!=0 );
73426 pC->nullRow = 1;
 
73427 pC->cacheStatus = CACHE_STALE;
73428 if( pC->pCursor ){
73429 sqlite3BtreeClearCursor(pC->pCursor);
73430 }
73431 break;
@@ -73414,11 +73455,10 @@
73455 res = 0;
73456 assert( pCrsr!=0 );
73457 rc = sqlite3BtreeLast(pCrsr, &res);
73458 pC->nullRow = (u8)res;
73459 pC->deferredMoveto = 0;
 
73460 pC->cacheStatus = CACHE_STALE;
73461 #ifdef SQLITE_DEBUG
73462 pC->seekOp = OP_Last;
73463 #endif
73464 if( pOp->p2>0 ){
@@ -73481,11 +73521,10 @@
73521 pCrsr = pC->pCursor;
73522 assert( pCrsr );
73523 rc = sqlite3BtreeFirst(pCrsr, &res);
73524 pC->deferredMoveto = 0;
73525 pC->cacheStatus = CACHE_STALE;
 
73526 }
73527 pC->nullRow = (u8)res;
73528 assert( pOp->p2>0 && pOp->p2<p->nOp );
73529 VdbeBranchTaken(res!=0,2);
73530 if( res ){
@@ -73607,11 +73646,10 @@
73646 sqlite3_search_count++;
73647 #endif
73648 }else{
73649 pC->nullRow = 1;
73650 }
 
73651 goto check_for_interrupt;
73652 }
73653
73654 /* Opcode: IdxInsert P1 P2 P3 * P5
73655 ** Synopsis: key=r[P2]
@@ -73723,14 +73761,20 @@
73761 pC = p->apCsr[pOp->p1];
73762 assert( pC!=0 );
73763 pCrsr = pC->pCursor;
73764 assert( pCrsr!=0 );
73765 pOut->flags = MEM_Null;
73766 assert( pC->isTable==0 );
 
73767 assert( pC->deferredMoveto==0 );
73768
73769 /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
73770 ** out from under the cursor. That will never happend for an IdxRowid
73771 ** opcode, hence the NEVER() arround the check of the return value.
73772 */
73773 rc = sqlite3VdbeCursorRestore(pC);
73774 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73775
73776 if( !pC->nullRow ){
73777 rowid = 0; /* Not needed. Only used to silence a warning. */
73778 rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
73779 if( rc!=SQLITE_OK ){
73780 goto abort_due_to_error;
@@ -78187,11 +78231,11 @@
78231 if( rc==SQLITE_OK ){
78232 #if SQLITE_MAX_WORKER_THREADS
78233 assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
78234 if( pSorter->bUseThreads ){
78235 int iTask;
78236 PmaReader *pReadr = 0;
78237 SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
78238 rc = vdbeSortAllocUnpacked(pLast);
78239 if( rc==SQLITE_OK ){
78240 pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
78241 pSorter->pReader = pReadr;
@@ -87168,29 +87212,27 @@
87212 tRowcnt v;
87213
87214 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87215 if( z==0 ) z = "";
87216 #else
87217 assert( z!=0 );
87218 #endif
87219 for(i=0; *z && i<nOut; i++){
87220 v = 0;
87221 while( (c=z[0])>='0' && c<='9' ){
87222 v = v*10 + c - '0';
87223 z++;
87224 }
87225 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87226 if( aOut ) aOut[i] = v;
87227 if( aLog ) aLog[i] = sqlite3LogEst(v);
 
87228 #else
87229 assert( aOut==0 );
87230 UNUSED_PARAMETER(aOut);
87231 assert( aLog!=0 );
87232 aLog[i] = sqlite3LogEst(v);
87233 #endif
 
 
 
87234 if( *z==' ' ) z++;
87235 }
87236 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4
87237 assert( pIndex!=0 );
87238 #else
@@ -87247,12 +87289,21 @@
87289 pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
87290 }
87291 z = argv[2];
87292
87293 if( pIndex ){
87294 int nCol = pIndex->nKeyCol+1;
87295 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87296 tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
87297 sizeof(tRowcnt) * nCol
87298 );
87299 if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
87300 #else
87301 tRowcnt * const aiRowEst = 0;
87302 #endif
87303 pIndex->bUnordered = 0;
87304 decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
87305 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
87306 }else{
87307 Index fakeIdx;
87308 fakeIdx.szIdxRow = pTable->szTabRow;
87309 #ifdef SQLITE_ENABLE_COSTMULT
@@ -87307,29 +87358,42 @@
87358 ** unique. */
87359 nCol = pIdx->nSampleCol-1;
87360 pIdx->aAvgEq[nCol] = 1;
87361 }
87362 for(iCol=0; iCol<nCol; iCol++){
87363 int nSample = pIdx->nSample;
87364 int i; /* Used to iterate through samples */
87365 tRowcnt sumEq = 0; /* Sum of the nEq values */
 
87366 tRowcnt avgEq = 0;
87367 tRowcnt nRow; /* Number of rows in index */
87368 i64 nSum100 = 0; /* Number of terms contributing to sumEq */
87369 i64 nDist100; /* Number of distinct values in index */
87370
87371 if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
87372 nRow = pFinal->anLt[iCol];
87373 nDist100 = (i64)100 * pFinal->anDLt[iCol];
87374 nSample--;
87375 }else{
87376 nRow = pIdx->aiRowEst[0];
87377 nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
87378 }
87379
87380 /* Set nSum to the number of distinct (iCol+1) field prefixes that
87381 ** occur in the stat4 table for this index. Set sumEq to the sum of
87382 ** the nEq values for column iCol for the same set (adding the value
87383 ** only once where there exist duplicate prefixes). */
87384 for(i=0; i<nSample; i++){
87385 if( i==(pIdx->nSample-1)
87386 || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
87387 ){
87388 sumEq += aSample[i].anEq[iCol];
87389 nSum100 += 100;
87390 }
87391 }
87392
87393 if( nDist100>nSum100 ){
87394 avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
87395 }
87396 if( avgEq==0 ) avgEq = 1;
87397 pIdx->aAvgEq[iCol] = avgEq;
87398 }
87399 }
@@ -87576,10 +87640,15 @@
87640 if( rc==SQLITE_OK ){
87641 int lookasideEnabled = db->lookaside.bEnabled;
87642 db->lookaside.bEnabled = 0;
87643 rc = loadStat4(db, sInfo.zDatabase);
87644 db->lookaside.bEnabled = lookasideEnabled;
87645 }
87646 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
87647 Index *pIdx = sqliteHashData(i);
87648 sqlite3_free(pIdx->aiRowEst);
87649 pIdx->aiRowEst = 0;
87650 }
87651 #endif
87652
87653 if( rc==SQLITE_NOMEM ){
87654 db->mallocFailed = 1;
@@ -88870,10 +88939,13 @@
88939 #endif
88940 if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
88941 sqlite3ExprDelete(db, p->pPartIdxWhere);
88942 sqlite3DbFree(db, p->zColAff);
88943 if( p->isResized ) sqlite3DbFree(db, p->azColl);
88944 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
88945 sqlite3_free(p->aiRowEst);
88946 #endif
88947 sqlite3DbFree(db, p);
88948 }
88949
88950 /*
88951 ** For the index called zIdxName which is found in the database iDb,
@@ -91179,11 +91251,11 @@
91251 pIndex->nKeyCol); VdbeCoverage(v);
91252 sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
91253 }else{
91254 addr2 = sqlite3VdbeCurrentAddr(v);
91255 }
91256 sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
91257 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
91258 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
91259 sqlite3ReleaseTempReg(pParse, regRecord);
91260 sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
91261 sqlite3VdbeJumpHere(v, addr1);
@@ -93687,11 +93759,11 @@
93759 if( okOnePass ){
93760 /* Just one row. Hence the top-of-loop is a no-op */
93761 assert( nKey==nPk ); /* OP_Found will use an unpacked key */
93762 assert( !IsVirtual(pTab) );
93763 if( aToOpen[iDataCur-iTabCur] ){
93764 assert( pPk!=0 || pTab->pSelect!=0 );
93765 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
93766 VdbeCoverage(v);
93767 }
93768 }else if( pPk ){
93769 addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
@@ -105122,11 +105194,10 @@
105194 int regRow;
105195 int regRowid;
105196 int nKey;
105197 int iSortTab; /* Sorter cursor to read from */
105198 int nSortData; /* Trailing values to read from sorter */
 
105199 int i;
105200 int bSeq; /* True if sorter record includes seq. no. */
105201 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
105202 struct ExprList_item *aOutEx = p->pEList->a;
105203 #endif
@@ -105156,23 +105227,20 @@
105227 sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
105228 if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
105229 addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
105230 VdbeCoverage(v);
105231 codeOffset(v, p->iOffset, addrContinue);
105232 sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
 
105233 bSeq = 0;
105234 }else{
105235 addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
105236 codeOffset(v, p->iOffset, addrContinue);
105237 iSortTab = iTab;
 
105238 bSeq = 1;
105239 }
105240 for(i=0; i<nSortData; i++){
105241 sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
 
105242 VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
105243 }
105244 switch( eDest ){
105245 case SRT_Table:
105246 case SRT_EphemTab: {
@@ -109097,16 +109165,15 @@
109165 ** from the previous row currently stored in a0, a1, a2...
109166 */
109167 addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
109168 sqlite3ExprCacheClear(pParse);
109169 if( groupBySort ){
109170 sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
109171 }
109172 for(j=0; j<pGroupBy->nExpr; j++){
109173 if( groupBySort ){
109174 sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
 
109175 }else{
109176 sAggInfo.directMode = 1;
109177 sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
109178 }
109179 }
@@ -111216,12 +111283,12 @@
111283 0, 0);
111284 }
111285
111286 /* Top of the update loop */
111287 if( okOnePass ){
111288 if( aToOpen[iDataCur-iBaseCur] && !isView ){
111289 assert( pPk );
111290 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
111291 VdbeCoverageNeverTaken(v);
111292 }
111293 labelContinue = labelBreak;
111294 sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
@@ -112450,10 +112517,11 @@
112517 }
112518 sqlite3DbFree(db, pVTable);
112519 }else if( ALWAYS(pVTable->pVtab) ){
112520 /* Justification of ALWAYS(): A correct vtab constructor must allocate
112521 ** the sqlite3_vtab object if successful. */
112522 memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
112523 pVTable->pVtab->pModule = pMod->pModule;
112524 pVTable->nRef = 1;
112525 if( sCtx.pTab ){
112526 const char *zFormat = "vtable constructor did not declare schema: %s";
112527 *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
@@ -115700,21 +115768,28 @@
115768 ** have been requested when testing key $P in whereEqualScanEst(). */
115769 whereKeyStats(pParse, p, pRec, 0, a);
115770 iLower = a[0];
115771 iUpper = a[0] + a[1];
115772 }
115773
115774 assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115775 assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115776 assert( p->aSortOrder!=0 );
115777 if( p->aSortOrder[nEq] ){
115778 /* The roles of pLower and pUpper are swapped for a DESC index */
115779 SWAP(WhereTerm*, pLower, pUpper);
115780 }
115781
115782 /* If possible, improve on the iLower estimate using ($P:$L). */
115783 if( pLower ){
115784 int bOk; /* True if value is extracted from pExpr */
115785 Expr *pExpr = pLower->pExpr->pRight;
 
115786 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115787 if( rc==SQLITE_OK && bOk ){
115788 tRowcnt iNew;
115789 whereKeyStats(pParse, p, pRec, 0, a);
115790 iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115791 if( iNew>iLower ) iLower = iNew;
115792 nOut--;
115793 pLower = 0;
115794 }
115795 }
@@ -115721,16 +115796,15 @@
115796
115797 /* If possible, improve on the iUpper estimate using ($P:$U). */
115798 if( pUpper ){
115799 int bOk; /* True if value is extracted from pExpr */
115800 Expr *pExpr = pUpper->pExpr->pRight;
 
115801 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115802 if( rc==SQLITE_OK && bOk ){
115803 tRowcnt iNew;
115804 whereKeyStats(pParse, p, pRec, 1, a);
115805 iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115806 if( iNew<iUpper ) iUpper = iNew;
115807 nOut--;
115808 pUpper = 0;
115809 }
115810 }
@@ -116225,65 +116299,52 @@
116299 sqlite3StrAccumAppend(pStr, "?", 1);
116300 }
116301
116302 /*
116303 ** Argument pLevel describes a strategy for scanning table pTab. This
116304 ** function appends text to pStr that describes the subset of table
116305 ** rows scanned by the strategy in the form of an SQL expression.
 
116306 **
116307 ** For example, if the query:
116308 **
116309 ** SELECT * FROM t1 WHERE a=1 AND b>2;
116310 **
116311 ** is run and there is an index on (a, b), then this function returns a
116312 ** string similar to:
116313 **
116314 ** "a=? AND b>?"
 
 
 
 
116315 */
116316 static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
116317 Index *pIndex = pLoop->u.btree.pIndex;
116318 u16 nEq = pLoop->u.btree.nEq;
116319 u16 nSkip = pLoop->u.btree.nSkip;
116320 int i, j;
116321 Column *aCol = pTab->aCol;
116322 i16 *aiColumn = pIndex->aiColumn;
116323
116324 if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
116325 sqlite3StrAccumAppend(pStr, " (", 2);
 
 
 
 
 
116326 for(i=0; i<nEq; i++){
116327 char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
116328 if( i>=nSkip ){
116329 explainAppendTerm(pStr, i, z, "=");
116330 }else{
116331 if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
116332 sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
 
 
116333 }
116334 }
116335
116336 j = i;
116337 if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
116338 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116339 explainAppendTerm(pStr, i++, z, ">");
116340 }
116341 if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
116342 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116343 explainAppendTerm(pStr, i, z, "<");
116344 }
116345 sqlite3StrAccumAppend(pStr, ")", 1);
 
116346 }
116347
116348 /*
116349 ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
116350 ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
@@ -116303,72 +116364,90 @@
116364 #endif
116365 {
116366 struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
116367 Vdbe *v = pParse->pVdbe; /* VM being constructed */
116368 sqlite3 *db = pParse->db; /* Database handle */
 
116369 int iId = pParse->iSelectId; /* Select id (left-most output column) */
116370 int isSearch; /* True for a SEARCH. False for SCAN. */
116371 WhereLoop *pLoop; /* The controlling WhereLoop object */
116372 u32 flags; /* Flags that describe this loop */
116373 char *zMsg; /* Text to add to EQP output */
116374 StrAccum str; /* EQP output string */
116375 char zBuf[100]; /* Initial space for EQP output string */
116376
116377 pLoop = pLevel->pWLoop;
116378 flags = pLoop->wsFlags;
116379 if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
116380
116381 isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
116382 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
116383 || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
116384
116385 sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
116386 str.db = db;
116387 sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
116388 if( pItem->pSelect ){
116389 sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
116390 }else{
116391 sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
116392 }
116393
116394 if( pItem->zAlias ){
116395 sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
116396 }
116397 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
116398 const char *zFmt = 0;
116399 Index *pIdx;
116400
116401 assert( pLoop->u.btree.pIndex!=0 );
116402 pIdx = pLoop->u.btree.pIndex;
116403 assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
116404 if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
116405 if( isSearch ){
116406 zFmt = "PRIMARY KEY";
116407 }
116408 }else if( flags & WHERE_AUTO_INDEX ){
116409 zFmt = "AUTOMATIC COVERING INDEX";
116410 }else if( flags & WHERE_IDX_ONLY ){
116411 zFmt = "COVERING INDEX %s";
116412 }else{
116413 zFmt = "INDEX %s";
116414 }
116415 if( zFmt ){
116416 sqlite3StrAccumAppend(&str, " USING ", 7);
116417 sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
116418 explainIndexRange(&str, pLoop, pItem->pTab);
116419 }
116420 }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
116421 const char *zRange;
 
116422 if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
116423 zRange = "(rowid=?)";
116424 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
116425 zRange = "(rowid>? AND rowid<?)";
116426 }else if( flags&WHERE_BTM_LIMIT ){
116427 zRange = "(rowid>?)";
116428 }else{
116429 assert( flags&WHERE_TOP_LIMIT);
116430 zRange = "(rowid<?)";
116431 }
116432 sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
116433 sqlite3StrAccumAppendAll(&str, zRange);
116434 }
116435 #ifndef SQLITE_OMIT_VIRTUALTABLE
116436 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
116437 sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
116438 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
116439 }
116440 #endif
116441 #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
116442 if( pLoop->nOut>=10 ){
116443 sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
116444 }else{
116445 sqlite3StrAccumAppend(&str, " (~1 row)", 9);
116446 }
116447 #endif
116448 zMsg = sqlite3StrAccumFinish(&str);
116449 sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
116450 }
116451 }
116452 #else
116453 # define explainOneScan(u,v,w,x,y,z)
@@ -117633,11 +117712,11 @@
117712 if( ppPrev==0 ){
117713 /* There already exists a WhereLoop on the list that is better
117714 ** than pTemplate, so just ignore pTemplate */
117715 #if WHERETRACE_ENABLED /* 0x8 */
117716 if( sqlite3WhereTrace & 0x8 ){
117717 sqlite3DebugPrintf(" skip: ");
117718 whereLoopPrint(pTemplate, pBuilder->pWC);
117719 }
117720 #endif
117721 return SQLITE_OK;
117722 }else{
@@ -117649,14 +117728,14 @@
117728 ** WhereLoop and insert it.
117729 */
117730 #if WHERETRACE_ENABLED /* 0x8 */
117731 if( sqlite3WhereTrace & 0x8 ){
117732 if( p!=0 ){
117733 sqlite3DebugPrintf("replace: ");
117734 whereLoopPrint(p, pBuilder->pWC);
117735 }
117736 sqlite3DebugPrintf(" add: ");
117737 whereLoopPrint(pTemplate, pBuilder->pWC);
117738 }
117739 #endif
117740 if( p==0 ){
117741 /* Allocate a new WhereLoop to add to the end of the list */
@@ -117676,11 +117755,11 @@
117755 pToDel = *ppTail;
117756 if( pToDel==0 ) break;
117757 *ppTail = pToDel->pNextLoop;
117758 #if WHERETRACE_ENABLED /* 0x8 */
117759 if( sqlite3WhereTrace & 0x8 ){
117760 sqlite3DebugPrintf(" delete: ");
117761 whereLoopPrint(pToDel, pBuilder->pWC);
117762 }
117763 #endif
117764 whereLoopDelete(db, pToDel);
117765 }
@@ -118843,11 +118922,11 @@
118922 if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
118923 }
118924 isMatch = 1;
118925 break;
118926 }
118927 if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
118928 /* Make sure the sort order is compatible in an ORDER BY clause.
118929 ** Sort order is irrelevant for a GROUP BY clause. */
118930 if( revSet ){
118931 if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
118932 }else{
@@ -119308,16 +119387,19 @@
119387 pWInfo->revMask = pFrom->revLoop;
119388 }
119389 if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
119390 && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
119391 ){
119392 Bitmask revMask = 0;
119393 int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
119394 pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
119395 );
119396 assert( pWInfo->sorted==0 );
119397 if( nOrder==pWInfo->pOrderBy->nExpr ){
119398 pWInfo->sorted = 1;
119399 pWInfo->revMask = revMask;
119400 }
119401 }
119402 }
119403
119404
119405 pWInfo->nRowOut = pFrom->nRow;
@@ -132620,10 +132702,11 @@
132702 assert( iIdx==nVal );
132703
132704 /* In case the cursor has been used before, clear it now. */
132705 sqlite3_finalize(pCsr->pStmt);
132706 sqlite3_free(pCsr->aDoclist);
132707 sqlite3_free(pCsr->aMatchinfo);
132708 sqlite3Fts3ExprFree(pCsr->pExpr);
132709 memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
132710
132711 /* Set the lower and upper bounds on docids to return */
132712 pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -133930,11 +134013,11 @@
134013 if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
134014 iMax = a[i].iDocid;
134015 bMaxSet = 1;
134016 }
134017 }
134018 assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
134019 assert( rc!=SQLITE_OK || bMaxSet );
134020
134021 /* Keep advancing iterators until they all point to the same document */
134022 for(i=0; i<p->nToken; i++){
134023 while( rc==SQLITE_OK && bEof==0
@@ -136047,11 +136130,11 @@
136130 int i = 0;
136131
136132 /* Set variable i to the maximum number of bytes of input to tokenize. */
136133 for(i=0; i<n; i++){
136134 if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
136135 if( z[i]=='"' ) break;
136136 }
136137
136138 *pnConsumed = i;
136139 rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
136140 if( rc==SQLITE_OK ){
136141
+2 -2
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105105
**
106106
** See also: [sqlite3_libversion()],
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110
-#define SQLITE_VERSION "3.8.7"
110
+#define SQLITE_VERSION "3.8.7.1"
111111
#define SQLITE_VERSION_NUMBER 3008007
112
-#define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d"
112
+#define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.8.7"
111 #define SQLITE_VERSION_NUMBER 3008007
112 #define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.8.7.1"
111 #define SQLITE_VERSION_NUMBER 3008007
112 #define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
+7 -7
--- src/stash.c
+++ src/stash.c
@@ -23,17 +23,17 @@
2323
2424
/*
2525
** SQL code to implement the tables needed by the stash.
2626
*/
2727
static const char zStashInit[] =
28
-@ CREATE TABLE IF NOT EXISTS %s.stash(
28
+@ CREATE TABLE IF NOT EXISTS "%w".stash(
2929
@ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
3030
@ vid INTEGER, -- The baseline check-out for this stash
3131
@ comment TEXT, -- Comment for this stash. Or NULL
3232
@ ctime TIMESTAMP -- When the stash was created
3333
@ );
34
-@ CREATE TABLE IF NOT EXISTS %s.stashfile(
34
+@ CREATE TABLE IF NOT EXISTS "%w".stashfile(
3535
@ stashid INTEGER REFERENCES stash, -- Stash that contains this file
3636
@ rid INTEGER, -- Baseline content in BLOB table or 0.
3737
@ isAdded BOOLEAN, -- True if this is an added file
3838
@ isRemoved BOOLEAN, -- True if this file is deleted
3939
@ isExec BOOLEAN, -- True if file is executable
@@ -61,24 +61,24 @@
6161
6262
zFile = mprintf("%/", zFName);
6363
file_tree_name(zFile, &fname, 1);
6464
zTreename = blob_str(&fname);
6565
blob_zero(&sql);
66
- blob_appendf(&sql,
66
+ blob_append_sql(&sql,
6767
"SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
6868
" FROM vfile"
6969
" WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
7070
vid
7171
);
7272
if( fossil_strcmp(zTreename,".")!=0 ){
73
- blob_appendf(&sql,
73
+ blob_append_sql(&sql,
7474
" AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
7575
" OR pathname=%Q OR origname=%Q)",
7676
zTreename, zTreename, zTreename, zTreename
7777
);
7878
}
79
- db_prepare(&q, blob_str(&sql));
79
+ db_prepare(&q, "%s", blob_sql_text(&sql));
8080
blob_reset(&sql);
8181
db_prepare(&ins,
8282
"INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
8383
"origname, newname, delta)"
8484
"VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
@@ -481,11 +481,11 @@
481481
undo_capture_command_line();
482482
db_must_be_within_tree();
483483
db_open_config(0);
484484
db_begin_transaction();
485485
zDb = db_name("localdb");
486
- db_multi_exec(zStashInit, zDb, zDb);
486
+ db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb);
487487
if( g.argc<=2 ){
488488
zCmd = "save";
489489
}else{
490490
zCmd = g.argv[2];
491491
}
@@ -534,11 +534,11 @@
534534
}
535535
verify_all_options();
536536
db_prepare(&q,
537537
"SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
538538
" comment, datetime(ctime) FROM stash"
539
- " ORDER BY ctime DESC"
539
+ " ORDER BY ctime"
540540
);
541541
if( verboseFlag ){
542542
db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
543543
" FROM stashfile WHERE stashid=$id");
544544
}
545545
--- src/stash.c
+++ src/stash.c
@@ -23,17 +23,17 @@
23
24 /*
25 ** SQL code to implement the tables needed by the stash.
26 */
27 static const char zStashInit[] =
28 @ CREATE TABLE IF NOT EXISTS %s.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 %s.stashfile(
35 @ stashid INTEGER REFERENCES stash, -- Stash that contains this file
36 @ rid INTEGER, -- Baseline content in BLOB table or 0.
37 @ isAdded BOOLEAN, -- True if this is an added file
38 @ isRemoved BOOLEAN, -- True if this file is deleted
39 @ isExec BOOLEAN, -- True if file is executable
@@ -61,24 +61,24 @@
61
62 zFile = mprintf("%/", zFName);
63 file_tree_name(zFile, &fname, 1);
64 zTreename = blob_str(&fname);
65 blob_zero(&sql);
66 blob_appendf(&sql,
67 "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
68 " FROM vfile"
69 " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
70 vid
71 );
72 if( fossil_strcmp(zTreename,".")!=0 ){
73 blob_appendf(&sql,
74 " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
75 " OR pathname=%Q OR origname=%Q)",
76 zTreename, zTreename, zTreename, zTreename
77 );
78 }
79 db_prepare(&q, blob_str(&sql));
80 blob_reset(&sql);
81 db_prepare(&ins,
82 "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
83 "origname, newname, delta)"
84 "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
@@ -481,11 +481,11 @@
481 undo_capture_command_line();
482 db_must_be_within_tree();
483 db_open_config(0);
484 db_begin_transaction();
485 zDb = db_name("localdb");
486 db_multi_exec(zStashInit, zDb, zDb);
487 if( g.argc<=2 ){
488 zCmd = "save";
489 }else{
490 zCmd = g.argv[2];
491 }
@@ -534,11 +534,11 @@
534 }
535 verify_all_options();
536 db_prepare(&q,
537 "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
538 " comment, datetime(ctime) FROM stash"
539 " ORDER BY ctime DESC"
540 );
541 if( verboseFlag ){
542 db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
543 " FROM stashfile WHERE stashid=$id");
544 }
545
--- src/stash.c
+++ src/stash.c
@@ -23,17 +23,17 @@
23
24 /*
25 ** SQL code to implement the tables needed by the stash.
26 */
27 static const char zStashInit[] =
28 @ CREATE TABLE IF NOT EXISTS "%w".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 "%w".stashfile(
35 @ stashid INTEGER REFERENCES stash, -- Stash that contains this file
36 @ rid INTEGER, -- Baseline content in BLOB table or 0.
37 @ isAdded BOOLEAN, -- True if this is an added file
38 @ isRemoved BOOLEAN, -- True if this file is deleted
39 @ isExec BOOLEAN, -- True if file is executable
@@ -61,24 +61,24 @@
61
62 zFile = mprintf("%/", zFName);
63 file_tree_name(zFile, &fname, 1);
64 zTreename = blob_str(&fname);
65 blob_zero(&sql);
66 blob_append_sql(&sql,
67 "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
68 " FROM vfile"
69 " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
70 vid
71 );
72 if( fossil_strcmp(zTreename,".")!=0 ){
73 blob_append_sql(&sql,
74 " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
75 " OR pathname=%Q OR origname=%Q)",
76 zTreename, zTreename, zTreename, zTreename
77 );
78 }
79 db_prepare(&q, "%s", blob_sql_text(&sql));
80 blob_reset(&sql);
81 db_prepare(&ins,
82 "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
83 "origname, newname, delta)"
84 "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
@@ -481,11 +481,11 @@
481 undo_capture_command_line();
482 db_must_be_within_tree();
483 db_open_config(0);
484 db_begin_transaction();
485 zDb = db_name("localdb");
486 db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb);
487 if( g.argc<=2 ){
488 zCmd = "save";
489 }else{
490 zCmd = g.argv[2];
491 }
@@ -534,11 +534,11 @@
534 }
535 verify_all_options();
536 db_prepare(&q,
537 "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
538 " comment, datetime(ctime) FROM stash"
539 " ORDER BY ctime"
540 );
541 if( verboseFlag ){
542 db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
543 " FROM stashfile WHERE stashid=$id");
544 }
545
+47 -24
--- src/stat.c
+++ src/stat.c
@@ -137,49 +137,59 @@
137137
@ <tr><th>Repository Rebuilt:</th><td>
138138
@ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
139139
@ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
140140
@ <tr><th>Database&nbsp;Stats:</th><td>
141141
zDb = db_name("repository");
142
- @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
143
- @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
144
- @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
145
- @ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
146
- @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
142
+ @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages,
143
+ @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page,
144
+ @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages,
145
+ @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)),
146
+ @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode
147147
@ </td></tr>
148148
149149
@ </table>
150150
style_footer();
151151
}
152152
153153
/*
154154
** COMMAND: dbstat*
155155
**
156
-** Usage: %fossil dbstat ?-brief | -b?
156
+** Usage: %fossil dbstat OPTIONS
157157
**
158158
** Shows statistics and global information about the repository.
159159
**
160
-** The (-brief|-b) option removes any "long-running" statistics, namely
161
-** those whose calculations are known to slow down as the repository
162
-** grows.
160
+** Options:
163161
**
162
+** --brief|-b Only show essential elements
163
+** --db-check Run a PRAGMA quick_check on the repository database
164
+** --omit-version-info Omit the SQLite and Fossil version information
164165
*/
165166
void dbstat_cmd(void){
166167
i64 t, fsize;
167168
int n, m;
168169
int szMax, szAvg;
169170
const char *zDb;
170171
int brief;
172
+ int omitVers; /* Omit Fossil and SQLite version information */
173
+ int dbCheck; /* True for the --db-check option */
171174
char zBuf[100];
172175
const int colWidth = -19 /* printf alignment/width for left column */;
173
- const char *p;
176
+ const char *p, *z;
174177
175178
brief = find_option("brief", "b",0)!=0;
179
+ omitVers = find_option("omit-version-info", 0, 0)!=0;
180
+ dbCheck = find_option("db-check",0,0)!=0;
176181
db_find_and_open_repository(0,0);
177182
178183
/* We should be done with options.. */
179184
verify_all_options();
180185
186
+ if( (z = db_get("project-name",0))!=0
187
+ || (z = db_get("short-project-name",0))!=0
188
+ ){
189
+ fossil_print("%*s%s\n", colWidth, "project-name:", z);
190
+ }
181191
fsize = file_size(g.zRepositoryName);
182192
bigSizeName(sizeof(zBuf), zBuf, fsize);
183193
fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
184194
if( !brief ){
185195
n = db_int(0, "SELECT count(*) FROM blob");
@@ -225,38 +235,51 @@
225235
fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
226236
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
227237
fossil_print("%*s%d\n", colWidth, "events:", n);
228238
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
229239
fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
240
+ z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
241
+ " CAST(julianday('now') - mtime AS INTEGER)"
242
+ " || ' days ago' FROM event "
243
+ " ORDER BY mtime DESC LIMIT 1");
244
+ fossil_print("%*s%s\n", colWidth, "latest-change:", z);
230245
}
231246
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
232247
" + 0.99");
233248
fossil_print("%*s%d days or approximately %.2f years.\n",
234249
colWidth, "project-age:", n, n/365.2425);
235250
p = db_get("project-code", 0);
236251
if( p ){
237252
fossil_print("%*s%s\n", colWidth, "project-id:", p);
238253
}
254
+#if 0
255
+ /* Server-id is not useful information any more */
239256
fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
240
- fossil_print("%*s%s %s [%s] (%s)\n",
241
- colWidth, "fossil-version:",
242
- MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
243
- COMPILER_NAME);
244
- fossil_print("%*s%.19s [%.10s] (%s)\n",
245
- colWidth, "sqlite-version:",
246
- sqlite3_sourceid(), &sqlite3_sourceid()[20],
247
- sqlite3_libversion());
257
+#endif
258
+ if( !omitVers ){
259
+ fossil_print("%*s%s %s [%s] (%s)\n",
260
+ colWidth, "fossil-version:",
261
+ MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
262
+ COMPILER_NAME);
263
+ fossil_print("%*s%.19s [%.10s] (%s)\n",
264
+ colWidth, "sqlite-version:",
265
+ sqlite3_sourceid(), &sqlite3_sourceid()[20],
266
+ sqlite3_libversion());
267
+ }
248268
zDb = db_name("repository");
249269
fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
250270
"%s, %s mode\n",
251271
colWidth, "database-stats:",
252
- db_int(0, "PRAGMA %s.page_count", zDb),
253
- db_int(0, "PRAGMA %s.page_size", zDb),
254
- db_int(0, "PRAGMA %s.freelist_count", zDb),
255
- db_text(0, "PRAGMA %s.encoding", zDb),
256
- db_text(0, "PRAGMA %s.journal_mode", zDb));
257
-
272
+ db_int(0, "PRAGMA \"%w\".page_count", zDb),
273
+ db_int(0, "PRAGMA \"%w\".page_size", zDb),
274
+ db_int(0, "PRAGMA \"%w\".freelist_count", zDb),
275
+ db_text(0, "PRAGMA \"%w\".encoding", zDb),
276
+ db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
277
+ if( dbCheck ){
278
+ fossil_print("%*s%s\n", colWidth, "database-check:",
279
+ db_text(0, "PRAGMA quick_check(1)"));
280
+ }
258281
}
259282
260283
/*
261284
** WEBPAGE: urllist
262285
**
263286
--- src/stat.c
+++ src/stat.c
@@ -137,49 +137,59 @@
137 @ <tr><th>Repository Rebuilt:</th><td>
138 @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
139 @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
140 @ <tr><th>Database&nbsp;Stats:</th><td>
141 zDb = db_name("repository");
142 @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
143 @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
144 @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
145 @ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
146 @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
147 @ </td></tr>
148
149 @ </table>
150 style_footer();
151 }
152
153 /*
154 ** COMMAND: dbstat*
155 **
156 ** Usage: %fossil dbstat ?-brief | -b?
157 **
158 ** Shows statistics and global information about the repository.
159 **
160 ** The (-brief|-b) option removes any "long-running" statistics, namely
161 ** those whose calculations are known to slow down as the repository
162 ** grows.
163 **
 
 
 
164 */
165 void dbstat_cmd(void){
166 i64 t, fsize;
167 int n, m;
168 int szMax, szAvg;
169 const char *zDb;
170 int brief;
 
 
171 char zBuf[100];
172 const int colWidth = -19 /* printf alignment/width for left column */;
173 const char *p;
174
175 brief = find_option("brief", "b",0)!=0;
 
 
176 db_find_and_open_repository(0,0);
177
178 /* We should be done with options.. */
179 verify_all_options();
180
 
 
 
 
 
181 fsize = file_size(g.zRepositoryName);
182 bigSizeName(sizeof(zBuf), zBuf, fsize);
183 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
184 if( !brief ){
185 n = db_int(0, "SELECT count(*) FROM blob");
@@ -225,38 +235,51 @@
225 fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
226 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
227 fossil_print("%*s%d\n", colWidth, "events:", n);
228 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
229 fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
 
 
 
 
 
230 }
231 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
232 " + 0.99");
233 fossil_print("%*s%d days or approximately %.2f years.\n",
234 colWidth, "project-age:", n, n/365.2425);
235 p = db_get("project-code", 0);
236 if( p ){
237 fossil_print("%*s%s\n", colWidth, "project-id:", p);
238 }
 
 
239 fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
240 fossil_print("%*s%s %s [%s] (%s)\n",
241 colWidth, "fossil-version:",
242 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
243 COMPILER_NAME);
244 fossil_print("%*s%.19s [%.10s] (%s)\n",
245 colWidth, "sqlite-version:",
246 sqlite3_sourceid(), &sqlite3_sourceid()[20],
247 sqlite3_libversion());
 
 
 
248 zDb = db_name("repository");
249 fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
250 "%s, %s mode\n",
251 colWidth, "database-stats:",
252 db_int(0, "PRAGMA %s.page_count", zDb),
253 db_int(0, "PRAGMA %s.page_size", zDb),
254 db_int(0, "PRAGMA %s.freelist_count", zDb),
255 db_text(0, "PRAGMA %s.encoding", zDb),
256 db_text(0, "PRAGMA %s.journal_mode", zDb));
257
 
 
 
258 }
259
260 /*
261 ** WEBPAGE: urllist
262 **
263
--- src/stat.c
+++ src/stat.c
@@ -137,49 +137,59 @@
137 @ <tr><th>Repository Rebuilt:</th><td>
138 @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
139 @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
140 @ <tr><th>Database&nbsp;Stats:</th><td>
141 zDb = db_name("repository");
142 @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages,
143 @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page,
144 @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages,
145 @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)),
146 @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode
147 @ </td></tr>
148
149 @ </table>
150 style_footer();
151 }
152
153 /*
154 ** COMMAND: dbstat*
155 **
156 ** Usage: %fossil dbstat OPTIONS
157 **
158 ** Shows statistics and global information about the repository.
159 **
160 ** Options:
 
 
161 **
162 ** --brief|-b Only show essential elements
163 ** --db-check Run a PRAGMA quick_check on the repository database
164 ** --omit-version-info Omit the SQLite and Fossil version information
165 */
166 void dbstat_cmd(void){
167 i64 t, fsize;
168 int n, m;
169 int szMax, szAvg;
170 const char *zDb;
171 int brief;
172 int omitVers; /* Omit Fossil and SQLite version information */
173 int dbCheck; /* True for the --db-check option */
174 char zBuf[100];
175 const int colWidth = -19 /* printf alignment/width for left column */;
176 const char *p, *z;
177
178 brief = find_option("brief", "b",0)!=0;
179 omitVers = find_option("omit-version-info", 0, 0)!=0;
180 dbCheck = find_option("db-check",0,0)!=0;
181 db_find_and_open_repository(0,0);
182
183 /* We should be done with options.. */
184 verify_all_options();
185
186 if( (z = db_get("project-name",0))!=0
187 || (z = db_get("short-project-name",0))!=0
188 ){
189 fossil_print("%*s%s\n", colWidth, "project-name:", z);
190 }
191 fsize = file_size(g.zRepositoryName);
192 bigSizeName(sizeof(zBuf), zBuf, fsize);
193 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
194 if( !brief ){
195 n = db_int(0, "SELECT count(*) FROM blob");
@@ -225,38 +235,51 @@
235 fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
236 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
237 fossil_print("%*s%d\n", colWidth, "events:", n);
238 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
239 fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
240 z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
241 " CAST(julianday('now') - mtime AS INTEGER)"
242 " || ' days ago' FROM event "
243 " ORDER BY mtime DESC LIMIT 1");
244 fossil_print("%*s%s\n", colWidth, "latest-change:", z);
245 }
246 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
247 " + 0.99");
248 fossil_print("%*s%d days or approximately %.2f years.\n",
249 colWidth, "project-age:", n, n/365.2425);
250 p = db_get("project-code", 0);
251 if( p ){
252 fossil_print("%*s%s\n", colWidth, "project-id:", p);
253 }
254 #if 0
255 /* Server-id is not useful information any more */
256 fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
257 #endif
258 if( !omitVers ){
259 fossil_print("%*s%s %s [%s] (%s)\n",
260 colWidth, "fossil-version:",
261 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
262 COMPILER_NAME);
263 fossil_print("%*s%.19s [%.10s] (%s)\n",
264 colWidth, "sqlite-version:",
265 sqlite3_sourceid(), &sqlite3_sourceid()[20],
266 sqlite3_libversion());
267 }
268 zDb = db_name("repository");
269 fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
270 "%s, %s mode\n",
271 colWidth, "database-stats:",
272 db_int(0, "PRAGMA \"%w\".page_count", zDb),
273 db_int(0, "PRAGMA \"%w\".page_size", zDb),
274 db_int(0, "PRAGMA \"%w\".freelist_count", zDb),
275 db_text(0, "PRAGMA \"%w\".encoding", zDb),
276 db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
277 if( dbCheck ){
278 fossil_print("%*s%s\n", colWidth, "database-check:",
279 db_text(0, "PRAGMA quick_check(1)"));
280 }
281 }
282
283 /*
284 ** WEBPAGE: urllist
285 **
286
+7 -3
--- src/style.c
+++ src/style.c
@@ -175,25 +175,29 @@
175175
}
176176
for(i=0; i<nFormAction; i++){
177177
@ gebi("form%d(i+1)").action="%s(aFormAction[i])";
178178
}
179179
@ }
180
- if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){
180
+ if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){
181181
/* Special case for Opera Mini, which executes JS server-side */
182182
@ var isOperaMini = Object.prototype.toString.call(window.operamini)
183183
@ === "[object OperaMini]";
184184
@ if( isOperaMini ){
185185
@ setTimeout("setAllHrefs();",%d(nDelay));
186186
@ }
187
+ }else if( db_get_boolean("auto-hyperlink-ishuman",0) && g.isHuman ){
188
+ /* Active hyperlinks after a delay */
189
+ @ setTimeout("setAllHrefs();",%d(nDelay));
187190
}else if( db_get_boolean("auto-hyperlink-mouseover",0) ){
188
- /* Require mouse movement prior to activating hyperlinks */
191
+ /* Require mouse movement before starting the teim that will
192
+ ** activating hyperlinks */
189193
@ document.getElementsByTagName("body")[0].onmousemove=function(){
190194
@ setTimeout("setAllHrefs();",%d(nDelay));
191195
@ this.onmousemove = null;
192196
@ }
193197
}else{
194
- /* Active hyperlinks right away */
198
+ /* Active hyperlinks after a delay */
195199
@ setTimeout("setAllHrefs();",%d(nDelay));
196200
}
197201
@ </script>
198202
}
199203
200204
--- src/style.c
+++ src/style.c
@@ -175,25 +175,29 @@
175 }
176 for(i=0; i<nFormAction; i++){
177 @ gebi("form%d(i+1)").action="%s(aFormAction[i])";
178 }
179 @ }
180 if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){
181 /* Special case for Opera Mini, which executes JS server-side */
182 @ var isOperaMini = Object.prototype.toString.call(window.operamini)
183 @ === "[object OperaMini]";
184 @ if( isOperaMini ){
185 @ setTimeout("setAllHrefs();",%d(nDelay));
186 @ }
 
 
 
187 }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){
188 /* Require mouse movement prior to activating hyperlinks */
 
189 @ document.getElementsByTagName("body")[0].onmousemove=function(){
190 @ setTimeout("setAllHrefs();",%d(nDelay));
191 @ this.onmousemove = null;
192 @ }
193 }else{
194 /* Active hyperlinks right away */
195 @ setTimeout("setAllHrefs();",%d(nDelay));
196 }
197 @ </script>
198 }
199
200
--- src/style.c
+++ src/style.c
@@ -175,25 +175,29 @@
175 }
176 for(i=0; i<nFormAction; i++){
177 @ gebi("form%d(i+1)").action="%s(aFormAction[i])";
178 }
179 @ }
180 if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){
181 /* Special case for Opera Mini, which executes JS server-side */
182 @ var isOperaMini = Object.prototype.toString.call(window.operamini)
183 @ === "[object OperaMini]";
184 @ if( isOperaMini ){
185 @ setTimeout("setAllHrefs();",%d(nDelay));
186 @ }
187 }else if( db_get_boolean("auto-hyperlink-ishuman",0) && g.isHuman ){
188 /* Active hyperlinks after a delay */
189 @ setTimeout("setAllHrefs();",%d(nDelay));
190 }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){
191 /* Require mouse movement before starting the teim that will
192 ** activating hyperlinks */
193 @ document.getElementsByTagName("body")[0].onmousemove=function(){
194 @ setTimeout("setAllHrefs();",%d(nDelay));
195 @ this.onmousemove = null;
196 @ }
197 }else{
198 /* Active hyperlinks after a delay */
199 @ setTimeout("setAllHrefs();",%d(nDelay));
200 }
201 @ </script>
202 }
203
204
+7 -6
--- src/tag.c
+++ src/tag.c
@@ -213,11 +213,12 @@
213213
rid
214214
);
215215
}
216216
}
217217
if( zCol ){
218
- db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
218
+ db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
219
+ zCol, zValue, rid);
219220
if( tagid==TAG_COMMENT ){
220221
char *zCopy = mprintf("%s", zValue);
221222
wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
222223
free(zCopy);
223224
}
@@ -437,41 +438,41 @@
437438
if( zType==0 || zType[0]==0 ) zType = "*";
438439
if( g.argc!=4 ){
439440
usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
440441
}
441442
if( fRaw ){
442
- blob_appendf(&sql,
443
+ blob_append_sql(&sql,
443444
"SELECT blob.uuid FROM tagxref, blob"
444445
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
445446
" AND tagxref.tagtype>0"
446447
" AND blob.rid=tagxref.rid",
447448
g.argv[3]
448449
);
449450
if( nFindLimit>0 ){
450
- blob_appendf(&sql, " LIMIT %d", nFindLimit);
451
+ blob_append_sql(&sql, " LIMIT %d", nFindLimit);
451452
}
452
- db_prepare(&q, "%s", blob_str(&sql));
453
+ db_prepare(&q, "%s", blob_sql_text(&sql));
453454
blob_reset(&sql);
454455
while( db_step(&q)==SQLITE_ROW ){
455456
fossil_print("%s\n", db_column_text(&q, 0));
456457
}
457458
db_finalize(&q);
458459
}else{
459460
int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
460461
g.argv[3]);
461462
if( tagid>0 ){
462
- blob_appendf(&sql,
463
+ blob_append_sql(&sql,
463464
"%s"
464465
" AND event.type GLOB '%q'"
465466
" AND blob.rid IN ("
466467
" SELECT rid FROM tagxref"
467468
" WHERE tagtype>0 AND tagid=%d"
468469
")"
469470
" ORDER BY event.mtime DESC",
470471
timeline_query_for_tty(), zType, tagid
471472
);
472
- db_prepare(&q, "%s", blob_str(&sql));
473
+ db_prepare(&q, "%s", blob_sql_text(&sql));
473474
blob_reset(&sql);
474475
print_timeline(&q, nFindLimit, 79, 0);
475476
db_finalize(&q);
476477
}
477478
}
478479
--- src/tag.c
+++ src/tag.c
@@ -213,11 +213,12 @@
213 rid
214 );
215 }
216 }
217 if( zCol ){
218 db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
 
219 if( tagid==TAG_COMMENT ){
220 char *zCopy = mprintf("%s", zValue);
221 wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
222 free(zCopy);
223 }
@@ -437,41 +438,41 @@
437 if( zType==0 || zType[0]==0 ) zType = "*";
438 if( g.argc!=4 ){
439 usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
440 }
441 if( fRaw ){
442 blob_appendf(&sql,
443 "SELECT blob.uuid FROM tagxref, blob"
444 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
445 " AND tagxref.tagtype>0"
446 " AND blob.rid=tagxref.rid",
447 g.argv[3]
448 );
449 if( nFindLimit>0 ){
450 blob_appendf(&sql, " LIMIT %d", nFindLimit);
451 }
452 db_prepare(&q, "%s", blob_str(&sql));
453 blob_reset(&sql);
454 while( db_step(&q)==SQLITE_ROW ){
455 fossil_print("%s\n", db_column_text(&q, 0));
456 }
457 db_finalize(&q);
458 }else{
459 int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
460 g.argv[3]);
461 if( tagid>0 ){
462 blob_appendf(&sql,
463 "%s"
464 " AND event.type GLOB '%q'"
465 " AND blob.rid IN ("
466 " SELECT rid FROM tagxref"
467 " WHERE tagtype>0 AND tagid=%d"
468 ")"
469 " ORDER BY event.mtime DESC",
470 timeline_query_for_tty(), zType, tagid
471 );
472 db_prepare(&q, "%s", blob_str(&sql));
473 blob_reset(&sql);
474 print_timeline(&q, nFindLimit, 79, 0);
475 db_finalize(&q);
476 }
477 }
478
--- src/tag.c
+++ src/tag.c
@@ -213,11 +213,12 @@
213 rid
214 );
215 }
216 }
217 if( zCol ){
218 db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
219 zCol, zValue, rid);
220 if( tagid==TAG_COMMENT ){
221 char *zCopy = mprintf("%s", zValue);
222 wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
223 free(zCopy);
224 }
@@ -437,41 +438,41 @@
438 if( zType==0 || zType[0]==0 ) zType = "*";
439 if( g.argc!=4 ){
440 usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
441 }
442 if( fRaw ){
443 blob_append_sql(&sql,
444 "SELECT blob.uuid FROM tagxref, blob"
445 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
446 " AND tagxref.tagtype>0"
447 " AND blob.rid=tagxref.rid",
448 g.argv[3]
449 );
450 if( nFindLimit>0 ){
451 blob_append_sql(&sql, " LIMIT %d", nFindLimit);
452 }
453 db_prepare(&q, "%s", blob_sql_text(&sql));
454 blob_reset(&sql);
455 while( db_step(&q)==SQLITE_ROW ){
456 fossil_print("%s\n", db_column_text(&q, 0));
457 }
458 db_finalize(&q);
459 }else{
460 int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
461 g.argv[3]);
462 if( tagid>0 ){
463 blob_append_sql(&sql,
464 "%s"
465 " AND event.type GLOB '%q'"
466 " AND blob.rid IN ("
467 " SELECT rid FROM tagxref"
468 " WHERE tagtype>0 AND tagid=%d"
469 ")"
470 " ORDER BY event.mtime DESC",
471 timeline_query_for_tty(), zType, tagid
472 );
473 db_prepare(&q, "%s", blob_sql_text(&sql));
474 blob_reset(&sql);
475 print_timeline(&q, nFindLimit, 79, 0);
476 db_finalize(&q);
477 }
478 }
479
+116 -83
--- src/timeline.c
+++ src/timeline.c
@@ -393,14 +393,14 @@
393393
}else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
394394
Blob truncated;
395395
blob_zero(&truncated);
396396
blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
397397
blob_append(&truncated, "...", 3);
398
- @ <span class="timelineComment">%w(blob_str(&truncated))</span>
398
+ @ <span class="timelineComment">%W(blob_str(&truncated))</span>
399399
blob_reset(&truncated);
400400
}else{
401
- @ <span class="timelineComment">%w(blob_str(&comment))</span>
401
+ @ <span class="timelineComment">%W(blob_str(&comment))</span>
402402
}
403403
blob_reset(&comment);
404404
405405
/* Generate the "user: USERNAME" at the end of the comment, together
406406
** with a hyperlink to another timeline for that user.
@@ -860,11 +860,11 @@
860860
@ tagid INTEGER,
861861
@ short TEXT,
862862
@ sortby REAL
863863
@ )
864864
;
865
- db_multi_exec(zSql);
865
+ db_multi_exec("%s", zSql/*safe-for-%s*/);
866866
}
867867
868868
/*
869869
** Return a pointer to a constant string that forms the basis
870870
** for a timeline query for the WWW interface.
@@ -889,11 +889,11 @@
889889
@ event.mtime AS mtime
890890
@ FROM event CROSS JOIN blob
891891
@ WHERE blob.rid=event.objid
892892
;
893893
if( zBase==0 ){
894
- zBase = mprintf(zBaseSql, timeline_utc());
894
+ zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
895895
}
896896
return zBase;
897897
}
898898
899899
/*
@@ -965,11 +965,11 @@
965965
Stmt q;
966966
Blob out;
967967
const char *zSep = "";
968968
db_prepare(&q,
969969
"SELECT DISTINCT filename.name FROM mlink, filename"
970
- " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')"
970
+ " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)"
971971
" AND filename.fnid=mlink.fnid",
972972
zUuid
973973
);
974974
blob_zero(&out);
975975
while( db_step(&q)==SQLITE_ROW ){
@@ -1129,13 +1129,15 @@
11291129
if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
11301130
tmFlags |= TIMELINE_FCHANGES;
11311131
url_add_parameter(&url, "v", 0);
11321132
}
11331133
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1134
- blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref"
1135
- " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1136
- TAG_HIDDEN);
1134
+ blob_append_sql(&sql,
1135
+ " AND NOT EXISTS(SELECT 1 FROM tagxref"
1136
+ " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1137
+ TAG_HIDDEN
1138
+ );
11371139
}
11381140
if( !useDividers ) url_add_parameter(&url, "nd", 0);
11391141
if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
11401142
/* If from= and to= are present, display all nodes on a path connecting
11411143
** the two */
@@ -1154,21 +1156,21 @@
11541156
zFrom = P("me");
11551157
zTo = P("you");
11561158
}
11571159
blob_append(&sql, " AND event.objid IN (0", -1);
11581160
while( p ){
1159
- blob_appendf(&sql, ",%d", p->rid);
1161
+ blob_append_sql(&sql, ",%d", p->rid);
11601162
p = p->u.pTo;
11611163
}
11621164
blob_append(&sql, ")", -1);
11631165
path_reset();
11641166
blob_append(&desc, "All nodes on the path from ", -1);
11651167
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
11661168
blob_append(&desc, " to ", -1);
11671169
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
11681170
tmFlags |= TIMELINE_DISJOINT;
1169
- db_multi_exec("%s", blob_str(&sql));
1171
+ db_multi_exec("%s", blob_sql_text(&sql));
11701172
}else if( (p_rid || d_rid) && g.perm.Read ){
11711173
/* If p= or d= is present, ignore all other parameters other than n= */
11721174
char *zUuid;
11731175
int np, nd;
11741176
@@ -1179,16 +1181,16 @@
11791181
db_multi_exec(
11801182
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
11811183
);
11821184
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
11831185
p_rid ? p_rid : d_rid);
1184
- blob_appendf(&sql, " AND event.objid IN ok");
1186
+ blob_append_sql(&sql, " AND event.objid IN ok");
11851187
nd = 0;
11861188
if( d_rid ){
11871189
compute_descendants(d_rid, nEntry+1);
11881190
nd = db_int(0, "SELECT count(*)-1 FROM ok");
1189
- if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
1191
+ if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
11901192
if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
11911193
if( useDividers ) timeline_add_dividers(0, d_rid);
11921194
db_multi_exec("DELETE FROM ok");
11931195
}
11941196
if( p_rid ){
@@ -1195,11 +1197,11 @@
11951197
compute_ancestors(p_rid, nEntry+1, 0);
11961198
np = db_int(0, "SELECT count(*)-1 FROM ok");
11971199
if( np>0 ){
11981200
if( nd>0 ) blob_appendf(&desc, " and ");
11991201
blob_appendf(&desc, "%d ancestors", np);
1200
- db_multi_exec("%s", blob_str(&sql));
1202
+ db_multi_exec("%s", blob_sql_text(&sql));
12011203
}
12021204
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
12031205
}
12041206
blob_appendf(&desc, " of %z[%S]</a>",
12051207
href("%R/info/%s", zUuid), zUuid);
@@ -1235,12 +1237,12 @@
12351237
"INSERT INTO ok VALUES(%d);"
12361238
"INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
12371239
"INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
12381240
f_rid, f_rid, f_rid
12391241
);
1240
- blob_appendf(&sql, " AND event.objid IN ok");
1241
- db_multi_exec("%s", blob_str(&sql));
1242
+ blob_append_sql(&sql, " AND event.objid IN ok");
1243
+ db_multi_exec("%s", blob_sql_text(&sql));
12421244
if( useDividers ) timeline_add_dividers(0, f_rid);
12431245
blob_appendf(&desc, "Parents and children of check-in ");
12441246
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
12451247
blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
12461248
tmFlags |= TIMELINE_DISJOINT;
@@ -1257,25 +1259,25 @@
12571259
/* Otherwise, a timeline based on a span of time */
12581260
int n;
12591261
const char *zEType = "timeline item";
12601262
char *zDate;
12611263
if( zUses ){
1262
- blob_appendf(&sql, " AND event.objid IN usesfile ");
1264
+ blob_append_sql(&sql, " AND event.objid IN usesfile ");
12631265
}
12641266
if( renameOnly ){
1265
- blob_appendf(&sql, " AND event.objid IN rnfile ");
1267
+ blob_append_sql(&sql, " AND event.objid IN rnfile ");
12661268
}
12671269
if( zYearMonth ){
1268
- blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1270
+ blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
12691271
zYearMonth);
12701272
}
12711273
else if( zYearWeek ){
1272
- blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1274
+ blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
12731275
zYearWeek);
12741276
}
12751277
if( tagid>0 ){
1276
- blob_appendf(&sql,
1278
+ blob_append_sql(&sql,
12771279
"AND (EXISTS(SELECT 1 FROM tagxref"
12781280
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
12791281
12801282
if( zBrName ){
12811283
url_add_parameter(&url, "r", zBrName);
@@ -1283,40 +1285,42 @@
12831285
** are not part of the branch which are parents or children of the
12841286
** branch to be included in the report. This related check-ins are
12851287
** useful in helping to visualize what has happened on a quiescent
12861288
** branch that is infrequently merged with a much more activate branch.
12871289
*/
1288
- blob_appendf(&sql,
1290
+ blob_append_sql(&sql,
12891291
" OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
12901292
" WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
12911293
tagid
12921294
);
12931295
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1294
- blob_appendf(&sql,
1296
+ blob_append_sql(&sql,
12951297
" AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
12961298
" WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
12971299
TAG_HIDDEN
12981300
);
12991301
}
13001302
if( P("mionly")==0 ){
1301
- blob_appendf(&sql,
1303
+ blob_append_sql(&sql,
13021304
" OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
13031305
" WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
13041306
tagid
13051307
);
13061308
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1307
- blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1308
- " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1309
- TAG_HIDDEN);
1309
+ blob_append_sql(&sql,
1310
+ " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1311
+ " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1312
+ TAG_HIDDEN
1313
+ );
13101314
}
13111315
}else{
13121316
url_add_parameter(&url, "mionly", "1");
13131317
}
13141318
}else{
13151319
url_add_parameter(&url, "t", zTagName);
13161320
}
1317
- blob_appendf(&sql, ")");
1321
+ blob_append_sql(&sql, ")");
13181322
}
13191323
if( (zType[0]=='w' && !g.perm.RdWiki)
13201324
|| (zType[0]=='t' && !g.perm.RdTkt)
13211325
|| (zType[0]=='e' && !g.perm.RdWiki)
13221326
|| (zType[0]=='c' && !g.perm.Read)
@@ -1325,27 +1329,27 @@
13251329
zType = "all";
13261330
}
13271331
if( zType[0]=='a' ){
13281332
if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
13291333
char cSep = '(';
1330
- blob_appendf(&sql, " AND event.type IN ");
1334
+ blob_append_sql(&sql, " AND event.type IN ");
13311335
if( g.perm.Read ){
1332
- blob_appendf(&sql, "%c'ci','g'", cSep);
1336
+ blob_append_sql(&sql, "%c'ci','g'", cSep);
13331337
cSep = ',';
13341338
}
13351339
if( g.perm.RdWiki ){
1336
- blob_appendf(&sql, "%c'w','e'", cSep);
1340
+ blob_append_sql(&sql, "%c'w','e'", cSep);
13371341
cSep = ',';
13381342
}
13391343
if( g.perm.RdTkt ){
1340
- blob_appendf(&sql, "%c't'", cSep);
1344
+ blob_append_sql(&sql, "%c't'", cSep);
13411345
cSep = ',';
13421346
}
1343
- blob_appendf(&sql, ")");
1347
+ blob_append_sql(&sql, ")");
13441348
}
13451349
}else{ /* zType!="all" */
1346
- blob_appendf(&sql, " AND event.type=%Q", zType);
1350
+ blob_append_sql(&sql, " AND event.type=%Q", zType);
13471351
url_add_parameter(&url, "y", zType);
13481352
if( zType[0]=='c' ){
13491353
zEType = "checkin";
13501354
}else if( zType[0]=='w' ){
13511355
zEType = "wiki edit";
@@ -1356,64 +1360,64 @@
13561360
}else if( zType[0]=='g' ){
13571361
zEType = "tag";
13581362
}
13591363
}
13601364
if( zUser ){
1361
- blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1365
+ blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
13621366
zUser, zUser);
13631367
url_add_parameter(&url, "u", zUser);
13641368
zThisUser = zUser;
13651369
}
13661370
if( zSearch ){
1367
- blob_appendf(&sql,
1371
+ blob_append_sql(&sql,
13681372
" AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
13691373
zSearch, zSearch);
13701374
url_add_parameter(&url, "s", zSearch);
13711375
}
13721376
rBefore = symbolic_name_to_mtime(zBefore);
13731377
rAfter = symbolic_name_to_mtime(zAfter);
13741378
rCirca = symbolic_name_to_mtime(zCirca);
13751379
if( rAfter>0.0 ){
13761380
if( rBefore>0.0 ){
1377
- blob_appendf(&sql,
1381
+ blob_append_sql(&sql,
13781382
" AND event.mtime>=%.17g AND event.mtime<=%.17g"
13791383
" ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
13801384
url_add_parameter(&url, "a", zAfter);
13811385
url_add_parameter(&url, "b", zBefore);
13821386
nEntry = 1000000;
13831387
}else{
1384
- blob_appendf(&sql,
1388
+ blob_append_sql(&sql,
13851389
" AND event.mtime>=%.17g ORDER BY event.mtime ASC",
13861390
rAfter-ONE_SECOND);
13871391
url_add_parameter(&url, "a", zAfter);
13881392
}
13891393
}else if( rBefore>0.0 ){
1390
- blob_appendf(&sql,
1394
+ blob_append_sql(&sql,
13911395
" AND event.mtime<=%.17g ORDER BY event.mtime DESC",
13921396
rBefore+ONE_SECOND);
13931397
url_add_parameter(&url, "b", zBefore);
13941398
}else if( rCirca>0.0 ){
13951399
Blob sql2;
1396
- blob_init(&sql2, blob_str(&sql), -1);
1397
- blob_appendf(&sql2,
1400
+ blob_init(&sql2, blob_sql_text(&sql), -1);
1401
+ blob_append_sql(&sql2,
13981402
" AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
13991403
rCirca, (nEntry+1)/2
14001404
);
1401
- db_multi_exec("%s", blob_str(&sql2));
1405
+ db_multi_exec("%s", blob_sql_text(&sql2));
14021406
blob_reset(&sql2);
1403
- blob_appendf(&sql,
1407
+ blob_append_sql(&sql,
14041408
" AND event.mtime>=%f ORDER BY event.mtime ASC",
14051409
rCirca
14061410
);
14071411
nEntry -= (nEntry+1)/2;
14081412
if( useDividers ) timeline_add_dividers(rCirca, 0);
14091413
url_add_parameter(&url, "c", zCirca);
14101414
}else{
1411
- blob_appendf(&sql, " ORDER BY event.mtime DESC");
1415
+ blob_append_sql(&sql, " ORDER BY event.mtime DESC");
14121416
}
1413
- blob_appendf(&sql, " LIMIT %d", nEntry);
1414
- db_multi_exec("%s", blob_str(&sql));
1417
+ blob_append_sql(&sql, " LIMIT %d", nEntry);
1418
+ db_multi_exec("%s", blob_sql_text(&sql));
14151419
14161420
n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
14171421
if( zYearMonth ){
14181422
blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
14191423
}else if( zYearWeek ){
@@ -1506,11 +1510,11 @@
15061510
}
15071511
}
15081512
}
15091513
}
15101514
if( P("showsql") ){
1511
- @ <blockquote>%h(blob_str(&sql))</blockquote>
1515
+ @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
15121516
}
15131517
blob_zero(&sql);
15141518
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
15151519
@ <h2>%b(&desc)</h2>
15161520
blob_reset(&desc);
@@ -1655,11 +1659,10 @@
16551659
/*
16561660
** Return a pointer to a static string that forms the basis for
16571661
** a timeline query for display on a TTY.
16581662
*/
16591663
const char *timeline_query_for_tty(void){
1660
- static const char *zBase = 0;
16611664
static const char zBaseSql[] =
16621665
@ SELECT
16631666
@ blob.rid AS rid,
16641667
@ uuid,
16651668
@ datetime(event.mtime%s) AS mDateTime,
@@ -1675,20 +1678,17 @@
16751678
@ AS primPlinkCount,
16761679
@ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
16771680
@ event.mtime AS mtime,
16781681
@ tagxref.value AS branch
16791682
@ FROM tag CROSS JOIN event CROSS JOIN blob
1680
- @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
1683
+ @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
16811684
@ AND tagxref.tagtype>0
16821685
@ AND tagxref.rid=blob.rid
16831686
@ WHERE blob.rid=event.objid
16841687
@ AND tag.tagname='branch'
16851688
;
1686
- if( zBase==0 ){
1687
- zBase = mprintf(zBaseSql, timeline_utc());
1688
- }
1689
- return zBase;
1689
+ return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
16901690
}
16911691
16921692
/*
16931693
** Return true if the input string is a date in the ISO 8601 format:
16941694
** YYYY-MM-DD.
@@ -1702,11 +1702,11 @@
17021702
}
17031703
17041704
/*
17051705
** COMMAND: timeline
17061706
**
1707
-** Usage: %fossil timeline ?WHEN? ?BASELINE|DATETIME? ?OPTIONS?
1707
+** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
17081708
**
17091709
** Print a summary of activity going backwards in date and time
17101710
** specified or from the current date and time if no arguments
17111711
** are given. The WHEN argument can be any unique abbreviation
17121712
** of one of these keywords:
@@ -1722,10 +1722,12 @@
17221722
** for the current version or "now" for the current time.
17231723
**
17241724
** Options:
17251725
** -n|--limit N Output the first N entries (default 20 lines).
17261726
** N=0 means no limit.
1727
+** -p|--path PATH Output items affecting PATH only.
1728
+** PATH can be a file or a sub directory.
17271729
** --offset P skip P changes
17281730
** -t|--type TYPE Output items from the given types only, such as:
17291731
** ci = file commits only
17301732
** e = events only
17311733
** t = tickets only
@@ -1752,19 +1754,23 @@
17521754
int objid = 0;
17531755
Blob uuid;
17541756
int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
17551757
int verboseFlag = 0 ;
17561758
int iOffset;
1759
+ const char *zFilePattern = 0;
1760
+ Blob treeName;
17571761
17581762
verboseFlag = find_option("verbose","v", 0)!=0;
17591763
if( !verboseFlag){
17601764
verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
17611765
}
17621766
db_find_and_open_repository(0, 0);
17631767
zLimit = find_option("limit","n",1);
17641768
zWidth = find_option("width","W",1);
17651769
zType = find_option("type","t",1);
1770
+ zFilePattern = find_option("path","p",1);
1771
+
17661772
if( !zLimit ){
17671773
zLimit = find_option("count",0,1);
17681774
}
17691775
if( zLimit ){
17701776
n = atoi(zLimit);
@@ -1798,12 +1804,12 @@
17981804
}else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
17991805
mode = 4;
18001806
}else if( strncmp(g.argv[2],"parents",k)==0 ){
18011807
mode = 4;
18021808
}else if(!zType && !zLimit){
1803
- usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
1804
- "?-W|--width WIDTH?");
1809
+ usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
1810
+ "?-W|--width WIDTH? ?-p|--path PATH");
18051811
}
18061812
if( '-' != *g.argv[3] ){
18071813
zOrigin = g.argv[3];
18081814
}else{
18091815
zOrigin = "now";
@@ -1838,37 +1844,72 @@
18381844
if( mode==0 ){
18391845
if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
18401846
}
18411847
zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
18421848
}
1849
+
1850
+ if( zFilePattern ){
1851
+ if( zType==0 ){
1852
+ /* When zFilePattern is specified and type is not specified, only show
1853
+ * file checkins */
1854
+ zType="ci";
1855
+ }
1856
+ file_tree_name(zFilePattern, &treeName, 1);
1857
+ if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
1858
+ /* When zTreeName refers to g.zLocalRoot, it's like not specifying
1859
+ * zFilePattern. */
1860
+ zFilePattern = 0;
1861
+ }
1862
+ }
1863
+
18431864
if( mode==0 ) mode = 1;
18441865
blob_zero(&sql);
18451866
blob_append(&sql, timeline_query_for_tty(), -1);
1846
- blob_appendf(&sql, " AND event.mtime %s %s",
1867
+ blob_append_sql(&sql, " AND event.mtime %s %s",
18471868
(mode==1 || mode==4) ? "<=" : ">=",
1848
- zDate
1869
+ zDate /*safe-for-%s*/
18491870
);
18501871
18511872
if( mode==3 || mode==4 ){
18521873
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
18531874
if( mode==3 ){
18541875
compute_descendants(objid, n);
18551876
}else{
18561877
compute_ancestors(objid, n, 0);
18571878
}
1858
- blob_appendf(&sql, " AND blob.rid IN ok");
1879
+ blob_append_sql(&sql, "\n AND blob.rid IN ok");
18591880
}
18601881
if( zType && (zType[0]!='a') ){
1861
- blob_appendf(&sql, " AND event.type=%Q ", zType);
1882
+ blob_append_sql(&sql, "\n AND event.type=%Q ", zType);
1883
+ }
1884
+ if( zFilePattern ){
1885
+ blob_append(&sql,
1886
+ "\n AND EXISTS(SELECT 1 FROM mlink\n"
1887
+ " WHERE mlink.mid=event.objid\n"
1888
+ " AND mlink.fnid IN ", -1);
1889
+ if( filenames_are_case_sensitive() ){
1890
+ blob_append_sql(&sql,
1891
+ "(SELECT fnid FROM filename"
1892
+ " WHERE name=%Q"
1893
+ " OR name GLOB '%q/*')",
1894
+ blob_str(&treeName), blob_str(&treeName));
1895
+ }else{
1896
+ blob_append_sql(&sql,
1897
+ "(SELECT fnid FROM filename"
1898
+ " WHERE name=%Q COLLATE nocase"
1899
+ " OR lower(name) GLOB lower('%q/*'))",
1900
+ blob_str(&treeName), blob_str(&treeName));
1901
+ }
1902
+ blob_append(&sql, ")", -1);
18621903
}
1863
- blob_appendf(&sql, " ORDER BY event.mtime DESC");
1904
+ blob_append_sql(&sql, "\nORDER BY event.mtime DESC");
18641905
if( iOffset>0 ){
18651906
/* Don't handle LIMIT here, otherwise print_timeline()
18661907
* will not determine the end-marker correctly! */
1867
- blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset);
1908
+ blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
18681909
}
1869
- db_prepare(&q, blob_str(&sql));
1910
+ db_prepare(&q, "%s", blob_sql_text(&sql));
18701911
blob_reset(&sql);
18711912
print_timeline(&q, n, width, verboseFlag);
18721913
db_finalize(&q);
18731914
}
18741915
@@ -2178,24 +2219,24 @@
21782219
stats_report_init_view();
21792220
stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
21802221
blob_appendf(&header, "Timeline Events (%s) by year%s",
21812222
stats_report_label_for_type(),
21822223
(includeMonth ? "/month" : ""));
2183
- blob_appendf(&sql,
2224
+ blob_append_sql(&sql,
21842225
"SELECT substr(date(mtime),1,%d) AS timeframe, "
21852226
"count(*) AS eventCount "
21862227
"FROM v_reports ",
21872228
includeMonth ? 7 : 4);
21882229
if(zUserName&&*zUserName){
2189
- blob_appendf(&sql, " WHERE user=%Q ", zUserName);
2230
+ blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
21902231
blob_appendf(&header," for user %q", zUserName);
21912232
}
21922233
blob_append(&sql,
21932234
" GROUP BY timeframe"
21942235
" ORDER BY timeframe DESC",
21952236
-1);
2196
- db_prepare(&query, blob_str(&sql));
2237
+ db_prepare(&query, "%s", blob_sql_text(&sql));
21972238
blob_reset(&sql);
21982239
@ <h1>%b(&header)</h1>
21992240
@ <table class='statistics-report-table-events' border='0' cellpadding='2'
22002241
@ cellspacing='0' id='statsTable'>
22012242
@ <thead>
@@ -2321,23 +2362,19 @@
23212362
Stmt query = empty_Stmt;
23222363
int nRowNumber = 0; /* current TR number */
23232364
int nEventTotal = 0; /* Total event count */
23242365
int rowClass = 0; /* counter for alternating
23252366
row colors */
2326
- Blob sql = empty_blob; /* SQL */
23272367
int nMaxEvents = 1; /* max number of events for
23282368
all rows. */
23292369
stats_report_init_view();
23302370
stats_report_event_types_menu("byuser", NULL);
2331
- blob_append(&sql,
2371
+ db_prepare(&query,
23322372
"SELECT user, "
23332373
"COUNT(*) AS eventCount "
23342374
"FROM v_reports "
2335
- "GROUP BY user ORDER BY eventCount DESC",
2336
- -1);
2337
- db_prepare(&query, blob_str(&sql));
2338
- blob_reset(&sql);
2375
+ "GROUP BY user ORDER BY eventCount DESC");
23392376
@ <h1>Timeline Events
23402377
@ (%s(stats_report_label_for_type())) by User</h1>
23412378
@ <table class='statistics-report-table-events' border='0'
23422379
@ cellpadding='2' cellspacing='0' id='statsTable'>
23432380
@ <thead><tr>
@@ -2388,28 +2425,24 @@
23882425
Stmt query = empty_Stmt;
23892426
int nRowNumber = 0; /* current TR number */
23902427
int nEventTotal = 0; /* Total event count */
23912428
int rowClass = 0; /* counter for alternating
23922429
row colors */
2393
- Blob sql = empty_blob; /* SQL */
23942430
int nMaxEvents = 1; /* max number of events for
23952431
all rows. */
23962432
static const char *const daysOfWeek[] = {
23972433
"Monday", "Tuesday", "Wednesday", "Thursday",
23982434
"Friday", "Saturday", "Sunday"
23992435
};
24002436
24012437
stats_report_init_view();
24022438
stats_report_event_types_menu("byweekday", NULL);
2403
- blob_append(&sql,
2439
+ db_prepare(&query,
24042440
"SELECT cast(mtime %% 7 AS INTEGER) dow, "
24052441
"COUNT(*) AS eventCount "
24062442
"FROM v_reports "
2407
- "GROUP BY dow ORDER BY dow",
2408
- -1);
2409
- db_prepare(&query, blob_str(&sql));
2410
- blob_reset(&sql);
2443
+ "GROUP BY dow ORDER BY dow");
24112444
@ <h1>Timeline Events
24122445
@ (%s(stats_report_label_for_type())) by Day of the Week</h1>
24132446
@ <table class='statistics-report-table-events' border='0'
24142447
@ cellpadding='2' cellspacing='0' id='statsTable'>
24152448
@ <thead><tr>
@@ -2477,14 +2510,14 @@
24772510
}
24782511
blob_append(&sql,
24792512
"SELECT DISTINCT substr(date(mtime),1,4) AS y "
24802513
"FROM v_reports WHERE 1 ", -1);
24812514
if(zUserName&&*zUserName){
2482
- blob_appendf(&sql,"AND user=%Q ", zUserName);
2515
+ blob_append_sql(&sql,"AND user=%Q ", zUserName);
24832516
}
24842517
blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2485
- db_prepare(&qYears, blob_str(&sql));
2518
+ db_prepare(&qYears, "%s", blob_sql_text(&sql));
24862519
blob_reset(&sql);
24872520
cgi_printf("Select year: ");
24882521
while( SQLITE_ROW == db_step(&qYears) ){
24892522
const char *zT = db_column_text(&qYears, 0);
24902523
if( i++ ){
@@ -2510,22 +2543,22 @@
25102543
int total = 0;
25112544
Blob header = empty_blob;
25122545
blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
25132546
"of %h", stats_report_label_for_type(),
25142547
zYear);
2515
- blob_appendf(&sql,
2548
+ blob_append_sql(&sql,
25162549
"SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
25172550
"count(*) AS n "
25182551
"FROM v_reports "
25192552
"WHERE %Q=substr(date(mtime),1,4) "
25202553
"AND mtime < current_timestamp ",
25212554
zYear);
25222555
if(zUserName&&*zUserName){
2523
- blob_appendf(&sql, " AND user=%Q ", zUserName);
2556
+ blob_append_sql(&sql, " AND user=%Q ", zUserName);
25242557
blob_appendf(&header," for user %h", zUserName);
25252558
}
2526
- blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
2559
+ blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
25272560
cgi_printf("<h1>%h</h1>", blob_str(&header));
25282561
blob_reset(&header);
25292562
cgi_printf("<table class='statistics-report-table-events' "
25302563
"border='0' cellpadding='2' width='100%%' "
25312564
"cellspacing='0' id='statsTable'>");
@@ -2533,11 +2566,11 @@
25332566
"<th>Week</th>"
25342567
"<th>Events</th>"
25352568
"<th width='90%%'><!-- relative commits graph --></th>"
25362569
"</tr></thead>"
25372570
"<tbody>");
2538
- db_prepare(&stWeek, blob_str(&sql));
2571
+ db_prepare(&stWeek, "%s", blob_sql_text(&sql));
25392572
blob_reset(&sql);
25402573
while( SQLITE_ROW == db_step(&stWeek) ){
25412574
const int nCount = db_column_int(&stWeek, 1);
25422575
if(nCount>nMaxEvents){
25432576
nMaxEvents = nCount;
25442577
--- src/timeline.c
+++ src/timeline.c
@@ -393,14 +393,14 @@
393 }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
394 Blob truncated;
395 blob_zero(&truncated);
396 blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
397 blob_append(&truncated, "...", 3);
398 @ <span class="timelineComment">%w(blob_str(&truncated))</span>
399 blob_reset(&truncated);
400 }else{
401 @ <span class="timelineComment">%w(blob_str(&comment))</span>
402 }
403 blob_reset(&comment);
404
405 /* Generate the "user: USERNAME" at the end of the comment, together
406 ** with a hyperlink to another timeline for that user.
@@ -860,11 +860,11 @@
860 @ tagid INTEGER,
861 @ short TEXT,
862 @ sortby REAL
863 @ )
864 ;
865 db_multi_exec(zSql);
866 }
867
868 /*
869 ** Return a pointer to a constant string that forms the basis
870 ** for a timeline query for the WWW interface.
@@ -889,11 +889,11 @@
889 @ event.mtime AS mtime
890 @ FROM event CROSS JOIN blob
891 @ WHERE blob.rid=event.objid
892 ;
893 if( zBase==0 ){
894 zBase = mprintf(zBaseSql, timeline_utc());
895 }
896 return zBase;
897 }
898
899 /*
@@ -965,11 +965,11 @@
965 Stmt q;
966 Blob out;
967 const char *zSep = "";
968 db_prepare(&q,
969 "SELECT DISTINCT filename.name FROM mlink, filename"
970 " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')"
971 " AND filename.fnid=mlink.fnid",
972 zUuid
973 );
974 blob_zero(&out);
975 while( db_step(&q)==SQLITE_ROW ){
@@ -1129,13 +1129,15 @@
1129 if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
1130 tmFlags |= TIMELINE_FCHANGES;
1131 url_add_parameter(&url, "v", 0);
1132 }
1133 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1134 blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref"
1135 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1136 TAG_HIDDEN);
 
 
1137 }
1138 if( !useDividers ) url_add_parameter(&url, "nd", 0);
1139 if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
1140 /* If from= and to= are present, display all nodes on a path connecting
1141 ** the two */
@@ -1154,21 +1156,21 @@
1154 zFrom = P("me");
1155 zTo = P("you");
1156 }
1157 blob_append(&sql, " AND event.objid IN (0", -1);
1158 while( p ){
1159 blob_appendf(&sql, ",%d", p->rid);
1160 p = p->u.pTo;
1161 }
1162 blob_append(&sql, ")", -1);
1163 path_reset();
1164 blob_append(&desc, "All nodes on the path from ", -1);
1165 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
1166 blob_append(&desc, " to ", -1);
1167 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
1168 tmFlags |= TIMELINE_DISJOINT;
1169 db_multi_exec("%s", blob_str(&sql));
1170 }else if( (p_rid || d_rid) && g.perm.Read ){
1171 /* If p= or d= is present, ignore all other parameters other than n= */
1172 char *zUuid;
1173 int np, nd;
1174
@@ -1179,16 +1181,16 @@
1179 db_multi_exec(
1180 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
1181 );
1182 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
1183 p_rid ? p_rid : d_rid);
1184 blob_appendf(&sql, " AND event.objid IN ok");
1185 nd = 0;
1186 if( d_rid ){
1187 compute_descendants(d_rid, nEntry+1);
1188 nd = db_int(0, "SELECT count(*)-1 FROM ok");
1189 if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
1190 if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
1191 if( useDividers ) timeline_add_dividers(0, d_rid);
1192 db_multi_exec("DELETE FROM ok");
1193 }
1194 if( p_rid ){
@@ -1195,11 +1197,11 @@
1195 compute_ancestors(p_rid, nEntry+1, 0);
1196 np = db_int(0, "SELECT count(*)-1 FROM ok");
1197 if( np>0 ){
1198 if( nd>0 ) blob_appendf(&desc, " and ");
1199 blob_appendf(&desc, "%d ancestors", np);
1200 db_multi_exec("%s", blob_str(&sql));
1201 }
1202 if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
1203 }
1204 blob_appendf(&desc, " of %z[%S]</a>",
1205 href("%R/info/%s", zUuid), zUuid);
@@ -1235,12 +1237,12 @@
1235 "INSERT INTO ok VALUES(%d);"
1236 "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
1237 "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
1238 f_rid, f_rid, f_rid
1239 );
1240 blob_appendf(&sql, " AND event.objid IN ok");
1241 db_multi_exec("%s", blob_str(&sql));
1242 if( useDividers ) timeline_add_dividers(0, f_rid);
1243 blob_appendf(&desc, "Parents and children of check-in ");
1244 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
1245 blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
1246 tmFlags |= TIMELINE_DISJOINT;
@@ -1257,25 +1259,25 @@
1257 /* Otherwise, a timeline based on a span of time */
1258 int n;
1259 const char *zEType = "timeline item";
1260 char *zDate;
1261 if( zUses ){
1262 blob_appendf(&sql, " AND event.objid IN usesfile ");
1263 }
1264 if( renameOnly ){
1265 blob_appendf(&sql, " AND event.objid IN rnfile ");
1266 }
1267 if( zYearMonth ){
1268 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1269 zYearMonth);
1270 }
1271 else if( zYearWeek ){
1272 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1273 zYearWeek);
1274 }
1275 if( tagid>0 ){
1276 blob_appendf(&sql,
1277 "AND (EXISTS(SELECT 1 FROM tagxref"
1278 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1279
1280 if( zBrName ){
1281 url_add_parameter(&url, "r", zBrName);
@@ -1283,40 +1285,42 @@
1283 ** are not part of the branch which are parents or children of the
1284 ** branch to be included in the report. This related check-ins are
1285 ** useful in helping to visualize what has happened on a quiescent
1286 ** branch that is infrequently merged with a much more activate branch.
1287 */
1288 blob_appendf(&sql,
1289 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
1290 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1291 tagid
1292 );
1293 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1294 blob_appendf(&sql,
1295 " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
1296 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1297 TAG_HIDDEN
1298 );
1299 }
1300 if( P("mionly")==0 ){
1301 blob_appendf(&sql,
1302 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
1303 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1304 tagid
1305 );
1306 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1307 blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1308 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1309 TAG_HIDDEN);
 
 
1310 }
1311 }else{
1312 url_add_parameter(&url, "mionly", "1");
1313 }
1314 }else{
1315 url_add_parameter(&url, "t", zTagName);
1316 }
1317 blob_appendf(&sql, ")");
1318 }
1319 if( (zType[0]=='w' && !g.perm.RdWiki)
1320 || (zType[0]=='t' && !g.perm.RdTkt)
1321 || (zType[0]=='e' && !g.perm.RdWiki)
1322 || (zType[0]=='c' && !g.perm.Read)
@@ -1325,27 +1329,27 @@
1325 zType = "all";
1326 }
1327 if( zType[0]=='a' ){
1328 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
1329 char cSep = '(';
1330 blob_appendf(&sql, " AND event.type IN ");
1331 if( g.perm.Read ){
1332 blob_appendf(&sql, "%c'ci','g'", cSep);
1333 cSep = ',';
1334 }
1335 if( g.perm.RdWiki ){
1336 blob_appendf(&sql, "%c'w','e'", cSep);
1337 cSep = ',';
1338 }
1339 if( g.perm.RdTkt ){
1340 blob_appendf(&sql, "%c't'", cSep);
1341 cSep = ',';
1342 }
1343 blob_appendf(&sql, ")");
1344 }
1345 }else{ /* zType!="all" */
1346 blob_appendf(&sql, " AND event.type=%Q", zType);
1347 url_add_parameter(&url, "y", zType);
1348 if( zType[0]=='c' ){
1349 zEType = "checkin";
1350 }else if( zType[0]=='w' ){
1351 zEType = "wiki edit";
@@ -1356,64 +1360,64 @@
1356 }else if( zType[0]=='g' ){
1357 zEType = "tag";
1358 }
1359 }
1360 if( zUser ){
1361 blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1362 zUser, zUser);
1363 url_add_parameter(&url, "u", zUser);
1364 zThisUser = zUser;
1365 }
1366 if( zSearch ){
1367 blob_appendf(&sql,
1368 " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
1369 zSearch, zSearch);
1370 url_add_parameter(&url, "s", zSearch);
1371 }
1372 rBefore = symbolic_name_to_mtime(zBefore);
1373 rAfter = symbolic_name_to_mtime(zAfter);
1374 rCirca = symbolic_name_to_mtime(zCirca);
1375 if( rAfter>0.0 ){
1376 if( rBefore>0.0 ){
1377 blob_appendf(&sql,
1378 " AND event.mtime>=%.17g AND event.mtime<=%.17g"
1379 " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
1380 url_add_parameter(&url, "a", zAfter);
1381 url_add_parameter(&url, "b", zBefore);
1382 nEntry = 1000000;
1383 }else{
1384 blob_appendf(&sql,
1385 " AND event.mtime>=%.17g ORDER BY event.mtime ASC",
1386 rAfter-ONE_SECOND);
1387 url_add_parameter(&url, "a", zAfter);
1388 }
1389 }else if( rBefore>0.0 ){
1390 blob_appendf(&sql,
1391 " AND event.mtime<=%.17g ORDER BY event.mtime DESC",
1392 rBefore+ONE_SECOND);
1393 url_add_parameter(&url, "b", zBefore);
1394 }else if( rCirca>0.0 ){
1395 Blob sql2;
1396 blob_init(&sql2, blob_str(&sql), -1);
1397 blob_appendf(&sql2,
1398 " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
1399 rCirca, (nEntry+1)/2
1400 );
1401 db_multi_exec("%s", blob_str(&sql2));
1402 blob_reset(&sql2);
1403 blob_appendf(&sql,
1404 " AND event.mtime>=%f ORDER BY event.mtime ASC",
1405 rCirca
1406 );
1407 nEntry -= (nEntry+1)/2;
1408 if( useDividers ) timeline_add_dividers(rCirca, 0);
1409 url_add_parameter(&url, "c", zCirca);
1410 }else{
1411 blob_appendf(&sql, " ORDER BY event.mtime DESC");
1412 }
1413 blob_appendf(&sql, " LIMIT %d", nEntry);
1414 db_multi_exec("%s", blob_str(&sql));
1415
1416 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1417 if( zYearMonth ){
1418 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1419 }else if( zYearWeek ){
@@ -1506,11 +1510,11 @@
1506 }
1507 }
1508 }
1509 }
1510 if( P("showsql") ){
1511 @ <blockquote>%h(blob_str(&sql))</blockquote>
1512 }
1513 blob_zero(&sql);
1514 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
1515 @ <h2>%b(&desc)</h2>
1516 blob_reset(&desc);
@@ -1655,11 +1659,10 @@
1655 /*
1656 ** Return a pointer to a static string that forms the basis for
1657 ** a timeline query for display on a TTY.
1658 */
1659 const char *timeline_query_for_tty(void){
1660 static const char *zBase = 0;
1661 static const char zBaseSql[] =
1662 @ SELECT
1663 @ blob.rid AS rid,
1664 @ uuid,
1665 @ datetime(event.mtime%s) AS mDateTime,
@@ -1675,20 +1678,17 @@
1675 @ AS primPlinkCount,
1676 @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1677 @ event.mtime AS mtime,
1678 @ tagxref.value AS branch
1679 @ FROM tag CROSS JOIN event CROSS JOIN blob
1680 @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
1681 @ AND tagxref.tagtype>0
1682 @ AND tagxref.rid=blob.rid
1683 @ WHERE blob.rid=event.objid
1684 @ AND tag.tagname='branch'
1685 ;
1686 if( zBase==0 ){
1687 zBase = mprintf(zBaseSql, timeline_utc());
1688 }
1689 return zBase;
1690 }
1691
1692 /*
1693 ** Return true if the input string is a date in the ISO 8601 format:
1694 ** YYYY-MM-DD.
@@ -1702,11 +1702,11 @@
1702 }
1703
1704 /*
1705 ** COMMAND: timeline
1706 **
1707 ** Usage: %fossil timeline ?WHEN? ?BASELINE|DATETIME? ?OPTIONS?
1708 **
1709 ** Print a summary of activity going backwards in date and time
1710 ** specified or from the current date and time if no arguments
1711 ** are given. The WHEN argument can be any unique abbreviation
1712 ** of one of these keywords:
@@ -1722,10 +1722,12 @@
1722 ** for the current version or "now" for the current time.
1723 **
1724 ** Options:
1725 ** -n|--limit N Output the first N entries (default 20 lines).
1726 ** N=0 means no limit.
 
 
1727 ** --offset P skip P changes
1728 ** -t|--type TYPE Output items from the given types only, such as:
1729 ** ci = file commits only
1730 ** e = events only
1731 ** t = tickets only
@@ -1752,19 +1754,23 @@
1752 int objid = 0;
1753 Blob uuid;
1754 int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
1755 int verboseFlag = 0 ;
1756 int iOffset;
 
 
1757
1758 verboseFlag = find_option("verbose","v", 0)!=0;
1759 if( !verboseFlag){
1760 verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
1761 }
1762 db_find_and_open_repository(0, 0);
1763 zLimit = find_option("limit","n",1);
1764 zWidth = find_option("width","W",1);
1765 zType = find_option("type","t",1);
 
 
1766 if( !zLimit ){
1767 zLimit = find_option("count",0,1);
1768 }
1769 if( zLimit ){
1770 n = atoi(zLimit);
@@ -1798,12 +1804,12 @@
1798 }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
1799 mode = 4;
1800 }else if( strncmp(g.argv[2],"parents",k)==0 ){
1801 mode = 4;
1802 }else if(!zType && !zLimit){
1803 usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
1804 "?-W|--width WIDTH?");
1805 }
1806 if( '-' != *g.argv[3] ){
1807 zOrigin = g.argv[3];
1808 }else{
1809 zOrigin = "now";
@@ -1838,37 +1844,72 @@
1838 if( mode==0 ){
1839 if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
1840 }
1841 zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
1842 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1843 if( mode==0 ) mode = 1;
1844 blob_zero(&sql);
1845 blob_append(&sql, timeline_query_for_tty(), -1);
1846 blob_appendf(&sql, " AND event.mtime %s %s",
1847 (mode==1 || mode==4) ? "<=" : ">=",
1848 zDate
1849 );
1850
1851 if( mode==3 || mode==4 ){
1852 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
1853 if( mode==3 ){
1854 compute_descendants(objid, n);
1855 }else{
1856 compute_ancestors(objid, n, 0);
1857 }
1858 blob_appendf(&sql, " AND blob.rid IN ok");
1859 }
1860 if( zType && (zType[0]!='a') ){
1861 blob_appendf(&sql, " AND event.type=%Q ", zType);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1862 }
1863 blob_appendf(&sql, " ORDER BY event.mtime DESC");
1864 if( iOffset>0 ){
1865 /* Don't handle LIMIT here, otherwise print_timeline()
1866 * will not determine the end-marker correctly! */
1867 blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset);
1868 }
1869 db_prepare(&q, blob_str(&sql));
1870 blob_reset(&sql);
1871 print_timeline(&q, n, width, verboseFlag);
1872 db_finalize(&q);
1873 }
1874
@@ -2178,24 +2219,24 @@
2178 stats_report_init_view();
2179 stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
2180 blob_appendf(&header, "Timeline Events (%s) by year%s",
2181 stats_report_label_for_type(),
2182 (includeMonth ? "/month" : ""));
2183 blob_appendf(&sql,
2184 "SELECT substr(date(mtime),1,%d) AS timeframe, "
2185 "count(*) AS eventCount "
2186 "FROM v_reports ",
2187 includeMonth ? 7 : 4);
2188 if(zUserName&&*zUserName){
2189 blob_appendf(&sql, " WHERE user=%Q ", zUserName);
2190 blob_appendf(&header," for user %q", zUserName);
2191 }
2192 blob_append(&sql,
2193 " GROUP BY timeframe"
2194 " ORDER BY timeframe DESC",
2195 -1);
2196 db_prepare(&query, blob_str(&sql));
2197 blob_reset(&sql);
2198 @ <h1>%b(&header)</h1>
2199 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
2200 @ cellspacing='0' id='statsTable'>
2201 @ <thead>
@@ -2321,23 +2362,19 @@
2321 Stmt query = empty_Stmt;
2322 int nRowNumber = 0; /* current TR number */
2323 int nEventTotal = 0; /* Total event count */
2324 int rowClass = 0; /* counter for alternating
2325 row colors */
2326 Blob sql = empty_blob; /* SQL */
2327 int nMaxEvents = 1; /* max number of events for
2328 all rows. */
2329 stats_report_init_view();
2330 stats_report_event_types_menu("byuser", NULL);
2331 blob_append(&sql,
2332 "SELECT user, "
2333 "COUNT(*) AS eventCount "
2334 "FROM v_reports "
2335 "GROUP BY user ORDER BY eventCount DESC",
2336 -1);
2337 db_prepare(&query, blob_str(&sql));
2338 blob_reset(&sql);
2339 @ <h1>Timeline Events
2340 @ (%s(stats_report_label_for_type())) by User</h1>
2341 @ <table class='statistics-report-table-events' border='0'
2342 @ cellpadding='2' cellspacing='0' id='statsTable'>
2343 @ <thead><tr>
@@ -2388,28 +2425,24 @@
2388 Stmt query = empty_Stmt;
2389 int nRowNumber = 0; /* current TR number */
2390 int nEventTotal = 0; /* Total event count */
2391 int rowClass = 0; /* counter for alternating
2392 row colors */
2393 Blob sql = empty_blob; /* SQL */
2394 int nMaxEvents = 1; /* max number of events for
2395 all rows. */
2396 static const char *const daysOfWeek[] = {
2397 "Monday", "Tuesday", "Wednesday", "Thursday",
2398 "Friday", "Saturday", "Sunday"
2399 };
2400
2401 stats_report_init_view();
2402 stats_report_event_types_menu("byweekday", NULL);
2403 blob_append(&sql,
2404 "SELECT cast(mtime %% 7 AS INTEGER) dow, "
2405 "COUNT(*) AS eventCount "
2406 "FROM v_reports "
2407 "GROUP BY dow ORDER BY dow",
2408 -1);
2409 db_prepare(&query, blob_str(&sql));
2410 blob_reset(&sql);
2411 @ <h1>Timeline Events
2412 @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
2413 @ <table class='statistics-report-table-events' border='0'
2414 @ cellpadding='2' cellspacing='0' id='statsTable'>
2415 @ <thead><tr>
@@ -2477,14 +2510,14 @@
2477 }
2478 blob_append(&sql,
2479 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2480 "FROM v_reports WHERE 1 ", -1);
2481 if(zUserName&&*zUserName){
2482 blob_appendf(&sql,"AND user=%Q ", zUserName);
2483 }
2484 blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2485 db_prepare(&qYears, blob_str(&sql));
2486 blob_reset(&sql);
2487 cgi_printf("Select year: ");
2488 while( SQLITE_ROW == db_step(&qYears) ){
2489 const char *zT = db_column_text(&qYears, 0);
2490 if( i++ ){
@@ -2510,22 +2543,22 @@
2510 int total = 0;
2511 Blob header = empty_blob;
2512 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2513 "of %h", stats_report_label_for_type(),
2514 zYear);
2515 blob_appendf(&sql,
2516 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2517 "count(*) AS n "
2518 "FROM v_reports "
2519 "WHERE %Q=substr(date(mtime),1,4) "
2520 "AND mtime < current_timestamp ",
2521 zYear);
2522 if(zUserName&&*zUserName){
2523 blob_appendf(&sql, " AND user=%Q ", zUserName);
2524 blob_appendf(&header," for user %h", zUserName);
2525 }
2526 blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
2527 cgi_printf("<h1>%h</h1>", blob_str(&header));
2528 blob_reset(&header);
2529 cgi_printf("<table class='statistics-report-table-events' "
2530 "border='0' cellpadding='2' width='100%%' "
2531 "cellspacing='0' id='statsTable'>");
@@ -2533,11 +2566,11 @@
2533 "<th>Week</th>"
2534 "<th>Events</th>"
2535 "<th width='90%%'><!-- relative commits graph --></th>"
2536 "</tr></thead>"
2537 "<tbody>");
2538 db_prepare(&stWeek, blob_str(&sql));
2539 blob_reset(&sql);
2540 while( SQLITE_ROW == db_step(&stWeek) ){
2541 const int nCount = db_column_int(&stWeek, 1);
2542 if(nCount>nMaxEvents){
2543 nMaxEvents = nCount;
2544
--- src/timeline.c
+++ src/timeline.c
@@ -393,14 +393,14 @@
393 }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
394 Blob truncated;
395 blob_zero(&truncated);
396 blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
397 blob_append(&truncated, "...", 3);
398 @ <span class="timelineComment">%W(blob_str(&truncated))</span>
399 blob_reset(&truncated);
400 }else{
401 @ <span class="timelineComment">%W(blob_str(&comment))</span>
402 }
403 blob_reset(&comment);
404
405 /* Generate the "user: USERNAME" at the end of the comment, together
406 ** with a hyperlink to another timeline for that user.
@@ -860,11 +860,11 @@
860 @ tagid INTEGER,
861 @ short TEXT,
862 @ sortby REAL
863 @ )
864 ;
865 db_multi_exec("%s", zSql/*safe-for-%s*/);
866 }
867
868 /*
869 ** Return a pointer to a constant string that forms the basis
870 ** for a timeline query for the WWW interface.
@@ -889,11 +889,11 @@
889 @ event.mtime AS mtime
890 @ FROM event CROSS JOIN blob
891 @ WHERE blob.rid=event.objid
892 ;
893 if( zBase==0 ){
894 zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
895 }
896 return zBase;
897 }
898
899 /*
@@ -965,11 +965,11 @@
965 Stmt q;
966 Blob out;
967 const char *zSep = "";
968 db_prepare(&q,
969 "SELECT DISTINCT filename.name FROM mlink, filename"
970 " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)"
971 " AND filename.fnid=mlink.fnid",
972 zUuid
973 );
974 blob_zero(&out);
975 while( db_step(&q)==SQLITE_ROW ){
@@ -1129,13 +1129,15 @@
1129 if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
1130 tmFlags |= TIMELINE_FCHANGES;
1131 url_add_parameter(&url, "v", 0);
1132 }
1133 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1134 blob_append_sql(&sql,
1135 " AND NOT EXISTS(SELECT 1 FROM tagxref"
1136 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1137 TAG_HIDDEN
1138 );
1139 }
1140 if( !useDividers ) url_add_parameter(&url, "nd", 0);
1141 if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
1142 /* If from= and to= are present, display all nodes on a path connecting
1143 ** the two */
@@ -1154,21 +1156,21 @@
1156 zFrom = P("me");
1157 zTo = P("you");
1158 }
1159 blob_append(&sql, " AND event.objid IN (0", -1);
1160 while( p ){
1161 blob_append_sql(&sql, ",%d", p->rid);
1162 p = p->u.pTo;
1163 }
1164 blob_append(&sql, ")", -1);
1165 path_reset();
1166 blob_append(&desc, "All nodes on the path from ", -1);
1167 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
1168 blob_append(&desc, " to ", -1);
1169 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
1170 tmFlags |= TIMELINE_DISJOINT;
1171 db_multi_exec("%s", blob_sql_text(&sql));
1172 }else if( (p_rid || d_rid) && g.perm.Read ){
1173 /* If p= or d= is present, ignore all other parameters other than n= */
1174 char *zUuid;
1175 int np, nd;
1176
@@ -1179,16 +1181,16 @@
1181 db_multi_exec(
1182 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
1183 );
1184 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
1185 p_rid ? p_rid : d_rid);
1186 blob_append_sql(&sql, " AND event.objid IN ok");
1187 nd = 0;
1188 if( d_rid ){
1189 compute_descendants(d_rid, nEntry+1);
1190 nd = db_int(0, "SELECT count(*)-1 FROM ok");
1191 if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
1192 if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
1193 if( useDividers ) timeline_add_dividers(0, d_rid);
1194 db_multi_exec("DELETE FROM ok");
1195 }
1196 if( p_rid ){
@@ -1195,11 +1197,11 @@
1197 compute_ancestors(p_rid, nEntry+1, 0);
1198 np = db_int(0, "SELECT count(*)-1 FROM ok");
1199 if( np>0 ){
1200 if( nd>0 ) blob_appendf(&desc, " and ");
1201 blob_appendf(&desc, "%d ancestors", np);
1202 db_multi_exec("%s", blob_sql_text(&sql));
1203 }
1204 if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
1205 }
1206 blob_appendf(&desc, " of %z[%S]</a>",
1207 href("%R/info/%s", zUuid), zUuid);
@@ -1235,12 +1237,12 @@
1237 "INSERT INTO ok VALUES(%d);"
1238 "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
1239 "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
1240 f_rid, f_rid, f_rid
1241 );
1242 blob_append_sql(&sql, " AND event.objid IN ok");
1243 db_multi_exec("%s", blob_sql_text(&sql));
1244 if( useDividers ) timeline_add_dividers(0, f_rid);
1245 blob_appendf(&desc, "Parents and children of check-in ");
1246 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
1247 blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
1248 tmFlags |= TIMELINE_DISJOINT;
@@ -1257,25 +1259,25 @@
1259 /* Otherwise, a timeline based on a span of time */
1260 int n;
1261 const char *zEType = "timeline item";
1262 char *zDate;
1263 if( zUses ){
1264 blob_append_sql(&sql, " AND event.objid IN usesfile ");
1265 }
1266 if( renameOnly ){
1267 blob_append_sql(&sql, " AND event.objid IN rnfile ");
1268 }
1269 if( zYearMonth ){
1270 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1271 zYearMonth);
1272 }
1273 else if( zYearWeek ){
1274 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1275 zYearWeek);
1276 }
1277 if( tagid>0 ){
1278 blob_append_sql(&sql,
1279 "AND (EXISTS(SELECT 1 FROM tagxref"
1280 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1281
1282 if( zBrName ){
1283 url_add_parameter(&url, "r", zBrName);
@@ -1283,40 +1285,42 @@
1285 ** are not part of the branch which are parents or children of the
1286 ** branch to be included in the report. This related check-ins are
1287 ** useful in helping to visualize what has happened on a quiescent
1288 ** branch that is infrequently merged with a much more activate branch.
1289 */
1290 blob_append_sql(&sql,
1291 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
1292 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1293 tagid
1294 );
1295 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1296 blob_append_sql(&sql,
1297 " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
1298 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1299 TAG_HIDDEN
1300 );
1301 }
1302 if( P("mionly")==0 ){
1303 blob_append_sql(&sql,
1304 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
1305 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1306 tagid
1307 );
1308 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1309 blob_append_sql(&sql,
1310 " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1311 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1312 TAG_HIDDEN
1313 );
1314 }
1315 }else{
1316 url_add_parameter(&url, "mionly", "1");
1317 }
1318 }else{
1319 url_add_parameter(&url, "t", zTagName);
1320 }
1321 blob_append_sql(&sql, ")");
1322 }
1323 if( (zType[0]=='w' && !g.perm.RdWiki)
1324 || (zType[0]=='t' && !g.perm.RdTkt)
1325 || (zType[0]=='e' && !g.perm.RdWiki)
1326 || (zType[0]=='c' && !g.perm.Read)
@@ -1325,27 +1329,27 @@
1329 zType = "all";
1330 }
1331 if( zType[0]=='a' ){
1332 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
1333 char cSep = '(';
1334 blob_append_sql(&sql, " AND event.type IN ");
1335 if( g.perm.Read ){
1336 blob_append_sql(&sql, "%c'ci','g'", cSep);
1337 cSep = ',';
1338 }
1339 if( g.perm.RdWiki ){
1340 blob_append_sql(&sql, "%c'w','e'", cSep);
1341 cSep = ',';
1342 }
1343 if( g.perm.RdTkt ){
1344 blob_append_sql(&sql, "%c't'", cSep);
1345 cSep = ',';
1346 }
1347 blob_append_sql(&sql, ")");
1348 }
1349 }else{ /* zType!="all" */
1350 blob_append_sql(&sql, " AND event.type=%Q", zType);
1351 url_add_parameter(&url, "y", zType);
1352 if( zType[0]=='c' ){
1353 zEType = "checkin";
1354 }else if( zType[0]=='w' ){
1355 zEType = "wiki edit";
@@ -1356,64 +1360,64 @@
1360 }else if( zType[0]=='g' ){
1361 zEType = "tag";
1362 }
1363 }
1364 if( zUser ){
1365 blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1366 zUser, zUser);
1367 url_add_parameter(&url, "u", zUser);
1368 zThisUser = zUser;
1369 }
1370 if( zSearch ){
1371 blob_append_sql(&sql,
1372 " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
1373 zSearch, zSearch);
1374 url_add_parameter(&url, "s", zSearch);
1375 }
1376 rBefore = symbolic_name_to_mtime(zBefore);
1377 rAfter = symbolic_name_to_mtime(zAfter);
1378 rCirca = symbolic_name_to_mtime(zCirca);
1379 if( rAfter>0.0 ){
1380 if( rBefore>0.0 ){
1381 blob_append_sql(&sql,
1382 " AND event.mtime>=%.17g AND event.mtime<=%.17g"
1383 " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
1384 url_add_parameter(&url, "a", zAfter);
1385 url_add_parameter(&url, "b", zBefore);
1386 nEntry = 1000000;
1387 }else{
1388 blob_append_sql(&sql,
1389 " AND event.mtime>=%.17g ORDER BY event.mtime ASC",
1390 rAfter-ONE_SECOND);
1391 url_add_parameter(&url, "a", zAfter);
1392 }
1393 }else if( rBefore>0.0 ){
1394 blob_append_sql(&sql,
1395 " AND event.mtime<=%.17g ORDER BY event.mtime DESC",
1396 rBefore+ONE_SECOND);
1397 url_add_parameter(&url, "b", zBefore);
1398 }else if( rCirca>0.0 ){
1399 Blob sql2;
1400 blob_init(&sql2, blob_sql_text(&sql), -1);
1401 blob_append_sql(&sql2,
1402 " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
1403 rCirca, (nEntry+1)/2
1404 );
1405 db_multi_exec("%s", blob_sql_text(&sql2));
1406 blob_reset(&sql2);
1407 blob_append_sql(&sql,
1408 " AND event.mtime>=%f ORDER BY event.mtime ASC",
1409 rCirca
1410 );
1411 nEntry -= (nEntry+1)/2;
1412 if( useDividers ) timeline_add_dividers(rCirca, 0);
1413 url_add_parameter(&url, "c", zCirca);
1414 }else{
1415 blob_append_sql(&sql, " ORDER BY event.mtime DESC");
1416 }
1417 blob_append_sql(&sql, " LIMIT %d", nEntry);
1418 db_multi_exec("%s", blob_sql_text(&sql));
1419
1420 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1421 if( zYearMonth ){
1422 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1423 }else if( zYearWeek ){
@@ -1506,11 +1510,11 @@
1510 }
1511 }
1512 }
1513 }
1514 if( P("showsql") ){
1515 @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
1516 }
1517 blob_zero(&sql);
1518 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
1519 @ <h2>%b(&desc)</h2>
1520 blob_reset(&desc);
@@ -1655,11 +1659,10 @@
1659 /*
1660 ** Return a pointer to a static string that forms the basis for
1661 ** a timeline query for display on a TTY.
1662 */
1663 const char *timeline_query_for_tty(void){
 
1664 static const char zBaseSql[] =
1665 @ SELECT
1666 @ blob.rid AS rid,
1667 @ uuid,
1668 @ datetime(event.mtime%s) AS mDateTime,
@@ -1675,20 +1678,17 @@
1678 @ AS primPlinkCount,
1679 @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1680 @ event.mtime AS mtime,
1681 @ tagxref.value AS branch
1682 @ FROM tag CROSS JOIN event CROSS JOIN blob
1683 @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
1684 @ AND tagxref.tagtype>0
1685 @ AND tagxref.rid=blob.rid
1686 @ WHERE blob.rid=event.objid
1687 @ AND tag.tagname='branch'
1688 ;
1689 return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
 
 
 
1690 }
1691
1692 /*
1693 ** Return true if the input string is a date in the ISO 8601 format:
1694 ** YYYY-MM-DD.
@@ -1702,11 +1702,11 @@
1702 }
1703
1704 /*
1705 ** COMMAND: timeline
1706 **
1707 ** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS?
1708 **
1709 ** Print a summary of activity going backwards in date and time
1710 ** specified or from the current date and time if no arguments
1711 ** are given. The WHEN argument can be any unique abbreviation
1712 ** of one of these keywords:
@@ -1722,10 +1722,12 @@
1722 ** for the current version or "now" for the current time.
1723 **
1724 ** Options:
1725 ** -n|--limit N Output the first N entries (default 20 lines).
1726 ** N=0 means no limit.
1727 ** -p|--path PATH Output items affecting PATH only.
1728 ** PATH can be a file or a sub directory.
1729 ** --offset P skip P changes
1730 ** -t|--type TYPE Output items from the given types only, such as:
1731 ** ci = file commits only
1732 ** e = events only
1733 ** t = tickets only
@@ -1752,19 +1754,23 @@
1754 int objid = 0;
1755 Blob uuid;
1756 int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
1757 int verboseFlag = 0 ;
1758 int iOffset;
1759 const char *zFilePattern = 0;
1760 Blob treeName;
1761
1762 verboseFlag = find_option("verbose","v", 0)!=0;
1763 if( !verboseFlag){
1764 verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
1765 }
1766 db_find_and_open_repository(0, 0);
1767 zLimit = find_option("limit","n",1);
1768 zWidth = find_option("width","W",1);
1769 zType = find_option("type","t",1);
1770 zFilePattern = find_option("path","p",1);
1771
1772 if( !zLimit ){
1773 zLimit = find_option("count",0,1);
1774 }
1775 if( zLimit ){
1776 n = atoi(zLimit);
@@ -1798,12 +1804,12 @@
1804 }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
1805 mode = 4;
1806 }else if( strncmp(g.argv[2],"parents",k)==0 ){
1807 mode = 4;
1808 }else if(!zType && !zLimit){
1809 usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
1810 "?-W|--width WIDTH? ?-p|--path PATH");
1811 }
1812 if( '-' != *g.argv[3] ){
1813 zOrigin = g.argv[3];
1814 }else{
1815 zOrigin = "now";
@@ -1838,37 +1844,72 @@
1844 if( mode==0 ){
1845 if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
1846 }
1847 zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
1848 }
1849
1850 if( zFilePattern ){
1851 if( zType==0 ){
1852 /* When zFilePattern is specified and type is not specified, only show
1853 * file checkins */
1854 zType="ci";
1855 }
1856 file_tree_name(zFilePattern, &treeName, 1);
1857 if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
1858 /* When zTreeName refers to g.zLocalRoot, it's like not specifying
1859 * zFilePattern. */
1860 zFilePattern = 0;
1861 }
1862 }
1863
1864 if( mode==0 ) mode = 1;
1865 blob_zero(&sql);
1866 blob_append(&sql, timeline_query_for_tty(), -1);
1867 blob_append_sql(&sql, " AND event.mtime %s %s",
1868 (mode==1 || mode==4) ? "<=" : ">=",
1869 zDate /*safe-for-%s*/
1870 );
1871
1872 if( mode==3 || mode==4 ){
1873 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
1874 if( mode==3 ){
1875 compute_descendants(objid, n);
1876 }else{
1877 compute_ancestors(objid, n, 0);
1878 }
1879 blob_append_sql(&sql, "\n AND blob.rid IN ok");
1880 }
1881 if( zType && (zType[0]!='a') ){
1882 blob_append_sql(&sql, "\n AND event.type=%Q ", zType);
1883 }
1884 if( zFilePattern ){
1885 blob_append(&sql,
1886 "\n AND EXISTS(SELECT 1 FROM mlink\n"
1887 " WHERE mlink.mid=event.objid\n"
1888 " AND mlink.fnid IN ", -1);
1889 if( filenames_are_case_sensitive() ){
1890 blob_append_sql(&sql,
1891 "(SELECT fnid FROM filename"
1892 " WHERE name=%Q"
1893 " OR name GLOB '%q/*')",
1894 blob_str(&treeName), blob_str(&treeName));
1895 }else{
1896 blob_append_sql(&sql,
1897 "(SELECT fnid FROM filename"
1898 " WHERE name=%Q COLLATE nocase"
1899 " OR lower(name) GLOB lower('%q/*'))",
1900 blob_str(&treeName), blob_str(&treeName));
1901 }
1902 blob_append(&sql, ")", -1);
1903 }
1904 blob_append_sql(&sql, "\nORDER BY event.mtime DESC");
1905 if( iOffset>0 ){
1906 /* Don't handle LIMIT here, otherwise print_timeline()
1907 * will not determine the end-marker correctly! */
1908 blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
1909 }
1910 db_prepare(&q, "%s", blob_sql_text(&sql));
1911 blob_reset(&sql);
1912 print_timeline(&q, n, width, verboseFlag);
1913 db_finalize(&q);
1914 }
1915
@@ -2178,24 +2219,24 @@
2219 stats_report_init_view();
2220 stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
2221 blob_appendf(&header, "Timeline Events (%s) by year%s",
2222 stats_report_label_for_type(),
2223 (includeMonth ? "/month" : ""));
2224 blob_append_sql(&sql,
2225 "SELECT substr(date(mtime),1,%d) AS timeframe, "
2226 "count(*) AS eventCount "
2227 "FROM v_reports ",
2228 includeMonth ? 7 : 4);
2229 if(zUserName&&*zUserName){
2230 blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
2231 blob_appendf(&header," for user %q", zUserName);
2232 }
2233 blob_append(&sql,
2234 " GROUP BY timeframe"
2235 " ORDER BY timeframe DESC",
2236 -1);
2237 db_prepare(&query, "%s", blob_sql_text(&sql));
2238 blob_reset(&sql);
2239 @ <h1>%b(&header)</h1>
2240 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
2241 @ cellspacing='0' id='statsTable'>
2242 @ <thead>
@@ -2321,23 +2362,19 @@
2362 Stmt query = empty_Stmt;
2363 int nRowNumber = 0; /* current TR number */
2364 int nEventTotal = 0; /* Total event count */
2365 int rowClass = 0; /* counter for alternating
2366 row colors */
 
2367 int nMaxEvents = 1; /* max number of events for
2368 all rows. */
2369 stats_report_init_view();
2370 stats_report_event_types_menu("byuser", NULL);
2371 db_prepare(&query,
2372 "SELECT user, "
2373 "COUNT(*) AS eventCount "
2374 "FROM v_reports "
2375 "GROUP BY user ORDER BY eventCount DESC");
 
 
 
2376 @ <h1>Timeline Events
2377 @ (%s(stats_report_label_for_type())) by User</h1>
2378 @ <table class='statistics-report-table-events' border='0'
2379 @ cellpadding='2' cellspacing='0' id='statsTable'>
2380 @ <thead><tr>
@@ -2388,28 +2425,24 @@
2425 Stmt query = empty_Stmt;
2426 int nRowNumber = 0; /* current TR number */
2427 int nEventTotal = 0; /* Total event count */
2428 int rowClass = 0; /* counter for alternating
2429 row colors */
 
2430 int nMaxEvents = 1; /* max number of events for
2431 all rows. */
2432 static const char *const daysOfWeek[] = {
2433 "Monday", "Tuesday", "Wednesday", "Thursday",
2434 "Friday", "Saturday", "Sunday"
2435 };
2436
2437 stats_report_init_view();
2438 stats_report_event_types_menu("byweekday", NULL);
2439 db_prepare(&query,
2440 "SELECT cast(mtime %% 7 AS INTEGER) dow, "
2441 "COUNT(*) AS eventCount "
2442 "FROM v_reports "
2443 "GROUP BY dow ORDER BY dow");
 
 
 
2444 @ <h1>Timeline Events
2445 @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
2446 @ <table class='statistics-report-table-events' border='0'
2447 @ cellpadding='2' cellspacing='0' id='statsTable'>
2448 @ <thead><tr>
@@ -2477,14 +2510,14 @@
2510 }
2511 blob_append(&sql,
2512 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2513 "FROM v_reports WHERE 1 ", -1);
2514 if(zUserName&&*zUserName){
2515 blob_append_sql(&sql,"AND user=%Q ", zUserName);
2516 }
2517 blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2518 db_prepare(&qYears, "%s", blob_sql_text(&sql));
2519 blob_reset(&sql);
2520 cgi_printf("Select year: ");
2521 while( SQLITE_ROW == db_step(&qYears) ){
2522 const char *zT = db_column_text(&qYears, 0);
2523 if( i++ ){
@@ -2510,22 +2543,22 @@
2543 int total = 0;
2544 Blob header = empty_blob;
2545 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2546 "of %h", stats_report_label_for_type(),
2547 zYear);
2548 blob_append_sql(&sql,
2549 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2550 "count(*) AS n "
2551 "FROM v_reports "
2552 "WHERE %Q=substr(date(mtime),1,4) "
2553 "AND mtime < current_timestamp ",
2554 zYear);
2555 if(zUserName&&*zUserName){
2556 blob_append_sql(&sql, " AND user=%Q ", zUserName);
2557 blob_appendf(&header," for user %h", zUserName);
2558 }
2559 blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
2560 cgi_printf("<h1>%h</h1>", blob_str(&header));
2561 blob_reset(&header);
2562 cgi_printf("<table class='statistics-report-table-events' "
2563 "border='0' cellpadding='2' width='100%%' "
2564 "cellspacing='0' id='statsTable'>");
@@ -2533,11 +2566,11 @@
2566 "<th>Week</th>"
2567 "<th>Events</th>"
2568 "<th width='90%%'><!-- relative commits graph --></th>"
2569 "</tr></thead>"
2570 "<tbody>");
2571 db_prepare(&stWeek, "%s", blob_sql_text(&sql));
2572 blob_reset(&sql);
2573 while( SQLITE_ROW == db_step(&stWeek) ){
2574 const int nCount = db_column_int(&stWeek, 1);
2575 if(nCount>nMaxEvents){
2576 nMaxEvents = nCount;
2577
+21 -23
--- src/tkt.c
+++ src/tkt.c
@@ -203,13 +203,13 @@
203203
tktid = db_last_insert_rowid();
204204
}
205205
blob_zero(&sql1);
206206
blob_zero(&sql2);
207207
blob_zero(&sql3);
208
- blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
208
+ blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
209209
if( haveTicketCTime ){
210
- blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
210
+ blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
211211
}
212212
aUsed = fossil_malloc( nField );
213213
memset(aUsed, 0, nField);
214214
for(i=0; i<p->nField; i++){
215215
const char *zName = p->aField[i].zName;
@@ -218,55 +218,56 @@
218218
if( j<0 ) continue;
219219
aUsed[j] = 1;
220220
if( aField[j].mUsed & USEDBY_TICKET ){
221221
if( zName[0]=='+' ){
222222
zName++;
223
- blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
223
+ blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
224224
zName, zName, p->aField[i].zValue);
225225
}else{
226
- blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
226
+ blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue);
227227
}
228228
}
229229
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230
- blob_appendf(&sql2, ",%s", zName);
231
- blob_appendf(&sql3, ",%Q", p->aField[i].zValue);
230
+ blob_append_sql(&sql2, ",\"%w\"", zName);
231
+ blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
232232
}
233233
if( rid>0 ){
234234
wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
235235
}
236236
}
237
- blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
238
- db_prepare(&q, "%s", blob_str(&sql1));
237
+ blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
238
+ db_prepare(&q, "%s", blob_sql_text(&sql1));
239239
db_bind_double(&q, ":mtime", p->rDate);
240240
db_step(&q);
241241
db_finalize(&q);
242242
blob_reset(&sql1);
243243
if( blob_size(&sql2)>0 || haveTicketChngRid ){
244244
int fromTkt = 0;
245245
if( haveTicketChngRid ){
246246
blob_append(&sql2, ",tkt_rid", -1);
247
- blob_appendf(&sql3, ",%d", rid);
247
+ blob_append_sql(&sql3, ",%d", rid);
248248
}
249249
for(i=0; i<nField; i++){
250250
if( aUsed[i]==0
251251
&& (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
252252
){
253253
const char *z = aField[i].zName;
254254
if( z[0]=='+' ) z++;
255255
fromTkt = 1;
256
- blob_appendf(&sql2, ",%s", z);
257
- blob_appendf(&sql3, ",%s", z);
256
+ blob_append_sql(&sql2, ",\"%w\"", z);
257
+ blob_append_sql(&sql3, ",\"%w\"", z);
258258
}
259259
}
260260
if( fromTkt ){
261261
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
262262
"SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
263
- blob_str(&sql2), tktid, blob_str(&sql3), tktid);
263
+ blob_sql_text(&sql2), tktid,
264
+ blob_sql_text(&sql3), tktid);
264265
}else{
265266
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
266267
"VALUES(%d,:mtime%s)",
267
- blob_str(&sql2), tktid, blob_str(&sql3));
268
+ blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
268269
}
269270
db_bind_double(&q, ":mtime", p->rDate);
270271
db_step(&q);
271272
db_finalize(&q);
272273
}
@@ -368,11 +369,11 @@
368369
zSql = ticket_table_schema();
369370
if( separateConnection ){
370371
db_end_transaction(0);
371372
db_init_database(g.zRepositoryName, zSql, 0);
372373
}else{
373
- db_multi_exec("%s", zSql);
374
+ db_multi_exec("%s", zSql/*safe-for-%s*/);
374375
}
375376
}
376377
377378
/*
378379
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
@@ -551,11 +552,11 @@
551552
fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
552553
}
553554
if( needMod ){
554555
moderation_table_create();
555556
db_multi_exec(
556
- "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
557
+ "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)",
557558
rid, zTktId
558559
);
559560
}else{
560561
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
561562
db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
@@ -855,12 +856,11 @@
855856
if( zType[0]=='c' ){
856857
zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
857858
}else{
858859
zTitle = mprintf("Timeline Of Ticket %h", zUuid);
859860
}
860
- style_header(zTitle);
861
- free(zTitle);
861
+ style_header("%z", zTitle);
862862
863863
sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
864864
canonical16(zGlobPattern, strlen(zGlobPattern));
865865
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
866866
if( tagid==0 ){
@@ -889,12 +889,11 @@
889889
" WHERE target=%Q) "
890890
"ORDER BY mtime DESC",
891891
timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
892892
);
893893
}
894
- db_prepare(&q, zSQL);
895
- free(zSQL);
894
+ db_prepare(&q, "%z", zSQL/*safe-for-%s*/);
896895
www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
897896
0, 0, 0);
898897
db_finalize(&q);
899898
style_footer();
900899
}
@@ -927,12 +926,11 @@
927926
"%R/tkthistory/%s", zUuid);
928927
}else{
929928
style_submenu_element("Plaintext", "Plaintext",
930929
"%R/tkthistory/%s?plaintext", zUuid);
931930
}
932
- style_header(zTitle);
933
- free(zTitle);
931
+ style_header("%z", zTitle);
934932
935933
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
936934
if( tagid==0 ){
937935
@ No such ticket: %h(zUuid)
938936
style_footer();
@@ -1213,11 +1211,11 @@
12131211
}
12141212
if( g.argc==3 ){
12151213
usage("set|change|history TICKETUUID");
12161214
}
12171215
zTktUuid = db_text(0,
1218
- "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
1216
+ "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3]
12191217
);
12201218
if( !zTktUuid ){
12211219
fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
12221220
}
12231221
i=4;
@@ -1292,11 +1290,11 @@
12921290
}else{
12931291
fossil_print(" Change ");
12941292
}
12951293
fossil_print("%h: ",z);
12961294
if( blob_size(&val)>50 || contains_newline(&val)) {
1297
- fossil_print("\n ",blob_str(&val));
1295
+ fossil_print("\n ");
12981296
comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
12991297
}else{
13001298
fossil_print("%s\n",blob_str(&val));
13011299
}
13021300
blob_reset(&val);
13031301
--- src/tkt.c
+++ src/tkt.c
@@ -203,13 +203,13 @@
203 tktid = db_last_insert_rowid();
204 }
205 blob_zero(&sql1);
206 blob_zero(&sql2);
207 blob_zero(&sql3);
208 blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
209 if( haveTicketCTime ){
210 blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
211 }
212 aUsed = fossil_malloc( nField );
213 memset(aUsed, 0, nField);
214 for(i=0; i<p->nField; i++){
215 const char *zName = p->aField[i].zName;
@@ -218,55 +218,56 @@
218 if( j<0 ) continue;
219 aUsed[j] = 1;
220 if( aField[j].mUsed & USEDBY_TICKET ){
221 if( zName[0]=='+' ){
222 zName++;
223 blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
224 zName, zName, p->aField[i].zValue);
225 }else{
226 blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
227 }
228 }
229 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230 blob_appendf(&sql2, ",%s", zName);
231 blob_appendf(&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 }
236 }
237 blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
238 db_prepare(&q, "%s", blob_str(&sql1));
239 db_bind_double(&q, ":mtime", p->rDate);
240 db_step(&q);
241 db_finalize(&q);
242 blob_reset(&sql1);
243 if( blob_size(&sql2)>0 || haveTicketChngRid ){
244 int fromTkt = 0;
245 if( haveTicketChngRid ){
246 blob_append(&sql2, ",tkt_rid", -1);
247 blob_appendf(&sql3, ",%d", rid);
248 }
249 for(i=0; i<nField; i++){
250 if( aUsed[i]==0
251 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
252 ){
253 const char *z = aField[i].zName;
254 if( z[0]=='+' ) z++;
255 fromTkt = 1;
256 blob_appendf(&sql2, ",%s", z);
257 blob_appendf(&sql3, ",%s", z);
258 }
259 }
260 if( fromTkt ){
261 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
262 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
263 blob_str(&sql2), tktid, blob_str(&sql3), tktid);
 
264 }else{
265 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
266 "VALUES(%d,:mtime%s)",
267 blob_str(&sql2), tktid, blob_str(&sql3));
268 }
269 db_bind_double(&q, ":mtime", p->rDate);
270 db_step(&q);
271 db_finalize(&q);
272 }
@@ -368,11 +369,11 @@
368 zSql = ticket_table_schema();
369 if( separateConnection ){
370 db_end_transaction(0);
371 db_init_database(g.zRepositoryName, zSql, 0);
372 }else{
373 db_multi_exec("%s", zSql);
374 }
375 }
376
377 /*
378 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
@@ -551,11 +552,11 @@
551 fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
552 }
553 if( needMod ){
554 moderation_table_create();
555 db_multi_exec(
556 "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
557 rid, zTktId
558 );
559 }else{
560 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
561 db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
@@ -855,12 +856,11 @@
855 if( zType[0]=='c' ){
856 zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
857 }else{
858 zTitle = mprintf("Timeline Of Ticket %h", zUuid);
859 }
860 style_header(zTitle);
861 free(zTitle);
862
863 sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
864 canonical16(zGlobPattern, strlen(zGlobPattern));
865 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
866 if( tagid==0 ){
@@ -889,12 +889,11 @@
889 " WHERE target=%Q) "
890 "ORDER BY mtime DESC",
891 timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
892 );
893 }
894 db_prepare(&q, zSQL);
895 free(zSQL);
896 www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
897 0, 0, 0);
898 db_finalize(&q);
899 style_footer();
900 }
@@ -927,12 +926,11 @@
927 "%R/tkthistory/%s", zUuid);
928 }else{
929 style_submenu_element("Plaintext", "Plaintext",
930 "%R/tkthistory/%s?plaintext", zUuid);
931 }
932 style_header(zTitle);
933 free(zTitle);
934
935 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
936 if( tagid==0 ){
937 @ No such ticket: %h(zUuid)
938 style_footer();
@@ -1213,11 +1211,11 @@
1213 }
1214 if( g.argc==3 ){
1215 usage("set|change|history TICKETUUID");
1216 }
1217 zTktUuid = db_text(0,
1218 "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
1219 );
1220 if( !zTktUuid ){
1221 fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
1222 }
1223 i=4;
@@ -1292,11 +1290,11 @@
1292 }else{
1293 fossil_print(" Change ");
1294 }
1295 fossil_print("%h: ",z);
1296 if( blob_size(&val)>50 || contains_newline(&val)) {
1297 fossil_print("\n ",blob_str(&val));
1298 comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
1299 }else{
1300 fossil_print("%s\n",blob_str(&val));
1301 }
1302 blob_reset(&val);
1303
--- src/tkt.c
+++ src/tkt.c
@@ -203,13 +203,13 @@
203 tktid = db_last_insert_rowid();
204 }
205 blob_zero(&sql1);
206 blob_zero(&sql2);
207 blob_zero(&sql3);
208 blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
209 if( haveTicketCTime ){
210 blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
211 }
212 aUsed = fossil_malloc( nField );
213 memset(aUsed, 0, nField);
214 for(i=0; i<p->nField; i++){
215 const char *zName = p->aField[i].zName;
@@ -218,55 +218,56 @@
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 }
236 }
237 blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
238 db_prepare(&q, "%s", blob_sql_text(&sql1));
239 db_bind_double(&q, ":mtime", p->rDate);
240 db_step(&q);
241 db_finalize(&q);
242 blob_reset(&sql1);
243 if( blob_size(&sql2)>0 || haveTicketChngRid ){
244 int fromTkt = 0;
245 if( haveTicketChngRid ){
246 blob_append(&sql2, ",tkt_rid", -1);
247 blob_append_sql(&sql3, ",%d", rid);
248 }
249 for(i=0; i<nField; i++){
250 if( aUsed[i]==0
251 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
252 ){
253 const char *z = aField[i].zName;
254 if( z[0]=='+' ) z++;
255 fromTkt = 1;
256 blob_append_sql(&sql2, ",\"%w\"", z);
257 blob_append_sql(&sql3, ",\"%w\"", z);
258 }
259 }
260 if( fromTkt ){
261 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
262 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
263 blob_sql_text(&sql2), tktid,
264 blob_sql_text(&sql3), tktid);
265 }else{
266 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
267 "VALUES(%d,:mtime%s)",
268 blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
269 }
270 db_bind_double(&q, ":mtime", p->rDate);
271 db_step(&q);
272 db_finalize(&q);
273 }
@@ -368,11 +369,11 @@
369 zSql = ticket_table_schema();
370 if( separateConnection ){
371 db_end_transaction(0);
372 db_init_database(g.zRepositoryName, zSql, 0);
373 }else{
374 db_multi_exec("%s", zSql/*safe-for-%s*/);
375 }
376 }
377
378 /*
379 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
@@ -551,11 +552,11 @@
552 fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
553 }
554 if( needMod ){
555 moderation_table_create();
556 db_multi_exec(
557 "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)",
558 rid, zTktId
559 );
560 }else{
561 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
562 db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
@@ -855,12 +856,11 @@
856 if( zType[0]=='c' ){
857 zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
858 }else{
859 zTitle = mprintf("Timeline Of Ticket %h", zUuid);
860 }
861 style_header("%z", zTitle);
 
862
863 sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
864 canonical16(zGlobPattern, strlen(zGlobPattern));
865 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
866 if( tagid==0 ){
@@ -889,12 +889,11 @@
889 " WHERE target=%Q) "
890 "ORDER BY mtime DESC",
891 timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
892 );
893 }
894 db_prepare(&q, "%z", zSQL/*safe-for-%s*/);
 
895 www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
896 0, 0, 0);
897 db_finalize(&q);
898 style_footer();
899 }
@@ -927,12 +926,11 @@
926 "%R/tkthistory/%s", zUuid);
927 }else{
928 style_submenu_element("Plaintext", "Plaintext",
929 "%R/tkthistory/%s?plaintext", zUuid);
930 }
931 style_header("%z", zTitle);
 
932
933 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
934 if( tagid==0 ){
935 @ No such ticket: %h(zUuid)
936 style_footer();
@@ -1213,11 +1211,11 @@
1211 }
1212 if( g.argc==3 ){
1213 usage("set|change|history TICKETUUID");
1214 }
1215 zTktUuid = db_text(0,
1216 "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3]
1217 );
1218 if( !zTktUuid ){
1219 fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
1220 }
1221 i=4;
@@ -1292,11 +1290,11 @@
1290 }else{
1291 fossil_print(" Change ");
1292 }
1293 fossil_print("%h: ",z);
1294 if( blob_size(&val)>50 || contains_newline(&val)) {
1295 fossil_print("\n ");
1296 comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
1297 }else{
1298 fossil_print("%s\n",blob_str(&val));
1299 }
1300 blob_reset(&val);
1301
+7 -7
--- src/translate.c
+++ src/translate.c
@@ -13,11 +13,11 @@
1313
** [email protected]
1414
** http://www.hwaci.com/drh/
1515
**
1616
*******************************************************************************
1717
**
18
-** SYNOPSIS:
18
+** SYNOPSIS:
1919
**
2020
** Input lines that begin with the "@" character are translated into
2121
** either cgi_printf() statements or string literals and the
2222
** translated code is written on standard output.
2323
**
@@ -34,22 +34,22 @@
3434
** punctuation.
3535
**
3636
** Enhancement #1:
3737
**
3838
** If the last non-whitespace character prior to the first "@" of a
39
-** @-block is "=" or "," then the @-block is a string literal initializer
39
+** @-block is "=" or "," then the @-block is a string literal initializer
4040
** rather than text that is to be output via cgi_printf(). Render it
4141
** as such.
4242
**
4343
** Enhancement #2:
4444
**
45
-** Comments of the form: "/* @-comment: CC" cause CC to become a
45
+** Comments of the form: "/* @-comment: CC" cause CC to become a
4646
** comment character for the @-substitution. Typical values for CC are
4747
** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
4848
** Lines of subsequent @-blocks that begin with CC are omitted from the
4949
** output.
50
-**
50
+**
5151
*/
5252
#include <stdio.h>
5353
#include <ctype.h>
5454
#include <stdlib.h>
5555
#include <string.h>
@@ -122,11 +122,11 @@
122122
indent = i - 2;
123123
if( indent<0 ) indent = 0;
124124
omitline = 0;
125125
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
126126
if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
127
- omitline = 1; break;
127
+ omitline = 1; break;
128128
}
129129
if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
130130
zOut[j++] = zLine[i];
131131
}
132132
while( j>0 && isspace(zOut[j-1]) ){ j--; }
@@ -137,11 +137,11 @@
137137
fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
138138
}
139139
}else{
140140
/* Otherwise (if the last non-whitespace was not '=') then generate
141141
** a cgi_printf() statement whose format is the text following the '@'.
142
- ** Substrings of the form "%C(...)" (where C is any sequence of
142
+ ** Substrings of the form "%C(...)" (where C is any sequence of
143143
** characters other than \000 and '(') will put "%C" in the
144144
** format and add the "(...)" as an argument to the cgi_printf call.
145145
*/
146146
int indent;
147147
int nC;
@@ -174,11 +174,11 @@
174174
fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
175175
inPrint = 1;
176176
}else{
177177
fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
178178
}
179
- }
179
+ }
180180
}
181181
}
182182
183183
int main(int argc, char **argv){
184184
if( argc==2 ){
185185
--- src/translate.c
+++ src/translate.c
@@ -13,11 +13,11 @@
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** SYNOPSIS:
19 **
20 ** Input lines that begin with the "@" character are translated into
21 ** either cgi_printf() statements or string literals and the
22 ** translated code is written on standard output.
23 **
@@ -34,22 +34,22 @@
34 ** punctuation.
35 **
36 ** Enhancement #1:
37 **
38 ** If the last non-whitespace character prior to the first "@" of a
39 ** @-block is "=" or "," then the @-block is a string literal initializer
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55 #include <string.h>
@@ -122,11 +122,11 @@
122 indent = i - 2;
123 if( indent<0 ) indent = 0;
124 omitline = 0;
125 for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
126 if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
127 omitline = 1; break;
128 }
129 if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
130 zOut[j++] = zLine[i];
131 }
132 while( j>0 && isspace(zOut[j-1]) ){ j--; }
@@ -137,11 +137,11 @@
137 fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
138 }
139 }else{
140 /* Otherwise (if the last non-whitespace was not '=') then generate
141 ** a cgi_printf() statement whose format is the text following the '@'.
142 ** Substrings of the form "%C(...)" (where C is any sequence of
143 ** characters other than \000 and '(') will put "%C" in the
144 ** format and add the "(...)" as an argument to the cgi_printf call.
145 */
146 int indent;
147 int nC;
@@ -174,11 +174,11 @@
174 fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
175 inPrint = 1;
176 }else{
177 fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
178 }
179 }
180 }
181 }
182
183 int main(int argc, char **argv){
184 if( argc==2 ){
185
--- src/translate.c
+++ src/translate.c
@@ -13,11 +13,11 @@
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** SYNOPSIS:
19 **
20 ** Input lines that begin with the "@" character are translated into
21 ** either cgi_printf() statements or string literals and the
22 ** translated code is written on standard output.
23 **
@@ -34,22 +34,22 @@
34 ** punctuation.
35 **
36 ** Enhancement #1:
37 **
38 ** If the last non-whitespace character prior to the first "@" of a
39 ** @-block is "=" or "," then the @-block is a string literal initializer
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55 #include <string.h>
@@ -122,11 +122,11 @@
122 indent = i - 2;
123 if( indent<0 ) indent = 0;
124 omitline = 0;
125 for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
126 if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
127 omitline = 1; break;
128 }
129 if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
130 zOut[j++] = zLine[i];
131 }
132 while( j>0 && isspace(zOut[j-1]) ){ j--; }
@@ -137,11 +137,11 @@
137 fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
138 }
139 }else{
140 /* Otherwise (if the last non-whitespace was not '=') then generate
141 ** a cgi_printf() statement whose format is the text following the '@'.
142 ** Substrings of the form "%C(...)" (where C is any sequence of
143 ** characters other than \000 and '(') will put "%C" in the
144 ** format and add the "(...)" as an argument to the cgi_printf call.
145 */
146 int indent;
147 int nC;
@@ -174,11 +174,11 @@
174 fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
175 inPrint = 1;
176 }else{
177 fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
178 }
179 }
180 }
181 }
182
183 int main(int argc, char **argv){
184 if( argc==2 ){
185
+9 -8
--- src/undo.c
+++ src/undo.c
@@ -143,11 +143,12 @@
143143
"INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144144
"DELETE FROM undo_vmerge;"
145145
"INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146146
"DROP TABLE undo_vmerge_2;"
147147
);
148
- if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){
148
+ if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
149
+ " WHERE name='undo_stash'", zDb) ){
149150
if( redoFlag ){
150151
db_multi_exec(
151152
"DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
152153
"DELETE FROM stashfile"
153154
" WHERE stashid NOT IN (SELECT stashid FROM stash);"
@@ -174,11 +175,11 @@
174175
@ DROP TABLE IF EXISTS undo_vfile;
175176
@ DROP TABLE IF EXISTS undo_vmerge;
176177
@ DROP TABLE IF EXISTS undo_stash;
177178
@ DROP TABLE IF EXISTS undo_stashfile;
178179
;
179
- db_multi_exec(zSql);
180
+ db_multi_exec(zSql /*works-like:""*/);
180181
db_lset_int("undo_available", 0);
181182
db_lset_int("undo_checkout", 0);
182183
}
183184
184185
/*
@@ -219,24 +220,24 @@
219220
*/
220221
void undo_begin(void){
221222
int cid;
222223
const char *zDb = db_name("localdb");
223224
static const char zSql[] =
224
- @ CREATE TABLE %s.undo(
225
+ @ CREATE TABLE "%w".undo(
225226
@ pathname TEXT UNIQUE, -- Name of the file
226227
@ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
227228
@ existsflag BOOLEAN, -- True if the file exists
228229
@ isExe BOOLEAN, -- True if the file is executable
229230
@ isLink BOOLEAN, -- True if the file is symlink
230231
@ content BLOB -- Saved content
231232
@ );
232
- @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
233
- @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
233
+ @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile;
234
+ @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge;
234235
;
235236
if( undoDisable ) return;
236237
undo_reset();
237
- db_multi_exec(zSql, zDb, zDb, zDb);
238
+ db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb);
238239
cid = db_lget_int("checkout", 0);
239240
db_lset_int("undo_checkout", cid);
240241
db_lset_int("undo_available", 1);
241242
db_lset("undo_cmdline", undoCmd);
242243
undoActive = 1;
@@ -301,18 +302,18 @@
301302
** Make the current state of stashid undoable.
302303
*/
303304
void undo_save_stash(int stashid){
304305
const char *zDb = db_name("localdb");
305306
db_multi_exec(
306
- "CREATE TABLE IF NOT EXISTS %s.undo_stash"
307
+ "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash"
307308
" AS SELECT * FROM stash WHERE 0;"
308309
"INSERT INTO undo_stash"
309310
" SELECT * FROM stash WHERE stashid=%d;",
310311
zDb, stashid
311312
);
312313
db_multi_exec(
313
- "CREATE TABLE IF NOT EXISTS %s.undo_stashfile"
314
+ "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile"
314315
" AS SELECT * FROM stashfile WHERE 0;"
315316
"INSERT INTO undo_stashfile"
316317
" SELECT * FROM stashfile WHERE stashid=%d;",
317318
zDb, stashid
318319
);
319320
--- src/undo.c
+++ src/undo.c
@@ -143,11 +143,12 @@
143 "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144 "DELETE FROM undo_vmerge;"
145 "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146 "DROP TABLE undo_vmerge_2;"
147 );
148 if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){
 
149 if( redoFlag ){
150 db_multi_exec(
151 "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
152 "DELETE FROM stashfile"
153 " WHERE stashid NOT IN (SELECT stashid FROM stash);"
@@ -174,11 +175,11 @@
174 @ DROP TABLE IF EXISTS undo_vfile;
175 @ DROP TABLE IF EXISTS undo_vmerge;
176 @ DROP TABLE IF EXISTS undo_stash;
177 @ DROP TABLE IF EXISTS undo_stashfile;
178 ;
179 db_multi_exec(zSql);
180 db_lset_int("undo_available", 0);
181 db_lset_int("undo_checkout", 0);
182 }
183
184 /*
@@ -219,24 +220,24 @@
219 */
220 void undo_begin(void){
221 int cid;
222 const char *zDb = db_name("localdb");
223 static const char zSql[] =
224 @ CREATE TABLE %s.undo(
225 @ pathname TEXT UNIQUE, -- Name of the file
226 @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
227 @ existsflag BOOLEAN, -- True if the file exists
228 @ isExe BOOLEAN, -- True if the file is executable
229 @ isLink BOOLEAN, -- True if the file is symlink
230 @ content BLOB -- Saved content
231 @ );
232 @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
233 @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
234 ;
235 if( undoDisable ) return;
236 undo_reset();
237 db_multi_exec(zSql, zDb, zDb, zDb);
238 cid = db_lget_int("checkout", 0);
239 db_lset_int("undo_checkout", cid);
240 db_lset_int("undo_available", 1);
241 db_lset("undo_cmdline", undoCmd);
242 undoActive = 1;
@@ -301,18 +302,18 @@
301 ** Make the current state of stashid undoable.
302 */
303 void undo_save_stash(int stashid){
304 const char *zDb = db_name("localdb");
305 db_multi_exec(
306 "CREATE TABLE IF NOT EXISTS %s.undo_stash"
307 " AS SELECT * FROM stash WHERE 0;"
308 "INSERT INTO undo_stash"
309 " SELECT * FROM stash WHERE stashid=%d;",
310 zDb, stashid
311 );
312 db_multi_exec(
313 "CREATE TABLE IF NOT EXISTS %s.undo_stashfile"
314 " AS SELECT * FROM stashfile WHERE 0;"
315 "INSERT INTO undo_stashfile"
316 " SELECT * FROM stashfile WHERE stashid=%d;",
317 zDb, stashid
318 );
319
--- src/undo.c
+++ src/undo.c
@@ -143,11 +143,12 @@
143 "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144 "DELETE FROM undo_vmerge;"
145 "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146 "DROP TABLE undo_vmerge_2;"
147 );
148 if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
149 " WHERE name='undo_stash'", zDb) ){
150 if( redoFlag ){
151 db_multi_exec(
152 "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
153 "DELETE FROM stashfile"
154 " WHERE stashid NOT IN (SELECT stashid FROM stash);"
@@ -174,11 +175,11 @@
175 @ DROP TABLE IF EXISTS undo_vfile;
176 @ DROP TABLE IF EXISTS undo_vmerge;
177 @ DROP TABLE IF EXISTS undo_stash;
178 @ DROP TABLE IF EXISTS undo_stashfile;
179 ;
180 db_multi_exec(zSql /*works-like:""*/);
181 db_lset_int("undo_available", 0);
182 db_lset_int("undo_checkout", 0);
183 }
184
185 /*
@@ -219,24 +220,24 @@
220 */
221 void undo_begin(void){
222 int cid;
223 const char *zDb = db_name("localdb");
224 static const char zSql[] =
225 @ CREATE TABLE "%w".undo(
226 @ pathname TEXT UNIQUE, -- Name of the file
227 @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
228 @ existsflag BOOLEAN, -- True if the file exists
229 @ isExe BOOLEAN, -- True if the file is executable
230 @ isLink BOOLEAN, -- True if the file is symlink
231 @ content BLOB -- Saved content
232 @ );
233 @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile;
234 @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge;
235 ;
236 if( undoDisable ) return;
237 undo_reset();
238 db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb);
239 cid = db_lget_int("checkout", 0);
240 db_lset_int("undo_checkout", cid);
241 db_lset_int("undo_available", 1);
242 db_lset("undo_cmdline", undoCmd);
243 undoActive = 1;
@@ -301,18 +302,18 @@
302 ** Make the current state of stashid undoable.
303 */
304 void undo_save_stash(int stashid){
305 const char *zDb = db_name("localdb");
306 db_multi_exec(
307 "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash"
308 " AS SELECT * FROM stash WHERE 0;"
309 "INSERT INTO undo_stash"
310 " SELECT * FROM stash WHERE stashid=%d;",
311 zDb, stashid
312 );
313 db_multi_exec(
314 "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile"
315 " AS SELECT * FROM stashfile WHERE 0;"
316 "INSERT INTO undo_stashfile"
317 " SELECT * FROM stashfile WHERE stashid=%d;",
318 zDb, stashid
319 );
320
+5 -3
--- src/update.c
+++ src/update.c
@@ -357,22 +357,24 @@
357357
zSep = "";
358358
for(i=3; i<g.argc; i++){
359359
file_tree_name(g.argv[i], &treename, 1);
360360
if( file_wd_isdir(g.argv[i])==1 ){
361361
if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
362
- blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename);
362
+ blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
363
+ zSep /*safe-for-%s*/, blob_str(&treename));
363364
}else{
364365
blob_reset(&sql);
365366
break;
366367
}
367368
}else{
368
- blob_appendf(&sql, "%sfn<>%B ", zSep, &treename);
369
+ blob_append_sql(&sql, "%sfn<>%Q ",
370
+ zSep /*safe-for-%s*/, blob_str(&treename));
369371
}
370372
zSep = "AND ";
371373
blob_reset(&treename);
372374
}
373
- db_multi_exec(blob_str(&sql));
375
+ db_multi_exec("%s", blob_sql_text(&sql));
374376
blob_reset(&sql);
375377
}
376378
377379
/*
378380
** Alter the content of the checkout so that it conforms with the
379381
--- src/update.c
+++ src/update.c
@@ -357,22 +357,24 @@
357 zSep = "";
358 for(i=3; i<g.argc; i++){
359 file_tree_name(g.argv[i], &treename, 1);
360 if( file_wd_isdir(g.argv[i])==1 ){
361 if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
362 blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename);
 
363 }else{
364 blob_reset(&sql);
365 break;
366 }
367 }else{
368 blob_appendf(&sql, "%sfn<>%B ", zSep, &treename);
 
369 }
370 zSep = "AND ";
371 blob_reset(&treename);
372 }
373 db_multi_exec(blob_str(&sql));
374 blob_reset(&sql);
375 }
376
377 /*
378 ** Alter the content of the checkout so that it conforms with the
379
--- src/update.c
+++ src/update.c
@@ -357,22 +357,24 @@
357 zSep = "";
358 for(i=3; i<g.argc; i++){
359 file_tree_name(g.argv[i], &treename, 1);
360 if( file_wd_isdir(g.argv[i])==1 ){
361 if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
362 blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
363 zSep /*safe-for-%s*/, blob_str(&treename));
364 }else{
365 blob_reset(&sql);
366 break;
367 }
368 }else{
369 blob_append_sql(&sql, "%sfn<>%Q ",
370 zSep /*safe-for-%s*/, blob_str(&treename));
371 }
372 zSep = "AND ";
373 blob_reset(&treename);
374 }
375 db_multi_exec("%s", blob_sql_text(&sql));
376 blob_reset(&sql);
377 }
378
379 /*
380 ** Alter the content of the checkout so that it conforms with the
381
+3 -3
--- src/user.c
+++ src/user.c
@@ -451,26 +451,26 @@
451451
cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
452452
return;
453453
}
454454
style_header("Access Log");
455455
blob_zero(&sql);
456
- blob_appendf(&sql,
456
+ blob_append_sql(&sql,
457457
"SELECT uname, ipaddr, datetime(mtime%s), success"
458458
" FROM accesslog", timeline_utc()
459459
);
460460
if( y==1 ){
461461
blob_append(&sql, " WHERE success", -1);
462462
}else if( y==2 ){
463463
blob_append(&sql, " WHERE NOT success", -1);
464464
}
465
- blob_appendf(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
465
+ blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
466466
if( skip ){
467467
style_submenu_element("Newer", "Newer entries",
468468
"%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
469469
n, y);
470470
}
471
- rc = db_prepare_ignore_error(&q, blob_str(&sql));
471
+ rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
472472
@ <center><table border="1" cellpadding="5">
473473
@ <tr><th width="33%%">Date</th><th width="34%%">User</th>
474474
@ <th width="33%%">IP Address</th></tr>
475475
while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
476476
const char *zName = db_column_text(&q, 0);
477477
--- src/user.c
+++ src/user.c
@@ -451,26 +451,26 @@
451 cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
452 return;
453 }
454 style_header("Access Log");
455 blob_zero(&sql);
456 blob_appendf(&sql,
457 "SELECT uname, ipaddr, datetime(mtime%s), success"
458 " FROM accesslog", timeline_utc()
459 );
460 if( y==1 ){
461 blob_append(&sql, " WHERE success", -1);
462 }else if( y==2 ){
463 blob_append(&sql, " WHERE NOT success", -1);
464 }
465 blob_appendf(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
466 if( skip ){
467 style_submenu_element("Newer", "Newer entries",
468 "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
469 n, y);
470 }
471 rc = db_prepare_ignore_error(&q, blob_str(&sql));
472 @ <center><table border="1" cellpadding="5">
473 @ <tr><th width="33%%">Date</th><th width="34%%">User</th>
474 @ <th width="33%%">IP Address</th></tr>
475 while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
476 const char *zName = db_column_text(&q, 0);
477
--- src/user.c
+++ src/user.c
@@ -451,26 +451,26 @@
451 cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
452 return;
453 }
454 style_header("Access Log");
455 blob_zero(&sql);
456 blob_append_sql(&sql,
457 "SELECT uname, ipaddr, datetime(mtime%s), success"
458 " FROM accesslog", timeline_utc()
459 );
460 if( y==1 ){
461 blob_append(&sql, " WHERE success", -1);
462 }else if( y==2 ){
463 blob_append(&sql, " WHERE NOT success", -1);
464 }
465 blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
466 if( skip ){
467 style_submenu_element("Newer", "Newer entries",
468 "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
469 n, y);
470 }
471 rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
472 @ <center><table border="1" cellpadding="5">
473 @ <tr><th width="33%%">Date</th><th width="34%%">User</th>
474 @ <th width="33%%">IP Address</th></tr>
475 while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
476 const char *zName = db_column_text(&q, 0);
477
+2 -2
--- src/vfile.c
+++ src/vfile.c
@@ -397,13 +397,13 @@
397397
"original",
398398
"output",
399399
};
400400
int i, j, n;
401401
402
- if( strglob("ci-comment-????????????.txt", zName) ) return 1;
402
+ if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1;
403403
for(; zName[0]!=0; zName++){
404
- if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){
404
+ if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){
405405
return 1;
406406
}
407407
if( zName[0]!='-' ) continue;
408408
for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
409409
n = (int)strlen(azTemp[i]);
410410
--- src/vfile.c
+++ src/vfile.c
@@ -397,13 +397,13 @@
397 "original",
398 "output",
399 };
400 int i, j, n;
401
402 if( strglob("ci-comment-????????????.txt", zName) ) return 1;
403 for(; zName[0]!=0; zName++){
404 if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){
405 return 1;
406 }
407 if( zName[0]!='-' ) continue;
408 for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
409 n = (int)strlen(azTemp[i]);
410
--- src/vfile.c
+++ src/vfile.c
@@ -397,13 +397,13 @@
397 "original",
398 "output",
399 };
400 int i, j, n;
401
402 if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1;
403 for(; zName[0]!=0; zName++){
404 if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){
405 return 1;
406 }
407 if( zName[0]!='-' ) continue;
408 for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
409 n = (int)strlen(azTemp[i]);
410
+5 -14
--- src/wiki.c
+++ src/wiki.c
@@ -292,11 +292,11 @@
292292
style_submenu_element("History", "History", "%s/whistory?name=%T",
293293
g.zTop, zPageName);
294294
}
295295
}
296296
style_set_current_page("%T?name=%T", g.zPath, zPageName);
297
- style_header(zPageName);
297
+ style_header("%s", zPageName);
298298
blob_init(&wiki, zBody, -1);
299299
wiki_render_by_mimetype(&wiki, zMimetype);
300300
blob_reset(&wiki);
301301
attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
302302
manifest_destroy(pWiki);
@@ -649,11 +649,11 @@
649649
Blob wiki;
650650
Manifest *pWiki = 0;
651651
652652
blob_zero(&body);
653653
if( isSandbox ){
654
- blob_appendf(&body, db_get("sandbox",""));
654
+ blob_append(&body, db_get("sandbox",""), -1);
655655
appendRemark(&body, zMimetype);
656656
db_set("sandbox", blob_str(&body), 0);
657657
}else{
658658
login_verify_csrf_secret();
659659
pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
@@ -746,29 +746,23 @@
746746
**
747747
** Show the complete change history for a single wiki page.
748748
*/
749749
void whistory_page(void){
750750
Stmt q;
751
- char *zTitle;
752
- char *zSQL;
753751
const char *zPageName;
754752
login_check_credentials();
755753
if( !g.perm.Hyperlink ){ login_needed(); return; }
756754
zPageName = PD("name","");
757
- zTitle = mprintf("History Of %s", zPageName);
758
- style_header(zTitle);
759
- free(zTitle);
755
+ style_header("History Of %s", zPageName);
760756
761
- zSQL = mprintf("%s AND event.objid IN "
757
+ db_prepare(&q, "%s AND event.objid IN "
762758
" (SELECT rid FROM tagxref WHERE tagid="
763759
"(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
764760
" UNION SELECT attachid FROM attachment"
765761
" WHERE target=%Q)"
766762
"ORDER BY mtime DESC",
767763
timeline_query_for_www(), zPageName, zPageName);
768
- db_prepare(&q, zSQL);
769
- free(zSQL);
770764
zWikiPageName = zPageName;
771765
www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
772766
db_finalize(&q);
773767
style_footer();
774768
}
@@ -778,11 +772,10 @@
778772
** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
779773
**
780774
** Show the difference between two wiki pages.
781775
*/
782776
void wdiff_page(void){
783
- char *zTitle;
784777
int rid1, rid2;
785778
const char *zPageName;
786779
Manifest *pW1, *pW2 = 0;
787780
Blob w1, w2, d;
788781
u64 diffFlags;
@@ -791,13 +784,11 @@
791784
rid1 = atoi(PD("a","0"));
792785
if( !g.perm.Hyperlink ){ login_needed(); return; }
793786
if( rid1==0 ) fossil_redirect_home();
794787
rid2 = atoi(PD("b","0"));
795788
zPageName = PD("name","");
796
- zTitle = mprintf("Changes To %s", zPageName);
797
- style_header(zTitle);
798
- free(zTitle);
789
+ style_header("Changes To %s", zPageName);
799790
800791
if( rid2==0 ){
801792
rid2 = db_int(0,
802793
"SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
803794
"(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
804795
--- src/wiki.c
+++ src/wiki.c
@@ -292,11 +292,11 @@
292 style_submenu_element("History", "History", "%s/whistory?name=%T",
293 g.zTop, zPageName);
294 }
295 }
296 style_set_current_page("%T?name=%T", g.zPath, zPageName);
297 style_header(zPageName);
298 blob_init(&wiki, zBody, -1);
299 wiki_render_by_mimetype(&wiki, zMimetype);
300 blob_reset(&wiki);
301 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
302 manifest_destroy(pWiki);
@@ -649,11 +649,11 @@
649 Blob wiki;
650 Manifest *pWiki = 0;
651
652 blob_zero(&body);
653 if( isSandbox ){
654 blob_appendf(&body, db_get("sandbox",""));
655 appendRemark(&body, zMimetype);
656 db_set("sandbox", blob_str(&body), 0);
657 }else{
658 login_verify_csrf_secret();
659 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
@@ -746,29 +746,23 @@
746 **
747 ** Show the complete change history for a single wiki page.
748 */
749 void whistory_page(void){
750 Stmt q;
751 char *zTitle;
752 char *zSQL;
753 const char *zPageName;
754 login_check_credentials();
755 if( !g.perm.Hyperlink ){ login_needed(); return; }
756 zPageName = PD("name","");
757 zTitle = mprintf("History Of %s", zPageName);
758 style_header(zTitle);
759 free(zTitle);
760
761 zSQL = mprintf("%s AND event.objid IN "
762 " (SELECT rid FROM tagxref WHERE tagid="
763 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
764 " UNION SELECT attachid FROM attachment"
765 " WHERE target=%Q)"
766 "ORDER BY mtime DESC",
767 timeline_query_for_www(), zPageName, zPageName);
768 db_prepare(&q, zSQL);
769 free(zSQL);
770 zWikiPageName = zPageName;
771 www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
772 db_finalize(&q);
773 style_footer();
774 }
@@ -778,11 +772,10 @@
778 ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
779 **
780 ** Show the difference between two wiki pages.
781 */
782 void wdiff_page(void){
783 char *zTitle;
784 int rid1, rid2;
785 const char *zPageName;
786 Manifest *pW1, *pW2 = 0;
787 Blob w1, w2, d;
788 u64 diffFlags;
@@ -791,13 +784,11 @@
791 rid1 = atoi(PD("a","0"));
792 if( !g.perm.Hyperlink ){ login_needed(); return; }
793 if( rid1==0 ) fossil_redirect_home();
794 rid2 = atoi(PD("b","0"));
795 zPageName = PD("name","");
796 zTitle = mprintf("Changes To %s", zPageName);
797 style_header(zTitle);
798 free(zTitle);
799
800 if( rid2==0 ){
801 rid2 = db_int(0,
802 "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
803 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
804
--- src/wiki.c
+++ src/wiki.c
@@ -292,11 +292,11 @@
292 style_submenu_element("History", "History", "%s/whistory?name=%T",
293 g.zTop, zPageName);
294 }
295 }
296 style_set_current_page("%T?name=%T", g.zPath, zPageName);
297 style_header("%s", zPageName);
298 blob_init(&wiki, zBody, -1);
299 wiki_render_by_mimetype(&wiki, zMimetype);
300 blob_reset(&wiki);
301 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
302 manifest_destroy(pWiki);
@@ -649,11 +649,11 @@
649 Blob wiki;
650 Manifest *pWiki = 0;
651
652 blob_zero(&body);
653 if( isSandbox ){
654 blob_append(&body, db_get("sandbox",""), -1);
655 appendRemark(&body, zMimetype);
656 db_set("sandbox", blob_str(&body), 0);
657 }else{
658 login_verify_csrf_secret();
659 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
@@ -746,29 +746,23 @@
746 **
747 ** Show the complete change history for a single wiki page.
748 */
749 void whistory_page(void){
750 Stmt q;
 
 
751 const char *zPageName;
752 login_check_credentials();
753 if( !g.perm.Hyperlink ){ login_needed(); return; }
754 zPageName = PD("name","");
755 style_header("History Of %s", zPageName);
 
 
756
757 db_prepare(&q, "%s AND event.objid IN "
758 " (SELECT rid FROM tagxref WHERE tagid="
759 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
760 " UNION SELECT attachid FROM attachment"
761 " WHERE target=%Q)"
762 "ORDER BY mtime DESC",
763 timeline_query_for_www(), zPageName, zPageName);
 
 
764 zWikiPageName = zPageName;
765 www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
766 db_finalize(&q);
767 style_footer();
768 }
@@ -778,11 +772,10 @@
772 ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
773 **
774 ** Show the difference between two wiki pages.
775 */
776 void wdiff_page(void){
 
777 int rid1, rid2;
778 const char *zPageName;
779 Manifest *pW1, *pW2 = 0;
780 Blob w1, w2, d;
781 u64 diffFlags;
@@ -791,13 +784,11 @@
784 rid1 = atoi(PD("a","0"));
785 if( !g.perm.Hyperlink ){ login_needed(); return; }
786 if( rid1==0 ) fossil_redirect_home();
787 rid2 = atoi(PD("b","0"));
788 zPageName = PD("name","");
789 style_header("Changes To %s", zPageName);
 
 
790
791 if( rid2==0 ){
792 rid2 = db_int(0,
793 "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
794 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
795
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1046,11 +1046,11 @@
10461046
*/
10471047
static void startAutoParagraph(Renderer *p){
10481048
if( p->wantAutoParagraph==0 ) return;
10491049
if( p->state & WIKI_LINKSONLY ) return;
10501050
if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
1051
- blob_appendf(p->pOut, "<p>", -1);
1051
+ blob_append(p->pOut, "<p>", -1);
10521052
p->wantAutoParagraph = 0;
10531053
p->inAutoParagraph = 1;
10541054
}
10551055
10561056
/*
@@ -1121,11 +1121,11 @@
11211121
if( once ){
11221122
const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
11231123
db_static_prepare(&q,
11241124
"SELECT %s FROM ticket "
11251125
" WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
1126
- zClosedExpr
1126
+ zClosedExpr /*safe-for-%s*/
11271127
);
11281128
once = 0;
11291129
}
11301130
db_bind_text(&q, ":lwr", zLower);
11311131
db_bind_text(&q, ":upr", zUpper);
@@ -1243,11 +1243,11 @@
12431243
}
12441244
}else if( !in_this_repo(zTarget) ){
12451245
if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
12461246
zTerm = "";
12471247
}else{
1248
- blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
1248
+ blob_appendf(p->pOut, "<span class=\"brokenlink\">[");
12491249
zTerm = "]</span>";
12501250
}
12511251
}else if( g.perm.Hyperlink ){
12521252
blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
12531253
zTerm = "]</a>";
@@ -1328,11 +1328,11 @@
13281328
if( p->wikiList ){
13291329
popStackToTag(p, p->wikiList);
13301330
p->wikiList = 0;
13311331
}
13321332
endAutoParagraph(p);
1333
- blob_appendf(p->pOut, "\n\n", 1);
1333
+ blob_append(p->pOut, "\n\n", 1);
13341334
p->wantAutoParagraph = 1;
13351335
}
13361336
p->state |= AT_PARAGRAPH|AT_NEWLINE;
13371337
break;
13381338
}
13391339
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1046,11 +1046,11 @@
1046 */
1047 static void startAutoParagraph(Renderer *p){
1048 if( p->wantAutoParagraph==0 ) return;
1049 if( p->state & WIKI_LINKSONLY ) return;
1050 if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
1051 blob_appendf(p->pOut, "<p>", -1);
1052 p->wantAutoParagraph = 0;
1053 p->inAutoParagraph = 1;
1054 }
1055
1056 /*
@@ -1121,11 +1121,11 @@
1121 if( once ){
1122 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
1123 db_static_prepare(&q,
1124 "SELECT %s FROM ticket "
1125 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
1126 zClosedExpr
1127 );
1128 once = 0;
1129 }
1130 db_bind_text(&q, ":lwr", zLower);
1131 db_bind_text(&q, ":upr", zUpper);
@@ -1243,11 +1243,11 @@
1243 }
1244 }else if( !in_this_repo(zTarget) ){
1245 if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
1246 zTerm = "";
1247 }else{
1248 blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
1249 zTerm = "]</span>";
1250 }
1251 }else if( g.perm.Hyperlink ){
1252 blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
1253 zTerm = "]</a>";
@@ -1328,11 +1328,11 @@
1328 if( p->wikiList ){
1329 popStackToTag(p, p->wikiList);
1330 p->wikiList = 0;
1331 }
1332 endAutoParagraph(p);
1333 blob_appendf(p->pOut, "\n\n", 1);
1334 p->wantAutoParagraph = 1;
1335 }
1336 p->state |= AT_PARAGRAPH|AT_NEWLINE;
1337 break;
1338 }
1339
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1046,11 +1046,11 @@
1046 */
1047 static void startAutoParagraph(Renderer *p){
1048 if( p->wantAutoParagraph==0 ) return;
1049 if( p->state & WIKI_LINKSONLY ) return;
1050 if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
1051 blob_append(p->pOut, "<p>", -1);
1052 p->wantAutoParagraph = 0;
1053 p->inAutoParagraph = 1;
1054 }
1055
1056 /*
@@ -1121,11 +1121,11 @@
1121 if( once ){
1122 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
1123 db_static_prepare(&q,
1124 "SELECT %s FROM ticket "
1125 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
1126 zClosedExpr /*safe-for-%s*/
1127 );
1128 once = 0;
1129 }
1130 db_bind_text(&q, ":lwr", zLower);
1131 db_bind_text(&q, ":upr", zUpper);
@@ -1243,11 +1243,11 @@
1243 }
1244 }else if( !in_this_repo(zTarget) ){
1245 if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
1246 zTerm = "";
1247 }else{
1248 blob_appendf(p->pOut, "<span class=\"brokenlink\">[");
1249 zTerm = "]</span>";
1250 }
1251 }else if( g.perm.Hyperlink ){
1252 blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
1253 zTerm = "]</a>";
@@ -1328,11 +1328,11 @@
1328 if( p->wikiList ){
1329 popStackToTag(p, p->wikiList);
1330 p->wikiList = 0;
1331 }
1332 endAutoParagraph(p);
1333 blob_append(p->pOut, "\n\n", 1);
1334 p->wantAutoParagraph = 1;
1335 }
1336 p->state |= AT_PARAGRAPH|AT_NEWLINE;
1337 break;
1338 }
1339
+33 -27
--- src/winhttp.c
+++ src/winhttp.c
@@ -58,10 +58,21 @@
5858
}
5959
zHdr++;
6060
}
6161
return 0;
6262
}
63
+
64
+/*
65
+** Issue a fatal error.
66
+*/
67
+static NORETURN void winhttp_fatal(
68
+ const char *zOp,
69
+ const char *zService,
70
+ const char *zErr
71
+){
72
+ fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
73
+}
6374
6475
/*
6576
** Process a single incoming HTTP request.
6677
*/
6778
static void win32_http_request(void *pAppData){
@@ -297,11 +308,11 @@
297308
zTempPrefix = mprintf("%sfossil_server_P%d_",
298309
fossil_unicode_to_utf8(zTmpPath), iPort);
299310
fossil_print("Listening for %s requests on TCP port %d\n",
300311
(flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
301312
if( zBrowser ){
302
- zBrowser = mprintf(zBrowser, iPort);
313
+ zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
303314
fossil_print("Launch webbrowser: %s\n", zBrowser);
304315
fossil_system(zBrowser);
305316
}
306317
fossil_print("Type Ctrl-C to stop the HTTP server\n");
307318
/* Set the service status to running and pass the listener socket to the
@@ -679,11 +690,10 @@
679690
if( strncmp(zMethod, "create", n)==0 ){
680691
SC_HANDLE hScm;
681692
SC_HANDLE hSvc;
682693
SERVICE_DESCRIPTIONW
683694
svcDescr = {L"Fossil - Distributed Software Configuration Management"};
684
- char *zErrFmt = "unable to create service '%s': %s";
685695
DWORD dwStartType = SERVICE_DEMAND_START;
686696
const char *zDisplay = find_option("display", "D", 1);
687697
const char *zStart = find_option("start", "S", 1);
688698
const char *zUsername = find_option("username", "U", 1);
689699
const char *zPassword = find_option("password", "W", 1);
@@ -714,17 +724,17 @@
714724
if( strncmp(zStart, "auto", strlen(zStart))==0 ){
715725
dwStartType = SERVICE_AUTO_START;
716726
}else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
717727
dwStartType = SERVICE_DEMAND_START;
718728
}else{
719
- fossil_fatal(zErrFmt, zSvcName,
729
+ winhttp_fatal("create", zSvcName,
720730
"specify 'auto' or 'manual' for the '-S|--start' option");
721731
}
722732
}
723733
/* Process options for Fossil running as server. */
724734
if( zPort && (atoi(zPort)<=0) ){
725
- fossil_fatal(zErrFmt, zSvcName,
735
+ winhttp_fatal("create", zSvcName,
726736
"port number must be in the range 1 - 65535.");
727737
}
728738
if( !zRepository ){
729739
db_must_be_within_tree();
730740
}else if( file_isdir(zRepository)==1 ){
@@ -743,11 +753,11 @@
743753
if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
744754
if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
745755
blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
746756
/* Create the service. */
747757
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
748
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
758
+ if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
749759
hSvc = CreateServiceW(
750760
hScm, /* Handle to the SCM */
751761
fossil_utf8_to_unicode(zSvcName), /* Name of the service */
752762
fossil_utf8_to_unicode(zDisplay), /* Display name */
753763
SERVICE_ALL_ACCESS, /* Desired access */
@@ -759,11 +769,11 @@
759769
NULL, /* Tag value */
760770
NULL, /* Service dependencies */
761771
zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
762772
fossil_utf8_to_unicode(zPassword) /* Account password */
763773
);
764
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
774
+ if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
765775
/* Set the service description. */
766776
ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
767777
fossil_print("Service '%s' successfully created.\n", zSvcName);
768778
CloseServiceHandle(hSvc);
769779
CloseServiceHandle(hScm);
@@ -770,29 +780,28 @@
770780
}else
771781
if( strncmp(zMethod, "delete", n)==0 ){
772782
SC_HANDLE hScm;
773783
SC_HANDLE hSvc;
774784
SERVICE_STATUS sstat;
775
- char *zErrFmt = "unable to delete service '%s': %s";
776785
777786
verify_all_options();
778787
if( g.argc==4 ){
779788
zSvcName = g.argv[3];
780789
}else if( g.argc>4 ){
781790
fossil_fatal("too many arguments for delete method.");
782791
}
783792
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
784
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
793
+ if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
785794
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
786795
SERVICE_ALL_ACCESS);
787
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
796
+ if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
788797
QueryServiceStatus(hSvc, &sstat);
789798
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
790799
fossil_print("Stopping service '%s'", zSvcName);
791800
if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
792801
if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
793
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
802
+ winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
794803
}
795804
}
796805
while( sstat.dwCurrentState!=SERVICE_STOPPED ){
797806
Sleep(100);
798807
fossil_print(".");
@@ -802,11 +811,11 @@
802811
}
803812
if( !DeleteService(hSvc) ){
804813
if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
805814
fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
806815
}else{
807
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
816
+ winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
808817
}
809818
}else{
810819
fossil_print("Service '%s' successfully deleted.\n", zSvcName);
811820
}
812821
CloseServiceHandle(hSvc);
@@ -818,11 +827,10 @@
818827
SERVICE_STATUS sstat;
819828
LPQUERY_SERVICE_CONFIGW pSvcConfig;
820829
LPSERVICE_DESCRIPTIONW pSvcDescr;
821830
BOOL bStatus;
822831
DWORD nRequired;
823
- const char *zErrFmt = "unable to show service '%s': %s";
824832
static const char *const zSvcTypes[] = {
825833
"Driver service",
826834
"File system driver service",
827835
"Service runs in its own process",
828836
"Service shares a process with other services",
@@ -848,21 +856,21 @@
848856
zSvcName = g.argv[3];
849857
}else if( g.argc>4 ){
850858
fossil_fatal("too many arguments for show method.");
851859
}
852860
hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
853
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
861
+ if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
854862
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
855
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
863
+ if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
856864
/* Get the service configuration */
857865
bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
858866
if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
859
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
867
+ winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
860868
}
861869
pSvcConfig = fossil_malloc(nRequired);
862870
bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
863
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
871
+ if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
864872
/* Translate the service type */
865873
switch( pSvcConfig->dwServiceType ){
866874
case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break;
867875
case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break;
868876
case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break;
@@ -879,19 +887,19 @@
879887
}
880888
/* Get the service description. */
881889
bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
882890
NULL, 0, &nRequired);
883891
if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
884
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
892
+ winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
885893
}
886894
pSvcDescr = fossil_malloc(nRequired);
887895
bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
888896
(LPBYTE)pSvcDescr, nRequired, &nRequired);
889
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
897
+ if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
890898
/* Retrieves the current status of the specified service. */
891899
bStatus = QueryServiceStatus(hSvc, &sstat);
892
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
900
+ if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
893901
/* Translate the current state. */
894902
switch( sstat.dwCurrentState ){
895903
case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break;
896904
case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break;
897905
case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break;
@@ -921,29 +929,28 @@
921929
}else
922930
if( strncmp(zMethod, "start", n)==0 ){
923931
SC_HANDLE hScm;
924932
SC_HANDLE hSvc;
925933
SERVICE_STATUS sstat;
926
- char *zErrFmt = "unable to start service '%s': %s";
927934
928935
verify_all_options();
929936
if( g.argc==4 ){
930937
zSvcName = g.argv[3];
931938
}else if( g.argc>4 ){
932939
fossil_fatal("too many arguments for start method.");
933940
}
934941
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
935
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
942
+ if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
936943
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
937944
SERVICE_ALL_ACCESS);
938
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
945
+ if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
939946
QueryServiceStatus(hSvc, &sstat);
940947
if( sstat.dwCurrentState!=SERVICE_RUNNING ){
941948
fossil_print("Starting service '%s'", zSvcName);
942949
if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
943950
if( !StartServiceW(hSvc, 0, NULL) ){
944
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
951
+ winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
945952
}
946953
}
947954
while( sstat.dwCurrentState!=SERVICE_RUNNING ){
948955
Sleep(100);
949956
fossil_print(".");
@@ -958,29 +965,28 @@
958965
}else
959966
if( strncmp(zMethod, "stop", n)==0 ){
960967
SC_HANDLE hScm;
961968
SC_HANDLE hSvc;
962969
SERVICE_STATUS sstat;
963
- char *zErrFmt = "unable to stop service '%s': %s";
964970
965971
verify_all_options();
966972
if( g.argc==4 ){
967973
zSvcName = g.argv[3];
968974
}else if( g.argc>4 ){
969975
fossil_fatal("too many arguments for stop method.");
970976
}
971977
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
972
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
978
+ if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
973979
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
974980
SERVICE_ALL_ACCESS);
975
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
981
+ if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
976982
QueryServiceStatus(hSvc, &sstat);
977983
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
978984
fossil_print("Stopping service '%s'", zSvcName);
979985
if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
980986
if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
981
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
987
+ winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
982988
}
983989
}
984990
while( sstat.dwCurrentState!=SERVICE_STOPPED ){
985991
Sleep(100);
986992
fossil_print(".");
987993
--- src/winhttp.c
+++ src/winhttp.c
@@ -58,10 +58,21 @@
58 }
59 zHdr++;
60 }
61 return 0;
62 }
 
 
 
 
 
 
 
 
 
 
 
63
64 /*
65 ** Process a single incoming HTTP request.
66 */
67 static void win32_http_request(void *pAppData){
@@ -297,11 +308,11 @@
297 zTempPrefix = mprintf("%sfossil_server_P%d_",
298 fossil_unicode_to_utf8(zTmpPath), iPort);
299 fossil_print("Listening for %s requests on TCP port %d\n",
300 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
301 if( zBrowser ){
302 zBrowser = mprintf(zBrowser, iPort);
303 fossil_print("Launch webbrowser: %s\n", zBrowser);
304 fossil_system(zBrowser);
305 }
306 fossil_print("Type Ctrl-C to stop the HTTP server\n");
307 /* Set the service status to running and pass the listener socket to the
@@ -679,11 +690,10 @@
679 if( strncmp(zMethod, "create", n)==0 ){
680 SC_HANDLE hScm;
681 SC_HANDLE hSvc;
682 SERVICE_DESCRIPTIONW
683 svcDescr = {L"Fossil - Distributed Software Configuration Management"};
684 char *zErrFmt = "unable to create service '%s': %s";
685 DWORD dwStartType = SERVICE_DEMAND_START;
686 const char *zDisplay = find_option("display", "D", 1);
687 const char *zStart = find_option("start", "S", 1);
688 const char *zUsername = find_option("username", "U", 1);
689 const char *zPassword = find_option("password", "W", 1);
@@ -714,17 +724,17 @@
714 if( strncmp(zStart, "auto", strlen(zStart))==0 ){
715 dwStartType = SERVICE_AUTO_START;
716 }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
717 dwStartType = SERVICE_DEMAND_START;
718 }else{
719 fossil_fatal(zErrFmt, zSvcName,
720 "specify 'auto' or 'manual' for the '-S|--start' option");
721 }
722 }
723 /* Process options for Fossil running as server. */
724 if( zPort && (atoi(zPort)<=0) ){
725 fossil_fatal(zErrFmt, zSvcName,
726 "port number must be in the range 1 - 65535.");
727 }
728 if( !zRepository ){
729 db_must_be_within_tree();
730 }else if( file_isdir(zRepository)==1 ){
@@ -743,11 +753,11 @@
743 if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
744 if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
745 blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
746 /* Create the service. */
747 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
748 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
749 hSvc = CreateServiceW(
750 hScm, /* Handle to the SCM */
751 fossil_utf8_to_unicode(zSvcName), /* Name of the service */
752 fossil_utf8_to_unicode(zDisplay), /* Display name */
753 SERVICE_ALL_ACCESS, /* Desired access */
@@ -759,11 +769,11 @@
759 NULL, /* Tag value */
760 NULL, /* Service dependencies */
761 zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
762 fossil_utf8_to_unicode(zPassword) /* Account password */
763 );
764 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
765 /* Set the service description. */
766 ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
767 fossil_print("Service '%s' successfully created.\n", zSvcName);
768 CloseServiceHandle(hSvc);
769 CloseServiceHandle(hScm);
@@ -770,29 +780,28 @@
770 }else
771 if( strncmp(zMethod, "delete", n)==0 ){
772 SC_HANDLE hScm;
773 SC_HANDLE hSvc;
774 SERVICE_STATUS sstat;
775 char *zErrFmt = "unable to delete service '%s': %s";
776
777 verify_all_options();
778 if( g.argc==4 ){
779 zSvcName = g.argv[3];
780 }else if( g.argc>4 ){
781 fossil_fatal("too many arguments for delete method.");
782 }
783 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
784 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
785 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
786 SERVICE_ALL_ACCESS);
787 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
788 QueryServiceStatus(hSvc, &sstat);
789 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
790 fossil_print("Stopping service '%s'", zSvcName);
791 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
792 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
793 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
794 }
795 }
796 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
797 Sleep(100);
798 fossil_print(".");
@@ -802,11 +811,11 @@
802 }
803 if( !DeleteService(hSvc) ){
804 if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
805 fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
806 }else{
807 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
808 }
809 }else{
810 fossil_print("Service '%s' successfully deleted.\n", zSvcName);
811 }
812 CloseServiceHandle(hSvc);
@@ -818,11 +827,10 @@
818 SERVICE_STATUS sstat;
819 LPQUERY_SERVICE_CONFIGW pSvcConfig;
820 LPSERVICE_DESCRIPTIONW pSvcDescr;
821 BOOL bStatus;
822 DWORD nRequired;
823 const char *zErrFmt = "unable to show service '%s': %s";
824 static const char *const zSvcTypes[] = {
825 "Driver service",
826 "File system driver service",
827 "Service runs in its own process",
828 "Service shares a process with other services",
@@ -848,21 +856,21 @@
848 zSvcName = g.argv[3];
849 }else if( g.argc>4 ){
850 fossil_fatal("too many arguments for show method.");
851 }
852 hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
853 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
854 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
855 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
856 /* Get the service configuration */
857 bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
858 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
859 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
860 }
861 pSvcConfig = fossil_malloc(nRequired);
862 bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
863 if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
864 /* Translate the service type */
865 switch( pSvcConfig->dwServiceType ){
866 case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break;
867 case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break;
868 case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break;
@@ -879,19 +887,19 @@
879 }
880 /* Get the service description. */
881 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
882 NULL, 0, &nRequired);
883 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
884 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
885 }
886 pSvcDescr = fossil_malloc(nRequired);
887 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
888 (LPBYTE)pSvcDescr, nRequired, &nRequired);
889 if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
890 /* Retrieves the current status of the specified service. */
891 bStatus = QueryServiceStatus(hSvc, &sstat);
892 if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
893 /* Translate the current state. */
894 switch( sstat.dwCurrentState ){
895 case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break;
896 case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break;
897 case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break;
@@ -921,29 +929,28 @@
921 }else
922 if( strncmp(zMethod, "start", n)==0 ){
923 SC_HANDLE hScm;
924 SC_HANDLE hSvc;
925 SERVICE_STATUS sstat;
926 char *zErrFmt = "unable to start service '%s': %s";
927
928 verify_all_options();
929 if( g.argc==4 ){
930 zSvcName = g.argv[3];
931 }else if( g.argc>4 ){
932 fossil_fatal("too many arguments for start method.");
933 }
934 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
935 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
936 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
937 SERVICE_ALL_ACCESS);
938 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
939 QueryServiceStatus(hSvc, &sstat);
940 if( sstat.dwCurrentState!=SERVICE_RUNNING ){
941 fossil_print("Starting service '%s'", zSvcName);
942 if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
943 if( !StartServiceW(hSvc, 0, NULL) ){
944 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
945 }
946 }
947 while( sstat.dwCurrentState!=SERVICE_RUNNING ){
948 Sleep(100);
949 fossil_print(".");
@@ -958,29 +965,28 @@
958 }else
959 if( strncmp(zMethod, "stop", n)==0 ){
960 SC_HANDLE hScm;
961 SC_HANDLE hSvc;
962 SERVICE_STATUS sstat;
963 char *zErrFmt = "unable to stop service '%s': %s";
964
965 verify_all_options();
966 if( g.argc==4 ){
967 zSvcName = g.argv[3];
968 }else if( g.argc>4 ){
969 fossil_fatal("too many arguments for stop method.");
970 }
971 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
972 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
973 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
974 SERVICE_ALL_ACCESS);
975 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
976 QueryServiceStatus(hSvc, &sstat);
977 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
978 fossil_print("Stopping service '%s'", zSvcName);
979 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
980 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
981 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
982 }
983 }
984 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
985 Sleep(100);
986 fossil_print(".");
987
--- src/winhttp.c
+++ src/winhttp.c
@@ -58,10 +58,21 @@
58 }
59 zHdr++;
60 }
61 return 0;
62 }
63
64 /*
65 ** Issue a fatal error.
66 */
67 static NORETURN void winhttp_fatal(
68 const char *zOp,
69 const char *zService,
70 const char *zErr
71 ){
72 fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
73 }
74
75 /*
76 ** Process a single incoming HTTP request.
77 */
78 static void win32_http_request(void *pAppData){
@@ -297,11 +308,11 @@
308 zTempPrefix = mprintf("%sfossil_server_P%d_",
309 fossil_unicode_to_utf8(zTmpPath), iPort);
310 fossil_print("Listening for %s requests on TCP port %d\n",
311 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
312 if( zBrowser ){
313 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
314 fossil_print("Launch webbrowser: %s\n", zBrowser);
315 fossil_system(zBrowser);
316 }
317 fossil_print("Type Ctrl-C to stop the HTTP server\n");
318 /* Set the service status to running and pass the listener socket to the
@@ -679,11 +690,10 @@
690 if( strncmp(zMethod, "create", n)==0 ){
691 SC_HANDLE hScm;
692 SC_HANDLE hSvc;
693 SERVICE_DESCRIPTIONW
694 svcDescr = {L"Fossil - Distributed Software Configuration Management"};
 
695 DWORD dwStartType = SERVICE_DEMAND_START;
696 const char *zDisplay = find_option("display", "D", 1);
697 const char *zStart = find_option("start", "S", 1);
698 const char *zUsername = find_option("username", "U", 1);
699 const char *zPassword = find_option("password", "W", 1);
@@ -714,17 +724,17 @@
724 if( strncmp(zStart, "auto", strlen(zStart))==0 ){
725 dwStartType = SERVICE_AUTO_START;
726 }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
727 dwStartType = SERVICE_DEMAND_START;
728 }else{
729 winhttp_fatal("create", zSvcName,
730 "specify 'auto' or 'manual' for the '-S|--start' option");
731 }
732 }
733 /* Process options for Fossil running as server. */
734 if( zPort && (atoi(zPort)<=0) ){
735 winhttp_fatal("create", zSvcName,
736 "port number must be in the range 1 - 65535.");
737 }
738 if( !zRepository ){
739 db_must_be_within_tree();
740 }else if( file_isdir(zRepository)==1 ){
@@ -743,11 +753,11 @@
753 if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
754 if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
755 blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
756 /* Create the service. */
757 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
758 if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
759 hSvc = CreateServiceW(
760 hScm, /* Handle to the SCM */
761 fossil_utf8_to_unicode(zSvcName), /* Name of the service */
762 fossil_utf8_to_unicode(zDisplay), /* Display name */
763 SERVICE_ALL_ACCESS, /* Desired access */
@@ -759,11 +769,11 @@
769 NULL, /* Tag value */
770 NULL, /* Service dependencies */
771 zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
772 fossil_utf8_to_unicode(zPassword) /* Account password */
773 );
774 if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
775 /* Set the service description. */
776 ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
777 fossil_print("Service '%s' successfully created.\n", zSvcName);
778 CloseServiceHandle(hSvc);
779 CloseServiceHandle(hScm);
@@ -770,29 +780,28 @@
780 }else
781 if( strncmp(zMethod, "delete", n)==0 ){
782 SC_HANDLE hScm;
783 SC_HANDLE hSvc;
784 SERVICE_STATUS sstat;
 
785
786 verify_all_options();
787 if( g.argc==4 ){
788 zSvcName = g.argv[3];
789 }else if( g.argc>4 ){
790 fossil_fatal("too many arguments for delete method.");
791 }
792 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
793 if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
794 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
795 SERVICE_ALL_ACCESS);
796 if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
797 QueryServiceStatus(hSvc, &sstat);
798 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
799 fossil_print("Stopping service '%s'", zSvcName);
800 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
801 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
802 winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
803 }
804 }
805 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
806 Sleep(100);
807 fossil_print(".");
@@ -802,11 +811,11 @@
811 }
812 if( !DeleteService(hSvc) ){
813 if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
814 fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
815 }else{
816 winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
817 }
818 }else{
819 fossil_print("Service '%s' successfully deleted.\n", zSvcName);
820 }
821 CloseServiceHandle(hSvc);
@@ -818,11 +827,10 @@
827 SERVICE_STATUS sstat;
828 LPQUERY_SERVICE_CONFIGW pSvcConfig;
829 LPSERVICE_DESCRIPTIONW pSvcDescr;
830 BOOL bStatus;
831 DWORD nRequired;
 
832 static const char *const zSvcTypes[] = {
833 "Driver service",
834 "File system driver service",
835 "Service runs in its own process",
836 "Service shares a process with other services",
@@ -848,21 +856,21 @@
856 zSvcName = g.argv[3];
857 }else if( g.argc>4 ){
858 fossil_fatal("too many arguments for show method.");
859 }
860 hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
861 if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
862 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
863 if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
864 /* Get the service configuration */
865 bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
866 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
867 winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
868 }
869 pSvcConfig = fossil_malloc(nRequired);
870 bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
871 if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
872 /* Translate the service type */
873 switch( pSvcConfig->dwServiceType ){
874 case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break;
875 case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break;
876 case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break;
@@ -879,19 +887,19 @@
887 }
888 /* Get the service description. */
889 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
890 NULL, 0, &nRequired);
891 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
892 winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
893 }
894 pSvcDescr = fossil_malloc(nRequired);
895 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
896 (LPBYTE)pSvcDescr, nRequired, &nRequired);
897 if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
898 /* Retrieves the current status of the specified service. */
899 bStatus = QueryServiceStatus(hSvc, &sstat);
900 if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
901 /* Translate the current state. */
902 switch( sstat.dwCurrentState ){
903 case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break;
904 case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break;
905 case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break;
@@ -921,29 +929,28 @@
929 }else
930 if( strncmp(zMethod, "start", n)==0 ){
931 SC_HANDLE hScm;
932 SC_HANDLE hSvc;
933 SERVICE_STATUS sstat;
 
934
935 verify_all_options();
936 if( g.argc==4 ){
937 zSvcName = g.argv[3];
938 }else if( g.argc>4 ){
939 fossil_fatal("too many arguments for start method.");
940 }
941 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
942 if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
943 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
944 SERVICE_ALL_ACCESS);
945 if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
946 QueryServiceStatus(hSvc, &sstat);
947 if( sstat.dwCurrentState!=SERVICE_RUNNING ){
948 fossil_print("Starting service '%s'", zSvcName);
949 if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
950 if( !StartServiceW(hSvc, 0, NULL) ){
951 winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
952 }
953 }
954 while( sstat.dwCurrentState!=SERVICE_RUNNING ){
955 Sleep(100);
956 fossil_print(".");
@@ -958,29 +965,28 @@
965 }else
966 if( strncmp(zMethod, "stop", n)==0 ){
967 SC_HANDLE hScm;
968 SC_HANDLE hSvc;
969 SERVICE_STATUS sstat;
 
970
971 verify_all_options();
972 if( g.argc==4 ){
973 zSvcName = g.argv[3];
974 }else if( g.argc>4 ){
975 fossil_fatal("too many arguments for stop method.");
976 }
977 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
978 if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
979 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
980 SERVICE_ALL_ACCESS);
981 if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
982 QueryServiceStatus(hSvc, &sstat);
983 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
984 fossil_print("Stopping service '%s'", zSvcName);
985 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
986 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
987 winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
988 }
989 }
990 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
991 Sleep(100);
992 fossil_print(".");
993
+16 -13
--- src/xfer.c
+++ src/xfer.c
@@ -201,11 +201,11 @@
201201
if( rid==0 ){
202202
blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203203
blob_reset(&content);
204204
}else{
205205
if( !isPriv ) content_make_public(rid);
206
- manifest_crosslink(rid, &content, MC_NONE);
206
+ manifest_crosslink(rid, &content, MC_NO_ERRORS);
207207
}
208208
assert( blob_is_reset(&content) );
209209
remote_has(rid);
210210
}
211211
@@ -311,11 +311,11 @@
311311
Blob src, delta;
312312
int size = 0;
313313
int srcId = 0;
314314
315315
for(i=0; srcId==0 && i<count(azQuery); i++){
316
- srcId = db_int(0, azQuery[i], rid);
316
+ srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
317317
}
318318
if( srcId>0
319319
&& (pXfer->syncPrivate || !content_is_private(srcId))
320320
&& content_get(srcId, &src)
321321
){
@@ -422,11 +422,11 @@
422422
return;
423423
}
424424
if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425425
pXfer->mxSend<=blob_size(pXfer->pOut) ){
426426
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427
- blob_appendf(pXfer->pOut, zFormat, pUuid);
427
+ blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
428428
pXfer->nIGotSent++;
429429
blob_reset(&uuid);
430430
return;
431431
}
432432
if( nativeDelta ){
@@ -454,11 +454,11 @@
454454
}
455455
remote_has(rid);
456456
blob_reset(&uuid);
457457
#if 0
458458
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459
- blob_appendf(pXfer->pOut, "\n", 1);
459
+ blob_append(pXfer->pOut, "\n", 1);
460460
}
461461
#endif
462462
}
463463
464464
/*
@@ -514,11 +514,11 @@
514514
pXfer->nFileSent++;
515515
}
516516
blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517517
blob_append(pXfer->pOut, zContent, szC);
518518
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519
- blob_appendf(pXfer->pOut, "\n", 1);
519
+ blob_append(pXfer->pOut, "\n", 1);
520520
}
521521
if( !isPrivate && srcIsPrivate ){
522522
blob_reset(&fullContent);
523523
}
524524
}
@@ -711,18 +711,18 @@
711711
blob_reset(&cksum);
712712
rid = content_put(&cluster);
713713
blob_reset(&cluster);
714714
nUncl -= nRow;
715715
nRow = 0;
716
- blob_appendf(&deleteWhere, ",%d", rid);
716
+ blob_append_sql(&deleteWhere, ",%d", rid);
717717
}
718718
}
719719
db_finalize(&q);
720720
db_multi_exec(
721721
"DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722722
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723
- blob_str(&deleteWhere)
723
+ blob_sql_text(&deleteWhere)
724724
);
725725
blob_reset(&deleteWhere);
726726
if( nRow>0 ){
727727
md5sum_blob(&cluster, &cksum);
728728
blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1501,11 +1501,12 @@
15011501
nCardSent++;
15021502
if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
15031503
if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
15041504
}
15051505
if( syncFlags & SYNC_VERBOSE ){
1506
- fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
1506
+ fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
1507
+ "", "Bytes", "Cards", "Artifacts", "Deltas");
15071508
}
15081509
15091510
while( go ){
15101511
int newPhantom = 0;
15111512
char *zRandomness;
@@ -1598,17 +1599,18 @@
15981599
break;
15991600
}
16001601
16011602
/* Output current stats */
16021603
if( syncFlags & SYNC_VERBOSE ){
1603
- fossil_print(zValueFormat, "Sent:",
1604
+ fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
16041605
blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
16051606
xfer.nFileSent, xfer.nDeltaSent);
16061607
}else{
16071608
nRoundtrip++;
16081609
nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1609
- fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
1610
+ fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1611
+ nRoundtrip, nArtifactSent, nArtifactRcvd);
16101612
}
16111613
nCardSent = 0;
16121614
nCardRcvd = 0;
16131615
xfer.nFileSent = 0;
16141616
xfer.nDeltaSent = 0;
@@ -1819,11 +1821,11 @@
18191821
** to the next cycle.
18201822
*/
18211823
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
18221824
char *zMsg = blob_terminate(&xfer.aToken[1]);
18231825
defossilize(zMsg);
1824
- if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
1826
+ if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
18251827
syncFlags &= ~SYNC_PUSH;
18261828
zMsg = 0;
18271829
}
18281830
if( zMsg && zMsg[0] ){
18291831
fossil_force_newline();
@@ -1905,15 +1907,16 @@
19051907
){
19061908
configure_finalize_receive();
19071909
}
19081910
origConfigRcvMask = 0;
19091911
if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1910
- fossil_print(zValueFormat, "Received:",
1912
+ fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
19111913
blob_size(&recv), nCardRcvd,
19121914
xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
19131915
}else{
1914
- fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
1916
+ fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1917
+ nRoundtrip, nArtifactSent, nArtifactRcvd);
19151918
}
19161919
blob_reset(&recv);
19171920
nCycle++;
19181921
19191922
/* If we received one or more files on the previous exchange but
19201923
--- src/xfer.c
+++ src/xfer.c
@@ -201,11 +201,11 @@
201 if( rid==0 ){
202 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203 blob_reset(&content);
204 }else{
205 if( !isPriv ) content_make_public(rid);
206 manifest_crosslink(rid, &content, MC_NONE);
207 }
208 assert( blob_is_reset(&content) );
209 remote_has(rid);
210 }
211
@@ -311,11 +311,11 @@
311 Blob src, delta;
312 int size = 0;
313 int srcId = 0;
314
315 for(i=0; srcId==0 && i<count(azQuery); i++){
316 srcId = db_int(0, azQuery[i], rid);
317 }
318 if( srcId>0
319 && (pXfer->syncPrivate || !content_is_private(srcId))
320 && content_get(srcId, &src)
321 ){
@@ -422,11 +422,11 @@
422 return;
423 }
424 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425 pXfer->mxSend<=blob_size(pXfer->pOut) ){
426 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427 blob_appendf(pXfer->pOut, zFormat, pUuid);
428 pXfer->nIGotSent++;
429 blob_reset(&uuid);
430 return;
431 }
432 if( nativeDelta ){
@@ -454,11 +454,11 @@
454 }
455 remote_has(rid);
456 blob_reset(&uuid);
457 #if 0
458 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459 blob_appendf(pXfer->pOut, "\n", 1);
460 }
461 #endif
462 }
463
464 /*
@@ -514,11 +514,11 @@
514 pXfer->nFileSent++;
515 }
516 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517 blob_append(pXfer->pOut, zContent, szC);
518 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519 blob_appendf(pXfer->pOut, "\n", 1);
520 }
521 if( !isPrivate && srcIsPrivate ){
522 blob_reset(&fullContent);
523 }
524 }
@@ -711,18 +711,18 @@
711 blob_reset(&cksum);
712 rid = content_put(&cluster);
713 blob_reset(&cluster);
714 nUncl -= nRow;
715 nRow = 0;
716 blob_appendf(&deleteWhere, ",%d", rid);
717 }
718 }
719 db_finalize(&q);
720 db_multi_exec(
721 "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723 blob_str(&deleteWhere)
724 );
725 blob_reset(&deleteWhere);
726 if( nRow>0 ){
727 md5sum_blob(&cluster, &cksum);
728 blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1501,11 +1501,12 @@
1501 nCardSent++;
1502 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1503 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1504 }
1505 if( syncFlags & SYNC_VERBOSE ){
1506 fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
 
1507 }
1508
1509 while( go ){
1510 int newPhantom = 0;
1511 char *zRandomness;
@@ -1598,17 +1599,18 @@
1598 break;
1599 }
1600
1601 /* Output current stats */
1602 if( syncFlags & SYNC_VERBOSE ){
1603 fossil_print(zValueFormat, "Sent:",
1604 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1605 xfer.nFileSent, xfer.nDeltaSent);
1606 }else{
1607 nRoundtrip++;
1608 nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1609 fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
 
1610 }
1611 nCardSent = 0;
1612 nCardRcvd = 0;
1613 xfer.nFileSent = 0;
1614 xfer.nDeltaSent = 0;
@@ -1819,11 +1821,11 @@
1819 ** to the next cycle.
1820 */
1821 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
1822 char *zMsg = blob_terminate(&xfer.aToken[1]);
1823 defossilize(zMsg);
1824 if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
1825 syncFlags &= ~SYNC_PUSH;
1826 zMsg = 0;
1827 }
1828 if( zMsg && zMsg[0] ){
1829 fossil_force_newline();
@@ -1905,15 +1907,16 @@
1905 ){
1906 configure_finalize_receive();
1907 }
1908 origConfigRcvMask = 0;
1909 if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1910 fossil_print(zValueFormat, "Received:",
1911 blob_size(&recv), nCardRcvd,
1912 xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1913 }else{
1914 fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
 
1915 }
1916 blob_reset(&recv);
1917 nCycle++;
1918
1919 /* If we received one or more files on the previous exchange but
1920
--- src/xfer.c
+++ src/xfer.c
@@ -201,11 +201,11 @@
201 if( rid==0 ){
202 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203 blob_reset(&content);
204 }else{
205 if( !isPriv ) content_make_public(rid);
206 manifest_crosslink(rid, &content, MC_NO_ERRORS);
207 }
208 assert( blob_is_reset(&content) );
209 remote_has(rid);
210 }
211
@@ -311,11 +311,11 @@
311 Blob src, delta;
312 int size = 0;
313 int srcId = 0;
314
315 for(i=0; srcId==0 && i<count(azQuery); i++){
316 srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
317 }
318 if( srcId>0
319 && (pXfer->syncPrivate || !content_is_private(srcId))
320 && content_get(srcId, &src)
321 ){
@@ -422,11 +422,11 @@
422 return;
423 }
424 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425 pXfer->mxSend<=blob_size(pXfer->pOut) ){
426 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427 blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
428 pXfer->nIGotSent++;
429 blob_reset(&uuid);
430 return;
431 }
432 if( nativeDelta ){
@@ -454,11 +454,11 @@
454 }
455 remote_has(rid);
456 blob_reset(&uuid);
457 #if 0
458 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459 blob_append(pXfer->pOut, "\n", 1);
460 }
461 #endif
462 }
463
464 /*
@@ -514,11 +514,11 @@
514 pXfer->nFileSent++;
515 }
516 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517 blob_append(pXfer->pOut, zContent, szC);
518 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519 blob_append(pXfer->pOut, "\n", 1);
520 }
521 if( !isPrivate && srcIsPrivate ){
522 blob_reset(&fullContent);
523 }
524 }
@@ -711,18 +711,18 @@
711 blob_reset(&cksum);
712 rid = content_put(&cluster);
713 blob_reset(&cluster);
714 nUncl -= nRow;
715 nRow = 0;
716 blob_append_sql(&deleteWhere, ",%d", rid);
717 }
718 }
719 db_finalize(&q);
720 db_multi_exec(
721 "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723 blob_sql_text(&deleteWhere)
724 );
725 blob_reset(&deleteWhere);
726 if( nRow>0 ){
727 md5sum_blob(&cluster, &cksum);
728 blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1501,11 +1501,12 @@
1501 nCardSent++;
1502 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1503 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1504 }
1505 if( syncFlags & SYNC_VERBOSE ){
1506 fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
1507 "", "Bytes", "Cards", "Artifacts", "Deltas");
1508 }
1509
1510 while( go ){
1511 int newPhantom = 0;
1512 char *zRandomness;
@@ -1598,17 +1599,18 @@
1599 break;
1600 }
1601
1602 /* Output current stats */
1603 if( syncFlags & SYNC_VERBOSE ){
1604 fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
1605 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1606 xfer.nFileSent, xfer.nDeltaSent);
1607 }else{
1608 nRoundtrip++;
1609 nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1610 fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1611 nRoundtrip, nArtifactSent, nArtifactRcvd);
1612 }
1613 nCardSent = 0;
1614 nCardRcvd = 0;
1615 xfer.nFileSent = 0;
1616 xfer.nDeltaSent = 0;
@@ -1819,11 +1821,11 @@
1821 ** to the next cycle.
1822 */
1823 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
1824 char *zMsg = blob_terminate(&xfer.aToken[1]);
1825 defossilize(zMsg);
1826 if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
1827 syncFlags &= ~SYNC_PUSH;
1828 zMsg = 0;
1829 }
1830 if( zMsg && zMsg[0] ){
1831 fossil_force_newline();
@@ -1905,15 +1907,16 @@
1907 ){
1908 configure_finalize_receive();
1909 }
1910 origConfigRcvMask = 0;
1911 if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1912 fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
1913 blob_size(&recv), nCardRcvd,
1914 xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1915 }else{
1916 fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1917 nRoundtrip, nArtifactSent, nArtifactRcvd);
1918 }
1919 blob_reset(&recv);
1920 nCycle++;
1921
1922 /* If we received one or more files on the previous exchange but
1923
+16 -13
--- src/xfer.c
+++ src/xfer.c
@@ -201,11 +201,11 @@
201201
if( rid==0 ){
202202
blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203203
blob_reset(&content);
204204
}else{
205205
if( !isPriv ) content_make_public(rid);
206
- manifest_crosslink(rid, &content, MC_NONE);
206
+ manifest_crosslink(rid, &content, MC_NO_ERRORS);
207207
}
208208
assert( blob_is_reset(&content) );
209209
remote_has(rid);
210210
}
211211
@@ -311,11 +311,11 @@
311311
Blob src, delta;
312312
int size = 0;
313313
int srcId = 0;
314314
315315
for(i=0; srcId==0 && i<count(azQuery); i++){
316
- srcId = db_int(0, azQuery[i], rid);
316
+ srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
317317
}
318318
if( srcId>0
319319
&& (pXfer->syncPrivate || !content_is_private(srcId))
320320
&& content_get(srcId, &src)
321321
){
@@ -422,11 +422,11 @@
422422
return;
423423
}
424424
if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425425
pXfer->mxSend<=blob_size(pXfer->pOut) ){
426426
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427
- blob_appendf(pXfer->pOut, zFormat, pUuid);
427
+ blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
428428
pXfer->nIGotSent++;
429429
blob_reset(&uuid);
430430
return;
431431
}
432432
if( nativeDelta ){
@@ -454,11 +454,11 @@
454454
}
455455
remote_has(rid);
456456
blob_reset(&uuid);
457457
#if 0
458458
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459
- blob_appendf(pXfer->pOut, "\n", 1);
459
+ blob_append(pXfer->pOut, "\n", 1);
460460
}
461461
#endif
462462
}
463463
464464
/*
@@ -514,11 +514,11 @@
514514
pXfer->nFileSent++;
515515
}
516516
blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517517
blob_append(pXfer->pOut, zContent, szC);
518518
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519
- blob_appendf(pXfer->pOut, "\n", 1);
519
+ blob_append(pXfer->pOut, "\n", 1);
520520
}
521521
if( !isPrivate && srcIsPrivate ){
522522
blob_reset(&fullContent);
523523
}
524524
}
@@ -711,18 +711,18 @@
711711
blob_reset(&cksum);
712712
rid = content_put(&cluster);
713713
blob_reset(&cluster);
714714
nUncl -= nRow;
715715
nRow = 0;
716
- blob_appendf(&deleteWhere, ",%d", rid);
716
+ blob_append_sql(&deleteWhere, ",%d", rid);
717717
}
718718
}
719719
db_finalize(&q);
720720
db_multi_exec(
721721
"DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722722
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723
- blob_str(&deleteWhere)
723
+ blob_sql_text(&deleteWhere)
724724
);
725725
blob_reset(&deleteWhere);
726726
if( nRow>0 ){
727727
md5sum_blob(&cluster, &cksum);
728728
blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1501,11 +1501,12 @@
15011501
nCardSent++;
15021502
if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
15031503
if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
15041504
}
15051505
if( syncFlags & SYNC_VERBOSE ){
1506
- fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
1506
+ fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
1507
+ "", "Bytes", "Cards", "Artifacts", "Deltas");
15071508
}
15081509
15091510
while( go ){
15101511
int newPhantom = 0;
15111512
char *zRandomness;
@@ -1598,17 +1599,18 @@
15981599
break;
15991600
}
16001601
16011602
/* Output current stats */
16021603
if( syncFlags & SYNC_VERBOSE ){
1603
- fossil_print(zValueFormat, "Sent:",
1604
+ fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
16041605
blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
16051606
xfer.nFileSent, xfer.nDeltaSent);
16061607
}else{
16071608
nRoundtrip++;
16081609
nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1609
- fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
1610
+ fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1611
+ nRoundtrip, nArtifactSent, nArtifactRcvd);
16101612
}
16111613
nCardSent = 0;
16121614
nCardRcvd = 0;
16131615
xfer.nFileSent = 0;
16141616
xfer.nDeltaSent = 0;
@@ -1819,11 +1821,11 @@
18191821
** to the next cycle.
18201822
*/
18211823
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
18221824
char *zMsg = blob_terminate(&xfer.aToken[1]);
18231825
defossilize(zMsg);
1824
- if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
1826
+ if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
18251827
syncFlags &= ~SYNC_PUSH;
18261828
zMsg = 0;
18271829
}
18281830
if( zMsg && zMsg[0] ){
18291831
fossil_force_newline();
@@ -1905,15 +1907,16 @@
19051907
){
19061908
configure_finalize_receive();
19071909
}
19081910
origConfigRcvMask = 0;
19091911
if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1910
- fossil_print(zValueFormat, "Received:",
1912
+ fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
19111913
blob_size(&recv), nCardRcvd,
19121914
xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
19131915
}else{
1914
- fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
1916
+ fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1917
+ nRoundtrip, nArtifactSent, nArtifactRcvd);
19151918
}
19161919
blob_reset(&recv);
19171920
nCycle++;
19181921
19191922
/* If we received one or more files on the previous exchange but
19201923
--- src/xfer.c
+++ src/xfer.c
@@ -201,11 +201,11 @@
201 if( rid==0 ){
202 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203 blob_reset(&content);
204 }else{
205 if( !isPriv ) content_make_public(rid);
206 manifest_crosslink(rid, &content, MC_NONE);
207 }
208 assert( blob_is_reset(&content) );
209 remote_has(rid);
210 }
211
@@ -311,11 +311,11 @@
311 Blob src, delta;
312 int size = 0;
313 int srcId = 0;
314
315 for(i=0; srcId==0 && i<count(azQuery); i++){
316 srcId = db_int(0, azQuery[i], rid);
317 }
318 if( srcId>0
319 && (pXfer->syncPrivate || !content_is_private(srcId))
320 && content_get(srcId, &src)
321 ){
@@ -422,11 +422,11 @@
422 return;
423 }
424 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425 pXfer->mxSend<=blob_size(pXfer->pOut) ){
426 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427 blob_appendf(pXfer->pOut, zFormat, pUuid);
428 pXfer->nIGotSent++;
429 blob_reset(&uuid);
430 return;
431 }
432 if( nativeDelta ){
@@ -454,11 +454,11 @@
454 }
455 remote_has(rid);
456 blob_reset(&uuid);
457 #if 0
458 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459 blob_appendf(pXfer->pOut, "\n", 1);
460 }
461 #endif
462 }
463
464 /*
@@ -514,11 +514,11 @@
514 pXfer->nFileSent++;
515 }
516 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517 blob_append(pXfer->pOut, zContent, szC);
518 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519 blob_appendf(pXfer->pOut, "\n", 1);
520 }
521 if( !isPrivate && srcIsPrivate ){
522 blob_reset(&fullContent);
523 }
524 }
@@ -711,18 +711,18 @@
711 blob_reset(&cksum);
712 rid = content_put(&cluster);
713 blob_reset(&cluster);
714 nUncl -= nRow;
715 nRow = 0;
716 blob_appendf(&deleteWhere, ",%d", rid);
717 }
718 }
719 db_finalize(&q);
720 db_multi_exec(
721 "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723 blob_str(&deleteWhere)
724 );
725 blob_reset(&deleteWhere);
726 if( nRow>0 ){
727 md5sum_blob(&cluster, &cksum);
728 blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1501,11 +1501,12 @@
1501 nCardSent++;
1502 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1503 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1504 }
1505 if( syncFlags & SYNC_VERBOSE ){
1506 fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
 
1507 }
1508
1509 while( go ){
1510 int newPhantom = 0;
1511 char *zRandomness;
@@ -1598,17 +1599,18 @@
1598 break;
1599 }
1600
1601 /* Output current stats */
1602 if( syncFlags & SYNC_VERBOSE ){
1603 fossil_print(zValueFormat, "Sent:",
1604 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1605 xfer.nFileSent, xfer.nDeltaSent);
1606 }else{
1607 nRoundtrip++;
1608 nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1609 fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
 
1610 }
1611 nCardSent = 0;
1612 nCardRcvd = 0;
1613 xfer.nFileSent = 0;
1614 xfer.nDeltaSent = 0;
@@ -1819,11 +1821,11 @@
1819 ** to the next cycle.
1820 */
1821 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
1822 char *zMsg = blob_terminate(&xfer.aToken[1]);
1823 defossilize(zMsg);
1824 if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
1825 syncFlags &= ~SYNC_PUSH;
1826 zMsg = 0;
1827 }
1828 if( zMsg && zMsg[0] ){
1829 fossil_force_newline();
@@ -1905,15 +1907,16 @@
1905 ){
1906 configure_finalize_receive();
1907 }
1908 origConfigRcvMask = 0;
1909 if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1910 fossil_print(zValueFormat, "Received:",
1911 blob_size(&recv), nCardRcvd,
1912 xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1913 }else{
1914 fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
 
1915 }
1916 blob_reset(&recv);
1917 nCycle++;
1918
1919 /* If we received one or more files on the previous exchange but
1920
--- src/xfer.c
+++ src/xfer.c
@@ -201,11 +201,11 @@
201 if( rid==0 ){
202 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
203 blob_reset(&content);
204 }else{
205 if( !isPriv ) content_make_public(rid);
206 manifest_crosslink(rid, &content, MC_NO_ERRORS);
207 }
208 assert( blob_is_reset(&content) );
209 remote_has(rid);
210 }
211
@@ -311,11 +311,11 @@
311 Blob src, delta;
312 int size = 0;
313 int srcId = 0;
314
315 for(i=0; srcId==0 && i<count(azQuery); i++){
316 srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
317 }
318 if( srcId>0
319 && (pXfer->syncPrivate || !content_is_private(srcId))
320 && content_get(srcId, &src)
321 ){
@@ -422,11 +422,11 @@
422 return;
423 }
424 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425 pXfer->mxSend<=blob_size(pXfer->pOut) ){
426 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427 blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
428 pXfer->nIGotSent++;
429 blob_reset(&uuid);
430 return;
431 }
432 if( nativeDelta ){
@@ -454,11 +454,11 @@
454 }
455 remote_has(rid);
456 blob_reset(&uuid);
457 #if 0
458 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459 blob_append(pXfer->pOut, "\n", 1);
460 }
461 #endif
462 }
463
464 /*
@@ -514,11 +514,11 @@
514 pXfer->nFileSent++;
515 }
516 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517 blob_append(pXfer->pOut, zContent, szC);
518 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519 blob_append(pXfer->pOut, "\n", 1);
520 }
521 if( !isPrivate && srcIsPrivate ){
522 blob_reset(&fullContent);
523 }
524 }
@@ -711,18 +711,18 @@
711 blob_reset(&cksum);
712 rid = content_put(&cluster);
713 blob_reset(&cluster);
714 nUncl -= nRow;
715 nRow = 0;
716 blob_append_sql(&deleteWhere, ",%d", rid);
717 }
718 }
719 db_finalize(&q);
720 db_multi_exec(
721 "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723 blob_sql_text(&deleteWhere)
724 );
725 blob_reset(&deleteWhere);
726 if( nRow>0 ){
727 md5sum_blob(&cluster, &cksum);
728 blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1501,11 +1501,12 @@
1501 nCardSent++;
1502 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1503 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1504 }
1505 if( syncFlags & SYNC_VERBOSE ){
1506 fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
1507 "", "Bytes", "Cards", "Artifacts", "Deltas");
1508 }
1509
1510 while( go ){
1511 int newPhantom = 0;
1512 char *zRandomness;
@@ -1598,17 +1599,18 @@
1599 break;
1600 }
1601
1602 /* Output current stats */
1603 if( syncFlags & SYNC_VERBOSE ){
1604 fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
1605 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1606 xfer.nFileSent, xfer.nDeltaSent);
1607 }else{
1608 nRoundtrip++;
1609 nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1610 fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1611 nRoundtrip, nArtifactSent, nArtifactRcvd);
1612 }
1613 nCardSent = 0;
1614 nCardRcvd = 0;
1615 xfer.nFileSent = 0;
1616 xfer.nDeltaSent = 0;
@@ -1819,11 +1821,11 @@
1821 ** to the next cycle.
1822 */
1823 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
1824 char *zMsg = blob_terminate(&xfer.aToken[1]);
1825 defossilize(zMsg);
1826 if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
1827 syncFlags &= ~SYNC_PUSH;
1828 zMsg = 0;
1829 }
1830 if( zMsg && zMsg[0] ){
1831 fossil_force_newline();
@@ -1905,15 +1907,16 @@
1907 ){
1908 configure_finalize_receive();
1909 }
1910 origConfigRcvMask = 0;
1911 if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1912 fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
1913 blob_size(&recv), nCardRcvd,
1914 xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1915 }else{
1916 fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1917 nRoundtrip, nArtifactSent, nArtifactRcvd);
1918 }
1919 blob_reset(&recv);
1920 nCycle++;
1921
1922 /* If we received one or more files on the previous exchange but
1923
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -75,11 +75,11 @@
7575
RC=$(PellesCDir)\bin\porc.exe
7676
RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
7777
7878
# define the special utilities files, needed to generate
7979
# the automatically generated source files
80
-UTILS=translate.exe mkindex.exe makeheaders.exe
80
+UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
8181
UTILS_OBJ=$(UTILS:.exe=.obj)
8282
UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
8383
8484
# define the SQLite files, which need special flags on compile
8585
SQLITESRC=sqlite3.c
@@ -114,11 +114,11 @@
114114
# main target file is the application
115115
APPLICATION=fossil.exe
116116
117117
# define the standard make target
118118
.PHONY: default
119
-default: page_index.h headers $(APPLICATION)
119
+default: page_index.h builtin_data.h headers $(APPLICATION)
120120
121121
# symbolic target to generate the source generate utils
122122
.PHONY: utils
123123
utils: $(UTILS)
124124
@@ -139,17 +139,20 @@
139139
translate.exe $< >$@
140140
141141
# generate the index source, containing all web references,..
142142
page_index.h: $(TRANSLATEDSRC) mkindex.exe
143143
mkindex.exe $(TRANSLATEDSRC) >$@
144
+
145
+builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
146
+ mkbuiltin.exe $(EXTRA_FILES) >$@
144147
145148
# extracting version info from manifest
146149
VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
147150
version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@
148151
149152
# generate the simplified headers
150
-headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
153
+headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
151154
makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
152155
echo Done >$@
153156
154157
# compile C sources with relevant options
155158
156159
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -75,11 +75,11 @@
75 RC=$(PellesCDir)\bin\porc.exe
76 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
77
78 # define the special utilities files, needed to generate
79 # the automatically generated source files
80 UTILS=translate.exe mkindex.exe makeheaders.exe
81 UTILS_OBJ=$(UTILS:.exe=.obj)
82 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
83
84 # define the SQLite files, which need special flags on compile
85 SQLITESRC=sqlite3.c
@@ -114,11 +114,11 @@
114 # main target file is the application
115 APPLICATION=fossil.exe
116
117 # define the standard make target
118 .PHONY: default
119 default: page_index.h headers $(APPLICATION)
120
121 # symbolic target to generate the source generate utils
122 .PHONY: utils
123 utils: $(UTILS)
124
@@ -139,17 +139,20 @@
139 translate.exe $< >$@
140
141 # generate the index source, containing all web references,..
142 page_index.h: $(TRANSLATEDSRC) mkindex.exe
143 mkindex.exe $(TRANSLATEDSRC) >$@
 
 
 
144
145 # extracting version info from manifest
146 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
147 version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@
148
149 # generate the simplified headers
150 headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
151 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
152 echo Done >$@
153
154 # compile C sources with relevant options
155
156
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -75,11 +75,11 @@
75 RC=$(PellesCDir)\bin\porc.exe
76 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
77
78 # define the special utilities files, needed to generate
79 # the automatically generated source files
80 UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
81 UTILS_OBJ=$(UTILS:.exe=.obj)
82 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c))
83
84 # define the SQLite files, which need special flags on compile
85 SQLITESRC=sqlite3.c
@@ -114,11 +114,11 @@
114 # main target file is the application
115 APPLICATION=fossil.exe
116
117 # define the standard make target
118 .PHONY: default
119 default: page_index.h builtin_data.h headers $(APPLICATION)
120
121 # symbolic target to generate the source generate utils
122 .PHONY: utils
123 utils: $(UTILS)
124
@@ -139,17 +139,20 @@
139 translate.exe $< >$@
140
141 # generate the index source, containing all web references,..
142 page_index.h: $(TRANSLATEDSRC) mkindex.exe
143 mkindex.exe $(TRANSLATEDSRC) >$@
144
145 builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
146 mkbuiltin.exe $(EXTRA_FILES) >$@
147
148 # extracting version info from manifest
149 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
150 version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@
151
152 # generate the simplified headers
153 headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h
154 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h
155 echo Done >$@
156
157 # compile C sources with relevant options
158
159
+25 -9
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,31 +28,32 @@
2828
2929
SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS
3030
3131
SHELL_OPTIONS = -Dmain=sqlite3_shell -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
33
-SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 doc_.c encode_.c event_.c export_.c file_.c finfo_.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 pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.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
33
+SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.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 doc_.c encode_.c event_.c export_.c file_.c finfo_.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 pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.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
35
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
35
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3636
3737
3838
RC=$(DMDIR)\bin\rcc
3939
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
4040
4141
APPNAME = $(OBJDIR)\fossil$(E)
4242
4343
all: $(APPNAME)
4444
45
-$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
45
+$(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
4646
cd $(OBJDIR)
47
+ codecheck1$E $(SRC)
4748
$(DMDIR)\bin\link @link
4849
4950
$(OBJDIR)\fossil.res: $B\win\fossil.rc
5051
$(RC) $(RCFLAGS) -o$@ $**
5152
5253
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
53
- +echo add allrepo attach bag bisect blob branch browse cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
54
+ +echo add allrepo attach bag bisect blob branch browse builtin cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
5455
+echo fossil >> $@
5556
+echo fossil >> $@
5657
+echo $(LIBS) >> $@
5758
+echo. >> $@
5859
+echo fossil >> $@
@@ -64,11 +65,17 @@
6465
$(BCC) -o$@ $**
6566
6667
mkindex$E: $(SRCDIR)\mkindex.c
6768
$(BCC) -o$@ $**
6869
69
-version$E: $B\src\mkversion.c
70
+mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
71
+ $(BCC) -o$@ $**
72
+
73
+mkversion$E: $(SRCDIR)\mkversion.c
74
+ $(BCC) -o$@ $**
75
+
76
+codecheck1$E: $(SRCDIR)\codecheck1.c
7077
$(BCC) -o$@ $**
7178
7279
$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
7380
$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
7481
@@ -82,22 +89,25 @@
8289
$(TCC) -o$@ -c $**
8390
8491
$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
8592
cp $@ $@
8693
87
-VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
94
+VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
8895
+$** > $@
8996
9097
page_index.h: mkindex$E $(SRC)
9198
+$** > $@
99
+
100
+builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
101
+ +$** > $@
92102
93103
clean:
94104
-del $(OBJDIR)\*.obj
95105
-del *.obj *_.c *.h *.map
96106
97107
realclean:
98
- -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
108
+ -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E
99109
100110
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
101111
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
102112
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
103113
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -160,10 +170,16 @@
160170
$(OBJDIR)\browse$O : browse_.c browse.h
161171
$(TCC) -o$@ -c browse_.c
162172
163173
browse_.c : $(SRCDIR)\browse.c
164174
+translate$E $** > $@
175
+
176
+$(OBJDIR)\builtin$O : builtin_.c builtin.h
177
+ $(TCC) -o$@ -c builtin_.c
178
+
179
+builtin_.c : $(SRCDIR)\builtin.c
180
+ +translate$E $** > $@
165181
166182
$(OBJDIR)\cache$O : cache_.c cache.h
167183
$(TCC) -o$@ -c cache_.c
168184
169185
cache_.c : $(SRCDIR)\cache.c
@@ -779,8 +795,8 @@
779795
$(TCC) -o$@ -c zip_.c
780796
781797
zip_.c : $(SRCDIR)\zip.c
782798
+translate$E $** > $@
783799
784
-headers: makeheaders$E page_index.h VERSION.h
785
- +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
800
+headers: makeheaders$E page_index.h builtin_data.h VERSION.h
801
+ +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
786802
@copy /Y nul: headers
787803
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,31 +28,32 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS
30
31 SHELL_OPTIONS = -Dmain=sqlite3_shell -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 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 doc_.c encode_.c event_.c export_.c file_.c finfo_.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 pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.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 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
41 APPNAME = $(OBJDIR)\fossil$(E)
42
43 all: $(APPNAME)
44
45 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
46 cd $(OBJDIR)
 
47 $(DMDIR)\bin\link @link
48
49 $(OBJDIR)\fossil.res: $B\win\fossil.rc
50 $(RC) $(RCFLAGS) -o$@ $**
51
52 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
53 +echo add allrepo attach bag bisect blob branch browse cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
54 +echo fossil >> $@
55 +echo fossil >> $@
56 +echo $(LIBS) >> $@
57 +echo. >> $@
58 +echo fossil >> $@
@@ -64,11 +65,17 @@
64 $(BCC) -o$@ $**
65
66 mkindex$E: $(SRCDIR)\mkindex.c
67 $(BCC) -o$@ $**
68
69 version$E: $B\src\mkversion.c
 
 
 
 
 
 
70 $(BCC) -o$@ $**
71
72 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
73 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
74
@@ -82,22 +89,25 @@
82 $(TCC) -o$@ -c $**
83
84 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
85 cp $@ $@
86
87 VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
88 +$** > $@
89
90 page_index.h: mkindex$E $(SRC)
91 +$** > $@
 
 
 
92
93 clean:
94 -del $(OBJDIR)\*.obj
95 -del *.obj *_.c *.h *.map
96
97 realclean:
98 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
99
100 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
101 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
102 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
103 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -160,10 +170,16 @@
160 $(OBJDIR)\browse$O : browse_.c browse.h
161 $(TCC) -o$@ -c browse_.c
162
163 browse_.c : $(SRCDIR)\browse.c
164 +translate$E $** > $@
 
 
 
 
 
 
165
166 $(OBJDIR)\cache$O : cache_.c cache.h
167 $(TCC) -o$@ -c cache_.c
168
169 cache_.c : $(SRCDIR)\cache.c
@@ -779,8 +795,8 @@
779 $(TCC) -o$@ -c zip_.c
780
781 zip_.c : $(SRCDIR)\zip.c
782 +translate$E $** > $@
783
784 headers: makeheaders$E page_index.h VERSION.h
785 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
786 @copy /Y nul: headers
787
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,31 +28,32 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS
30
31 SHELL_OPTIONS = -Dmain=sqlite3_shell -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 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 doc_.c encode_.c event_.c export_.c file_.c finfo_.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 pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.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 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
41 APPNAME = $(OBJDIR)\fossil$(E)
42
43 all: $(APPNAME)
44
45 $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
46 cd $(OBJDIR)
47 codecheck1$E $(SRC)
48 $(DMDIR)\bin\link @link
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add allrepo attach bag bisect blob branch browse builtin cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -64,11 +65,17 @@
65 $(BCC) -o$@ $**
66
67 mkindex$E: $(SRCDIR)\mkindex.c
68 $(BCC) -o$@ $**
69
70 mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
71 $(BCC) -o$@ $**
72
73 mkversion$E: $(SRCDIR)\mkversion.c
74 $(BCC) -o$@ $**
75
76 codecheck1$E: $(SRCDIR)\codecheck1.c
77 $(BCC) -o$@ $**
78
79 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
80 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
81
@@ -82,22 +89,25 @@
89 $(TCC) -o$@ -c $**
90
91 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
92 cp $@ $@
93
94 VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
95 +$** > $@
96
97 page_index.h: mkindex$E $(SRC)
98 +$** > $@
99
100 builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
101 +$** > $@
102
103 clean:
104 -del $(OBJDIR)\*.obj
105 -del *.obj *_.c *.h *.map
106
107 realclean:
108 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E
109
110 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
111 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
112 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
113 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -160,10 +170,16 @@
170 $(OBJDIR)\browse$O : browse_.c browse.h
171 $(TCC) -o$@ -c browse_.c
172
173 browse_.c : $(SRCDIR)\browse.c
174 +translate$E $** > $@
175
176 $(OBJDIR)\builtin$O : builtin_.c builtin.h
177 $(TCC) -o$@ -c builtin_.c
178
179 builtin_.c : $(SRCDIR)\builtin.c
180 +translate$E $** > $@
181
182 $(OBJDIR)\cache$O : cache_.c cache.h
183 $(TCC) -o$@ -c cache_.c
184
185 cache_.c : $(SRCDIR)\cache.c
@@ -779,8 +795,8 @@
795 $(TCC) -o$@ -c zip_.c
796
797 zip_.c : $(SRCDIR)\zip.c
798 +translate$E $** > $@
799
800 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
801 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
802 @copy /Y nul: headers
803
+42 -10
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -113,12 +113,12 @@
113113
#### The directories where the OpenSSL include and library files are located.
114114
# The recommended usage here is to use the Sysinternals junction tool
115115
# to create a hard link between an "openssl-1.x" sub-directory of the
116116
# Fossil source code directory and the target OpenSSL source directory.
117117
#
118
-OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119
-OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
118
+OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119
+OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120120
121121
#### Either the directory where the Tcl library is installed or the Tcl
122122
# source code directory resides (depending on the value of the macro
123123
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124124
# this directory must have "include" and "lib" sub-directories. If
@@ -339,10 +339,11 @@
339339
$(SRCDIR)/bag.c \
340340
$(SRCDIR)/bisect.c \
341341
$(SRCDIR)/blob.c \
342342
$(SRCDIR)/branch.c \
343343
$(SRCDIR)/browse.c \
344
+ $(SRCDIR)/builtin.c \
344345
$(SRCDIR)/cache.c \
345346
$(SRCDIR)/captcha.c \
346347
$(SRCDIR)/cgi.c \
347348
$(SRCDIR)/checkin.c \
348349
$(SRCDIR)/checkout.c \
@@ -443,19 +444,23 @@
443444
$(SRCDIR)/wysiwyg.c \
444445
$(SRCDIR)/xfer.c \
445446
$(SRCDIR)/xfersetup.c \
446447
$(SRCDIR)/zip.c
447448
449
+EXTRA_FILES = \
450
+ $(SRCDIR)/diff.tcl
451
+
448452
TRANS_SRC = \
449453
$(OBJDIR)/add_.c \
450454
$(OBJDIR)/allrepo_.c \
451455
$(OBJDIR)/attach_.c \
452456
$(OBJDIR)/bag_.c \
453457
$(OBJDIR)/bisect_.c \
454458
$(OBJDIR)/blob_.c \
455459
$(OBJDIR)/branch_.c \
456460
$(OBJDIR)/browse_.c \
461
+ $(OBJDIR)/builtin_.c \
457462
$(OBJDIR)/cache_.c \
458463
$(OBJDIR)/captcha_.c \
459464
$(OBJDIR)/cgi_.c \
460465
$(OBJDIR)/checkin_.c \
461466
$(OBJDIR)/checkout_.c \
@@ -565,10 +570,11 @@
565570
$(OBJDIR)/bag.o \
566571
$(OBJDIR)/bisect.o \
567572
$(OBJDIR)/blob.o \
568573
$(OBJDIR)/branch.o \
569574
$(OBJDIR)/browse.o \
575
+ $(OBJDIR)/builtin.o \
570576
$(OBJDIR)/cache.o \
571577
$(OBJDIR)/captcha.o \
572578
$(OBJDIR)/cgi.o \
573579
$(OBJDIR)/checkin.o \
574580
$(OBJDIR)/checkout.o \
@@ -684,11 +690,13 @@
684690
#
685691
ifdef USE_WINDOWS
686692
TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687693
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688694
MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689
-VERSION = $(subst /,\,$(OBJDIR)/version.exe)
695
+MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
696
+MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe)
697
+CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
690698
CAT = type
691699
CP = copy
692700
GREP = find
693701
MV = copy
694702
RM = del /Q
@@ -696,11 +704,13 @@
696704
RMDIR = rmdir /S /Q
697705
else
698706
TRANSLATE = $(OBJDIR)/translate.exe
699707
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700708
MKINDEX = $(OBJDIR)/mkindex.exe
701
-VERSION = $(OBJDIR)/version.exe
709
+MKBUILTIN = $(OBJDIR)/mkbuiltin.exe
710
+MKVERSION = $(OBJDIR)/mkversion.exe
711
+CODECHECK1 = $(OBJDIR)/codecheck1.exe
702712
CAT = cat
703713
CP = cp
704714
GREP = grep
705715
MV = mv
706716
RM = rm -f
@@ -747,21 +757,27 @@
747757
$(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
748758
749759
$(MKINDEX): $(SRCDIR)/mkindex.c
750760
$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751761
752
-$(VERSION): $(SRCDIR)/mkversion.c
753
- $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
762
+$(MKBUILTIN): $(SRCDIR)/mkbuiltin.c
763
+ $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c
764
+
765
+$(MKVERSION): $(SRCDIR)/mkversion.c
766
+ $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c
767
+
768
+$(CODECHECK1): $(SRCDIR)/codecheck1.c
769
+ $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
754770
755771
# WARNING. DANGER. Running the test suite modifies the repository the
756772
# build is done from, i.e. the checkout belongs to. Do not sync/push
757773
# the repository after running the tests.
758774
test: $(OBJDIR) $(APPNAME)
759775
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
760776
761
-$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
762
- $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
777
+$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
778
+ $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
763779
764780
# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
765781
# to 1. If it is set to 1, then there is no need to build or link
766782
# the sqlite3.o object. Instead, the system SQLite will be linked
767783
# using -lsqlite3.
@@ -815,11 +831,12 @@
815831
816832
ifdef FOSSIL_BUILD_SSL
817833
APPTARGETS += openssl
818834
endif
819835
820
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
836
+$(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
837
+ $(CODECHECK1) $(TRANS_SRC)
821838
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822839
823840
# This rule prevents make from using its default rules to try build
824841
# an executable named "manifest" out of the file named "manifest.c"
825842
#
@@ -842,19 +859,23 @@
842859
$(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)
843860
844861
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
845862
$(MKINDEX) $(TRANS_SRC) >$@
846863
847
-$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
864
+$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
865
+ $(MKBUILTIN) $(EXTRA_FILES) >$@
866
+
867
+$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
848868
$(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
849869
$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
850870
$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
851871
$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
852872
$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
853873
$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
854874
$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
855875
$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
876
+ $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
856877
$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
857878
$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
858879
$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
859880
$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
860881
$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -963,10 +984,13 @@
963984
964985
$(OBJDIR)/headers: Makefile
965986
966987
Makefile:
967988
989
+$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
990
+ $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h
991
+
968992
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE)
969993
$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c
970994
971995
$(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
972996
$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c
@@ -1026,10 +1050,18 @@
10261050
10271051
$(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
10281052
$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
10291053
10301054
$(OBJDIR)/browse.h: $(OBJDIR)/headers
1055
+
1056
+$(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE)
1057
+ $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c
1058
+
1059
+$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1060
+ $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1061
+
1062
+$(OBJDIR)/builtin.h: $(OBJDIR)/headers
10311063
10321064
$(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
10331065
$(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
10341066
10351067
$(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
10361068
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -339,10 +339,11 @@
339 $(SRCDIR)/bag.c \
340 $(SRCDIR)/bisect.c \
341 $(SRCDIR)/blob.c \
342 $(SRCDIR)/branch.c \
343 $(SRCDIR)/browse.c \
 
344 $(SRCDIR)/cache.c \
345 $(SRCDIR)/captcha.c \
346 $(SRCDIR)/cgi.c \
347 $(SRCDIR)/checkin.c \
348 $(SRCDIR)/checkout.c \
@@ -443,19 +444,23 @@
443 $(SRCDIR)/wysiwyg.c \
444 $(SRCDIR)/xfer.c \
445 $(SRCDIR)/xfersetup.c \
446 $(SRCDIR)/zip.c
447
 
 
 
448 TRANS_SRC = \
449 $(OBJDIR)/add_.c \
450 $(OBJDIR)/allrepo_.c \
451 $(OBJDIR)/attach_.c \
452 $(OBJDIR)/bag_.c \
453 $(OBJDIR)/bisect_.c \
454 $(OBJDIR)/blob_.c \
455 $(OBJDIR)/branch_.c \
456 $(OBJDIR)/browse_.c \
 
457 $(OBJDIR)/cache_.c \
458 $(OBJDIR)/captcha_.c \
459 $(OBJDIR)/cgi_.c \
460 $(OBJDIR)/checkin_.c \
461 $(OBJDIR)/checkout_.c \
@@ -565,10 +570,11 @@
565 $(OBJDIR)/bag.o \
566 $(OBJDIR)/bisect.o \
567 $(OBJDIR)/blob.o \
568 $(OBJDIR)/branch.o \
569 $(OBJDIR)/browse.o \
 
570 $(OBJDIR)/cache.o \
571 $(OBJDIR)/captcha.o \
572 $(OBJDIR)/cgi.o \
573 $(OBJDIR)/checkin.o \
574 $(OBJDIR)/checkout.o \
@@ -684,11 +690,13 @@
684 #
685 ifdef USE_WINDOWS
686 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
 
 
690 CAT = type
691 CP = copy
692 GREP = find
693 MV = copy
694 RM = del /Q
@@ -696,11 +704,13 @@
696 RMDIR = rmdir /S /Q
697 else
698 TRANSLATE = $(OBJDIR)/translate.exe
699 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700 MKINDEX = $(OBJDIR)/mkindex.exe
701 VERSION = $(OBJDIR)/version.exe
 
 
702 CAT = cat
703 CP = cp
704 GREP = grep
705 MV = mv
706 RM = rm -f
@@ -747,21 +757,27 @@
747 $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
748
749 $(MKINDEX): $(SRCDIR)/mkindex.c
750 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751
752 $(VERSION): $(SRCDIR)/mkversion.c
753 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
 
 
 
 
 
 
754
755 # WARNING. DANGER. Running the test suite modifies the repository the
756 # build is done from, i.e. the checkout belongs to. Do not sync/push
757 # the repository after running the tests.
758 test: $(OBJDIR) $(APPNAME)
759 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
760
761 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
762 $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
763
764 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
765 # to 1. If it is set to 1, then there is no need to build or link
766 # the sqlite3.o object. Instead, the system SQLite will be linked
767 # using -lsqlite3.
@@ -815,11 +831,12 @@
815
816 ifdef FOSSIL_BUILD_SSL
817 APPTARGETS += openssl
818 endif
819
820 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
 
821 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822
823 # This rule prevents make from using its default rules to try build
824 # an executable named "manifest" out of the file named "manifest.c"
825 #
@@ -842,19 +859,23 @@
842 $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)
843
844 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
845 $(MKINDEX) $(TRANS_SRC) >$@
846
847 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
 
 
 
848 $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
849 $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
850 $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
851 $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
852 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
853 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
854 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
855 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
 
856 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
857 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
858 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
859 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
860 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -963,10 +984,13 @@
963
964 $(OBJDIR)/headers: Makefile
965
966 Makefile:
967
 
 
 
968 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE)
969 $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c
970
971 $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
972 $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c
@@ -1026,10 +1050,18 @@
1026
1027 $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
1028 $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
1029
1030 $(OBJDIR)/browse.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1031
1032 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1033 $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
1034
1035 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
1036
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -339,10 +339,11 @@
339 $(SRCDIR)/bag.c \
340 $(SRCDIR)/bisect.c \
341 $(SRCDIR)/blob.c \
342 $(SRCDIR)/branch.c \
343 $(SRCDIR)/browse.c \
344 $(SRCDIR)/builtin.c \
345 $(SRCDIR)/cache.c \
346 $(SRCDIR)/captcha.c \
347 $(SRCDIR)/cgi.c \
348 $(SRCDIR)/checkin.c \
349 $(SRCDIR)/checkout.c \
@@ -443,19 +444,23 @@
444 $(SRCDIR)/wysiwyg.c \
445 $(SRCDIR)/xfer.c \
446 $(SRCDIR)/xfersetup.c \
447 $(SRCDIR)/zip.c
448
449 EXTRA_FILES = \
450 $(SRCDIR)/diff.tcl
451
452 TRANS_SRC = \
453 $(OBJDIR)/add_.c \
454 $(OBJDIR)/allrepo_.c \
455 $(OBJDIR)/attach_.c \
456 $(OBJDIR)/bag_.c \
457 $(OBJDIR)/bisect_.c \
458 $(OBJDIR)/blob_.c \
459 $(OBJDIR)/branch_.c \
460 $(OBJDIR)/browse_.c \
461 $(OBJDIR)/builtin_.c \
462 $(OBJDIR)/cache_.c \
463 $(OBJDIR)/captcha_.c \
464 $(OBJDIR)/cgi_.c \
465 $(OBJDIR)/checkin_.c \
466 $(OBJDIR)/checkout_.c \
@@ -565,10 +570,11 @@
570 $(OBJDIR)/bag.o \
571 $(OBJDIR)/bisect.o \
572 $(OBJDIR)/blob.o \
573 $(OBJDIR)/branch.o \
574 $(OBJDIR)/browse.o \
575 $(OBJDIR)/builtin.o \
576 $(OBJDIR)/cache.o \
577 $(OBJDIR)/captcha.o \
578 $(OBJDIR)/cgi.o \
579 $(OBJDIR)/checkin.o \
580 $(OBJDIR)/checkout.o \
@@ -684,11 +690,13 @@
690 #
691 ifdef USE_WINDOWS
692 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
693 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
694 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
695 MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
696 MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe)
697 CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
698 CAT = type
699 CP = copy
700 GREP = find
701 MV = copy
702 RM = del /Q
@@ -696,11 +704,13 @@
704 RMDIR = rmdir /S /Q
705 else
706 TRANSLATE = $(OBJDIR)/translate.exe
707 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
708 MKINDEX = $(OBJDIR)/mkindex.exe
709 MKBUILTIN = $(OBJDIR)/mkbuiltin.exe
710 MKVERSION = $(OBJDIR)/mkversion.exe
711 CODECHECK1 = $(OBJDIR)/codecheck1.exe
712 CAT = cat
713 CP = cp
714 GREP = grep
715 MV = mv
716 RM = rm -f
@@ -747,21 +757,27 @@
757 $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
758
759 $(MKINDEX): $(SRCDIR)/mkindex.c
760 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
761
762 $(MKBUILTIN): $(SRCDIR)/mkbuiltin.c
763 $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c
764
765 $(MKVERSION): $(SRCDIR)/mkversion.c
766 $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c
767
768 $(CODECHECK1): $(SRCDIR)/codecheck1.c
769 $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
770
771 # WARNING. DANGER. Running the test suite modifies the repository the
772 # build is done from, i.e. the checkout belongs to. Do not sync/push
773 # the repository after running the tests.
774 test: $(OBJDIR) $(APPNAME)
775 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
776
777 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
778 $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
779
780 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
781 # to 1. If it is set to 1, then there is no need to build or link
782 # the sqlite3.o object. Instead, the system SQLite will be linked
783 # using -lsqlite3.
@@ -815,11 +831,12 @@
831
832 ifdef FOSSIL_BUILD_SSL
833 APPTARGETS += openssl
834 endif
835
836 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
837 $(CODECHECK1) $(TRANS_SRC)
838 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
839
840 # This rule prevents make from using its default rules to try build
841 # an executable named "manifest" out of the file named "manifest.c"
842 #
@@ -842,19 +859,23 @@
859 $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)
860
861 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
862 $(MKINDEX) $(TRANS_SRC) >$@
863
864 $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
865 $(MKBUILTIN) $(EXTRA_FILES) >$@
866
867 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
868 $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
869 $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
870 $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
871 $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
872 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
873 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
874 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
875 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
876 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
877 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
878 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
879 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
880 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
881 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -963,10 +984,13 @@
984
985 $(OBJDIR)/headers: Makefile
986
987 Makefile:
988
989 $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
990 $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h
991
992 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE)
993 $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c
994
995 $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
996 $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c
@@ -1026,10 +1050,18 @@
1050
1051 $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
1052 $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
1053
1054 $(OBJDIR)/browse.h: $(OBJDIR)/headers
1055
1056 $(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE)
1057 $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c
1058
1059 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1060 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1061
1062 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
1063
1064 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1065 $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
1066
1067 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
1068
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -113,12 +113,12 @@
113113
#### The directories where the OpenSSL include and library files are located.
114114
# The recommended usage here is to use the Sysinternals junction tool
115115
# to create a hard link between an "openssl-1.x" sub-directory of the
116116
# Fossil source code directory and the target OpenSSL source directory.
117117
#
118
-OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119
-OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
118
+OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119
+OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120120
121121
#### Either the directory where the Tcl library is installed or the Tcl
122122
# source code directory resides (depending on the value of the macro
123123
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124124
# this directory must have "include" and "lib" sub-directories. If
@@ -339,10 +339,11 @@
339339
$(SRCDIR)/bag.c \
340340
$(SRCDIR)/bisect.c \
341341
$(SRCDIR)/blob.c \
342342
$(SRCDIR)/branch.c \
343343
$(SRCDIR)/browse.c \
344
+ $(SRCDIR)/builtin.c \
344345
$(SRCDIR)/cache.c \
345346
$(SRCDIR)/captcha.c \
346347
$(SRCDIR)/cgi.c \
347348
$(SRCDIR)/checkin.c \
348349
$(SRCDIR)/checkout.c \
@@ -443,19 +444,23 @@
443444
$(SRCDIR)/wysiwyg.c \
444445
$(SRCDIR)/xfer.c \
445446
$(SRCDIR)/xfersetup.c \
446447
$(SRCDIR)/zip.c
447448
449
+EXTRA_FILES = \
450
+ $(SRCDIR)/diff.tcl
451
+
448452
TRANS_SRC = \
449453
$(OBJDIR)/add_.c \
450454
$(OBJDIR)/allrepo_.c \
451455
$(OBJDIR)/attach_.c \
452456
$(OBJDIR)/bag_.c \
453457
$(OBJDIR)/bisect_.c \
454458
$(OBJDIR)/blob_.c \
455459
$(OBJDIR)/branch_.c \
456460
$(OBJDIR)/browse_.c \
461
+ $(OBJDIR)/builtin_.c \
457462
$(OBJDIR)/cache_.c \
458463
$(OBJDIR)/captcha_.c \
459464
$(OBJDIR)/cgi_.c \
460465
$(OBJDIR)/checkin_.c \
461466
$(OBJDIR)/checkout_.c \
@@ -565,10 +570,11 @@
565570
$(OBJDIR)/bag.o \
566571
$(OBJDIR)/bisect.o \
567572
$(OBJDIR)/blob.o \
568573
$(OBJDIR)/branch.o \
569574
$(OBJDIR)/browse.o \
575
+ $(OBJDIR)/builtin.o \
570576
$(OBJDIR)/cache.o \
571577
$(OBJDIR)/captcha.o \
572578
$(OBJDIR)/cgi.o \
573579
$(OBJDIR)/checkin.o \
574580
$(OBJDIR)/checkout.o \
@@ -684,11 +690,13 @@
684690
#
685691
ifdef USE_WINDOWS
686692
TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687693
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688694
MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689
-VERSION = $(subst /,\,$(OBJDIR)/version.exe)
695
+MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
696
+MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe)
697
+CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
690698
CAT = type
691699
CP = copy
692700
GREP = find
693701
MV = copy
694702
RM = del /Q
@@ -696,11 +704,13 @@
696704
RMDIR = rmdir /S /Q
697705
else
698706
TRANSLATE = $(OBJDIR)/translate.exe
699707
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700708
MKINDEX = $(OBJDIR)/mkindex.exe
701
-VERSION = $(OBJDIR)/version.exe
709
+MKBUILTIN = $(OBJDIR)/mkbuiltin.exe
710
+MKVERSION = $(OBJDIR)/mkversion.exe
711
+CODECHECK1 = $(OBJDIR)/codecheck1.exe
702712
CAT = cat
703713
CP = cp
704714
GREP = grep
705715
MV = mv
706716
RM = rm -f
@@ -747,21 +757,27 @@
747757
$(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
748758
749759
$(MKINDEX): $(SRCDIR)/mkindex.c
750760
$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751761
752
-$(VERSION): $(SRCDIR)/mkversion.c
753
- $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
762
+$(MKBUILTIN): $(SRCDIR)/mkbuiltin.c
763
+ $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c
764
+
765
+$(MKVERSION): $(SRCDIR)/mkversion.c
766
+ $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c
767
+
768
+$(CODECHECK1): $(SRCDIR)/codecheck1.c
769
+ $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
754770
755771
# WARNING. DANGER. Running the test suite modifies the repository the
756772
# build is done from, i.e. the checkout belongs to. Do not sync/push
757773
# the repository after running the tests.
758774
test: $(OBJDIR) $(APPNAME)
759775
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
760776
761
-$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
762
- $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
777
+$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
778
+ $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
763779
764780
# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
765781
# to 1. If it is set to 1, then there is no need to build or link
766782
# the sqlite3.o object. Instead, the system SQLite will be linked
767783
# using -lsqlite3.
@@ -815,11 +831,12 @@
815831
816832
ifdef FOSSIL_BUILD_SSL
817833
APPTARGETS += openssl
818834
endif
819835
820
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
836
+$(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
837
+ $(CODECHECK1) $(TRANS_SRC)
821838
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822839
823840
# This rule prevents make from using its default rules to try build
824841
# an executable named "manifest" out of the file named "manifest.c"
825842
#
@@ -842,19 +859,23 @@
842859
$(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)
843860
844861
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
845862
$(MKINDEX) $(TRANS_SRC) >$@
846863
847
-$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
864
+$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
865
+ $(MKBUILTIN) $(EXTRA_FILES) >$@
866
+
867
+$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
848868
$(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
849869
$(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
850870
$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
851871
$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
852872
$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
853873
$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
854874
$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
855875
$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
876
+ $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
856877
$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
857878
$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
858879
$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
859880
$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
860881
$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -963,10 +984,13 @@
963984
964985
$(OBJDIR)/headers: Makefile
965986
966987
Makefile:
967988
989
+$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
990
+ $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h
991
+
968992
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE)
969993
$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c
970994
971995
$(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
972996
$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c
@@ -1026,10 +1050,18 @@
10261050
10271051
$(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
10281052
$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
10291053
10301054
$(OBJDIR)/browse.h: $(OBJDIR)/headers
1055
+
1056
+$(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE)
1057
+ $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c
1058
+
1059
+$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1060
+ $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1061
+
1062
+$(OBJDIR)/builtin.h: $(OBJDIR)/headers
10311063
10321064
$(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
10331065
$(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
10341066
10351067
$(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
10361068
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -339,10 +339,11 @@
339 $(SRCDIR)/bag.c \
340 $(SRCDIR)/bisect.c \
341 $(SRCDIR)/blob.c \
342 $(SRCDIR)/branch.c \
343 $(SRCDIR)/browse.c \
 
344 $(SRCDIR)/cache.c \
345 $(SRCDIR)/captcha.c \
346 $(SRCDIR)/cgi.c \
347 $(SRCDIR)/checkin.c \
348 $(SRCDIR)/checkout.c \
@@ -443,19 +444,23 @@
443 $(SRCDIR)/wysiwyg.c \
444 $(SRCDIR)/xfer.c \
445 $(SRCDIR)/xfersetup.c \
446 $(SRCDIR)/zip.c
447
 
 
 
448 TRANS_SRC = \
449 $(OBJDIR)/add_.c \
450 $(OBJDIR)/allrepo_.c \
451 $(OBJDIR)/attach_.c \
452 $(OBJDIR)/bag_.c \
453 $(OBJDIR)/bisect_.c \
454 $(OBJDIR)/blob_.c \
455 $(OBJDIR)/branch_.c \
456 $(OBJDIR)/browse_.c \
 
457 $(OBJDIR)/cache_.c \
458 $(OBJDIR)/captcha_.c \
459 $(OBJDIR)/cgi_.c \
460 $(OBJDIR)/checkin_.c \
461 $(OBJDIR)/checkout_.c \
@@ -565,10 +570,11 @@
565 $(OBJDIR)/bag.o \
566 $(OBJDIR)/bisect.o \
567 $(OBJDIR)/blob.o \
568 $(OBJDIR)/branch.o \
569 $(OBJDIR)/browse.o \
 
570 $(OBJDIR)/cache.o \
571 $(OBJDIR)/captcha.o \
572 $(OBJDIR)/cgi.o \
573 $(OBJDIR)/checkin.o \
574 $(OBJDIR)/checkout.o \
@@ -684,11 +690,13 @@
684 #
685 ifdef USE_WINDOWS
686 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
 
 
690 CAT = type
691 CP = copy
692 GREP = find
693 MV = copy
694 RM = del /Q
@@ -696,11 +704,13 @@
696 RMDIR = rmdir /S /Q
697 else
698 TRANSLATE = $(OBJDIR)/translate.exe
699 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700 MKINDEX = $(OBJDIR)/mkindex.exe
701 VERSION = $(OBJDIR)/version.exe
 
 
702 CAT = cat
703 CP = cp
704 GREP = grep
705 MV = mv
706 RM = rm -f
@@ -747,21 +757,27 @@
747 $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
748
749 $(MKINDEX): $(SRCDIR)/mkindex.c
750 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751
752 $(VERSION): $(SRCDIR)/mkversion.c
753 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
 
 
 
 
 
 
754
755 # WARNING. DANGER. Running the test suite modifies the repository the
756 # build is done from, i.e. the checkout belongs to. Do not sync/push
757 # the repository after running the tests.
758 test: $(OBJDIR) $(APPNAME)
759 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
760
761 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
762 $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
763
764 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
765 # to 1. If it is set to 1, then there is no need to build or link
766 # the sqlite3.o object. Instead, the system SQLite will be linked
767 # using -lsqlite3.
@@ -815,11 +831,12 @@
815
816 ifdef FOSSIL_BUILD_SSL
817 APPTARGETS += openssl
818 endif
819
820 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
 
821 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822
823 # This rule prevents make from using its default rules to try build
824 # an executable named "manifest" out of the file named "manifest.c"
825 #
@@ -842,19 +859,23 @@
842 $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)
843
844 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
845 $(MKINDEX) $(TRANS_SRC) >$@
846
847 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
 
 
 
848 $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
849 $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
850 $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
851 $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
852 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
853 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
854 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
855 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
 
856 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
857 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
858 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
859 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
860 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -963,10 +984,13 @@
963
964 $(OBJDIR)/headers: Makefile
965
966 Makefile:
967
 
 
 
968 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE)
969 $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c
970
971 $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
972 $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c
@@ -1026,10 +1050,18 @@
1026
1027 $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
1028 $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
1029
1030 $(OBJDIR)/browse.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1031
1032 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1033 $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
1034
1035 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
1036
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -339,10 +339,11 @@
339 $(SRCDIR)/bag.c \
340 $(SRCDIR)/bisect.c \
341 $(SRCDIR)/blob.c \
342 $(SRCDIR)/branch.c \
343 $(SRCDIR)/browse.c \
344 $(SRCDIR)/builtin.c \
345 $(SRCDIR)/cache.c \
346 $(SRCDIR)/captcha.c \
347 $(SRCDIR)/cgi.c \
348 $(SRCDIR)/checkin.c \
349 $(SRCDIR)/checkout.c \
@@ -443,19 +444,23 @@
444 $(SRCDIR)/wysiwyg.c \
445 $(SRCDIR)/xfer.c \
446 $(SRCDIR)/xfersetup.c \
447 $(SRCDIR)/zip.c
448
449 EXTRA_FILES = \
450 $(SRCDIR)/diff.tcl
451
452 TRANS_SRC = \
453 $(OBJDIR)/add_.c \
454 $(OBJDIR)/allrepo_.c \
455 $(OBJDIR)/attach_.c \
456 $(OBJDIR)/bag_.c \
457 $(OBJDIR)/bisect_.c \
458 $(OBJDIR)/blob_.c \
459 $(OBJDIR)/branch_.c \
460 $(OBJDIR)/browse_.c \
461 $(OBJDIR)/builtin_.c \
462 $(OBJDIR)/cache_.c \
463 $(OBJDIR)/captcha_.c \
464 $(OBJDIR)/cgi_.c \
465 $(OBJDIR)/checkin_.c \
466 $(OBJDIR)/checkout_.c \
@@ -565,10 +570,11 @@
570 $(OBJDIR)/bag.o \
571 $(OBJDIR)/bisect.o \
572 $(OBJDIR)/blob.o \
573 $(OBJDIR)/branch.o \
574 $(OBJDIR)/browse.o \
575 $(OBJDIR)/builtin.o \
576 $(OBJDIR)/cache.o \
577 $(OBJDIR)/captcha.o \
578 $(OBJDIR)/cgi.o \
579 $(OBJDIR)/checkin.o \
580 $(OBJDIR)/checkout.o \
@@ -684,11 +690,13 @@
690 #
691 ifdef USE_WINDOWS
692 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
693 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
694 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
695 MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe)
696 MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe)
697 CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
698 CAT = type
699 CP = copy
700 GREP = find
701 MV = copy
702 RM = del /Q
@@ -696,11 +704,13 @@
704 RMDIR = rmdir /S /Q
705 else
706 TRANSLATE = $(OBJDIR)/translate.exe
707 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
708 MKINDEX = $(OBJDIR)/mkindex.exe
709 MKBUILTIN = $(OBJDIR)/mkbuiltin.exe
710 MKVERSION = $(OBJDIR)/mkversion.exe
711 CODECHECK1 = $(OBJDIR)/codecheck1.exe
712 CAT = cat
713 CP = cp
714 GREP = grep
715 MV = mv
716 RM = rm -f
@@ -747,21 +757,27 @@
757 $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c
758
759 $(MKINDEX): $(SRCDIR)/mkindex.c
760 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
761
762 $(MKBUILTIN): $(SRCDIR)/mkbuiltin.c
763 $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c
764
765 $(MKVERSION): $(SRCDIR)/mkversion.c
766 $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c
767
768 $(CODECHECK1): $(SRCDIR)/codecheck1.c
769 $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
770
771 # WARNING. DANGER. Running the test suite modifies the repository the
772 # build is done from, i.e. the checkout belongs to. Do not sync/push
773 # the repository after running the tests.
774 test: $(OBJDIR) $(APPNAME)
775 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
776
777 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION)
778 $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
779
780 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
781 # to 1. If it is set to 1, then there is no need to build or link
782 # the sqlite3.o object. Instead, the system SQLite will be linked
783 # using -lsqlite3.
@@ -815,11 +831,12 @@
831
832 ifdef FOSSIL_BUILD_SSL
833 APPTARGETS += openssl
834 endif
835
836 $(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
837 $(CODECHECK1) $(TRANS_SRC)
838 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
839
840 # This rule prevents make from using its default rules to try build
841 # an executable named "manifest" out of the file named "manifest.c"
842 #
@@ -842,19 +859,23 @@
859 $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION)
860
861 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX)
862 $(MKINDEX) $(TRANS_SRC) >$@
863
864 $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
865 $(MKBUILTIN) $(EXTRA_FILES) >$@
866
867 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h
868 $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \
869 $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \
870 $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
871 $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
872 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
873 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
874 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
875 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
876 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
877 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
878 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
879 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
880 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
881 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -963,10 +984,13 @@
984
985 $(OBJDIR)/headers: Makefile
986
987 Makefile:
988
989 $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES)
990 $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h
991
992 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE)
993 $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c
994
995 $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
996 $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c
@@ -1026,10 +1050,18 @@
1050
1051 $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h
1052 $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c
1053
1054 $(OBJDIR)/browse.h: $(OBJDIR)/headers
1055
1056 $(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE)
1057 $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c
1058
1059 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1060 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1061
1062 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
1063
1064 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1065 $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c
1066
1067 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
1068
+53 -4
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -29,10 +29,13 @@
2929
PERLDIR = C:\Perl\bin
3030
PERL = perl.exe
3131
3232
# Uncomment to enable debug symbols
3333
# DEBUG = 1
34
+
35
+# Uncomment to support Windows XP with Visual Studio 201x
36
+# FOSSIL_ENABLE_WINXP = 1
3437
3538
# Uncomment to enable JSON API
3639
# FOSSIL_ENABLE_JSON = 1
3740
3841
# Uncomment to enable miniz usage
@@ -52,13 +55,14 @@
5255
5356
# Uncomment to enable Tcl support
5457
# FOSSIL_ENABLE_TCL = 1
5558
5659
!ifdef FOSSIL_ENABLE_SSL
57
-SSLDIR = $(B)\compat\openssl-1.0.1i
60
+SSLDIR = $(B)\compat\openssl-1.0.1j
5861
SSLINCDIR = $(SSLDIR)\inc32
5962
SSLLIBDIR = $(SSLDIR)\out32
63
+SSLLFLAGS = /nologo /opt:ref /debug
6064
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
6165
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
6266
!message Using 'x64' platform for OpenSSL...
6367
SSLCONFIG = VC-WIN64A no-asm
6468
SSLSETUP = ms\do_win64a.bat
@@ -101,10 +105,21 @@
101105
INCL = $(INCL) /I$(TCLINCDIR)
102106
!endif
103107
104108
CFLAGS = /nologo
105109
LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
110
+
111
+!ifdef FOSSIL_ENABLE_WINXP
112
+XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
113
+CFLAGS = $(CFLAGS) $(XPCFLAGS)
114
+!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
115
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
116
+!else
117
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
118
+!endif
119
+LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
120
+!endif
106121
107122
!ifdef DEBUG
108123
CFLAGS = $(CFLAGS) /Zi /MTd /Od
109124
LDFLAGS = $(LDFLAGS) /DEBUG
110125
!else
@@ -188,10 +203,11 @@
188203
bag_.c \
189204
bisect_.c \
190205
blob_.c \
191206
branch_.c \
192207
browse_.c \
208
+ builtin_.c \
193209
cache_.c \
194210
captcha_.c \
195211
cgi_.c \
196212
checkin_.c \
197213
checkout_.c \
@@ -292,18 +308,21 @@
292308
wysiwyg_.c \
293309
xfer_.c \
294310
xfersetup_.c \
295311
zip_.c
296312
313
+EXTRA_FILES = $(SRCDIR)\diff.tcl
314
+
297315
OBJ = $(OX)\add$O \
298316
$(OX)\allrepo$O \
299317
$(OX)\attach$O \
300318
$(OX)\bag$O \
301319
$(OX)\bisect$O \
302320
$(OX)\blob$O \
303321
$(OX)\branch$O \
304322
$(OX)\browse$O \
323
+ $(OX)\builtin$O \
305324
$(OX)\cache$O \
306325
$(OX)\captcha$O \
307326
$(OX)\cgi$O \
308327
$(OX)\checkin$O \
309328
$(OX)\checkout$O \
@@ -423,21 +442,29 @@
423442
424443
all: $(OX) $(APPNAME)
425444
426445
zlib:
427446
@echo Building zlib from "$(ZLIBDIR)"...
447
+!ifdef FOSSIL_ENABLE_WINXP
448
+ @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
449
+!else
428450
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
451
+!endif
429452
430453
!ifdef FOSSIL_ENABLE_SSL
431454
openssl:
432455
@echo Building OpenSSL from "$(SSLDIR)"...
433456
!if "$(PERLDIR)" != ""
434457
@set PATH=$(PERLDIR);$(PATH)
435458
!endif
436459
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
437460
@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
461
+!ifdef FOSSIL_ENABLE_WINXP
462
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
463
+!else
438464
@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
465
+!endif
439466
!endif
440467
441468
!ifndef FOSSIL_ENABLE_MINIZ
442469
APPTARGETS = $(APPTARGETS) zlib
443470
!endif
@@ -446,12 +473,13 @@
446473
!ifdef FOSSIL_BUILD_SSL
447474
APPTARGETS = $(APPTARGETS) openssl
448475
!endif
449476
!endif
450477
451
-$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
478
+$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
452479
cd $(OX)
480
+ codecheck1$E $(SRC)
453481
link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
454482
455483
$(OX)\linkopts: $B\win\Makefile.msc
456484
echo $(OX)\add.obj > $@
457485
echo $(OX)\allrepo.obj >> $@
@@ -459,10 +487,11 @@
459487
echo $(OX)\bag.obj >> $@
460488
echo $(OX)\bisect.obj >> $@
461489
echo $(OX)\blob.obj >> $@
462490
echo $(OX)\branch.obj >> $@
463491
echo $(OX)\browse.obj >> $@
492
+ echo $(OX)\builtin.obj >> $@
464493
echo $(OX)\cache.obj >> $@
465494
echo $(OX)\captcha.obj >> $@
466495
echo $(OX)\cgi.obj >> $@
467496
echo $(OX)\checkin.obj >> $@
468497
echo $(OX)\checkout.obj >> $@
@@ -585,11 +614,17 @@
585614
$(BCC) $**
586615
587616
mkindex$E: $(SRCDIR)\mkindex.c
588617
$(BCC) $**
589618
590
-mkversion$E: $B\src\mkversion.c
619
+mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
620
+ $(BCC) $**
621
+
622
+mkversion$E: $(SRCDIR)\mkversion.c
623
+ $(BCC) $**
624
+
625
+codecheck1$E: $(SRCDIR)\codecheck1.c
591626
$(BCC) $**
592627
593628
$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
594629
$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
595630
@@ -614,10 +649,13 @@
614649
$(TCC) /Fo$@ /c $**
615650
616651
page_index.h: mkindex$E $(SRC)
617652
$** > $@
618653
654
+builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
655
+ $** > $@
656
+
619657
clean:
620658
-del $(OX)\*.obj
621659
-del *.obj
622660
-del *_.c
623661
-del *.h
@@ -637,10 +675,14 @@
637675
-del mkindex$P
638676
-del makeheaders$E
639677
-del makeheaders$P
640678
-del mkversion$E
641679
-del mkversion$P
680
+ -del codecheck1$E
681
+ -del codecheck1$P
682
+ -del mkbuiltin$E
683
+ -del mkbuiltin$P
642684
643685
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
644686
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
645687
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
646688
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -701,10 +743,16 @@
701743
$(OX)\browse$O : browse_.c browse.h
702744
$(TCC) /Fo$@ -c browse_.c
703745
704746
browse_.c : $(SRCDIR)\browse.c
705747
translate$E $** > $@
748
+
749
+$(OX)\builtin$O : builtin_.c builtin.h
750
+ $(TCC) /Fo$@ -c builtin_.c
751
+
752
+builtin_.c : $(SRCDIR)\builtin.c
753
+ translate$E $** > $@
706754
707755
$(OX)\cache$O : cache_.c cache.h
708756
$(TCC) /Fo$@ -c cache_.c
709757
710758
cache_.c : $(SRCDIR)\cache.c
@@ -1323,19 +1371,20 @@
13231371
translate$E $** > $@
13241372
13251373
fossil.res : $B\win\fossil.rc
13261374
$(RCC) /fo $@ $**
13271375
1328
-headers: makeheaders$E page_index.h VERSION.h
1376
+headers: makeheaders$E page_index.h builtin_data.h VERSION.h
13291377
makeheaders$E add_.c:add.h \
13301378
allrepo_.c:allrepo.h \
13311379
attach_.c:attach.h \
13321380
bag_.c:bag.h \
13331381
bisect_.c:bisect.h \
13341382
blob_.c:blob.h \
13351383
branch_.c:branch.h \
13361384
browse_.c:browse.h \
1385
+ builtin_.c:builtin.h \
13371386
cache_.c:cache.h \
13381387
captcha_.c:captcha.h \
13391388
cgi_.c:cgi.h \
13401389
checkin_.c:checkin.h \
13411390
checkout_.c:checkout.h \
13421391
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -29,10 +29,13 @@
29 PERLDIR = C:\Perl\bin
30 PERL = perl.exe
31
32 # Uncomment to enable debug symbols
33 # DEBUG = 1
 
 
 
34
35 # Uncomment to enable JSON API
36 # FOSSIL_ENABLE_JSON = 1
37
38 # Uncomment to enable miniz usage
@@ -52,13 +55,14 @@
52
53 # Uncomment to enable Tcl support
54 # FOSSIL_ENABLE_TCL = 1
55
56 !ifdef FOSSIL_ENABLE_SSL
57 SSLDIR = $(B)\compat\openssl-1.0.1i
58 SSLINCDIR = $(SSLDIR)\inc32
59 SSLLIBDIR = $(SSLDIR)\out32
 
60 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
61 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
62 !message Using 'x64' platform for OpenSSL...
63 SSLCONFIG = VC-WIN64A no-asm
64 SSLSETUP = ms\do_win64a.bat
@@ -101,10 +105,21 @@
101 INCL = $(INCL) /I$(TCLINCDIR)
102 !endif
103
104 CFLAGS = /nologo
105 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
 
 
 
 
 
 
 
 
 
 
 
106
107 !ifdef DEBUG
108 CFLAGS = $(CFLAGS) /Zi /MTd /Od
109 LDFLAGS = $(LDFLAGS) /DEBUG
110 !else
@@ -188,10 +203,11 @@
188 bag_.c \
189 bisect_.c \
190 blob_.c \
191 branch_.c \
192 browse_.c \
 
193 cache_.c \
194 captcha_.c \
195 cgi_.c \
196 checkin_.c \
197 checkout_.c \
@@ -292,18 +308,21 @@
292 wysiwyg_.c \
293 xfer_.c \
294 xfersetup_.c \
295 zip_.c
296
 
 
297 OBJ = $(OX)\add$O \
298 $(OX)\allrepo$O \
299 $(OX)\attach$O \
300 $(OX)\bag$O \
301 $(OX)\bisect$O \
302 $(OX)\blob$O \
303 $(OX)\branch$O \
304 $(OX)\browse$O \
 
305 $(OX)\cache$O \
306 $(OX)\captcha$O \
307 $(OX)\cgi$O \
308 $(OX)\checkin$O \
309 $(OX)\checkout$O \
@@ -423,21 +442,29 @@
423
424 all: $(OX) $(APPNAME)
425
426 zlib:
427 @echo Building zlib from "$(ZLIBDIR)"...
 
 
 
428 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
 
429
430 !ifdef FOSSIL_ENABLE_SSL
431 openssl:
432 @echo Building OpenSSL from "$(SSLDIR)"...
433 !if "$(PERLDIR)" != ""
434 @set PATH=$(PERLDIR);$(PATH)
435 !endif
436 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
437 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
 
 
 
438 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
 
439 !endif
440
441 !ifndef FOSSIL_ENABLE_MINIZ
442 APPTARGETS = $(APPTARGETS) zlib
443 !endif
@@ -446,12 +473,13 @@
446 !ifdef FOSSIL_BUILD_SSL
447 APPTARGETS = $(APPTARGETS) openssl
448 !endif
449 !endif
450
451 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
452 cd $(OX)
 
453 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
454
455 $(OX)\linkopts: $B\win\Makefile.msc
456 echo $(OX)\add.obj > $@
457 echo $(OX)\allrepo.obj >> $@
@@ -459,10 +487,11 @@
459 echo $(OX)\bag.obj >> $@
460 echo $(OX)\bisect.obj >> $@
461 echo $(OX)\blob.obj >> $@
462 echo $(OX)\branch.obj >> $@
463 echo $(OX)\browse.obj >> $@
 
464 echo $(OX)\cache.obj >> $@
465 echo $(OX)\captcha.obj >> $@
466 echo $(OX)\cgi.obj >> $@
467 echo $(OX)\checkin.obj >> $@
468 echo $(OX)\checkout.obj >> $@
@@ -585,11 +614,17 @@
585 $(BCC) $**
586
587 mkindex$E: $(SRCDIR)\mkindex.c
588 $(BCC) $**
589
590 mkversion$E: $B\src\mkversion.c
 
 
 
 
 
 
591 $(BCC) $**
592
593 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
594 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
595
@@ -614,10 +649,13 @@
614 $(TCC) /Fo$@ /c $**
615
616 page_index.h: mkindex$E $(SRC)
617 $** > $@
618
 
 
 
619 clean:
620 -del $(OX)\*.obj
621 -del *.obj
622 -del *_.c
623 -del *.h
@@ -637,10 +675,14 @@
637 -del mkindex$P
638 -del makeheaders$E
639 -del makeheaders$P
640 -del mkversion$E
641 -del mkversion$P
 
 
 
 
642
643 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
644 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
645 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
646 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -701,10 +743,16 @@
701 $(OX)\browse$O : browse_.c browse.h
702 $(TCC) /Fo$@ -c browse_.c
703
704 browse_.c : $(SRCDIR)\browse.c
705 translate$E $** > $@
 
 
 
 
 
 
706
707 $(OX)\cache$O : cache_.c cache.h
708 $(TCC) /Fo$@ -c cache_.c
709
710 cache_.c : $(SRCDIR)\cache.c
@@ -1323,19 +1371,20 @@
1323 translate$E $** > $@
1324
1325 fossil.res : $B\win\fossil.rc
1326 $(RCC) /fo $@ $**
1327
1328 headers: makeheaders$E page_index.h VERSION.h
1329 makeheaders$E add_.c:add.h \
1330 allrepo_.c:allrepo.h \
1331 attach_.c:attach.h \
1332 bag_.c:bag.h \
1333 bisect_.c:bisect.h \
1334 blob_.c:blob.h \
1335 branch_.c:branch.h \
1336 browse_.c:browse.h \
 
1337 cache_.c:cache.h \
1338 captcha_.c:captcha.h \
1339 cgi_.c:cgi.h \
1340 checkin_.c:checkin.h \
1341 checkout_.c:checkout.h \
1342
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -29,10 +29,13 @@
29 PERLDIR = C:\Perl\bin
30 PERL = perl.exe
31
32 # Uncomment to enable debug symbols
33 # DEBUG = 1
34
35 # Uncomment to support Windows XP with Visual Studio 201x
36 # FOSSIL_ENABLE_WINXP = 1
37
38 # Uncomment to enable JSON API
39 # FOSSIL_ENABLE_JSON = 1
40
41 # Uncomment to enable miniz usage
@@ -52,13 +55,14 @@
55
56 # Uncomment to enable Tcl support
57 # FOSSIL_ENABLE_TCL = 1
58
59 !ifdef FOSSIL_ENABLE_SSL
60 SSLDIR = $(B)\compat\openssl-1.0.1j
61 SSLINCDIR = $(SSLDIR)\inc32
62 SSLLIBDIR = $(SSLDIR)\out32
63 SSLLFLAGS = /nologo /opt:ref /debug
64 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
65 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
66 !message Using 'x64' platform for OpenSSL...
67 SSLCONFIG = VC-WIN64A no-asm
68 SSLSETUP = ms\do_win64a.bat
@@ -101,10 +105,21 @@
105 INCL = $(INCL) /I$(TCLINCDIR)
106 !endif
107
108 CFLAGS = /nologo
109 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
110
111 !ifdef FOSSIL_ENABLE_WINXP
112 XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
113 CFLAGS = $(CFLAGS) $(XPCFLAGS)
114 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
115 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
116 !else
117 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
118 !endif
119 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
120 !endif
121
122 !ifdef DEBUG
123 CFLAGS = $(CFLAGS) /Zi /MTd /Od
124 LDFLAGS = $(LDFLAGS) /DEBUG
125 !else
@@ -188,10 +203,11 @@
203 bag_.c \
204 bisect_.c \
205 blob_.c \
206 branch_.c \
207 browse_.c \
208 builtin_.c \
209 cache_.c \
210 captcha_.c \
211 cgi_.c \
212 checkin_.c \
213 checkout_.c \
@@ -292,18 +308,21 @@
308 wysiwyg_.c \
309 xfer_.c \
310 xfersetup_.c \
311 zip_.c
312
313 EXTRA_FILES = $(SRCDIR)\diff.tcl
314
315 OBJ = $(OX)\add$O \
316 $(OX)\allrepo$O \
317 $(OX)\attach$O \
318 $(OX)\bag$O \
319 $(OX)\bisect$O \
320 $(OX)\blob$O \
321 $(OX)\branch$O \
322 $(OX)\browse$O \
323 $(OX)\builtin$O \
324 $(OX)\cache$O \
325 $(OX)\captcha$O \
326 $(OX)\cgi$O \
327 $(OX)\checkin$O \
328 $(OX)\checkout$O \
@@ -423,21 +442,29 @@
442
443 all: $(OX) $(APPNAME)
444
445 zlib:
446 @echo Building zlib from "$(ZLIBDIR)"...
447 !ifdef FOSSIL_ENABLE_WINXP
448 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
449 !else
450 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
451 !endif
452
453 !ifdef FOSSIL_ENABLE_SSL
454 openssl:
455 @echo Building OpenSSL from "$(SSLDIR)"...
456 !if "$(PERLDIR)" != ""
457 @set PATH=$(PERLDIR);$(PATH)
458 !endif
459 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
460 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
461 !ifdef FOSSIL_ENABLE_WINXP
462 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
463 !else
464 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
465 !endif
466 !endif
467
468 !ifndef FOSSIL_ENABLE_MINIZ
469 APPTARGETS = $(APPTARGETS) zlib
470 !endif
@@ -446,12 +473,13 @@
473 !ifdef FOSSIL_BUILD_SSL
474 APPTARGETS = $(APPTARGETS) openssl
475 !endif
476 !endif
477
478 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
479 cd $(OX)
480 codecheck1$E $(SRC)
481 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
482
483 $(OX)\linkopts: $B\win\Makefile.msc
484 echo $(OX)\add.obj > $@
485 echo $(OX)\allrepo.obj >> $@
@@ -459,10 +487,11 @@
487 echo $(OX)\bag.obj >> $@
488 echo $(OX)\bisect.obj >> $@
489 echo $(OX)\blob.obj >> $@
490 echo $(OX)\branch.obj >> $@
491 echo $(OX)\browse.obj >> $@
492 echo $(OX)\builtin.obj >> $@
493 echo $(OX)\cache.obj >> $@
494 echo $(OX)\captcha.obj >> $@
495 echo $(OX)\cgi.obj >> $@
496 echo $(OX)\checkin.obj >> $@
497 echo $(OX)\checkout.obj >> $@
@@ -585,11 +614,17 @@
614 $(BCC) $**
615
616 mkindex$E: $(SRCDIR)\mkindex.c
617 $(BCC) $**
618
619 mkbuiltin$E: $(SRCDIR)\mkbuiltin.c
620 $(BCC) $**
621
622 mkversion$E: $(SRCDIR)\mkversion.c
623 $(BCC) $**
624
625 codecheck1$E: $(SRCDIR)\codecheck1.c
626 $(BCC) $**
627
628 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
629 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
630
@@ -614,10 +649,13 @@
649 $(TCC) /Fo$@ /c $**
650
651 page_index.h: mkindex$E $(SRC)
652 $** > $@
653
654 builtin_data.h: mkbuiltin$E $(EXTRA_FILES)
655 $** > $@
656
657 clean:
658 -del $(OX)\*.obj
659 -del *.obj
660 -del *_.c
661 -del *.h
@@ -637,10 +675,14 @@
675 -del mkindex$P
676 -del makeheaders$E
677 -del makeheaders$P
678 -del mkversion$E
679 -del mkversion$P
680 -del codecheck1$E
681 -del codecheck1$P
682 -del mkbuiltin$E
683 -del mkbuiltin$P
684
685 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
686 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
687 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
688 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -701,10 +743,16 @@
743 $(OX)\browse$O : browse_.c browse.h
744 $(TCC) /Fo$@ -c browse_.c
745
746 browse_.c : $(SRCDIR)\browse.c
747 translate$E $** > $@
748
749 $(OX)\builtin$O : builtin_.c builtin.h
750 $(TCC) /Fo$@ -c builtin_.c
751
752 builtin_.c : $(SRCDIR)\builtin.c
753 translate$E $** > $@
754
755 $(OX)\cache$O : cache_.c cache.h
756 $(TCC) /Fo$@ -c cache_.c
757
758 cache_.c : $(SRCDIR)\cache.c
@@ -1323,19 +1371,20 @@
1371 translate$E $** > $@
1372
1373 fossil.res : $B\win\fossil.rc
1374 $(RCC) /fo $@ $**
1375
1376 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1377 makeheaders$E add_.c:add.h \
1378 allrepo_.c:allrepo.h \
1379 attach_.c:attach.h \
1380 bag_.c:bag.h \
1381 bisect_.c:bisect.h \
1382 blob_.c:blob.h \
1383 branch_.c:branch.h \
1384 browse_.c:browse.h \
1385 builtin_.c:builtin.h \
1386 cache_.c:cache.h \
1387 captcha_.c:captcha.h \
1388 cgi_.c:cgi.h \
1389 checkin_.c:checkin.h \
1390 checkout_.c:checkout.h \
1391
--- win/buildmsvc.bat
+++ win/buildmsvc.bat
@@ -192,15 +192,30 @@
192192
IF ERRORLEVEL 1 (
193193
ECHO Could not change to directory "%ROOT%\msvcbld".
194194
GOTO errors
195195
)
196196
197
+REM
198
+REM NOTE: If requested, setup the build environment to refer to the Windows
199
+REM SDK v7.1A, which is required if the binaries are being built with
200
+REM Visual Studio 201x and need to work on Windows XP.
201
+REM
202
+IF DEFINED USE_V110SDK71A (
203
+ %_AECHO% Forcing use of the Windows SDK v7.1A...
204
+ CALL :fn_UseV110Sdk71A
205
+)
206
+
207
+%_VECHO% Path = '%PATH%'
208
+%_VECHO% Include = '%INCLUDE%'
209
+%_VECHO% Lib = '%LIB%'
210
+%_VECHO% NmakeArgs = '%NMAKE_ARGS%'
211
+
197212
REM
198213
REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
199214
REM anything extra from our command line along (e.g. extra options).
200215
REM
201
-%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %*
216
+%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %*
202217
203218
IF ERRORLEVEL 1 (
204219
GOTO errors
205220
)
206221
@@ -213,10 +228,35 @@
213228
ECHO Could not restore directory.
214229
GOTO errors
215230
)
216231
217232
GOTO no_errors
233
+
234
+:fn_UseV110Sdk71A
235
+ IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86
236
+ SET PFILES_SDK71A=%ProgramFiles(x86)%
237
+ GOTO set_v110Sdk71A_done
238
+ :set_v110Sdk71A_x86
239
+ SET PFILES_SDK71A=%ProgramFiles%
240
+ :set_v110Sdk71A_done
241
+ SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
242
+ SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
243
+ IF "%PLATFORM%" == "x64" (
244
+ SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB%
245
+ ) ELSE (
246
+ SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
247
+ )
248
+ CALL :fn_UnsetVariable PFILES_SDK71A
249
+ SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1
250
+ GOTO :EOF
251
+
252
+:fn_UnsetVariable
253
+ IF NOT "%1" == "" (
254
+ SET %1=
255
+ CALL :fn_ResetErrorLevel
256
+ )
257
+ GOTO :EOF
218258
219259
:fn_ResetErrorLevel
220260
VERIFY > NUL
221261
GOTO :EOF
222262
223263
--- win/buildmsvc.bat
+++ win/buildmsvc.bat
@@ -192,15 +192,30 @@
192 IF ERRORLEVEL 1 (
193 ECHO Could not change to directory "%ROOT%\msvcbld".
194 GOTO errors
195 )
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197 REM
198 REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
199 REM anything extra from our command line along (e.g. extra options).
200 REM
201 %__ECHO% nmake /f "%TOOLS%\Makefile.msc" %*
202
203 IF ERRORLEVEL 1 (
204 GOTO errors
205 )
206
@@ -213,10 +228,35 @@
213 ECHO Could not restore directory.
214 GOTO errors
215 )
216
217 GOTO no_errors
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
219 :fn_ResetErrorLevel
220 VERIFY > NUL
221 GOTO :EOF
222
223
--- win/buildmsvc.bat
+++ win/buildmsvc.bat
@@ -192,15 +192,30 @@
192 IF ERRORLEVEL 1 (
193 ECHO Could not change to directory "%ROOT%\msvcbld".
194 GOTO errors
195 )
196
197 REM
198 REM NOTE: If requested, setup the build environment to refer to the Windows
199 REM SDK v7.1A, which is required if the binaries are being built with
200 REM Visual Studio 201x and need to work on Windows XP.
201 REM
202 IF DEFINED USE_V110SDK71A (
203 %_AECHO% Forcing use of the Windows SDK v7.1A...
204 CALL :fn_UseV110Sdk71A
205 )
206
207 %_VECHO% Path = '%PATH%'
208 %_VECHO% Include = '%INCLUDE%'
209 %_VECHO% Lib = '%LIB%'
210 %_VECHO% NmakeArgs = '%NMAKE_ARGS%'
211
212 REM
213 REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
214 REM anything extra from our command line along (e.g. extra options).
215 REM
216 %__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %*
217
218 IF ERRORLEVEL 1 (
219 GOTO errors
220 )
221
@@ -213,10 +228,35 @@
228 ECHO Could not restore directory.
229 GOTO errors
230 )
231
232 GOTO no_errors
233
234 :fn_UseV110Sdk71A
235 IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86
236 SET PFILES_SDK71A=%ProgramFiles(x86)%
237 GOTO set_v110Sdk71A_done
238 :set_v110Sdk71A_x86
239 SET PFILES_SDK71A=%ProgramFiles%
240 :set_v110Sdk71A_done
241 SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
242 SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
243 IF "%PLATFORM%" == "x64" (
244 SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB%
245 ) ELSE (
246 SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
247 )
248 CALL :fn_UnsetVariable PFILES_SDK71A
249 SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1
250 GOTO :EOF
251
252 :fn_UnsetVariable
253 IF NOT "%1" == "" (
254 SET %1=
255 CALL :fn_ResetErrorLevel
256 )
257 GOTO :EOF
258
259 :fn_ResetErrorLevel
260 VERIFY > NUL
261 GOTO :EOF
262
263
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -13,10 +13,12 @@
1313
</requestedPrivileges>
1414
</security>
1515
</trustInfo>
1616
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
1717
<application>
18
+ <!-- Windows 10 -->
19
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
1820
<!-- Windows 8.1 -->
1921
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
2022
<!-- Windows 8 -->
2123
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
2224
<!-- Windows 7 -->
2325
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -13,10 +13,12 @@
13 </requestedPrivileges>
14 </security>
15 </trustInfo>
16 <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
17 <application>
 
 
18 <!-- Windows 8.1 -->
19 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
20 <!-- Windows 8 -->
21 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
22 <!-- Windows 7 -->
23
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -13,10 +13,12 @@
13 </requestedPrivileges>
14 </security>
15 </trustInfo>
16 <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
17 <application>
18 <!-- Windows 10 -->
19 <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
20 <!-- Windows 8.1 -->
21 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
22 <!-- Windows 8 -->
23 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
24 <!-- Windows 7 -->
25
+1 -1
--- www/build.wiki
+++ www/build.wiki
@@ -122,11 +122,11 @@
122122
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
123123
first <a href="https://www.openssl.org/source/">download the official
124124
source code for OpenSSL</a> and extract it to an appropriately named
125125
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
126126
[/tree?ci=trunk&name=compat | compat] directory (e.g.
127
-"<b>compat/openssl-1.0.1i</b>"), then make sure that some recent
127
+"<b>compat/openssl-1.0.1j</b>"), then make sure that some recent
128128
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
129129
and finally run one of the following commands:
130130
<blockquote><pre>
131131
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
132132
</pre></blockquote>
133133
--- www/build.wiki
+++ www/build.wiki
@@ -122,11 +122,11 @@
122 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
123 first <a href="https://www.openssl.org/source/">download the official
124 source code for OpenSSL</a> and extract it to an appropriately named
125 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
126 [/tree?ci=trunk&name=compat | compat] directory (e.g.
127 "<b>compat/openssl-1.0.1i</b>"), then make sure that some recent
128 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
129 and finally run one of the following commands:
130 <blockquote><pre>
131 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
132 </pre></blockquote>
133
--- www/build.wiki
+++ www/build.wiki
@@ -122,11 +122,11 @@
122 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
123 first <a href="https://www.openssl.org/source/">download the official
124 source code for OpenSSL</a> and extract it to an appropriately named
125 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
126 [/tree?ci=trunk&name=compat | compat] directory (e.g.
127 "<b>compat/openssl-1.0.1j</b>"), then make sure that some recent
128 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
129 and finally run one of the following commands:
130 <blockquote><pre>
131 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
132 </pre></blockquote>
133

Keyboard Shortcuts

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