Fossil SCM
merge trunk
Commit
aaa1cb04dd7139d389e0d252a2320e3a6481fbc5
Parent
3920fa67bdae08f…
21 files changed
+36
-4
+1
-1
+4
-5
+4
-5
+9
+9
+3
-3
+12
-5
+4
-4
+1
-1
+1
-1
+2
-2
+1
-1
+84
-12
+2
-1
+7
-3
+5
-5
+1
-1
+2
-2
+78
+49
~
src/add.c
~
src/attach.c
~
src/checkin.c
~
src/checkin.c
~
src/diff.c
~
src/diff.c
~
src/finfo.c
~
src/http_transport.c
~
src/info.c
~
src/login.c
~
src/report.c
~
src/setup.c
~
src/skins.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/style.c
~
src/timeline.c
~
src/url.c
~
src/wysiwyg.c
~
test/many-www.tcl
~
test/valgrind-www.tcl
+36
-4
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -60,22 +60,39 @@ | ||
| 60 | 60 | static const char *const azManifest[] = { |
| 61 | 61 | "manifest", |
| 62 | 62 | "manifest.uuid", |
| 63 | 63 | }; |
| 64 | 64 | |
| 65 | + /* | |
| 66 | + ** Names of repository files, if they exist in the checkout. | |
| 67 | + */ | |
| 68 | + static const char *azRepo[4] = { 0, 0, 0, 0 }; | |
| 69 | + | |
| 65 | 70 | /* Cached setting "manifest" */ |
| 66 | 71 | static int cachedManifest = -1; |
| 67 | 72 | |
| 68 | 73 | if( cachedManifest == -1 ){ |
| 74 | + Blob repo; | |
| 69 | 75 | cachedManifest = db_get_boolean("manifest",0); |
| 76 | + blob_zero(&repo); | |
| 77 | + if( file_tree_name(g.zRepositoryName, &repo, 0) ){ | |
| 78 | + const char *zRepo = blob_str(&repo); | |
| 79 | + azRepo[0] = zRepo; | |
| 80 | + azRepo[1] = mprintf("%s-journal", zRepo); | |
| 81 | + azRepo[2] = mprintf("%s-wal", zRepo); | |
| 82 | + azRepo[3] = mprintf("%s-shm", zRepo); | |
| 83 | + } | |
| 70 | 84 | } |
| 71 | 85 | |
| 72 | - if( N>=0 && N<count(azName) ) return azName[N]; | |
| 73 | - if( N>=count(azName) && N<count(azName)+count(azManifest) | |
| 74 | - && cachedManifest ){ | |
| 75 | - return azManifest[N-count(azName)]; | |
| 86 | + if( N<0 ) return 0; | |
| 87 | + if( N<count(azName) ) return azName[N]; | |
| 88 | + N -= count(azName); | |
| 89 | + if( cachedManifest ){ | |
| 90 | + if( N<count(azManifest) ) return azManifest[N]; | |
| 91 | + N -= count(azManifest); | |
| 76 | 92 | } |
| 93 | + if( N<count(azRepo) ) return azRepo[N]; | |
| 77 | 94 | return 0; |
| 78 | 95 | } |
| 79 | 96 | |
| 80 | 97 | /* |
| 81 | 98 | ** Return a list of all reserved filenames as an SQL list. |
| @@ -93,10 +110,25 @@ | ||
| 93 | 110 | } |
| 94 | 111 | zAll = blob_str(&x); |
| 95 | 112 | } |
| 96 | 113 | return zAll; |
| 97 | 114 | } |
| 115 | + | |
| 116 | +/* | |
| 117 | +** COMMAND: test-reserved-names | |
| 118 | +** | |
| 119 | +** Show all reserved filenames for the current check-out. | |
| 120 | +*/ | |
| 121 | +void test_reserved_names(void){ | |
| 122 | + int i; | |
| 123 | + const char *z; | |
| 124 | + db_must_be_within_tree(); | |
| 125 | + for(i=0; (z = fossil_reserved_name(i))!=0; i++){ | |
| 126 | + fossil_print("%3d: %s\n", i, z); | |
| 127 | + } | |
| 128 | + fossil_print("ALL: (%s)\n", fossil_all_reserved_names()); | |
| 129 | +} | |
| 98 | 130 | |
| 99 | 131 | /* |
| 100 | 132 | ** Add a single file named zName to the VFILE table with vid. |
| 101 | 133 | ** |
| 102 | 134 | ** Omit any file whose name is pOmit. |
| 103 | 135 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -60,22 +60,39 @@ | |
| 60 | static const char *const azManifest[] = { |
| 61 | "manifest", |
| 62 | "manifest.uuid", |
| 63 | }; |
| 64 | |
| 65 | /* Cached setting "manifest" */ |
| 66 | static int cachedManifest = -1; |
| 67 | |
| 68 | if( cachedManifest == -1 ){ |
| 69 | cachedManifest = db_get_boolean("manifest",0); |
| 70 | } |
| 71 | |
| 72 | if( N>=0 && N<count(azName) ) return azName[N]; |
| 73 | if( N>=count(azName) && N<count(azName)+count(azManifest) |
| 74 | && cachedManifest ){ |
| 75 | return azManifest[N-count(azName)]; |
| 76 | } |
| 77 | return 0; |
| 78 | } |
| 79 | |
| 80 | /* |
| 81 | ** Return a list of all reserved filenames as an SQL list. |
| @@ -93,10 +110,25 @@ | |
| 93 | } |
| 94 | zAll = blob_str(&x); |
| 95 | } |
| 96 | return zAll; |
| 97 | } |
| 98 | |
| 99 | /* |
| 100 | ** Add a single file named zName to the VFILE table with vid. |
| 101 | ** |
| 102 | ** Omit any file whose name is pOmit. |
| 103 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -60,22 +60,39 @@ | |
| 60 | static const char *const azManifest[] = { |
| 61 | "manifest", |
| 62 | "manifest.uuid", |
| 63 | }; |
| 64 | |
| 65 | /* |
| 66 | ** Names of repository files, if they exist in the checkout. |
| 67 | */ |
| 68 | static const char *azRepo[4] = { 0, 0, 0, 0 }; |
| 69 | |
| 70 | /* Cached setting "manifest" */ |
| 71 | static int cachedManifest = -1; |
| 72 | |
| 73 | if( cachedManifest == -1 ){ |
| 74 | Blob repo; |
| 75 | cachedManifest = db_get_boolean("manifest",0); |
| 76 | blob_zero(&repo); |
| 77 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 78 | const char *zRepo = blob_str(&repo); |
| 79 | azRepo[0] = zRepo; |
| 80 | azRepo[1] = mprintf("%s-journal", zRepo); |
| 81 | azRepo[2] = mprintf("%s-wal", zRepo); |
| 82 | azRepo[3] = mprintf("%s-shm", zRepo); |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | if( N<0 ) return 0; |
| 87 | if( N<count(azName) ) return azName[N]; |
| 88 | N -= count(azName); |
| 89 | if( cachedManifest ){ |
| 90 | if( N<count(azManifest) ) return azManifest[N]; |
| 91 | N -= count(azManifest); |
| 92 | } |
| 93 | if( N<count(azRepo) ) return azRepo[N]; |
| 94 | return 0; |
| 95 | } |
| 96 | |
| 97 | /* |
| 98 | ** Return a list of all reserved filenames as an SQL list. |
| @@ -93,10 +110,25 @@ | |
| 110 | } |
| 111 | zAll = blob_str(&x); |
| 112 | } |
| 113 | return zAll; |
| 114 | } |
| 115 | |
| 116 | /* |
| 117 | ** COMMAND: test-reserved-names |
| 118 | ** |
| 119 | ** Show all reserved filenames for the current check-out. |
| 120 | */ |
| 121 | void test_reserved_names(void){ |
| 122 | int i; |
| 123 | const char *z; |
| 124 | db_must_be_within_tree(); |
| 125 | for(i=0; (z = fossil_reserved_name(i))!=0; i++){ |
| 126 | fossil_print("%3d: %s\n", i, z); |
| 127 | } |
| 128 | fossil_print("ALL: (%s)\n", fossil_all_reserved_names()); |
| 129 | } |
| 130 | |
| 131 | /* |
| 132 | ** Add a single file named zName to the VFILE table with vid. |
| 133 | ** |
| 134 | ** Omit any file whose name is pOmit. |
| 135 |
+1
-1
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -525,11 +525,11 @@ | ||
| 525 | 525 | @ </pre> |
| 526 | 526 | } |
| 527 | 527 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 528 | 528 | @ <img src="%R/raw?name=%s(zSrc)&m=%s(zMime)"></img> |
| 529 | 529 | }else{ |
| 530 | - int sz = db_int(0, "SELECT sz FROM blob WHERE rid=%d", ridSrc); | |
| 530 | + int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); | |
| 531 | 531 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 532 | 532 | } |
| 533 | 533 | @ </blockquote> |
| 534 | 534 | manifest_destroy(pAttach); |
| 535 | 535 | blob_reset(&attach); |
| 536 | 536 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -525,11 +525,11 @@ | |
| 525 | @ </pre> |
| 526 | } |
| 527 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 528 | @ <img src="%R/raw?name=%s(zSrc)&m=%s(zMime)"></img> |
| 529 | }else{ |
| 530 | int sz = db_int(0, "SELECT sz FROM blob WHERE rid=%d", ridSrc); |
| 531 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 532 | } |
| 533 | @ </blockquote> |
| 534 | manifest_destroy(pAttach); |
| 535 | blob_reset(&attach); |
| 536 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -525,11 +525,11 @@ | |
| 525 | @ </pre> |
| 526 | } |
| 527 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 528 | @ <img src="%R/raw?name=%s(zSrc)&m=%s(zMime)"></img> |
| 529 | }else{ |
| 530 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 531 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 532 | } |
| 533 | @ </blockquote> |
| 534 | manifest_destroy(pAttach); |
| 535 | blob_reset(&attach); |
| 536 |
+4
-5
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -324,11 +324,10 @@ | ||
| 324 | 324 | ** |
| 325 | 325 | ** See also: changes, clean, status |
| 326 | 326 | */ |
| 327 | 327 | void extra_cmd(void){ |
| 328 | 328 | Blob path; |
| 329 | - Blob repo; | |
| 330 | 329 | Stmt q; |
| 331 | 330 | int n; |
| 332 | 331 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 333 | 332 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 334 | 333 | int cwdRelative = 0; |
| @@ -353,13 +352,10 @@ | ||
| 353 | 352 | "SELECT x FROM sfile" |
| 354 | 353 | " WHERE x NOT IN (%s)" |
| 355 | 354 | " ORDER BY 1", |
| 356 | 355 | fossil_all_reserved_names() |
| 357 | 356 | ); |
| 358 | - if( file_tree_name(g.zRepositoryName, &repo, 0) ){ | |
| 359 | - db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); | |
| 360 | - } | |
| 361 | 357 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 362 | 358 | blob_zero(&rewrittenPathname); |
| 363 | 359 | while( db_step(&q)==SQLITE_ROW ){ |
| 364 | 360 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 365 | 361 | if( cwdRelative ) { |
| @@ -1031,10 +1027,11 @@ | ||
| 1031 | 1027 | ** --message-file|-M FILE read the commit comment from given file |
| 1032 | 1028 | ** --nosign do not attempt to sign this commit with gpg |
| 1033 | 1029 | ** --private do not sync changes and their descendants |
| 1034 | 1030 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1035 | 1031 | ** --conflict allow unresolved merge conflicts |
| 1032 | +** --binary-ok do not warn about committing binary files | |
| 1036 | 1033 | ** |
| 1037 | 1034 | ** See also: branch, changes, checkout, extra, sync |
| 1038 | 1035 | */ |
| 1039 | 1036 | void commit_cmd(void){ |
| 1040 | 1037 | int hasChanges; /* True if unsaved changes exist */ |
| @@ -1049,10 +1046,11 @@ | ||
| 1049 | 1046 | int isAMerge = 0; /* True if checking in a merge */ |
| 1050 | 1047 | int forceFlag = 0; /* Force a fork */ |
| 1051 | 1048 | int forceDelta = 0; /* Force a delta-manifest */ |
| 1052 | 1049 | int forceBaseline = 0; /* Force a baseline-manifest */ |
| 1053 | 1050 | int allowConflict = 0; /* Allow unresolve merge conflicts */ |
| 1051 | + int binaryOk = 0; /* The --binary-ok flag */ | |
| 1054 | 1052 | char *zManifestFile; /* Name of the manifest file */ |
| 1055 | 1053 | int useCksum; /* True if checksums should be computed and verified */ |
| 1056 | 1054 | int outputManifest; /* True to output "manifest" and "manifest.uuid" */ |
| 1057 | 1055 | int testRun; /* True for a test run. Debugging only */ |
| 1058 | 1056 | const char *zBranch; /* Create a new branch with this name */ |
| @@ -1085,10 +1083,11 @@ | ||
| 1085 | 1083 | zComment = find_option("comment","m",1); |
| 1086 | 1084 | forceFlag = find_option("force", "f", 0)!=0; |
| 1087 | 1085 | zBranch = find_option("branch","b",1); |
| 1088 | 1086 | zColor = find_option("bgcolor",0,1); |
| 1089 | 1087 | zBrClr = find_option("branchcolor",0,1); |
| 1088 | + binaryOk = find_option("binary-ok",0,0)!=0; | |
| 1090 | 1089 | while( (zTag = find_option("tag",0,1))!=0 ){ |
| 1091 | 1090 | if( zTag[0]==0 ) continue; |
| 1092 | 1091 | azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2)); |
| 1093 | 1092 | azTag[nTag++] = zTag; |
| 1094 | 1093 | azTag[nTag] = 0; |
| @@ -1294,11 +1293,11 @@ | ||
| 1294 | 1293 | id = db_column_int(&q, 0); |
| 1295 | 1294 | zFullname = db_column_text(&q, 1); |
| 1296 | 1295 | rid = db_column_int(&q, 2); |
| 1297 | 1296 | crnlOk = db_column_int(&q, 3); |
| 1298 | 1297 | chnged = db_column_int(&q, 4); |
| 1299 | - binOk = db_column_int(&q, 5); | |
| 1298 | + binOk = binaryOk || db_column_int(&q, 5); | |
| 1300 | 1299 | |
| 1301 | 1300 | blob_zero(&content); |
| 1302 | 1301 | if( file_wd_islink(zFullname) ){ |
| 1303 | 1302 | /* Instead of file content, put link destination path */ |
| 1304 | 1303 | blob_read_link(&content, zFullname); |
| 1305 | 1304 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -324,11 +324,10 @@ | |
| 324 | ** |
| 325 | ** See also: changes, clean, status |
| 326 | */ |
| 327 | void extra_cmd(void){ |
| 328 | Blob path; |
| 329 | Blob repo; |
| 330 | Stmt q; |
| 331 | int n; |
| 332 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 333 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 334 | int cwdRelative = 0; |
| @@ -353,13 +352,10 @@ | |
| 353 | "SELECT x FROM sfile" |
| 354 | " WHERE x NOT IN (%s)" |
| 355 | " ORDER BY 1", |
| 356 | fossil_all_reserved_names() |
| 357 | ); |
| 358 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 359 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 360 | } |
| 361 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 362 | blob_zero(&rewrittenPathname); |
| 363 | while( db_step(&q)==SQLITE_ROW ){ |
| 364 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 365 | if( cwdRelative ) { |
| @@ -1031,10 +1027,11 @@ | |
| 1031 | ** --message-file|-M FILE read the commit comment from given file |
| 1032 | ** --nosign do not attempt to sign this commit with gpg |
| 1033 | ** --private do not sync changes and their descendants |
| 1034 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1035 | ** --conflict allow unresolved merge conflicts |
| 1036 | ** |
| 1037 | ** See also: branch, changes, checkout, extra, sync |
| 1038 | */ |
| 1039 | void commit_cmd(void){ |
| 1040 | int hasChanges; /* True if unsaved changes exist */ |
| @@ -1049,10 +1046,11 @@ | |
| 1049 | int isAMerge = 0; /* True if checking in a merge */ |
| 1050 | int forceFlag = 0; /* Force a fork */ |
| 1051 | int forceDelta = 0; /* Force a delta-manifest */ |
| 1052 | int forceBaseline = 0; /* Force a baseline-manifest */ |
| 1053 | int allowConflict = 0; /* Allow unresolve merge conflicts */ |
| 1054 | char *zManifestFile; /* Name of the manifest file */ |
| 1055 | int useCksum; /* True if checksums should be computed and verified */ |
| 1056 | int outputManifest; /* True to output "manifest" and "manifest.uuid" */ |
| 1057 | int testRun; /* True for a test run. Debugging only */ |
| 1058 | const char *zBranch; /* Create a new branch with this name */ |
| @@ -1085,10 +1083,11 @@ | |
| 1085 | zComment = find_option("comment","m",1); |
| 1086 | forceFlag = find_option("force", "f", 0)!=0; |
| 1087 | zBranch = find_option("branch","b",1); |
| 1088 | zColor = find_option("bgcolor",0,1); |
| 1089 | zBrClr = find_option("branchcolor",0,1); |
| 1090 | while( (zTag = find_option("tag",0,1))!=0 ){ |
| 1091 | if( zTag[0]==0 ) continue; |
| 1092 | azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2)); |
| 1093 | azTag[nTag++] = zTag; |
| 1094 | azTag[nTag] = 0; |
| @@ -1294,11 +1293,11 @@ | |
| 1294 | id = db_column_int(&q, 0); |
| 1295 | zFullname = db_column_text(&q, 1); |
| 1296 | rid = db_column_int(&q, 2); |
| 1297 | crnlOk = db_column_int(&q, 3); |
| 1298 | chnged = db_column_int(&q, 4); |
| 1299 | binOk = db_column_int(&q, 5); |
| 1300 | |
| 1301 | blob_zero(&content); |
| 1302 | if( file_wd_islink(zFullname) ){ |
| 1303 | /* Instead of file content, put link destination path */ |
| 1304 | blob_read_link(&content, zFullname); |
| 1305 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -324,11 +324,10 @@ | |
| 324 | ** |
| 325 | ** See also: changes, clean, status |
| 326 | */ |
| 327 | void extra_cmd(void){ |
| 328 | Blob path; |
| 329 | Stmt q; |
| 330 | int n; |
| 331 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 332 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 333 | int cwdRelative = 0; |
| @@ -353,13 +352,10 @@ | |
| 352 | "SELECT x FROM sfile" |
| 353 | " WHERE x NOT IN (%s)" |
| 354 | " ORDER BY 1", |
| 355 | fossil_all_reserved_names() |
| 356 | ); |
| 357 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 358 | blob_zero(&rewrittenPathname); |
| 359 | while( db_step(&q)==SQLITE_ROW ){ |
| 360 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 361 | if( cwdRelative ) { |
| @@ -1031,10 +1027,11 @@ | |
| 1027 | ** --message-file|-M FILE read the commit comment from given file |
| 1028 | ** --nosign do not attempt to sign this commit with gpg |
| 1029 | ** --private do not sync changes and their descendants |
| 1030 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1031 | ** --conflict allow unresolved merge conflicts |
| 1032 | ** --binary-ok do not warn about committing binary files |
| 1033 | ** |
| 1034 | ** See also: branch, changes, checkout, extra, sync |
| 1035 | */ |
| 1036 | void commit_cmd(void){ |
| 1037 | int hasChanges; /* True if unsaved changes exist */ |
| @@ -1049,10 +1046,11 @@ | |
| 1046 | int isAMerge = 0; /* True if checking in a merge */ |
| 1047 | int forceFlag = 0; /* Force a fork */ |
| 1048 | int forceDelta = 0; /* Force a delta-manifest */ |
| 1049 | int forceBaseline = 0; /* Force a baseline-manifest */ |
| 1050 | int allowConflict = 0; /* Allow unresolve merge conflicts */ |
| 1051 | int binaryOk = 0; /* The --binary-ok flag */ |
| 1052 | char *zManifestFile; /* Name of the manifest file */ |
| 1053 | int useCksum; /* True if checksums should be computed and verified */ |
| 1054 | int outputManifest; /* True to output "manifest" and "manifest.uuid" */ |
| 1055 | int testRun; /* True for a test run. Debugging only */ |
| 1056 | const char *zBranch; /* Create a new branch with this name */ |
| @@ -1085,10 +1083,11 @@ | |
| 1083 | zComment = find_option("comment","m",1); |
| 1084 | forceFlag = find_option("force", "f", 0)!=0; |
| 1085 | zBranch = find_option("branch","b",1); |
| 1086 | zColor = find_option("bgcolor",0,1); |
| 1087 | zBrClr = find_option("branchcolor",0,1); |
| 1088 | binaryOk = find_option("binary-ok",0,0)!=0; |
| 1089 | while( (zTag = find_option("tag",0,1))!=0 ){ |
| 1090 | if( zTag[0]==0 ) continue; |
| 1091 | azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2)); |
| 1092 | azTag[nTag++] = zTag; |
| 1093 | azTag[nTag] = 0; |
| @@ -1294,11 +1293,11 @@ | |
| 1293 | id = db_column_int(&q, 0); |
| 1294 | zFullname = db_column_text(&q, 1); |
| 1295 | rid = db_column_int(&q, 2); |
| 1296 | crnlOk = db_column_int(&q, 3); |
| 1297 | chnged = db_column_int(&q, 4); |
| 1298 | binOk = binaryOk || db_column_int(&q, 5); |
| 1299 | |
| 1300 | blob_zero(&content); |
| 1301 | if( file_wd_islink(zFullname) ){ |
| 1302 | /* Instead of file content, put link destination path */ |
| 1303 | blob_read_link(&content, zFullname); |
| 1304 |
+4
-5
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -324,11 +324,10 @@ | ||
| 324 | 324 | ** |
| 325 | 325 | ** See also: changes, clean, status |
| 326 | 326 | */ |
| 327 | 327 | void extra_cmd(void){ |
| 328 | 328 | Blob path; |
| 329 | - Blob repo; | |
| 330 | 329 | Stmt q; |
| 331 | 330 | int n; |
| 332 | 331 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 333 | 332 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 334 | 333 | int cwdRelative = 0; |
| @@ -353,13 +352,10 @@ | ||
| 353 | 352 | "SELECT x FROM sfile" |
| 354 | 353 | " WHERE x NOT IN (%s)" |
| 355 | 354 | " ORDER BY 1", |
| 356 | 355 | fossil_all_reserved_names() |
| 357 | 356 | ); |
| 358 | - if( file_tree_name(g.zRepositoryName, &repo, 0) ){ | |
| 359 | - db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); | |
| 360 | - } | |
| 361 | 357 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 362 | 358 | blob_zero(&rewrittenPathname); |
| 363 | 359 | while( db_step(&q)==SQLITE_ROW ){ |
| 364 | 360 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 365 | 361 | if( cwdRelative ) { |
| @@ -1031,10 +1027,11 @@ | ||
| 1031 | 1027 | ** --message-file|-M FILE read the commit comment from given file |
| 1032 | 1028 | ** --nosign do not attempt to sign this commit with gpg |
| 1033 | 1029 | ** --private do not sync changes and their descendants |
| 1034 | 1030 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1035 | 1031 | ** --conflict allow unresolved merge conflicts |
| 1032 | +** --binary-ok do not warn about committing binary files | |
| 1036 | 1033 | ** |
| 1037 | 1034 | ** See also: branch, changes, checkout, extra, sync |
| 1038 | 1035 | */ |
| 1039 | 1036 | void commit_cmd(void){ |
| 1040 | 1037 | int hasChanges; /* True if unsaved changes exist */ |
| @@ -1049,10 +1046,11 @@ | ||
| 1049 | 1046 | int isAMerge = 0; /* True if checking in a merge */ |
| 1050 | 1047 | int forceFlag = 0; /* Force a fork */ |
| 1051 | 1048 | int forceDelta = 0; /* Force a delta-manifest */ |
| 1052 | 1049 | int forceBaseline = 0; /* Force a baseline-manifest */ |
| 1053 | 1050 | int allowConflict = 0; /* Allow unresolve merge conflicts */ |
| 1051 | + int binaryOk = 0; /* The --binary-ok flag */ | |
| 1054 | 1052 | char *zManifestFile; /* Name of the manifest file */ |
| 1055 | 1053 | int useCksum; /* True if checksums should be computed and verified */ |
| 1056 | 1054 | int outputManifest; /* True to output "manifest" and "manifest.uuid" */ |
| 1057 | 1055 | int testRun; /* True for a test run. Debugging only */ |
| 1058 | 1056 | const char *zBranch; /* Create a new branch with this name */ |
| @@ -1085,10 +1083,11 @@ | ||
| 1085 | 1083 | zComment = find_option("comment","m",1); |
| 1086 | 1084 | forceFlag = find_option("force", "f", 0)!=0; |
| 1087 | 1085 | zBranch = find_option("branch","b",1); |
| 1088 | 1086 | zColor = find_option("bgcolor",0,1); |
| 1089 | 1087 | zBrClr = find_option("branchcolor",0,1); |
| 1088 | + binaryOk = find_option("binary-ok",0,0)!=0; | |
| 1090 | 1089 | while( (zTag = find_option("tag",0,1))!=0 ){ |
| 1091 | 1090 | if( zTag[0]==0 ) continue; |
| 1092 | 1091 | azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2)); |
| 1093 | 1092 | azTag[nTag++] = zTag; |
| 1094 | 1093 | azTag[nTag] = 0; |
| @@ -1294,11 +1293,11 @@ | ||
| 1294 | 1293 | id = db_column_int(&q, 0); |
| 1295 | 1294 | zFullname = db_column_text(&q, 1); |
| 1296 | 1295 | rid = db_column_int(&q, 2); |
| 1297 | 1296 | crnlOk = db_column_int(&q, 3); |
| 1298 | 1297 | chnged = db_column_int(&q, 4); |
| 1299 | - binOk = db_column_int(&q, 5); | |
| 1298 | + binOk = binaryOk || db_column_int(&q, 5); | |
| 1300 | 1299 | |
| 1301 | 1300 | blob_zero(&content); |
| 1302 | 1301 | if( file_wd_islink(zFullname) ){ |
| 1303 | 1302 | /* Instead of file content, put link destination path */ |
| 1304 | 1303 | blob_read_link(&content, zFullname); |
| 1305 | 1304 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -324,11 +324,10 @@ | |
| 324 | ** |
| 325 | ** See also: changes, clean, status |
| 326 | */ |
| 327 | void extra_cmd(void){ |
| 328 | Blob path; |
| 329 | Blob repo; |
| 330 | Stmt q; |
| 331 | int n; |
| 332 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 333 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 334 | int cwdRelative = 0; |
| @@ -353,13 +352,10 @@ | |
| 353 | "SELECT x FROM sfile" |
| 354 | " WHERE x NOT IN (%s)" |
| 355 | " ORDER BY 1", |
| 356 | fossil_all_reserved_names() |
| 357 | ); |
| 358 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 359 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 360 | } |
| 361 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 362 | blob_zero(&rewrittenPathname); |
| 363 | while( db_step(&q)==SQLITE_ROW ){ |
| 364 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 365 | if( cwdRelative ) { |
| @@ -1031,10 +1027,11 @@ | |
| 1031 | ** --message-file|-M FILE read the commit comment from given file |
| 1032 | ** --nosign do not attempt to sign this commit with gpg |
| 1033 | ** --private do not sync changes and their descendants |
| 1034 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1035 | ** --conflict allow unresolved merge conflicts |
| 1036 | ** |
| 1037 | ** See also: branch, changes, checkout, extra, sync |
| 1038 | */ |
| 1039 | void commit_cmd(void){ |
| 1040 | int hasChanges; /* True if unsaved changes exist */ |
| @@ -1049,10 +1046,11 @@ | |
| 1049 | int isAMerge = 0; /* True if checking in a merge */ |
| 1050 | int forceFlag = 0; /* Force a fork */ |
| 1051 | int forceDelta = 0; /* Force a delta-manifest */ |
| 1052 | int forceBaseline = 0; /* Force a baseline-manifest */ |
| 1053 | int allowConflict = 0; /* Allow unresolve merge conflicts */ |
| 1054 | char *zManifestFile; /* Name of the manifest file */ |
| 1055 | int useCksum; /* True if checksums should be computed and verified */ |
| 1056 | int outputManifest; /* True to output "manifest" and "manifest.uuid" */ |
| 1057 | int testRun; /* True for a test run. Debugging only */ |
| 1058 | const char *zBranch; /* Create a new branch with this name */ |
| @@ -1085,10 +1083,11 @@ | |
| 1085 | zComment = find_option("comment","m",1); |
| 1086 | forceFlag = find_option("force", "f", 0)!=0; |
| 1087 | zBranch = find_option("branch","b",1); |
| 1088 | zColor = find_option("bgcolor",0,1); |
| 1089 | zBrClr = find_option("branchcolor",0,1); |
| 1090 | while( (zTag = find_option("tag",0,1))!=0 ){ |
| 1091 | if( zTag[0]==0 ) continue; |
| 1092 | azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2)); |
| 1093 | azTag[nTag++] = zTag; |
| 1094 | azTag[nTag] = 0; |
| @@ -1294,11 +1293,11 @@ | |
| 1294 | id = db_column_int(&q, 0); |
| 1295 | zFullname = db_column_text(&q, 1); |
| 1296 | rid = db_column_int(&q, 2); |
| 1297 | crnlOk = db_column_int(&q, 3); |
| 1298 | chnged = db_column_int(&q, 4); |
| 1299 | binOk = db_column_int(&q, 5); |
| 1300 | |
| 1301 | blob_zero(&content); |
| 1302 | if( file_wd_islink(zFullname) ){ |
| 1303 | /* Instead of file content, put link destination path */ |
| 1304 | blob_read_link(&content, zFullname); |
| 1305 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -324,11 +324,10 @@ | |
| 324 | ** |
| 325 | ** See also: changes, clean, status |
| 326 | */ |
| 327 | void extra_cmd(void){ |
| 328 | Blob path; |
| 329 | Stmt q; |
| 330 | int n; |
| 331 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 332 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 333 | int cwdRelative = 0; |
| @@ -353,13 +352,10 @@ | |
| 352 | "SELECT x FROM sfile" |
| 353 | " WHERE x NOT IN (%s)" |
| 354 | " ORDER BY 1", |
| 355 | fossil_all_reserved_names() |
| 356 | ); |
| 357 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 358 | blob_zero(&rewrittenPathname); |
| 359 | while( db_step(&q)==SQLITE_ROW ){ |
| 360 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 361 | if( cwdRelative ) { |
| @@ -1031,10 +1027,11 @@ | |
| 1027 | ** --message-file|-M FILE read the commit comment from given file |
| 1028 | ** --nosign do not attempt to sign this commit with gpg |
| 1029 | ** --private do not sync changes and their descendants |
| 1030 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1031 | ** --conflict allow unresolved merge conflicts |
| 1032 | ** --binary-ok do not warn about committing binary files |
| 1033 | ** |
| 1034 | ** See also: branch, changes, checkout, extra, sync |
| 1035 | */ |
| 1036 | void commit_cmd(void){ |
| 1037 | int hasChanges; /* True if unsaved changes exist */ |
| @@ -1049,10 +1046,11 @@ | |
| 1046 | int isAMerge = 0; /* True if checking in a merge */ |
| 1047 | int forceFlag = 0; /* Force a fork */ |
| 1048 | int forceDelta = 0; /* Force a delta-manifest */ |
| 1049 | int forceBaseline = 0; /* Force a baseline-manifest */ |
| 1050 | int allowConflict = 0; /* Allow unresolve merge conflicts */ |
| 1051 | int binaryOk = 0; /* The --binary-ok flag */ |
| 1052 | char *zManifestFile; /* Name of the manifest file */ |
| 1053 | int useCksum; /* True if checksums should be computed and verified */ |
| 1054 | int outputManifest; /* True to output "manifest" and "manifest.uuid" */ |
| 1055 | int testRun; /* True for a test run. Debugging only */ |
| 1056 | const char *zBranch; /* Create a new branch with this name */ |
| @@ -1085,10 +1083,11 @@ | |
| 1083 | zComment = find_option("comment","m",1); |
| 1084 | forceFlag = find_option("force", "f", 0)!=0; |
| 1085 | zBranch = find_option("branch","b",1); |
| 1086 | zColor = find_option("bgcolor",0,1); |
| 1087 | zBrClr = find_option("branchcolor",0,1); |
| 1088 | binaryOk = find_option("binary-ok",0,0)!=0; |
| 1089 | while( (zTag = find_option("tag",0,1))!=0 ){ |
| 1090 | if( zTag[0]==0 ) continue; |
| 1091 | azTag = fossil_realloc((void *)azTag, sizeof(char*)*(nTag+2)); |
| 1092 | azTag[nTag++] = zTag; |
| 1093 | azTag[nTag] = 0; |
| @@ -1294,11 +1293,11 @@ | |
| 1293 | id = db_column_int(&q, 0); |
| 1294 | zFullname = db_column_text(&q, 1); |
| 1295 | rid = db_column_int(&q, 2); |
| 1296 | crnlOk = db_column_int(&q, 3); |
| 1297 | chnged = db_column_int(&q, 4); |
| 1298 | binOk = binaryOk || db_column_int(&q, 5); |
| 1299 | |
| 1300 | blob_zero(&content); |
| 1301 | if( file_wd_islink(zFullname) ){ |
| 1302 | /* Instead of file content, put link destination path */ |
| 1303 | blob_read_link(&content, zFullname); |
| 1304 |
+9
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -1027,10 +1027,19 @@ | ||
| 1027 | 1027 | } |
| 1028 | 1028 | if( nRight==0 ){ |
| 1029 | 1029 | memset(aM, 1, nLeft); |
| 1030 | 1030 | return aM; |
| 1031 | 1031 | } |
| 1032 | + | |
| 1033 | + /* This algorithm is O(N**2). So if N is too big, bail out with a | |
| 1034 | + ** simple (but stupid and ugly) result that doesn't take too long. */ | |
| 1035 | + if( nLeft*nRight>100000 ){ | |
| 1036 | + memset(aM, 3, nRight); | |
| 1037 | + memset(aM+nRight, 1, nLeft); | |
| 1038 | + return aM; | |
| 1039 | + } | |
| 1040 | + | |
| 1032 | 1041 | if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){ |
| 1033 | 1042 | pToFree = 0; |
| 1034 | 1043 | a = aBuf; |
| 1035 | 1044 | }else{ |
| 1036 | 1045 | a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) ); |
| 1037 | 1046 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1027,10 +1027,19 @@ | |
| 1027 | } |
| 1028 | if( nRight==0 ){ |
| 1029 | memset(aM, 1, nLeft); |
| 1030 | return aM; |
| 1031 | } |
| 1032 | if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){ |
| 1033 | pToFree = 0; |
| 1034 | a = aBuf; |
| 1035 | }else{ |
| 1036 | a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) ); |
| 1037 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1027,10 +1027,19 @@ | |
| 1027 | } |
| 1028 | if( nRight==0 ){ |
| 1029 | memset(aM, 1, nLeft); |
| 1030 | return aM; |
| 1031 | } |
| 1032 | |
| 1033 | /* This algorithm is O(N**2). So if N is too big, bail out with a |
| 1034 | ** simple (but stupid and ugly) result that doesn't take too long. */ |
| 1035 | if( nLeft*nRight>100000 ){ |
| 1036 | memset(aM, 3, nRight); |
| 1037 | memset(aM+nRight, 1, nLeft); |
| 1038 | return aM; |
| 1039 | } |
| 1040 | |
| 1041 | if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){ |
| 1042 | pToFree = 0; |
| 1043 | a = aBuf; |
| 1044 | }else{ |
| 1045 | a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) ); |
| 1046 |
+9
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -1027,10 +1027,19 @@ | ||
| 1027 | 1027 | } |
| 1028 | 1028 | if( nRight==0 ){ |
| 1029 | 1029 | memset(aM, 1, nLeft); |
| 1030 | 1030 | return aM; |
| 1031 | 1031 | } |
| 1032 | + | |
| 1033 | + /* This algorithm is O(N**2). So if N is too big, bail out with a | |
| 1034 | + ** simple (but stupid and ugly) result that doesn't take too long. */ | |
| 1035 | + if( nLeft*nRight>100000 ){ | |
| 1036 | + memset(aM, 3, nRight); | |
| 1037 | + memset(aM+nRight, 1, nLeft); | |
| 1038 | + return aM; | |
| 1039 | + } | |
| 1040 | + | |
| 1032 | 1041 | if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){ |
| 1033 | 1042 | pToFree = 0; |
| 1034 | 1043 | a = aBuf; |
| 1035 | 1044 | }else{ |
| 1036 | 1045 | a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) ); |
| 1037 | 1046 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1027,10 +1027,19 @@ | |
| 1027 | } |
| 1028 | if( nRight==0 ){ |
| 1029 | memset(aM, 1, nLeft); |
| 1030 | return aM; |
| 1031 | } |
| 1032 | if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){ |
| 1033 | pToFree = 0; |
| 1034 | a = aBuf; |
| 1035 | }else{ |
| 1036 | a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) ); |
| 1037 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1027,10 +1027,19 @@ | |
| 1027 | } |
| 1028 | if( nRight==0 ){ |
| 1029 | memset(aM, 1, nLeft); |
| 1030 | return aM; |
| 1031 | } |
| 1032 | |
| 1033 | /* This algorithm is O(N**2). So if N is too big, bail out with a |
| 1034 | ** simple (but stupid and ugly) result that doesn't take too long. */ |
| 1035 | if( nLeft*nRight>100000 ){ |
| 1036 | memset(aM, 3, nRight); |
| 1037 | memset(aM+nRight, 1, nLeft); |
| 1038 | return aM; |
| 1039 | } |
| 1040 | |
| 1041 | if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){ |
| 1042 | pToFree = 0; |
| 1043 | a = aBuf; |
| 1044 | }else{ |
| 1045 | a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) ); |
| 1046 |
+3
-3
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -331,11 +331,11 @@ | ||
| 331 | 331 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, 0); |
| 332 | 332 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 333 | 333 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 334 | 334 | @ <tr><td> |
| 335 | 335 | @ <div class="divider">%s(zPrevDate)</div> |
| 336 | - @ </td></tr> | |
| 336 | + @ </td><td></td><td></td></tr> | |
| 337 | 337 | } |
| 338 | 338 | memcpy(zTime, &zDate[11], 5); |
| 339 | 339 | zTime[5] = 0; |
| 340 | 340 | @ <tr><td class="timelineTime"> |
| 341 | 341 | @ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td> |
| @@ -357,11 +357,11 @@ | ||
| 357 | 357 | hyperlink_to_user(zUser, zDate, ""); |
| 358 | 358 | @ branch: %h(zBr)) |
| 359 | 359 | if( g.perm.Hyperlink && zUuid ){ |
| 360 | 360 | const char *z = zFilename; |
| 361 | 361 | if( fpid ){ |
| 362 | - @ %z(href("%R/fdiff?v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> | |
| 362 | + @ %z(href("%R/fdiff?v1=%S&v2=%S",zPUuid,zUuid))[diff]</a> | |
| 363 | 363 | } |
| 364 | 364 | @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) |
| 365 | 365 | @ [annotate]</a> |
| 366 | 366 | } |
| 367 | 367 | @ </td></tr> |
| @@ -373,12 +373,12 @@ | ||
| 373 | 373 | graph_free(pGraph); |
| 374 | 374 | pGraph = 0; |
| 375 | 375 | }else{ |
| 376 | 376 | @ <tr><td></td><td> |
| 377 | 377 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 378 | - @ </td></tr> | |
| 378 | + @ </td><td></td></tr> | |
| 379 | 379 | } |
| 380 | 380 | } |
| 381 | 381 | @ </table> |
| 382 | 382 | timeline_output_graph_javascript(pGraph, 0); |
| 383 | 383 | style_footer(); |
| 384 | 384 | } |
| 385 | 385 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -331,11 +331,11 @@ | |
| 331 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, 0); |
| 332 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 333 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 334 | @ <tr><td> |
| 335 | @ <div class="divider">%s(zPrevDate)</div> |
| 336 | @ </td></tr> |
| 337 | } |
| 338 | memcpy(zTime, &zDate[11], 5); |
| 339 | zTime[5] = 0; |
| 340 | @ <tr><td class="timelineTime"> |
| 341 | @ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td> |
| @@ -357,11 +357,11 @@ | |
| 357 | hyperlink_to_user(zUser, zDate, ""); |
| 358 | @ branch: %h(zBr)) |
| 359 | if( g.perm.Hyperlink && zUuid ){ |
| 360 | const char *z = zFilename; |
| 361 | if( fpid ){ |
| 362 | @ %z(href("%R/fdiff?v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> |
| 363 | } |
| 364 | @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) |
| 365 | @ [annotate]</a> |
| 366 | } |
| 367 | @ </td></tr> |
| @@ -373,12 +373,12 @@ | |
| 373 | graph_free(pGraph); |
| 374 | pGraph = 0; |
| 375 | }else{ |
| 376 | @ <tr><td></td><td> |
| 377 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 378 | @ </td></tr> |
| 379 | } |
| 380 | } |
| 381 | @ </table> |
| 382 | timeline_output_graph_javascript(pGraph, 0); |
| 383 | style_footer(); |
| 384 | } |
| 385 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -331,11 +331,11 @@ | |
| 331 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, 0); |
| 332 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 333 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 334 | @ <tr><td> |
| 335 | @ <div class="divider">%s(zPrevDate)</div> |
| 336 | @ </td><td></td><td></td></tr> |
| 337 | } |
| 338 | memcpy(zTime, &zDate[11], 5); |
| 339 | zTime[5] = 0; |
| 340 | @ <tr><td class="timelineTime"> |
| 341 | @ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td> |
| @@ -357,11 +357,11 @@ | |
| 357 | hyperlink_to_user(zUser, zDate, ""); |
| 358 | @ branch: %h(zBr)) |
| 359 | if( g.perm.Hyperlink && zUuid ){ |
| 360 | const char *z = zFilename; |
| 361 | if( fpid ){ |
| 362 | @ %z(href("%R/fdiff?v1=%S&v2=%S",zPUuid,zUuid))[diff]</a> |
| 363 | } |
| 364 | @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) |
| 365 | @ [annotate]</a> |
| 366 | } |
| 367 | @ </td></tr> |
| @@ -373,12 +373,12 @@ | |
| 373 | graph_free(pGraph); |
| 374 | pGraph = 0; |
| 375 | }else{ |
| 376 | @ <tr><td></td><td> |
| 377 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 378 | @ </td><td></td></tr> |
| 379 | } |
| 380 | } |
| 381 | @ </table> |
| 382 | timeline_output_graph_javascript(pGraph, 0); |
| 383 | style_footer(); |
| 384 | } |
| 385 |
+12
-5
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -110,10 +110,12 @@ | ||
| 110 | 110 | */ |
| 111 | 111 | const char *zSsh; /* The base SSH command */ |
| 112 | 112 | Blob zCmd; /* The SSH command */ |
| 113 | 113 | char *zHost; /* The host name to contact */ |
| 114 | 114 | char *zIn; /* An input line received back from remote */ |
| 115 | + unsigned iRandom; | |
| 116 | + char zProbe[30]; | |
| 115 | 117 | |
| 116 | 118 | zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 117 | 119 | blob_init(&zCmd, zSsh, -1); |
| 118 | 120 | if( g.urlPort!=g.urlDfltPort ){ |
| 119 | 121 | #ifdef __MINGW32__ |
| @@ -155,18 +157,23 @@ | ||
| 155 | 157 | if( sshPid==0 ){ |
| 156 | 158 | fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 157 | 159 | } |
| 158 | 160 | blob_reset(&zCmd); |
| 159 | 161 | |
| 160 | - /* Send an "echo" command to the other side to make sure that the | |
| 162 | + /* Send a couple of "echo" command to the other side to make sure that the | |
| 161 | 163 | ** connection is up and working. |
| 162 | 164 | */ |
| 163 | - fprintf(sshOut, "echo test\n"); | |
| 165 | + fprintf(sshOut, "echo test1\n"); | |
| 166 | + fflush(sshOut); | |
| 167 | + zIn = fossil_malloc(50000); | |
| 168 | + sshin_read(zIn, 50000); | |
| 169 | + sqlite3_randomness(sizeof(iRandom), &iRandom); | |
| 170 | + sqlite3_snprintf(sizeof(zProbe), zProbe, "probe-%08x", iRandom); | |
| 171 | + fprintf(sshOut, "echo %s\n", zProbe); | |
| 164 | 172 | fflush(sshOut); |
| 165 | - zIn = fossil_malloc(16000); | |
| 166 | - sshin_read(zIn, 16000); | |
| 167 | - if( memcmp(zIn, "test", 4)!=0 ){ | |
| 173 | + sshin_read(zIn, 500); | |
| 174 | + if( memcmp(zIn, zProbe, 14)!=0 ){ | |
| 168 | 175 | pclose2(sshIn, sshOut, sshPid); |
| 169 | 176 | fossil_fatal("ssh connection failed: [%s]", zIn); |
| 170 | 177 | } |
| 171 | 178 | fossil_free(zIn); |
| 172 | 179 | } |
| 173 | 180 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -110,10 +110,12 @@ | |
| 110 | */ |
| 111 | const char *zSsh; /* The base SSH command */ |
| 112 | Blob zCmd; /* The SSH command */ |
| 113 | char *zHost; /* The host name to contact */ |
| 114 | char *zIn; /* An input line received back from remote */ |
| 115 | |
| 116 | zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 117 | blob_init(&zCmd, zSsh, -1); |
| 118 | if( g.urlPort!=g.urlDfltPort ){ |
| 119 | #ifdef __MINGW32__ |
| @@ -155,18 +157,23 @@ | |
| 155 | if( sshPid==0 ){ |
| 156 | fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 157 | } |
| 158 | blob_reset(&zCmd); |
| 159 | |
| 160 | /* Send an "echo" command to the other side to make sure that the |
| 161 | ** connection is up and working. |
| 162 | */ |
| 163 | fprintf(sshOut, "echo test\n"); |
| 164 | fflush(sshOut); |
| 165 | zIn = fossil_malloc(16000); |
| 166 | sshin_read(zIn, 16000); |
| 167 | if( memcmp(zIn, "test", 4)!=0 ){ |
| 168 | pclose2(sshIn, sshOut, sshPid); |
| 169 | fossil_fatal("ssh connection failed: [%s]", zIn); |
| 170 | } |
| 171 | fossil_free(zIn); |
| 172 | } |
| 173 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -110,10 +110,12 @@ | |
| 110 | */ |
| 111 | const char *zSsh; /* The base SSH command */ |
| 112 | Blob zCmd; /* The SSH command */ |
| 113 | char *zHost; /* The host name to contact */ |
| 114 | char *zIn; /* An input line received back from remote */ |
| 115 | unsigned iRandom; |
| 116 | char zProbe[30]; |
| 117 | |
| 118 | zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 119 | blob_init(&zCmd, zSsh, -1); |
| 120 | if( g.urlPort!=g.urlDfltPort ){ |
| 121 | #ifdef __MINGW32__ |
| @@ -155,18 +157,23 @@ | |
| 157 | if( sshPid==0 ){ |
| 158 | fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 159 | } |
| 160 | blob_reset(&zCmd); |
| 161 | |
| 162 | /* Send a couple of "echo" command to the other side to make sure that the |
| 163 | ** connection is up and working. |
| 164 | */ |
| 165 | fprintf(sshOut, "echo test1\n"); |
| 166 | fflush(sshOut); |
| 167 | zIn = fossil_malloc(50000); |
| 168 | sshin_read(zIn, 50000); |
| 169 | sqlite3_randomness(sizeof(iRandom), &iRandom); |
| 170 | sqlite3_snprintf(sizeof(zProbe), zProbe, "probe-%08x", iRandom); |
| 171 | fprintf(sshOut, "echo %s\n", zProbe); |
| 172 | fflush(sshOut); |
| 173 | sshin_read(zIn, 500); |
| 174 | if( memcmp(zIn, zProbe, 14)!=0 ){ |
| 175 | pclose2(sshIn, sshOut, sshPid); |
| 176 | fossil_fatal("ssh connection failed: [%s]", zIn); |
| 177 | } |
| 178 | fossil_free(zIn); |
| 179 | } |
| 180 |
+4
-4
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -617,16 +617,16 @@ | ||
| 617 | 617 | @ </td></tr> |
| 618 | 618 | } |
| 619 | 619 | |
| 620 | 620 | /* The Download: line */ |
| 621 | 621 | if( g.perm.Zip ){ |
| 622 | - char *zUrl = mprintf("%R/tarball/%s-%S.tar.gz?uuid=%s", | |
| 622 | + char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s", | |
| 623 | 623 | zProjName, zUuid, zUuid); |
| 624 | 624 | @ </td></tr> |
| 625 | 625 | @ <tr><th>Downloads:</th><td> |
| 626 | 626 | @ %z(href("%s",zUrl))Tarball</a> |
| 627 | - @ | %z(href("%R/zip/%s-%S.zip?uuid=%s",zProjName,zUuid,zUuid)) | |
| 627 | + @ | %z(href("%R/zip/%t-%S.zip?uuid=%s",zProjName,zUuid,zUuid)) | |
| 628 | 628 | @ ZIP archive</a> |
| 629 | 629 | fossil_free(zUrl); |
| 630 | 630 | } |
| 631 | 631 | @ </td></tr> |
| 632 | 632 | @ <tr><th>Other Links:</th> |
| @@ -885,11 +885,11 @@ | ||
| 885 | 885 | blob_zero(&links); |
| 886 | 886 | while( z && z[0] ){ |
| 887 | 887 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 888 | 888 | blob_appendf(&links, |
| 889 | 889 | "%z%#h</a>%.2s", |
| 890 | - href("%R/timeline?r=%#t&nd&c=%s",i,z,zDate), i,z, &z[i] | |
| 890 | + href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] | |
| 891 | 891 | ); |
| 892 | 892 | if( z[i]==0 ) break; |
| 893 | 893 | z += i+2; |
| 894 | 894 | } |
| 895 | 895 | @ tags: %s(blob_str(&links)), |
| @@ -1723,14 +1723,14 @@ | ||
| 1723 | 1723 | } |
| 1724 | 1724 | @ <tr><th>Ticket:</th> |
| 1725 | 1725 | @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr> |
| 1726 | 1726 | @ <tr><th>Date:</th><td> |
| 1727 | 1727 | hyperlink_to_date(zDate, "</td></tr>"); |
| 1728 | - free(zDate); | |
| 1729 | 1728 | @ <tr><th>User:</th><td> |
| 1730 | 1729 | hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>"); |
| 1731 | 1730 | @ </table> |
| 1731 | + free(zDate); | |
| 1732 | 1732 | |
| 1733 | 1733 | if( g.perm.ModTkt && modPending ){ |
| 1734 | 1734 | @ <div class="section">Moderation</div> |
| 1735 | 1735 | @ <blockquote> |
| 1736 | 1736 | @ <form method="POST" action="%R/tinfo/%s(zUuid)"> |
| 1737 | 1737 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -617,16 +617,16 @@ | |
| 617 | @ </td></tr> |
| 618 | } |
| 619 | |
| 620 | /* The Download: line */ |
| 621 | if( g.perm.Zip ){ |
| 622 | char *zUrl = mprintf("%R/tarball/%s-%S.tar.gz?uuid=%s", |
| 623 | zProjName, zUuid, zUuid); |
| 624 | @ </td></tr> |
| 625 | @ <tr><th>Downloads:</th><td> |
| 626 | @ %z(href("%s",zUrl))Tarball</a> |
| 627 | @ | %z(href("%R/zip/%s-%S.zip?uuid=%s",zProjName,zUuid,zUuid)) |
| 628 | @ ZIP archive</a> |
| 629 | fossil_free(zUrl); |
| 630 | } |
| 631 | @ </td></tr> |
| 632 | @ <tr><th>Other Links:</th> |
| @@ -885,11 +885,11 @@ | |
| 885 | blob_zero(&links); |
| 886 | while( z && z[0] ){ |
| 887 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 888 | blob_appendf(&links, |
| 889 | "%z%#h</a>%.2s", |
| 890 | href("%R/timeline?r=%#t&nd&c=%s",i,z,zDate), i,z, &z[i] |
| 891 | ); |
| 892 | if( z[i]==0 ) break; |
| 893 | z += i+2; |
| 894 | } |
| 895 | @ tags: %s(blob_str(&links)), |
| @@ -1723,14 +1723,14 @@ | |
| 1723 | } |
| 1724 | @ <tr><th>Ticket:</th> |
| 1725 | @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr> |
| 1726 | @ <tr><th>Date:</th><td> |
| 1727 | hyperlink_to_date(zDate, "</td></tr>"); |
| 1728 | free(zDate); |
| 1729 | @ <tr><th>User:</th><td> |
| 1730 | hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>"); |
| 1731 | @ </table> |
| 1732 | |
| 1733 | if( g.perm.ModTkt && modPending ){ |
| 1734 | @ <div class="section">Moderation</div> |
| 1735 | @ <blockquote> |
| 1736 | @ <form method="POST" action="%R/tinfo/%s(zUuid)"> |
| 1737 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -617,16 +617,16 @@ | |
| 617 | @ </td></tr> |
| 618 | } |
| 619 | |
| 620 | /* The Download: line */ |
| 621 | if( g.perm.Zip ){ |
| 622 | char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s", |
| 623 | zProjName, zUuid, zUuid); |
| 624 | @ </td></tr> |
| 625 | @ <tr><th>Downloads:</th><td> |
| 626 | @ %z(href("%s",zUrl))Tarball</a> |
| 627 | @ | %z(href("%R/zip/%t-%S.zip?uuid=%s",zProjName,zUuid,zUuid)) |
| 628 | @ ZIP archive</a> |
| 629 | fossil_free(zUrl); |
| 630 | } |
| 631 | @ </td></tr> |
| 632 | @ <tr><th>Other Links:</th> |
| @@ -885,11 +885,11 @@ | |
| 885 | blob_zero(&links); |
| 886 | while( z && z[0] ){ |
| 887 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 888 | blob_appendf(&links, |
| 889 | "%z%#h</a>%.2s", |
| 890 | href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] |
| 891 | ); |
| 892 | if( z[i]==0 ) break; |
| 893 | z += i+2; |
| 894 | } |
| 895 | @ tags: %s(blob_str(&links)), |
| @@ -1723,14 +1723,14 @@ | |
| 1723 | } |
| 1724 | @ <tr><th>Ticket:</th> |
| 1725 | @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr> |
| 1726 | @ <tr><th>Date:</th><td> |
| 1727 | hyperlink_to_date(zDate, "</td></tr>"); |
| 1728 | @ <tr><th>User:</th><td> |
| 1729 | hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>"); |
| 1730 | @ </table> |
| 1731 | free(zDate); |
| 1732 | |
| 1733 | if( g.perm.ModTkt && modPending ){ |
| 1734 | @ <div class="section">Moderation</div> |
| 1735 | @ <blockquote> |
| 1736 | @ <form method="POST" action="%R/tinfo/%s(zUuid)"> |
| 1737 |
+1
-1
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -1145,11 +1145,11 @@ | ||
| 1145 | 1145 | db_exists("SELECT 1 FROM user" |
| 1146 | 1146 | " WHERE login='anonymous'" |
| 1147 | 1147 | " AND cap LIKE '%%h%%'") ){ |
| 1148 | 1148 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1149 | 1149 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1150 | - @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> | |
| 1150 | + @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> | |
| 1151 | 1151 | @ to enable hyperlinks.</p> |
| 1152 | 1152 | } |
| 1153 | 1153 | } |
| 1154 | 1154 | |
| 1155 | 1155 | /* |
| 1156 | 1156 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1145,11 +1145,11 @@ | |
| 1145 | db_exists("SELECT 1 FROM user" |
| 1146 | " WHERE login='anonymous'" |
| 1147 | " AND cap LIKE '%%h%%'") ){ |
| 1148 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1149 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1150 | @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 1151 | @ to enable hyperlinks.</p> |
| 1152 | } |
| 1153 | } |
| 1154 | |
| 1155 | /* |
| 1156 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1145,11 +1145,11 @@ | |
| 1145 | db_exists("SELECT 1 FROM user" |
| 1146 | " WHERE login='anonymous'" |
| 1147 | " AND cap LIKE '%%h%%'") ){ |
| 1148 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1149 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1150 | @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 1151 | @ to enable hyperlinks.</p> |
| 1152 | } |
| 1153 | } |
| 1154 | |
| 1155 | /* |
| 1156 |
+1
-1
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -60,11 +60,11 @@ | ||
| 60 | 60 | } else { |
| 61 | 61 | blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle); |
| 62 | 62 | } |
| 63 | 63 | blob_appendf(&ril, " "); |
| 64 | 64 | if( g.perm.Write && zOwner && zOwner[0] ){ |
| 65 | - blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner); | |
| 65 | + blob_appendf(&ril, "(by <i>%h</i>) ", zOwner); | |
| 66 | 66 | } |
| 67 | 67 | if( g.perm.TktFmt ){ |
| 68 | 68 | blob_appendf(&ril, "[%zcopy</a>] ", |
| 69 | 69 | href("%R/rptedit?rn=%d©=1", rn)); |
| 70 | 70 | } |
| 71 | 71 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | } else { |
| 61 | blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle); |
| 62 | } |
| 63 | blob_appendf(&ril, " "); |
| 64 | if( g.perm.Write && zOwner && zOwner[0] ){ |
| 65 | blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner); |
| 66 | } |
| 67 | if( g.perm.TktFmt ){ |
| 68 | blob_appendf(&ril, "[%zcopy</a>] ", |
| 69 | href("%R/rptedit?rn=%d©=1", rn)); |
| 70 | } |
| 71 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | } else { |
| 61 | blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle); |
| 62 | } |
| 63 | blob_appendf(&ril, " "); |
| 64 | if( g.perm.Write && zOwner && zOwner[0] ){ |
| 65 | blob_appendf(&ril, "(by <i>%h</i>) ", zOwner); |
| 66 | } |
| 67 | if( g.perm.TktFmt ){ |
| 68 | blob_appendf(&ril, "[%zcopy</a>] ", |
| 69 | href("%R/rptedit?rn=%d©=1", rn)); |
| 70 | } |
| 71 |
+2
-2
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -62,11 +62,11 @@ | ||
| 62 | 62 | |
| 63 | 63 | /* Make sure the header contains <base href="...">. Issue a warning |
| 64 | 64 | ** if it does not. */ |
| 65 | 65 | if( !cgi_header_contains("<base href=") ){ |
| 66 | 66 | @ <p class="generalError"><b>Configuration Error:</b> Please add |
| 67 | - @ <tt><base href="$baseurl/$current_page"></tt> after | |
| 67 | + @ <tt><base href="$baseurl/$current_page"></tt> after | |
| 68 | 68 | @ <tt><head></tt> in the <a href="setup_header">HTML header</a>!</p> |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | @ <table border="0" cellspacing="7"> |
| 72 | 72 | setup_menu_entry("Users", "setup_ulist", |
| @@ -1352,11 +1352,11 @@ | ||
| 1352 | 1352 | |
| 1353 | 1353 | /* Make sure the header contains <base href="...">. Issue a warning |
| 1354 | 1354 | ** if it does not. */ |
| 1355 | 1355 | if( !cgi_header_contains("<base href=") ){ |
| 1356 | 1356 | @ <p class="generalError">Please add |
| 1357 | - @ <tt><base href="$baseurl/$current_page"></tt> after | |
| 1357 | + @ <tt><base href="$baseurl/$current_page"></tt> after | |
| 1358 | 1358 | @ <tt><head></tt> in the header! |
| 1359 | 1359 | @ <input type="submit" name="fixbase" value="Add <base> Now"></p> |
| 1360 | 1360 | } |
| 1361 | 1361 | |
| 1362 | 1362 | login_insert_csrf_secret(); |
| 1363 | 1363 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -62,11 +62,11 @@ | |
| 62 | |
| 63 | /* Make sure the header contains <base href="...">. Issue a warning |
| 64 | ** if it does not. */ |
| 65 | if( !cgi_header_contains("<base href=") ){ |
| 66 | @ <p class="generalError"><b>Configuration Error:</b> Please add |
| 67 | @ <tt><base href="$baseurl/$current_page"></tt> after |
| 68 | @ <tt><head></tt> in the <a href="setup_header">HTML header</a>!</p> |
| 69 | } |
| 70 | |
| 71 | @ <table border="0" cellspacing="7"> |
| 72 | setup_menu_entry("Users", "setup_ulist", |
| @@ -1352,11 +1352,11 @@ | |
| 1352 | |
| 1353 | /* Make sure the header contains <base href="...">. Issue a warning |
| 1354 | ** if it does not. */ |
| 1355 | if( !cgi_header_contains("<base href=") ){ |
| 1356 | @ <p class="generalError">Please add |
| 1357 | @ <tt><base href="$baseurl/$current_page"></tt> after |
| 1358 | @ <tt><head></tt> in the header! |
| 1359 | @ <input type="submit" name="fixbase" value="Add <base> Now"></p> |
| 1360 | } |
| 1361 | |
| 1362 | login_insert_csrf_secret(); |
| 1363 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -62,11 +62,11 @@ | |
| 62 | |
| 63 | /* Make sure the header contains <base href="...">. Issue a warning |
| 64 | ** if it does not. */ |
| 65 | if( !cgi_header_contains("<base href=") ){ |
| 66 | @ <p class="generalError"><b>Configuration Error:</b> Please add |
| 67 | @ <tt><base href="$baseurl/$current_page"></tt> after |
| 68 | @ <tt><head></tt> in the <a href="setup_header">HTML header</a>!</p> |
| 69 | } |
| 70 | |
| 71 | @ <table border="0" cellspacing="7"> |
| 72 | setup_menu_entry("Users", "setup_ulist", |
| @@ -1352,11 +1352,11 @@ | |
| 1352 | |
| 1353 | /* Make sure the header contains <base href="...">. Issue a warning |
| 1354 | ** if it does not. */ |
| 1355 | if( !cgi_header_contains("<base href=") ){ |
| 1356 | @ <p class="generalError">Please add |
| 1357 | @ <tt><base href="$baseurl/$current_page"></tt> after |
| 1358 | @ <tt><head></tt> in the header! |
| 1359 | @ <input type="submit" name="fixbase" value="Add <base> Now"></p> |
| 1360 | } |
| 1361 | |
| 1362 | login_insert_csrf_secret(); |
| 1363 |
+1
-1
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -1218,11 +1218,11 @@ | ||
| 1218 | 1218 | @ set fossilUrl http://www.fossil-scm.org |
| 1219 | 1219 | @ </th1> |
| 1220 | 1220 | @ <a href="$fossilUrl/">Fossil</a> |
| 1221 | 1221 | @ version $release_version $tclVersion |
| 1222 | 1222 | @ <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> |
| 1223 | -@ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&y=ci">$manifest_date</a> | |
| 1223 | +@ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&y=ci">$manifest_date</a> | |
| 1224 | 1224 | @ </div> |
| 1225 | 1225 | @ </body></html> |
| 1226 | 1226 | @ '); |
| 1227 | 1227 | ; |
| 1228 | 1228 | |
| 1229 | 1229 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -1218,11 +1218,11 @@ | |
| 1218 | @ set fossilUrl http://www.fossil-scm.org |
| 1219 | @ </th1> |
| 1220 | @ <a href="$fossilUrl/">Fossil</a> |
| 1221 | @ version $release_version $tclVersion |
| 1222 | @ <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> |
| 1223 | @ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&y=ci">$manifest_date</a> |
| 1224 | @ </div> |
| 1225 | @ </body></html> |
| 1226 | @ '); |
| 1227 | ; |
| 1228 | |
| 1229 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -1218,11 +1218,11 @@ | |
| 1218 | @ set fossilUrl http://www.fossil-scm.org |
| 1219 | @ </th1> |
| 1220 | @ <a href="$fossilUrl/">Fossil</a> |
| 1221 | @ version $release_version $tclVersion |
| 1222 | @ <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> |
| 1223 | @ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&y=ci">$manifest_date</a> |
| 1224 | @ </div> |
| 1225 | @ </body></html> |
| 1226 | @ '); |
| 1227 | ; |
| 1228 | |
| 1229 |
+84
-12
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -673,11 +673,11 @@ | ||
| 673 | 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | 675 | */ |
| 676 | 676 | #define SQLITE_VERSION "3.7.15" |
| 677 | 677 | #define SQLITE_VERSION_NUMBER 3007015 |
| 678 | -#define SQLITE_SOURCE_ID "2012-10-30 18:09:46 9dca18f5fea84afbecb314ee1cdfb98430656af3" | |
| 678 | +#define SQLITE_SOURCE_ID "2012-11-09 21:40:02 5a3b07f0f5dfae7eea870303f52f37d6a17f1da2" | |
| 679 | 679 | |
| 680 | 680 | /* |
| 681 | 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | 683 | ** |
| @@ -1038,10 +1038,11 @@ | ||
| 1038 | 1038 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) |
| 1039 | 1039 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 1040 | 1040 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 1041 | 1041 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1042 | 1042 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1043 | +#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) | |
| 1043 | 1044 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1044 | 1045 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1045 | 1046 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1046 | 1047 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1047 | 1048 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| @@ -11008,10 +11009,11 @@ | ||
| 11008 | 11009 | int addrInTop; /* Top of the IN loop */ |
| 11009 | 11010 | } *aInLoop; /* Information about each nested IN operator */ |
| 11010 | 11011 | } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */ |
| 11011 | 11012 | Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ |
| 11012 | 11013 | } u; |
| 11014 | + double rOptCost; /* "Optimal" cost for this level */ | |
| 11013 | 11015 | |
| 11014 | 11016 | /* The following field is really not part of the current level. But |
| 11015 | 11017 | ** we need a place to cache virtual table index information for each |
| 11016 | 11018 | ** virtual table in the FROM clause and the WhereLevel structure is |
| 11017 | 11019 | ** a convenient place since there is one WhereLevel for each FROM clause |
| @@ -13716,10 +13718,11 @@ | ||
| 13716 | 13718 | int nByte = 0; /* Used to accumulate return value */ |
| 13717 | 13719 | |
| 13718 | 13720 | db->pnBytesFreed = &nByte; |
| 13719 | 13721 | for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ |
| 13720 | 13722 | sqlite3VdbeClearObject(db, pVdbe); |
| 13723 | + sqlite3DbFree(db, pVdbe); | |
| 13721 | 13724 | } |
| 13722 | 13725 | db->pnBytesFreed = 0; |
| 13723 | 13726 | |
| 13724 | 13727 | *pHighwater = 0; |
| 13725 | 13728 | *pCurrent = nByte; |
| @@ -28219,12 +28222,17 @@ | ||
| 28219 | 28222 | int dirSync /* If true, fsync() directory after deleting file */ |
| 28220 | 28223 | ){ |
| 28221 | 28224 | int rc = SQLITE_OK; |
| 28222 | 28225 | UNUSED_PARAMETER(NotUsed); |
| 28223 | 28226 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 28224 | - if( osUnlink(zPath)==(-1) && errno!=ENOENT ){ | |
| 28225 | - return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); | |
| 28227 | + if( osUnlink(zPath)==(-1) ){ | |
| 28228 | + if( errno==ENOENT ){ | |
| 28229 | + rc = SQLITE_IOERR_DELETE_NOENT; | |
| 28230 | + }else{ | |
| 28231 | + rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); | |
| 28232 | + } | |
| 28233 | + return rc; | |
| 28226 | 28234 | } |
| 28227 | 28235 | #ifndef SQLITE_DISABLE_DIRSYNC |
| 28228 | 28236 | if( (dirSync & 1)!=0 ){ |
| 28229 | 28237 | int fd; |
| 28230 | 28238 | rc = osOpenDirectory(zPath, &fd); |
| @@ -40388,10 +40396,11 @@ | ||
| 40388 | 40396 | |
| 40389 | 40397 | rc = pagerPagecount(pPager, &nPage); |
| 40390 | 40398 | if( rc ) return rc; |
| 40391 | 40399 | if( nPage==0 ){ |
| 40392 | 40400 | rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); |
| 40401 | + if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK; | |
| 40393 | 40402 | isWal = 0; |
| 40394 | 40403 | }else{ |
| 40395 | 40404 | rc = sqlite3OsAccess( |
| 40396 | 40405 | pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal |
| 40397 | 40406 | ); |
| @@ -77655,12 +77664,14 @@ | ||
| 77655 | 77664 | */ |
| 77656 | 77665 | assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 77657 | 77666 | ExprSetIrreducible(pExpr); |
| 77658 | 77667 | pExpr->iAgg = (i16)i; |
| 77659 | 77668 | pExpr->pAggInfo = pAggInfo; |
| 77669 | + return WRC_Prune; | |
| 77670 | + }else{ | |
| 77671 | + return WRC_Continue; | |
| 77660 | 77672 | } |
| 77661 | - return WRC_Prune; | |
| 77662 | 77673 | } |
| 77663 | 77674 | } |
| 77664 | 77675 | return WRC_Continue; |
| 77665 | 77676 | } |
| 77666 | 77677 | static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ |
| @@ -77668,13 +77679,14 @@ | ||
| 77668 | 77679 | UNUSED_PARAMETER(pSelect); |
| 77669 | 77680 | return WRC_Continue; |
| 77670 | 77681 | } |
| 77671 | 77682 | |
| 77672 | 77683 | /* |
| 77673 | -** Analyze the given expression looking for aggregate functions and | |
| 77674 | -** for variables that need to be added to the pParse->aAgg[] array. | |
| 77675 | -** Make additional entries to the pParse->aAgg[] array as necessary. | |
| 77684 | +** Analyze the pExpr expression looking for aggregate functions and | |
| 77685 | +** for variables that need to be added to AggInfo object that pNC->pAggInfo | |
| 77686 | +** points to. Additional entries are made on the AggInfo object as | |
| 77687 | +** necessary. | |
| 77676 | 77688 | ** |
| 77677 | 77689 | ** This routine should only be called after the expression has been |
| 77678 | 77690 | ** analyzed by sqlite3ResolveExprNames(). |
| 77679 | 77691 | */ |
| 77680 | 77692 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ |
| @@ -85700,10 +85712,59 @@ | ||
| 85700 | 85712 | sqlite3_result_double(context, rVal); |
| 85701 | 85713 | break; |
| 85702 | 85714 | } |
| 85703 | 85715 | } |
| 85704 | 85716 | } |
| 85717 | + | |
| 85718 | +/* | |
| 85719 | +** Implementation of the instr() function. | |
| 85720 | +** | |
| 85721 | +** instr(haystack,needle) finds the first occurrence of needle | |
| 85722 | +** in haystack and returns the number of previous characters plus 1, | |
| 85723 | +** or 0 if needle does not occur within haystack. | |
| 85724 | +** | |
| 85725 | +** If both haystack and needle are BLOBs, then the result is one more than | |
| 85726 | +** the number of bytes in haystack prior to the first occurrence of needle, | |
| 85727 | +** or 0 if needle never occurs in haystack. | |
| 85728 | +*/ | |
| 85729 | +static void instrFunc( | |
| 85730 | + sqlite3_context *context, | |
| 85731 | + int argc, | |
| 85732 | + sqlite3_value **argv | |
| 85733 | +){ | |
| 85734 | + const unsigned char *zHaystack; | |
| 85735 | + const unsigned char *zNeedle; | |
| 85736 | + int nHaystack; | |
| 85737 | + int nNeedle; | |
| 85738 | + int typeHaystack, typeNeedle; | |
| 85739 | + int N = 1; | |
| 85740 | + int isText; | |
| 85741 | + | |
| 85742 | + typeHaystack = sqlite3_value_type(argv[0]); | |
| 85743 | + typeNeedle = sqlite3_value_type(argv[1]); | |
| 85744 | + if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; | |
| 85745 | + nHaystack = sqlite3_value_bytes(argv[0]); | |
| 85746 | + nNeedle = sqlite3_value_bytes(argv[1]); | |
| 85747 | + if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ | |
| 85748 | + zHaystack = sqlite3_value_blob(argv[0]); | |
| 85749 | + zNeedle = sqlite3_value_blob(argv[1]); | |
| 85750 | + isText = 0; | |
| 85751 | + }else{ | |
| 85752 | + zHaystack = sqlite3_value_text(argv[0]); | |
| 85753 | + zNeedle = sqlite3_value_text(argv[1]); | |
| 85754 | + isText = 1; | |
| 85755 | + } | |
| 85756 | + while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ | |
| 85757 | + N++; | |
| 85758 | + do{ | |
| 85759 | + nHaystack--; | |
| 85760 | + zHaystack++; | |
| 85761 | + }while( isText && (zHaystack[0]&0xc0)==0x80 ); | |
| 85762 | + } | |
| 85763 | + if( nNeedle>nHaystack ) N = 0; | |
| 85764 | + sqlite3_result_int(context, N); | |
| 85765 | +} | |
| 85705 | 85766 | |
| 85706 | 85767 | /* |
| 85707 | 85768 | ** Implementation of the substr() function. |
| 85708 | 85769 | ** |
| 85709 | 85770 | ** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. |
| @@ -87069,10 +87130,11 @@ | ||
| 87069 | 87130 | FUNCTION(max, -1, 1, 1, minmaxFunc ), |
| 87070 | 87131 | FUNCTION(max, 0, 1, 1, 0 ), |
| 87071 | 87132 | AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), |
| 87072 | 87133 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), |
| 87073 | 87134 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), |
| 87135 | + FUNCTION(instr, 2, 0, 0, instrFunc ), | |
| 87074 | 87136 | FUNCTION(substr, 2, 0, 0, substrFunc ), |
| 87075 | 87137 | FUNCTION(substr, 3, 0, 0, substrFunc ), |
| 87076 | 87138 | FUNCTION(abs, 1, 0, 0, absFunc ), |
| 87077 | 87139 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 87078 | 87140 | FUNCTION(round, 1, 0, 0, roundFunc ), |
| @@ -107298,19 +107360,32 @@ | ||
| 107298 | 107360 | || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex ); |
| 107299 | 107361 | |
| 107300 | 107362 | if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ |
| 107301 | 107363 | notIndexed |= m; |
| 107302 | 107364 | } |
| 107365 | + if( isOptimal ){ | |
| 107366 | + pWInfo->a[j].rOptCost = sWBI.cost.rCost; | |
| 107367 | + }else if( iFrom<nTabList-1 ){ | |
| 107368 | + /* If two or more tables have nearly the same outer loop cost, | |
| 107369 | + ** very different inner loop (optimal) cost, we want to choose | |
| 107370 | + ** for the outer loop that table which benefits the least from | |
| 107371 | + ** being in the inner loop. The following code scales the | |
| 107372 | + ** outer loop cost estimate to accomplish that. */ | |
| 107373 | + WHERETRACE((" scaling cost from %.1f to %.1f\n", | |
| 107374 | + sWBI.cost.rCost, | |
| 107375 | + sWBI.cost.rCost/pWInfo->a[j].rOptCost)); | |
| 107376 | + sWBI.cost.rCost /= pWInfo->a[j].rOptCost; | |
| 107377 | + } | |
| 107303 | 107378 | |
| 107304 | 107379 | /* Conditions under which this table becomes the best so far: |
| 107305 | 107380 | ** |
| 107306 | 107381 | ** (1) The table must not depend on other tables that have not |
| 107307 | 107382 | ** yet run. (In other words, it must not depend on tables |
| 107308 | 107383 | ** in inner loops.) |
| 107309 | 107384 | ** |
| 107310 | - ** (2) A full-table-scan plan cannot supercede indexed plan unless | |
| 107311 | - ** the full-table-scan is an "optimal" plan as defined above. | |
| 107385 | + ** (2) (This rule was removed on 2012-11-09. The scaling of the | |
| 107386 | + ** cost using the optimal scan cost made this rule obsolete.) | |
| 107312 | 107387 | ** |
| 107313 | 107388 | ** (3) All tables have an INDEXED BY clause or this table lacks an |
| 107314 | 107389 | ** INDEXED BY clause or this table uses the specific |
| 107315 | 107390 | ** index specified by its INDEXED BY clause. This rule ensures |
| 107316 | 107391 | ** that a best-so-far is always selected even if an impossible |
| @@ -107321,13 +107396,10 @@ | ||
| 107321 | 107396 | ** |
| 107322 | 107397 | ** (4) The plan cost must be lower than prior plans, where "cost" |
| 107323 | 107398 | ** is defined by the compareCost() function above. |
| 107324 | 107399 | */ |
| 107325 | 107400 | if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */ |
| 107326 | - && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ | |
| 107327 | - || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 | |
| 107328 | - || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) | |
| 107329 | 107401 | && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */ |
| 107330 | 107402 | || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) |
| 107331 | 107403 | && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan)) /* (4) */ |
| 107332 | 107404 | ){ |
| 107333 | 107405 | WHERETRACE((" === table %d (%s) is best so far\n" |
| 107334 | 107406 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -673,11 +673,11 @@ | |
| 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | */ |
| 676 | #define SQLITE_VERSION "3.7.15" |
| 677 | #define SQLITE_VERSION_NUMBER 3007015 |
| 678 | #define SQLITE_SOURCE_ID "2012-10-30 18:09:46 9dca18f5fea84afbecb314ee1cdfb98430656af3" |
| 679 | |
| 680 | /* |
| 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | ** |
| @@ -1038,10 +1038,11 @@ | |
| 1038 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) |
| 1039 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 1040 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 1041 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1042 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1043 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1044 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1045 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1046 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1047 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| @@ -11008,10 +11009,11 @@ | |
| 11008 | int addrInTop; /* Top of the IN loop */ |
| 11009 | } *aInLoop; /* Information about each nested IN operator */ |
| 11010 | } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */ |
| 11011 | Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ |
| 11012 | } u; |
| 11013 | |
| 11014 | /* The following field is really not part of the current level. But |
| 11015 | ** we need a place to cache virtual table index information for each |
| 11016 | ** virtual table in the FROM clause and the WhereLevel structure is |
| 11017 | ** a convenient place since there is one WhereLevel for each FROM clause |
| @@ -13716,10 +13718,11 @@ | |
| 13716 | int nByte = 0; /* Used to accumulate return value */ |
| 13717 | |
| 13718 | db->pnBytesFreed = &nByte; |
| 13719 | for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ |
| 13720 | sqlite3VdbeClearObject(db, pVdbe); |
| 13721 | } |
| 13722 | db->pnBytesFreed = 0; |
| 13723 | |
| 13724 | *pHighwater = 0; |
| 13725 | *pCurrent = nByte; |
| @@ -28219,12 +28222,17 @@ | |
| 28219 | int dirSync /* If true, fsync() directory after deleting file */ |
| 28220 | ){ |
| 28221 | int rc = SQLITE_OK; |
| 28222 | UNUSED_PARAMETER(NotUsed); |
| 28223 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 28224 | if( osUnlink(zPath)==(-1) && errno!=ENOENT ){ |
| 28225 | return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); |
| 28226 | } |
| 28227 | #ifndef SQLITE_DISABLE_DIRSYNC |
| 28228 | if( (dirSync & 1)!=0 ){ |
| 28229 | int fd; |
| 28230 | rc = osOpenDirectory(zPath, &fd); |
| @@ -40388,10 +40396,11 @@ | |
| 40388 | |
| 40389 | rc = pagerPagecount(pPager, &nPage); |
| 40390 | if( rc ) return rc; |
| 40391 | if( nPage==0 ){ |
| 40392 | rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); |
| 40393 | isWal = 0; |
| 40394 | }else{ |
| 40395 | rc = sqlite3OsAccess( |
| 40396 | pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal |
| 40397 | ); |
| @@ -77655,12 +77664,14 @@ | |
| 77655 | */ |
| 77656 | assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 77657 | ExprSetIrreducible(pExpr); |
| 77658 | pExpr->iAgg = (i16)i; |
| 77659 | pExpr->pAggInfo = pAggInfo; |
| 77660 | } |
| 77661 | return WRC_Prune; |
| 77662 | } |
| 77663 | } |
| 77664 | return WRC_Continue; |
| 77665 | } |
| 77666 | static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ |
| @@ -77668,13 +77679,14 @@ | |
| 77668 | UNUSED_PARAMETER(pSelect); |
| 77669 | return WRC_Continue; |
| 77670 | } |
| 77671 | |
| 77672 | /* |
| 77673 | ** Analyze the given expression looking for aggregate functions and |
| 77674 | ** for variables that need to be added to the pParse->aAgg[] array. |
| 77675 | ** Make additional entries to the pParse->aAgg[] array as necessary. |
| 77676 | ** |
| 77677 | ** This routine should only be called after the expression has been |
| 77678 | ** analyzed by sqlite3ResolveExprNames(). |
| 77679 | */ |
| 77680 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ |
| @@ -85700,10 +85712,59 @@ | |
| 85700 | sqlite3_result_double(context, rVal); |
| 85701 | break; |
| 85702 | } |
| 85703 | } |
| 85704 | } |
| 85705 | |
| 85706 | /* |
| 85707 | ** Implementation of the substr() function. |
| 85708 | ** |
| 85709 | ** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. |
| @@ -87069,10 +87130,11 @@ | |
| 87069 | FUNCTION(max, -1, 1, 1, minmaxFunc ), |
| 87070 | FUNCTION(max, 0, 1, 1, 0 ), |
| 87071 | AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), |
| 87072 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), |
| 87073 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), |
| 87074 | FUNCTION(substr, 2, 0, 0, substrFunc ), |
| 87075 | FUNCTION(substr, 3, 0, 0, substrFunc ), |
| 87076 | FUNCTION(abs, 1, 0, 0, absFunc ), |
| 87077 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 87078 | FUNCTION(round, 1, 0, 0, roundFunc ), |
| @@ -107298,19 +107360,32 @@ | |
| 107298 | || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex ); |
| 107299 | |
| 107300 | if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ |
| 107301 | notIndexed |= m; |
| 107302 | } |
| 107303 | |
| 107304 | /* Conditions under which this table becomes the best so far: |
| 107305 | ** |
| 107306 | ** (1) The table must not depend on other tables that have not |
| 107307 | ** yet run. (In other words, it must not depend on tables |
| 107308 | ** in inner loops.) |
| 107309 | ** |
| 107310 | ** (2) A full-table-scan plan cannot supercede indexed plan unless |
| 107311 | ** the full-table-scan is an "optimal" plan as defined above. |
| 107312 | ** |
| 107313 | ** (3) All tables have an INDEXED BY clause or this table lacks an |
| 107314 | ** INDEXED BY clause or this table uses the specific |
| 107315 | ** index specified by its INDEXED BY clause. This rule ensures |
| 107316 | ** that a best-so-far is always selected even if an impossible |
| @@ -107321,13 +107396,10 @@ | |
| 107321 | ** |
| 107322 | ** (4) The plan cost must be lower than prior plans, where "cost" |
| 107323 | ** is defined by the compareCost() function above. |
| 107324 | */ |
| 107325 | if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */ |
| 107326 | && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ |
| 107327 | || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 |
| 107328 | || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) |
| 107329 | && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */ |
| 107330 | || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) |
| 107331 | && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan)) /* (4) */ |
| 107332 | ){ |
| 107333 | WHERETRACE((" === table %d (%s) is best so far\n" |
| 107334 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -673,11 +673,11 @@ | |
| 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | */ |
| 676 | #define SQLITE_VERSION "3.7.15" |
| 677 | #define SQLITE_VERSION_NUMBER 3007015 |
| 678 | #define SQLITE_SOURCE_ID "2012-11-09 21:40:02 5a3b07f0f5dfae7eea870303f52f37d6a17f1da2" |
| 679 | |
| 680 | /* |
| 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | ** |
| @@ -1038,10 +1038,11 @@ | |
| 1038 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) |
| 1039 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 1040 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 1041 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1042 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1043 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1044 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1045 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1046 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1047 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1048 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| @@ -11008,10 +11009,11 @@ | |
| 11009 | int addrInTop; /* Top of the IN loop */ |
| 11010 | } *aInLoop; /* Information about each nested IN operator */ |
| 11011 | } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */ |
| 11012 | Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ |
| 11013 | } u; |
| 11014 | double rOptCost; /* "Optimal" cost for this level */ |
| 11015 | |
| 11016 | /* The following field is really not part of the current level. But |
| 11017 | ** we need a place to cache virtual table index information for each |
| 11018 | ** virtual table in the FROM clause and the WhereLevel structure is |
| 11019 | ** a convenient place since there is one WhereLevel for each FROM clause |
| @@ -13716,10 +13718,11 @@ | |
| 13718 | int nByte = 0; /* Used to accumulate return value */ |
| 13719 | |
| 13720 | db->pnBytesFreed = &nByte; |
| 13721 | for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ |
| 13722 | sqlite3VdbeClearObject(db, pVdbe); |
| 13723 | sqlite3DbFree(db, pVdbe); |
| 13724 | } |
| 13725 | db->pnBytesFreed = 0; |
| 13726 | |
| 13727 | *pHighwater = 0; |
| 13728 | *pCurrent = nByte; |
| @@ -28219,12 +28222,17 @@ | |
| 28222 | int dirSync /* If true, fsync() directory after deleting file */ |
| 28223 | ){ |
| 28224 | int rc = SQLITE_OK; |
| 28225 | UNUSED_PARAMETER(NotUsed); |
| 28226 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 28227 | if( osUnlink(zPath)==(-1) ){ |
| 28228 | if( errno==ENOENT ){ |
| 28229 | rc = SQLITE_IOERR_DELETE_NOENT; |
| 28230 | }else{ |
| 28231 | rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); |
| 28232 | } |
| 28233 | return rc; |
| 28234 | } |
| 28235 | #ifndef SQLITE_DISABLE_DIRSYNC |
| 28236 | if( (dirSync & 1)!=0 ){ |
| 28237 | int fd; |
| 28238 | rc = osOpenDirectory(zPath, &fd); |
| @@ -40388,10 +40396,11 @@ | |
| 40396 | |
| 40397 | rc = pagerPagecount(pPager, &nPage); |
| 40398 | if( rc ) return rc; |
| 40399 | if( nPage==0 ){ |
| 40400 | rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); |
| 40401 | if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK; |
| 40402 | isWal = 0; |
| 40403 | }else{ |
| 40404 | rc = sqlite3OsAccess( |
| 40405 | pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal |
| 40406 | ); |
| @@ -77655,12 +77664,14 @@ | |
| 77664 | */ |
| 77665 | assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 77666 | ExprSetIrreducible(pExpr); |
| 77667 | pExpr->iAgg = (i16)i; |
| 77668 | pExpr->pAggInfo = pAggInfo; |
| 77669 | return WRC_Prune; |
| 77670 | }else{ |
| 77671 | return WRC_Continue; |
| 77672 | } |
| 77673 | } |
| 77674 | } |
| 77675 | return WRC_Continue; |
| 77676 | } |
| 77677 | static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ |
| @@ -77668,13 +77679,14 @@ | |
| 77679 | UNUSED_PARAMETER(pSelect); |
| 77680 | return WRC_Continue; |
| 77681 | } |
| 77682 | |
| 77683 | /* |
| 77684 | ** Analyze the pExpr expression looking for aggregate functions and |
| 77685 | ** for variables that need to be added to AggInfo object that pNC->pAggInfo |
| 77686 | ** points to. Additional entries are made on the AggInfo object as |
| 77687 | ** necessary. |
| 77688 | ** |
| 77689 | ** This routine should only be called after the expression has been |
| 77690 | ** analyzed by sqlite3ResolveExprNames(). |
| 77691 | */ |
| 77692 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ |
| @@ -85700,10 +85712,59 @@ | |
| 85712 | sqlite3_result_double(context, rVal); |
| 85713 | break; |
| 85714 | } |
| 85715 | } |
| 85716 | } |
| 85717 | |
| 85718 | /* |
| 85719 | ** Implementation of the instr() function. |
| 85720 | ** |
| 85721 | ** instr(haystack,needle) finds the first occurrence of needle |
| 85722 | ** in haystack and returns the number of previous characters plus 1, |
| 85723 | ** or 0 if needle does not occur within haystack. |
| 85724 | ** |
| 85725 | ** If both haystack and needle are BLOBs, then the result is one more than |
| 85726 | ** the number of bytes in haystack prior to the first occurrence of needle, |
| 85727 | ** or 0 if needle never occurs in haystack. |
| 85728 | */ |
| 85729 | static void instrFunc( |
| 85730 | sqlite3_context *context, |
| 85731 | int argc, |
| 85732 | sqlite3_value **argv |
| 85733 | ){ |
| 85734 | const unsigned char *zHaystack; |
| 85735 | const unsigned char *zNeedle; |
| 85736 | int nHaystack; |
| 85737 | int nNeedle; |
| 85738 | int typeHaystack, typeNeedle; |
| 85739 | int N = 1; |
| 85740 | int isText; |
| 85741 | |
| 85742 | typeHaystack = sqlite3_value_type(argv[0]); |
| 85743 | typeNeedle = sqlite3_value_type(argv[1]); |
| 85744 | if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; |
| 85745 | nHaystack = sqlite3_value_bytes(argv[0]); |
| 85746 | nNeedle = sqlite3_value_bytes(argv[1]); |
| 85747 | if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ |
| 85748 | zHaystack = sqlite3_value_blob(argv[0]); |
| 85749 | zNeedle = sqlite3_value_blob(argv[1]); |
| 85750 | isText = 0; |
| 85751 | }else{ |
| 85752 | zHaystack = sqlite3_value_text(argv[0]); |
| 85753 | zNeedle = sqlite3_value_text(argv[1]); |
| 85754 | isText = 1; |
| 85755 | } |
| 85756 | while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ |
| 85757 | N++; |
| 85758 | do{ |
| 85759 | nHaystack--; |
| 85760 | zHaystack++; |
| 85761 | }while( isText && (zHaystack[0]&0xc0)==0x80 ); |
| 85762 | } |
| 85763 | if( nNeedle>nHaystack ) N = 0; |
| 85764 | sqlite3_result_int(context, N); |
| 85765 | } |
| 85766 | |
| 85767 | /* |
| 85768 | ** Implementation of the substr() function. |
| 85769 | ** |
| 85770 | ** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. |
| @@ -87069,10 +87130,11 @@ | |
| 87130 | FUNCTION(max, -1, 1, 1, minmaxFunc ), |
| 87131 | FUNCTION(max, 0, 1, 1, 0 ), |
| 87132 | AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), |
| 87133 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), |
| 87134 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), |
| 87135 | FUNCTION(instr, 2, 0, 0, instrFunc ), |
| 87136 | FUNCTION(substr, 2, 0, 0, substrFunc ), |
| 87137 | FUNCTION(substr, 3, 0, 0, substrFunc ), |
| 87138 | FUNCTION(abs, 1, 0, 0, absFunc ), |
| 87139 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 87140 | FUNCTION(round, 1, 0, 0, roundFunc ), |
| @@ -107298,19 +107360,32 @@ | |
| 107360 | || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex ); |
| 107361 | |
| 107362 | if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ |
| 107363 | notIndexed |= m; |
| 107364 | } |
| 107365 | if( isOptimal ){ |
| 107366 | pWInfo->a[j].rOptCost = sWBI.cost.rCost; |
| 107367 | }else if( iFrom<nTabList-1 ){ |
| 107368 | /* If two or more tables have nearly the same outer loop cost, |
| 107369 | ** very different inner loop (optimal) cost, we want to choose |
| 107370 | ** for the outer loop that table which benefits the least from |
| 107371 | ** being in the inner loop. The following code scales the |
| 107372 | ** outer loop cost estimate to accomplish that. */ |
| 107373 | WHERETRACE((" scaling cost from %.1f to %.1f\n", |
| 107374 | sWBI.cost.rCost, |
| 107375 | sWBI.cost.rCost/pWInfo->a[j].rOptCost)); |
| 107376 | sWBI.cost.rCost /= pWInfo->a[j].rOptCost; |
| 107377 | } |
| 107378 | |
| 107379 | /* Conditions under which this table becomes the best so far: |
| 107380 | ** |
| 107381 | ** (1) The table must not depend on other tables that have not |
| 107382 | ** yet run. (In other words, it must not depend on tables |
| 107383 | ** in inner loops.) |
| 107384 | ** |
| 107385 | ** (2) (This rule was removed on 2012-11-09. The scaling of the |
| 107386 | ** cost using the optimal scan cost made this rule obsolete.) |
| 107387 | ** |
| 107388 | ** (3) All tables have an INDEXED BY clause or this table lacks an |
| 107389 | ** INDEXED BY clause or this table uses the specific |
| 107390 | ** index specified by its INDEXED BY clause. This rule ensures |
| 107391 | ** that a best-so-far is always selected even if an impossible |
| @@ -107321,13 +107396,10 @@ | |
| 107396 | ** |
| 107397 | ** (4) The plan cost must be lower than prior plans, where "cost" |
| 107398 | ** is defined by the compareCost() function above. |
| 107399 | */ |
| 107400 | if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */ |
| 107401 | && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */ |
| 107402 | || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) |
| 107403 | && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan)) /* (4) */ |
| 107404 | ){ |
| 107405 | WHERETRACE((" === table %d (%s) is best so far\n" |
| 107406 |
+2
-1
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.7.15" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007015 |
| 112 | -#define SQLITE_SOURCE_ID "2012-10-30 18:09:46 9dca18f5fea84afbecb314ee1cdfb98430656af3" | |
| 112 | +#define SQLITE_SOURCE_ID "2012-11-09 21:40:02 5a3b07f0f5dfae7eea870303f52f37d6a17f1da2" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -472,10 +472,11 @@ | ||
| 472 | 472 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) |
| 473 | 473 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 474 | 474 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 475 | 475 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 476 | 476 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 477 | +#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) | |
| 477 | 478 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 478 | 479 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 479 | 480 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 480 | 481 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 481 | 482 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 482 | 483 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.15" |
| 111 | #define SQLITE_VERSION_NUMBER 3007015 |
| 112 | #define SQLITE_SOURCE_ID "2012-10-30 18:09:46 9dca18f5fea84afbecb314ee1cdfb98430656af3" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -472,10 +472,11 @@ | |
| 472 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) |
| 473 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 474 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 475 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 476 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 477 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 478 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 479 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 480 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 481 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 482 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.15" |
| 111 | #define SQLITE_VERSION_NUMBER 3007015 |
| 112 | #define SQLITE_SOURCE_ID "2012-11-09 21:40:02 5a3b07f0f5dfae7eea870303f52f37d6a17f1da2" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -472,10 +472,11 @@ | |
| 472 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) |
| 473 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 474 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 475 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 476 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 477 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 478 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 479 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 480 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 481 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 482 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 483 |
+7
-3
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -90,11 +90,13 @@ | ||
| 90 | 90 | va_list ap; |
| 91 | 91 | va_start(ap, zFormat); |
| 92 | 92 | zUrl = vmprintf(zFormat, ap); |
| 93 | 93 | va_end(ap); |
| 94 | 94 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 95 | - return mprintf("<a %s href=\"%z\">", zExtra, zUrl); | |
| 95 | + char *zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl); | |
| 96 | + fossil_free(zUrl); | |
| 97 | + return zHUrl; | |
| 96 | 98 | } |
| 97 | 99 | if( nHref>=nHrefAlloc ){ |
| 98 | 100 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 99 | 101 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 100 | 102 | } |
| @@ -106,11 +108,13 @@ | ||
| 106 | 108 | va_list ap; |
| 107 | 109 | va_start(ap, zFormat); |
| 108 | 110 | zUrl = vmprintf(zFormat, ap); |
| 109 | 111 | va_end(ap); |
| 110 | 112 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 111 | - return mprintf("<a href=\"%z\">", zUrl); | |
| 113 | + char *zHUrl = mprintf("<a href=\"%h\">", zUrl); | |
| 114 | + fossil_free(zUrl); | |
| 115 | + return zHUrl; | |
| 112 | 116 | } |
| 113 | 117 | if( nHref>=nHrefAlloc ){ |
| 114 | 118 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 115 | 119 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 116 | 120 | } |
| @@ -278,11 +282,11 @@ | ||
| 278 | 282 | for(i=0; i<nSubmenu; i++){ |
| 279 | 283 | struct Submenu *p = &aSubmenu[i]; |
| 280 | 284 | if( p->zLink==0 ){ |
| 281 | 285 | @ <span class="label">%h(p->zLabel)</span> |
| 282 | 286 | }else{ |
| 283 | - @ <a class="label" href="%s(p->zLink)">%h(p->zLabel)</a> | |
| 287 | + @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a> | |
| 284 | 288 | } |
| 285 | 289 | } |
| 286 | 290 | @ </div> |
| 287 | 291 | } |
| 288 | 292 | style_ad_unit(); |
| 289 | 293 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -90,11 +90,13 @@ | |
| 90 | va_list ap; |
| 91 | va_start(ap, zFormat); |
| 92 | zUrl = vmprintf(zFormat, ap); |
| 93 | va_end(ap); |
| 94 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 95 | return mprintf("<a %s href=\"%z\">", zExtra, zUrl); |
| 96 | } |
| 97 | if( nHref>=nHrefAlloc ){ |
| 98 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 99 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 100 | } |
| @@ -106,11 +108,13 @@ | |
| 106 | va_list ap; |
| 107 | va_start(ap, zFormat); |
| 108 | zUrl = vmprintf(zFormat, ap); |
| 109 | va_end(ap); |
| 110 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 111 | return mprintf("<a href=\"%z\">", zUrl); |
| 112 | } |
| 113 | if( nHref>=nHrefAlloc ){ |
| 114 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 115 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 116 | } |
| @@ -278,11 +282,11 @@ | |
| 278 | for(i=0; i<nSubmenu; i++){ |
| 279 | struct Submenu *p = &aSubmenu[i]; |
| 280 | if( p->zLink==0 ){ |
| 281 | @ <span class="label">%h(p->zLabel)</span> |
| 282 | }else{ |
| 283 | @ <a class="label" href="%s(p->zLink)">%h(p->zLabel)</a> |
| 284 | } |
| 285 | } |
| 286 | @ </div> |
| 287 | } |
| 288 | style_ad_unit(); |
| 289 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -90,11 +90,13 @@ | |
| 90 | va_list ap; |
| 91 | va_start(ap, zFormat); |
| 92 | zUrl = vmprintf(zFormat, ap); |
| 93 | va_end(ap); |
| 94 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 95 | char *zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl); |
| 96 | fossil_free(zUrl); |
| 97 | return zHUrl; |
| 98 | } |
| 99 | if( nHref>=nHrefAlloc ){ |
| 100 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 101 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 102 | } |
| @@ -106,11 +108,13 @@ | |
| 108 | va_list ap; |
| 109 | va_start(ap, zFormat); |
| 110 | zUrl = vmprintf(zFormat, ap); |
| 111 | va_end(ap); |
| 112 | if( g.perm.Hyperlink && !g.javascriptHyperlink ){ |
| 113 | char *zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| 114 | fossil_free(zUrl); |
| 115 | return zHUrl; |
| 116 | } |
| 117 | if( nHref>=nHrefAlloc ){ |
| 118 | nHrefAlloc = nHrefAlloc*2 + 10; |
| 119 | aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0])); |
| 120 | } |
| @@ -278,11 +282,11 @@ | |
| 282 | for(i=0; i<nSubmenu; i++){ |
| 283 | struct Submenu *p = &aSubmenu[i]; |
| 284 | if( p->zLink==0 ){ |
| 285 | @ <span class="label">%h(p->zLabel)</span> |
| 286 | }else{ |
| 287 | @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a> |
| 288 | } |
| 289 | } |
| 290 | @ </div> |
| 291 | } |
| 292 | style_ad_unit(); |
| 293 |
+5
-5
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -276,11 +276,11 @@ | ||
| 276 | 276 | prevWasDivider = 0; |
| 277 | 277 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 278 | 278 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 279 | 279 | @ <tr><td> |
| 280 | 280 | @ <div class="divider">%s(zPrevDate)</div> |
| 281 | - @ </td></tr> | |
| 281 | + @ </td><td></td><td></td></tr> | |
| 282 | 282 | } |
| 283 | 283 | memcpy(zTime, &zDate[11], 5); |
| 284 | 284 | zTime[5] = 0; |
| 285 | 285 | @ <tr> |
| 286 | 286 | @ <td class="timelineTime">%s(zTime)</td> |
| @@ -373,11 +373,11 @@ | ||
| 373 | 373 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | 374 | ** with a hyperlink to another timeline for that user. |
| 375 | 375 | */ |
| 376 | 376 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | 377 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 378 | - char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); | |
| 378 | + char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); | |
| 379 | 379 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 380 | 380 | }else{ |
| 381 | 381 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 382 | 382 | } |
| 383 | 383 | |
| @@ -398,11 +398,11 @@ | ||
| 398 | 398 | while( z && z[0] ){ |
| 399 | 399 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 400 | 400 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 401 | 401 | blob_appendf(&links, |
| 402 | 402 | "%z%#h</a>%.2s", |
| 403 | - href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] | |
| 403 | + href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] | |
| 404 | 404 | ); |
| 405 | 405 | }else{ |
| 406 | 406 | blob_appendf(&links, "%#h", i+2, z); |
| 407 | 407 | } |
| 408 | 408 | if( z[i]==0 ) break; |
| @@ -494,11 +494,11 @@ | ||
| 494 | 494 | /* style is not moved to css, because this is |
| 495 | 495 | ** a technical div for the timeline graph |
| 496 | 496 | */ |
| 497 | 497 | @ <tr><td></td><td> |
| 498 | 498 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 499 | - @ </td></tr> | |
| 499 | + @ </td><td></td></tr> | |
| 500 | 500 | } |
| 501 | 501 | } |
| 502 | 502 | @ </table> |
| 503 | 503 | if( fchngQueryInit ) db_finalize(&fchngQuery); |
| 504 | 504 | timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0); |
| @@ -1662,10 +1662,10 @@ | ||
| 1662 | 1662 | " AND blob.rid=c.cid" |
| 1663 | 1663 | ); |
| 1664 | 1664 | while( db_step(&q)==SQLITE_ROW ){ |
| 1665 | 1665 | const char *zUuid = db_column_text(&q, 0); |
| 1666 | 1666 | @ <li> |
| 1667 | - @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)">%S(zUuid)</a> | |
| 1667 | + @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)">%S(zUuid)</a> | |
| 1668 | 1668 | } |
| 1669 | 1669 | db_finalize(&q); |
| 1670 | 1670 | style_footer(); |
| 1671 | 1671 | } |
| 1672 | 1672 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -276,11 +276,11 @@ | |
| 276 | prevWasDivider = 0; |
| 277 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 278 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 279 | @ <tr><td> |
| 280 | @ <div class="divider">%s(zPrevDate)</div> |
| 281 | @ </td></tr> |
| 282 | } |
| 283 | memcpy(zTime, &zDate[11], 5); |
| 284 | zTime[5] = 0; |
| 285 | @ <tr> |
| 286 | @ <td class="timelineTime">%s(zTime)</td> |
| @@ -373,11 +373,11 @@ | |
| 373 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | ** with a hyperlink to another timeline for that user. |
| 375 | */ |
| 376 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 378 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); |
| 379 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 380 | }else{ |
| 381 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 382 | } |
| 383 | |
| @@ -398,11 +398,11 @@ | |
| 398 | while( z && z[0] ){ |
| 399 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 400 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 401 | blob_appendf(&links, |
| 402 | "%z%#h</a>%.2s", |
| 403 | href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] |
| 404 | ); |
| 405 | }else{ |
| 406 | blob_appendf(&links, "%#h", i+2, z); |
| 407 | } |
| 408 | if( z[i]==0 ) break; |
| @@ -494,11 +494,11 @@ | |
| 494 | /* style is not moved to css, because this is |
| 495 | ** a technical div for the timeline graph |
| 496 | */ |
| 497 | @ <tr><td></td><td> |
| 498 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 499 | @ </td></tr> |
| 500 | } |
| 501 | } |
| 502 | @ </table> |
| 503 | if( fchngQueryInit ) db_finalize(&fchngQuery); |
| 504 | timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0); |
| @@ -1662,10 +1662,10 @@ | |
| 1662 | " AND blob.rid=c.cid" |
| 1663 | ); |
| 1664 | while( db_step(&q)==SQLITE_ROW ){ |
| 1665 | const char *zUuid = db_column_text(&q, 0); |
| 1666 | @ <li> |
| 1667 | @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)">%S(zUuid)</a> |
| 1668 | } |
| 1669 | db_finalize(&q); |
| 1670 | style_footer(); |
| 1671 | } |
| 1672 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -276,11 +276,11 @@ | |
| 276 | prevWasDivider = 0; |
| 277 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 278 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 279 | @ <tr><td> |
| 280 | @ <div class="divider">%s(zPrevDate)</div> |
| 281 | @ </td><td></td><td></td></tr> |
| 282 | } |
| 283 | memcpy(zTime, &zDate[11], 5); |
| 284 | zTime[5] = 0; |
| 285 | @ <tr> |
| 286 | @ <td class="timelineTime">%s(zTime)</td> |
| @@ -373,11 +373,11 @@ | |
| 373 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | ** with a hyperlink to another timeline for that user. |
| 375 | */ |
| 376 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 378 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); |
| 379 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 380 | }else{ |
| 381 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 382 | } |
| 383 | |
| @@ -398,11 +398,11 @@ | |
| 398 | while( z && z[0] ){ |
| 399 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 400 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 401 | blob_appendf(&links, |
| 402 | "%z%#h</a>%.2s", |
| 403 | href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] |
| 404 | ); |
| 405 | }else{ |
| 406 | blob_appendf(&links, "%#h", i+2, z); |
| 407 | } |
| 408 | if( z[i]==0 ) break; |
| @@ -494,11 +494,11 @@ | |
| 494 | /* style is not moved to css, because this is |
| 495 | ** a technical div for the timeline graph |
| 496 | */ |
| 497 | @ <tr><td></td><td> |
| 498 | @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> |
| 499 | @ </td><td></td></tr> |
| 500 | } |
| 501 | } |
| 502 | @ </table> |
| 503 | if( fchngQueryInit ) db_finalize(&fchngQuery); |
| 504 | timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0); |
| @@ -1662,10 +1662,10 @@ | |
| 1662 | " AND blob.rid=c.cid" |
| 1663 | ); |
| 1664 | while( db_step(&q)==SQLITE_ROW ){ |
| 1665 | const char *zUuid = db_column_text(&q, 0); |
| 1666 | @ <li> |
| 1667 | @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)">%S(zUuid)</a> |
| 1668 | } |
| 1669 | db_finalize(&q); |
| 1670 | style_footer(); |
| 1671 | } |
| 1672 |
+1
-1
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -352,11 +352,11 @@ | ||
| 352 | 352 | z = zValue2; |
| 353 | 353 | if( z==0 ) continue; |
| 354 | 354 | } |
| 355 | 355 | blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); |
| 356 | 356 | if( z && z[0] ) blob_appendf(&p->url, "=%T", z); |
| 357 | - zSep = "&"; | |
| 357 | + zSep = "&"; | |
| 358 | 358 | } |
| 359 | 359 | if( zName1 && zValue1 ){ |
| 360 | 360 | blob_appendf(&p->url, "%s%s", zSep, zName1); |
| 361 | 361 | if( zValue1[0] ) blob_appendf(&p->url, "=%T", zValue1); |
| 362 | 362 | } |
| 363 | 363 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -352,11 +352,11 @@ | |
| 352 | z = zValue2; |
| 353 | if( z==0 ) continue; |
| 354 | } |
| 355 | blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); |
| 356 | if( z && z[0] ) blob_appendf(&p->url, "=%T", z); |
| 357 | zSep = "&"; |
| 358 | } |
| 359 | if( zName1 && zValue1 ){ |
| 360 | blob_appendf(&p->url, "%s%s", zSep, zName1); |
| 361 | if( zValue1[0] ) blob_appendf(&p->url, "=%T", zValue1); |
| 362 | } |
| 363 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -352,11 +352,11 @@ | |
| 352 | z = zValue2; |
| 353 | if( z==0 ) continue; |
| 354 | } |
| 355 | blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); |
| 356 | if( z && z[0] ) blob_appendf(&p->url, "=%T", z); |
| 357 | zSep = "&"; |
| 358 | } |
| 359 | if( zName1 && zValue1 ){ |
| 360 | blob_appendf(&p->url, "%s%s", zSep, zName1); |
| 361 | if( zValue1[0] ) blob_appendf(&p->url, "=%T", zValue1); |
| 362 | } |
| 363 |
+2
-2
| --- src/wysiwyg.c | ||
| +++ src/wysiwyg.c | ||
| @@ -173,17 +173,17 @@ | ||
| 173 | 173 | @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////// |
| 174 | 174 | @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk |
| 175 | 175 | @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT |
| 176 | 176 | @ q/b7/i8fp8PAQA7" /> |
| 177 | 177 | |
| 178 | - @ <img class="intLink" title="Add indentation" | |
| 178 | + @ <img class="intLink" title="Delete indentation" | |
| 179 | 179 | @ onclick="formatDoc('outdent');" |
| 180 | 180 | @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P |
| 181 | 181 | @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz |
| 182 | 182 | @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" /> |
| 183 | 183 | |
| 184 | - @ <img class="intLink" title="Delete indentation" | |
| 184 | + @ <img class="intLink" title="Add indentation" | |
| 185 | 185 | @ onclick="formatDoc('indent');" |
| 186 | 186 | @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N |
| 187 | 187 | @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650 |
| 188 | 188 | @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw=="> |
| 189 | 189 | |
| 190 | 190 | |
| 191 | 191 | ADDED test/many-www.tcl |
| 192 | 192 | ADDED test/valgrind-www.tcl |
| --- src/wysiwyg.c | |
| +++ src/wysiwyg.c | |
| @@ -173,17 +173,17 @@ | |
| 173 | @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////// |
| 174 | @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk |
| 175 | @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT |
| 176 | @ q/b7/i8fp8PAQA7" /> |
| 177 | |
| 178 | @ <img class="intLink" title="Add indentation" |
| 179 | @ onclick="formatDoc('outdent');" |
| 180 | @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P |
| 181 | @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz |
| 182 | @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" /> |
| 183 | |
| 184 | @ <img class="intLink" title="Delete indentation" |
| 185 | @ onclick="formatDoc('indent');" |
| 186 | @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N |
| 187 | @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650 |
| 188 | @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw=="> |
| 189 | |
| 190 | |
| 191 | DDED test/many-www.tcl |
| 192 | DDED test/valgrind-www.tcl |
| --- src/wysiwyg.c | |
| +++ src/wysiwyg.c | |
| @@ -173,17 +173,17 @@ | |
| 173 | @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////// |
| 174 | @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk |
| 175 | @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT |
| 176 | @ q/b7/i8fp8PAQA7" /> |
| 177 | |
| 178 | @ <img class="intLink" title="Delete indentation" |
| 179 | @ onclick="formatDoc('outdent');" |
| 180 | @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P |
| 181 | @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz |
| 182 | @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" /> |
| 183 | |
| 184 | @ <img class="intLink" title="Add indentation" |
| 185 | @ onclick="formatDoc('indent');" |
| 186 | @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N |
| 187 | @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650 |
| 188 | @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw=="> |
| 189 | |
| 190 | |
| 191 | DDED test/many-www.tcl |
| 192 | DDED test/valgrind-www.tcl |
+78
| --- a/test/many-www.tcl | ||
| +++ b/test/many-www.tcl | ||
| @@ -0,0 +1,78 @@ | ||
| 1 | +#!/usr/bin/tclsh | |
| 2 | +# | |
| 3 | +# Run this script from within any open Fossil checkout. Example: | |
| 4 | +# | |
| 5 | +# tclsh many-www.tcl | tee out.txt | |
| 6 | +# | |
| 7 | +# About 10,000 different web page requests will be made. Each is timed | |
| 8 | +# and the time shown on output. Use this script to search for segfault problems | |
| 9 | +# or to look for pages that need optimization. | |
| 10 | +# | |
| 11 | +proc run_query {url} { | |
| 12 | + set fd [open q.txt w] | |
| 13 | + puts $fd "GET $url HTTP/1.0\r\n\r" | |
| 14 | + close $fd | |
| 15 | + return [exec fossil test-http <q.txt] | |
| 16 | +} | |
| 17 | +set todo {} | |
| 18 | +foreach url { | |
| 19 | + /home | |
| 20 | + /timeline | |
| 21 | + /brlist | |
| 22 | + /taglist | |
| 23 | + /reportlist | |
| 24 | + /setup | |
| 25 | + /dir | |
| 26 | + /wcontent | |
| 27 | + /attachlist | |
| 28 | + /taglist | |
| 29 | + /test_env | |
| 30 | + /stat | |
| 31 | + /rcvfromlist | |
| 32 | + /urllist | |
| 33 | + /modreq | |
| 34 | + /info/d5c4 | |
| 35 | + /test-all-help | |
| 36 | + /leaves | |
| 37 | + /timeline?a=1970-01-01 | |
| 38 | +} { | |
| 39 | + set seen($url) 1 | |
| 40 | + set pending($url) 1 | |
| 41 | +} | |
| 42 | +set round 1 | |
| 43 | +set limit 25000 | |
| 44 | +set npending [llength [array names pending]] | |
| 45 | +proc get_pending {} { | |
| 46 | + global pending npending round next | |
| 47 | + if {$npending==0} { | |
| 48 | + incr round | |
| 49 | + array set pending [array get next] | |
| 50 | + set npending [llength [array names pending]] | |
| 51 | + unset -nocomplain next | |
| 52 | + } | |
| 53 | + set res [lindex [array names pending] [expr {int(rand()*$npending)}]] | |
| 54 | + unset pending($res) | |
| 55 | + incr npending -1 | |
| 56 | + return $res | |
| 57 | +} | |
| 58 | +for {set i 0} {$i<$limit} {incr i} { | |
| 59 | + set url [get_pending] | |
| 60 | + puts -nonewline "($round/[expr {$i+1}]) $url " | |
| 61 | + flush stdout | |
| 62 | + set tm [time {set x [run_query $url]}] | |
| 63 | + set ms [lindex $tm 0] | |
| 64 | + puts [format {%.3fs} [expr {$ms/1000000.0}]] | |
| 65 | + flush stdout | |
| 66 | + if {[string length $x]>1000000} { | |
| 67 | + set x [string range $x 0 1000000] | |
| 68 | + } | |
| 69 | + set k 0 | |
| 70 | + while {[regexp {<[aA] .*?href="(/[a-z].*?)".*?>(.*)$} $x all url tail]} { | |
| 71 | + # if {$npending>2*($limit - $i)} break | |
| 72 | + incr k | |
| 73 | + if {$k>100} break | |
| 74 | + set u2 [string map {< < > > " \" & &} $url] | |
| 75 | + if {![info exists seen($u2)]} { | |
| 76 | + set next($u2) 1 | |
| 77 | + set seen($u2) 1 | |
| 78 | + |
| --- a/test/many-www.tcl | |
| +++ b/test/many-www.tcl | |
| @@ -0,0 +1,78 @@ | |
| --- a/test/many-www.tcl | |
| +++ b/test/many-www.tcl | |
| @@ -0,0 +1,78 @@ | |
| 1 | #!/usr/bin/tclsh |
| 2 | # |
| 3 | # Run this script from within any open Fossil checkout. Example: |
| 4 | # |
| 5 | # tclsh many-www.tcl | tee out.txt |
| 6 | # |
| 7 | # About 10,000 different web page requests will be made. Each is timed |
| 8 | # and the time shown on output. Use this script to search for segfault problems |
| 9 | # or to look for pages that need optimization. |
| 10 | # |
| 11 | proc run_query {url} { |
| 12 | set fd [open q.txt w] |
| 13 | puts $fd "GET $url HTTP/1.0\r\n\r" |
| 14 | close $fd |
| 15 | return [exec fossil test-http <q.txt] |
| 16 | } |
| 17 | set todo {} |
| 18 | foreach url { |
| 19 | /home |
| 20 | /timeline |
| 21 | /brlist |
| 22 | /taglist |
| 23 | /reportlist |
| 24 | /setup |
| 25 | /dir |
| 26 | /wcontent |
| 27 | /attachlist |
| 28 | /taglist |
| 29 | /test_env |
| 30 | /stat |
| 31 | /rcvfromlist |
| 32 | /urllist |
| 33 | /modreq |
| 34 | /info/d5c4 |
| 35 | /test-all-help |
| 36 | /leaves |
| 37 | /timeline?a=1970-01-01 |
| 38 | } { |
| 39 | set seen($url) 1 |
| 40 | set pending($url) 1 |
| 41 | } |
| 42 | set round 1 |
| 43 | set limit 25000 |
| 44 | set npending [llength [array names pending]] |
| 45 | proc get_pending {} { |
| 46 | global pending npending round next |
| 47 | if {$npending==0} { |
| 48 | incr round |
| 49 | array set pending [array get next] |
| 50 | set npending [llength [array names pending]] |
| 51 | unset -nocomplain next |
| 52 | } |
| 53 | set res [lindex [array names pending] [expr {int(rand()*$npending)}]] |
| 54 | unset pending($res) |
| 55 | incr npending -1 |
| 56 | return $res |
| 57 | } |
| 58 | for {set i 0} {$i<$limit} {incr i} { |
| 59 | set url [get_pending] |
| 60 | puts -nonewline "($round/[expr {$i+1}]) $url " |
| 61 | flush stdout |
| 62 | set tm [time {set x [run_query $url]}] |
| 63 | set ms [lindex $tm 0] |
| 64 | puts [format {%.3fs} [expr {$ms/1000000.0}]] |
| 65 | flush stdout |
| 66 | if {[string length $x]>1000000} { |
| 67 | set x [string range $x 0 1000000] |
| 68 | } |
| 69 | set k 0 |
| 70 | while {[regexp {<[aA] .*?href="(/[a-z].*?)".*?>(.*)$} $x all url tail]} { |
| 71 | # if {$npending>2*($limit - $i)} break |
| 72 | incr k |
| 73 | if {$k>100} break |
| 74 | set u2 [string map {< < > > " \" & &} $url] |
| 75 | if {![info exists seen($u2)]} { |
| 76 | set next($u2) 1 |
| 77 | set seen($u2) 1 |
| 78 |
+49
| --- a/test/valgrind-www.tcl | ||
| +++ b/test/valgrind-www.tcl | ||
| @@ -0,0 +1,49 @@ | ||
| 1 | +#!/usr/bin/tclsh | |
| 2 | +# | |
| 3 | +# Run this script in an open Fossil checkout at the top-level with a | |
| 4 | +# fresh build of Fossil itself. This script will run fossil on hundreds | |
| 5 | +# of different web-pages looking for memory allocation problems using y allocation problems using | |
| 6 | +# valgrind. Valgrind output appears on stderr. Suggested test scenario: | |
| 7 | +# | |
| 8 | +# make | |
| 9 | +# tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt | |
| 10 | +# | |
| 11 | +# Then examine the valgrind-out.txt file for issues. | |
| 12 | +# | |
| 13 | +proc run_query {url} { | |
| 14 | + set fd [open q.txt w] | |
| 15 | + puts $fd "GET $url HTTreturn [url HTTP/1.0\r\n\r" | |
| 16 | + c]/fossil test-http <q.txt 2>@ stderr} msg | |
| 17 | + return $msg | |
| 18 | +} | |
| 19 | +set todo {} | |
| 20 | +foreach url { | |
| 21 | + /home | |
| 22 | + /timeline | |
| 23 | + /brlist | |
| 24 | + /taglist | |
| 25 | + /reportlist | |
| 26 | + /setup | |
| 27 | + /dir | |
| 28 | + /wcontent | |
| 29 | +} { | |
| 30 | + set seen($url) 1 | |
| 31 | + set pending($url) 1 | |
| 32 | +} | |
| 33 | +set limit 1000 | |
| 34 | +set npending [llength [array names pending]] | |
| 35 | +proc get_pending {} { | |
| 36 | + global pending npending | |
| 37 | + set res [lindex [array names pending] [expr {int(rand()*$npending)}]] | |
| 38 | + unset pending($res) | |
| 39 | + incr npending -1 | |
| 40 | + return $res | |
| 41 | +} | |
| 42 | +for {set i 0} {$npending>0 && $i<$limit} {incr i} { | |
| 43 | + set url [get_pending] | |
| 44 | + puts "====== ([expr {$i+1}]) $url ======" | |
| 45 | + set x [run_query $url] | |
| 46 | + while {[regexp {<[aA] .*?href="(/[a-z].*?)".*?>(.*)$} $x all url tail]} { | |
| 47 | + set u2 [string map {< < > > " \" & &} $url] | |
| 48 | + if {![info exists seen($u2)]} { | |
| 49 | + set pend |
| --- a/test/valgrind-www.tcl | |
| +++ b/test/valgrind-www.tcl | |
| @@ -0,0 +1,49 @@ | |
| --- a/test/valgrind-www.tcl | |
| +++ b/test/valgrind-www.tcl | |
| @@ -0,0 +1,49 @@ | |
| 1 | #!/usr/bin/tclsh |
| 2 | # |
| 3 | # Run this script in an open Fossil checkout at the top-level with a |
| 4 | # fresh build of Fossil itself. This script will run fossil on hundreds |
| 5 | # of different web-pages looking for memory allocation problems using y allocation problems using |
| 6 | # valgrind. Valgrind output appears on stderr. Suggested test scenario: |
| 7 | # |
| 8 | # make |
| 9 | # tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt |
| 10 | # |
| 11 | # Then examine the valgrind-out.txt file for issues. |
| 12 | # |
| 13 | proc run_query {url} { |
| 14 | set fd [open q.txt w] |
| 15 | puts $fd "GET $url HTTreturn [url HTTP/1.0\r\n\r" |
| 16 | c]/fossil test-http <q.txt 2>@ stderr} msg |
| 17 | return $msg |
| 18 | } |
| 19 | set todo {} |
| 20 | foreach url { |
| 21 | /home |
| 22 | /timeline |
| 23 | /brlist |
| 24 | /taglist |
| 25 | /reportlist |
| 26 | /setup |
| 27 | /dir |
| 28 | /wcontent |
| 29 | } { |
| 30 | set seen($url) 1 |
| 31 | set pending($url) 1 |
| 32 | } |
| 33 | set limit 1000 |
| 34 | set npending [llength [array names pending]] |
| 35 | proc get_pending {} { |
| 36 | global pending npending |
| 37 | set res [lindex [array names pending] [expr {int(rand()*$npending)}]] |
| 38 | unset pending($res) |
| 39 | incr npending -1 |
| 40 | return $res |
| 41 | } |
| 42 | for {set i 0} {$npending>0 && $i<$limit} {incr i} { |
| 43 | set url [get_pending] |
| 44 | puts "====== ([expr {$i+1}]) $url ======" |
| 45 | set x [run_query $url] |
| 46 | while {[regexp {<[aA] .*?href="(/[a-z].*?)".*?>(.*)$} $x all url tail]} { |
| 47 | set u2 [string map {< < > > " \" & &} $url] |
| 48 | if {![info exists seen($u2)]} { |
| 49 | set pend |