Fossil SCM
Merge trunk (docker experiment continuing, but not yet in working state!)
Commit
96d1add988b3be64468c5b63a1a342aff7d226bd
Parent
3934d49a552138b…
85 files changed
+1
+19
-8
+8
-8
+36
-1
+2
-2
+2
-2
+1
+9
-9
+4
-3
+20
-17
+1
-1
+14
+2
-2
+36
-28
+2
-2
+32
-33
+32
-33
+10
-10
+10
-10
+12
-398
+69
-71
+27
-27
+2
-4
+2
-2
+12
-12
+2
-2
+6
-8
+7
-7
+2
-2
+6
-7
+1
-1
+1
-1
+2
-2
+9
-11
+9
-9
+5
-6
+3
-2
+14
-17
+14
-17
+9
-8
+30
-2
+140
-26
+26
-9
+4
-4
+61
+3
-3
+4
-4
+10
-10
+18
-14
+9
-8
+5
-7
+10
-10
+2
-2
+12
-4
+13
-1
+9
-9
+2
-2
+4
+315
-232
+2
-2
+7
-7
+47
-24
+7
-3
+7
-6
+116
-83
+21
-23
+7
-7
+9
-8
+5
-3
+3
-3
+2
-2
+5
-14
+4
-4
+33
-27
+16
-13
+16
-13
+6
-3
+25
-9
+42
-10
+42
-10
+53
-4
+41
-1
+2
+1
-1
~
auto.def
~
src/allrepo.c
~
src/attach.c
~
src/blob.c
~
src/branch.c
~
src/browse.c
~
src/builtin.c
~
src/cache.c
~
src/cgi.c
~
src/checkin.c
~
src/checkout.c
~
src/codecheck1.c
~
src/comformat.c
~
src/configure.c
~
src/content.c
~
src/db.c
~
src/db.c
~
src/delta.c
~
src/descendants.c
~
src/diff.tcl
~
src/diffcmd.c
~
src/doc.c
~
src/encode.c
~
src/event.c
~
src/export.c
~
src/finfo.c
~
src/http.c
~
src/info.c
~
src/json.c
~
src/json_config.c
~
src/json_finfo.c
~
src/json_query.c
~
src/json_report.c
~
src/json_tag.c
~
src/json_timeline.c
~
src/json_user.c
~
src/json_wiki.c
~
src/leaf.c
~
src/login.c
~
src/login.c
~
src/main.c
~
src/main.mk
~
src/makemake.tcl
~
src/manifest.c
~
src/merge3.c
~
src/mkbuiltin.c
~
src/moderate.c
~
src/name.c
~
src/path.c
~
src/printf.c
~
src/rebuild.c
~
src/report.c
~
src/rss.c
~
src/search.c
~
src/setup.c
~
src/shell.c
~
src/shun.c
~
src/skins.c
~
src/sqlcmd.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/stash.c
~
src/stat.c
~
src/style.c
~
src/tag.c
~
src/timeline.c
~
src/tkt.c
~
src/translate.c
~
src/undo.c
~
src/update.c
~
src/user.c
~
src/vfile.c
~
src/wiki.c
~
src/wikiformat.c
~
src/winhttp.c
~
src/xfer.c
~
src/xfer.c
~
win/Makefile.PellesCGMake
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.mingw.mistachkin
~
win/Makefile.msc
~
win/buildmsvc.bat
~
win/fossil.exe.manifest
~
www/build.wiki
M
auto.def
+1
| --- auto.def | ||
| +++ auto.def | ||
| @@ -278,10 +278,11 @@ | ||
| 278 | 278 | } |
| 279 | 279 | } |
| 280 | 280 | cc-check-function-in-lib iconv iconv |
| 281 | 281 | cc-check-functions utime |
| 282 | 282 | cc-check-functions usleep |
| 283 | +cc-check-functions strchrnul | |
| 283 | 284 | |
| 284 | 285 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 285 | 286 | if {![cc-check-functions getloadavg]} { |
| 286 | 287 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 287 | 288 | msg-result "Load average support unavailable" |
| 288 | 289 |
| --- auto.def | |
| +++ auto.def | |
| @@ -278,10 +278,11 @@ | |
| 278 | } |
| 279 | } |
| 280 | cc-check-function-in-lib iconv iconv |
| 281 | cc-check-functions utime |
| 282 | cc-check-functions usleep |
| 283 | |
| 284 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 285 | if {![cc-check-functions getloadavg]} { |
| 286 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 287 | msg-result "Load average support unavailable" |
| 288 |
| --- auto.def | |
| +++ auto.def | |
| @@ -278,10 +278,11 @@ | |
| 278 | } |
| 279 | } |
| 280 | cc-check-function-in-lib iconv iconv |
| 281 | cc-check-functions utime |
| 282 | cc-check-functions usleep |
| 283 | cc-check-functions strchrnul |
| 284 | |
| 285 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 286 | if {![cc-check-functions getloadavg]} { |
| 287 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 288 | msg-result "Load average support unavailable" |
| 289 |
+19
-8
| --- src/allrepo.c | ||
| +++ src/allrepo.c | ||
| @@ -98,10 +98,12 @@ | ||
| 98 | 98 | ** carefully review the local checkouts to be operated upon |
| 99 | 99 | ** and the --whatif option to carefully review the files to |
| 100 | 100 | ** be deleted beforehand is highly recommended. The command |
| 101 | 101 | ** line options supported by the clean command itself, if any |
| 102 | 102 | ** are present, are passed along verbatim. |
| 103 | +** | |
| 104 | +** dbstat Run the "dbstat" command on all repositories. | |
| 103 | 105 | ** |
| 104 | 106 | ** extras Shows "extra" files from all local checkouts. The command |
| 105 | 107 | ** line options supported by the extra command itself, if any |
| 106 | 108 | ** are present, are passed along verbatim. |
| 107 | 109 | ** |
| @@ -129,11 +131,11 @@ | ||
| 129 | 131 | ** sync Run a "sync" on all repositories. Only the --verbose |
| 130 | 132 | ** option is supported. |
| 131 | 133 | ** |
| 132 | 134 | ** setting Run the "setting", "set", or "unset" commands on all |
| 133 | 135 | ** set repositories. These command are particularly useful in |
| 134 | -** unset conjunection with the "max-loadavg" setting which cannot | |
| 136 | +** unset conjunction with the "max-loadavg" setting which cannot | |
| 135 | 137 | ** otherwise be set globally. |
| 136 | 138 | ** |
| 137 | 139 | ** Repositories are automatically added to the set of known repositories |
| 138 | 140 | ** when one of the following commands are run against the repository: |
| 139 | 141 | ** clone, info, pull, push, or sync. Even previously ignored repositories |
| @@ -190,10 +192,16 @@ | ||
| 190 | 192 | collect_argument_value(&extra, "keep"); |
| 191 | 193 | collect_argument(&extra, "temp",0); |
| 192 | 194 | collect_argument(&extra, "verbose","v"); |
| 193 | 195 | collect_argument(&extra, "whatif",0); |
| 194 | 196 | useCheckouts = 1; |
| 197 | + }else if( strncmp(zCmd, "dbstat", n)==0 ){ | |
| 198 | + zCmd = "dbstat --omit-version-info -R"; | |
| 199 | + showLabel = 1; | |
| 200 | + quiet = 1; | |
| 201 | + collect_argument(&extra, "brief", "b"); | |
| 202 | + collect_argument(&extra, "db-check", 0); | |
| 195 | 203 | }else if( strncmp(zCmd, "extras", n)==0 ){ |
| 196 | 204 | if( showFile ){ |
| 197 | 205 | zCmd = "extras --chdir"; |
| 198 | 206 | }else{ |
| 199 | 207 | zCmd = "extras --header --chdir"; |
| @@ -249,19 +257,22 @@ | ||
| 249 | 257 | int j; |
| 250 | 258 | useCheckouts = find_option("ckout","c",0)!=0; |
| 251 | 259 | verify_all_options(); |
| 252 | 260 | db_begin_transaction(); |
| 253 | 261 | for(j=3; j<g.argc; j++){ |
| 254 | - char *zSql = mprintf("DELETE FROM global_config" | |
| 255 | - " WHERE name GLOB '%s:%q'", | |
| 256 | - useCheckouts?"ckout":"repo", g.argv[j]); | |
| 262 | + Blob sql; | |
| 263 | + blob_zero(&sql); | |
| 264 | + blob_append_sql(&sql, | |
| 265 | + "DELETE FROM global_config WHERE name GLOB '%s:%q'", | |
| 266 | + useCheckouts?"ckout":"repo", g.argv[j] | |
| 267 | + ); | |
| 257 | 268 | if( dryRunFlag ){ |
| 258 | - fossil_print("%s\n", zSql); | |
| 269 | + fossil_print("%s\n", blob_sql_text(&sql)); | |
| 259 | 270 | }else{ |
| 260 | - db_multi_exec("%s", zSql); | |
| 271 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 261 | 272 | } |
| 262 | - fossil_free(zSql); | |
| 273 | + blob_reset(&sql); | |
| 263 | 274 | } |
| 264 | 275 | db_end_transaction(0); |
| 265 | 276 | return; |
| 266 | 277 | }else if( strncmp(zCmd, "info", n)==0 ){ |
| 267 | 278 | zCmd = "info"; |
| @@ -338,9 +349,9 @@ | ||
| 338 | 349 | if( nToDel>0 ){ |
| 339 | 350 | const char *zSql = "DELETE FROM global_config WHERE name IN toDel"; |
| 340 | 351 | if( dryRunFlag ){ |
| 341 | 352 | fossil_print("%s\n", zSql); |
| 342 | 353 | }else{ |
| 343 | - db_multi_exec(zSql); | |
| 354 | + db_multi_exec("%s", zSql /*safe-for-%s*/ ); | |
| 344 | 355 | } |
| 345 | 356 | } |
| 346 | 357 | } |
| 347 | 358 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -98,10 +98,12 @@ | |
| 98 | ** carefully review the local checkouts to be operated upon |
| 99 | ** and the --whatif option to carefully review the files to |
| 100 | ** be deleted beforehand is highly recommended. The command |
| 101 | ** line options supported by the clean command itself, if any |
| 102 | ** are present, are passed along verbatim. |
| 103 | ** |
| 104 | ** extras Shows "extra" files from all local checkouts. The command |
| 105 | ** line options supported by the extra command itself, if any |
| 106 | ** are present, are passed along verbatim. |
| 107 | ** |
| @@ -129,11 +131,11 @@ | |
| 129 | ** sync Run a "sync" on all repositories. Only the --verbose |
| 130 | ** option is supported. |
| 131 | ** |
| 132 | ** setting Run the "setting", "set", or "unset" commands on all |
| 133 | ** set repositories. These command are particularly useful in |
| 134 | ** unset conjunection with the "max-loadavg" setting which cannot |
| 135 | ** otherwise be set globally. |
| 136 | ** |
| 137 | ** Repositories are automatically added to the set of known repositories |
| 138 | ** when one of the following commands are run against the repository: |
| 139 | ** clone, info, pull, push, or sync. Even previously ignored repositories |
| @@ -190,10 +192,16 @@ | |
| 190 | collect_argument_value(&extra, "keep"); |
| 191 | collect_argument(&extra, "temp",0); |
| 192 | collect_argument(&extra, "verbose","v"); |
| 193 | collect_argument(&extra, "whatif",0); |
| 194 | useCheckouts = 1; |
| 195 | }else if( strncmp(zCmd, "extras", n)==0 ){ |
| 196 | if( showFile ){ |
| 197 | zCmd = "extras --chdir"; |
| 198 | }else{ |
| 199 | zCmd = "extras --header --chdir"; |
| @@ -249,19 +257,22 @@ | |
| 249 | int j; |
| 250 | useCheckouts = find_option("ckout","c",0)!=0; |
| 251 | verify_all_options(); |
| 252 | db_begin_transaction(); |
| 253 | for(j=3; j<g.argc; j++){ |
| 254 | char *zSql = mprintf("DELETE FROM global_config" |
| 255 | " WHERE name GLOB '%s:%q'", |
| 256 | useCheckouts?"ckout":"repo", g.argv[j]); |
| 257 | if( dryRunFlag ){ |
| 258 | fossil_print("%s\n", zSql); |
| 259 | }else{ |
| 260 | db_multi_exec("%s", zSql); |
| 261 | } |
| 262 | fossil_free(zSql); |
| 263 | } |
| 264 | db_end_transaction(0); |
| 265 | return; |
| 266 | }else if( strncmp(zCmd, "info", n)==0 ){ |
| 267 | zCmd = "info"; |
| @@ -338,9 +349,9 @@ | |
| 338 | if( nToDel>0 ){ |
| 339 | const char *zSql = "DELETE FROM global_config WHERE name IN toDel"; |
| 340 | if( dryRunFlag ){ |
| 341 | fossil_print("%s\n", zSql); |
| 342 | }else{ |
| 343 | db_multi_exec(zSql); |
| 344 | } |
| 345 | } |
| 346 | } |
| 347 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -98,10 +98,12 @@ | |
| 98 | ** carefully review the local checkouts to be operated upon |
| 99 | ** and the --whatif option to carefully review the files to |
| 100 | ** be deleted beforehand is highly recommended. The command |
| 101 | ** line options supported by the clean command itself, if any |
| 102 | ** are present, are passed along verbatim. |
| 103 | ** |
| 104 | ** dbstat Run the "dbstat" command on all repositories. |
| 105 | ** |
| 106 | ** extras Shows "extra" files from all local checkouts. The command |
| 107 | ** line options supported by the extra command itself, if any |
| 108 | ** are present, are passed along verbatim. |
| 109 | ** |
| @@ -129,11 +131,11 @@ | |
| 131 | ** sync Run a "sync" on all repositories. Only the --verbose |
| 132 | ** option is supported. |
| 133 | ** |
| 134 | ** setting Run the "setting", "set", or "unset" commands on all |
| 135 | ** set repositories. These command are particularly useful in |
| 136 | ** unset conjunction with the "max-loadavg" setting which cannot |
| 137 | ** otherwise be set globally. |
| 138 | ** |
| 139 | ** Repositories are automatically added to the set of known repositories |
| 140 | ** when one of the following commands are run against the repository: |
| 141 | ** clone, info, pull, push, or sync. Even previously ignored repositories |
| @@ -190,10 +192,16 @@ | |
| 192 | collect_argument_value(&extra, "keep"); |
| 193 | collect_argument(&extra, "temp",0); |
| 194 | collect_argument(&extra, "verbose","v"); |
| 195 | collect_argument(&extra, "whatif",0); |
| 196 | useCheckouts = 1; |
| 197 | }else if( strncmp(zCmd, "dbstat", n)==0 ){ |
| 198 | zCmd = "dbstat --omit-version-info -R"; |
| 199 | showLabel = 1; |
| 200 | quiet = 1; |
| 201 | collect_argument(&extra, "brief", "b"); |
| 202 | collect_argument(&extra, "db-check", 0); |
| 203 | }else if( strncmp(zCmd, "extras", n)==0 ){ |
| 204 | if( showFile ){ |
| 205 | zCmd = "extras --chdir"; |
| 206 | }else{ |
| 207 | zCmd = "extras --header --chdir"; |
| @@ -249,19 +257,22 @@ | |
| 257 | int j; |
| 258 | useCheckouts = find_option("ckout","c",0)!=0; |
| 259 | verify_all_options(); |
| 260 | db_begin_transaction(); |
| 261 | for(j=3; j<g.argc; j++){ |
| 262 | Blob sql; |
| 263 | blob_zero(&sql); |
| 264 | blob_append_sql(&sql, |
| 265 | "DELETE FROM global_config WHERE name GLOB '%s:%q'", |
| 266 | useCheckouts?"ckout":"repo", g.argv[j] |
| 267 | ); |
| 268 | if( dryRunFlag ){ |
| 269 | fossil_print("%s\n", blob_sql_text(&sql)); |
| 270 | }else{ |
| 271 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 272 | } |
| 273 | blob_reset(&sql); |
| 274 | } |
| 275 | db_end_transaction(0); |
| 276 | return; |
| 277 | }else if( strncmp(zCmd, "info", n)==0 ){ |
| 278 | zCmd = "info"; |
| @@ -338,9 +349,9 @@ | |
| 349 | if( nToDel>0 ){ |
| 350 | const char *zSql = "DELETE FROM global_config WHERE name IN toDel"; |
| 351 | if( dryRunFlag ){ |
| 352 | fossil_print("%s\n", zSql); |
| 353 | }else{ |
| 354 | db_multi_exec("%s", zSql /*safe-for-%s*/ ); |
| 355 | } |
| 356 | } |
| 357 | } |
| 358 |
+8
-8
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -40,31 +40,31 @@ | ||
| 40 | 40 | Stmt q; |
| 41 | 41 | |
| 42 | 42 | if( zPage && zTkt ) zTkt = 0; |
| 43 | 43 | login_check_credentials(); |
| 44 | 44 | blob_zero(&sql); |
| 45 | - blob_appendf(&sql, | |
| 45 | + blob_append_sql(&sql, | |
| 46 | 46 | "SELECT datetime(mtime%s), src, target, filename," |
| 47 | 47 | " comment, user," |
| 48 | 48 | " (SELECT uuid FROM blob WHERE rid=attachid), attachid" |
| 49 | 49 | " FROM attachment", |
| 50 | 50 | timeline_utc() |
| 51 | 51 | ); |
| 52 | 52 | if( zPage ){ |
| 53 | 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | 54 | style_header("Attachments To %h", zPage); |
| 55 | - blob_appendf(&sql, " WHERE target=%Q", zPage); | |
| 55 | + blob_append_sql(&sql, " WHERE target=%Q", zPage); | |
| 56 | 56 | }else if( zTkt ){ |
| 57 | 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | - blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt); | |
| 59 | + blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt); | |
| 60 | 60 | }else{ |
| 61 | 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | 62 | style_header("All Attachments"); |
| 63 | 63 | } |
| 64 | - blob_appendf(&sql, " ORDER BY mtime DESC"); | |
| 65 | - db_prepare(&q, "%s", blob_str(&sql)); | |
| 64 | + blob_append_sql(&sql, " ORDER BY mtime DESC"); | |
| 65 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 66 | 66 | @ <ol> |
| 67 | 67 | while( db_step(&q)==SQLITE_ROW ){ |
| 68 | 68 | const char *zDate = db_column_text(&q, 0); |
| 69 | 69 | const char *zSrc = db_column_text(&q, 1); |
| 70 | 70 | const char *zTarget = db_column_text(&q, 2); |
| @@ -377,11 +377,11 @@ | ||
| 377 | 377 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 378 | 378 | #if 0 |
| 379 | 379 | /* Shunning here needs to get both the attachment control artifact and |
| 380 | 380 | ** the object that is attached. */ |
| 381 | 381 | if( g.perm.Admin ){ |
| 382 | - if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ | |
| 382 | + if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){ | |
| 383 | 383 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 384 | 384 | g.zTop, zUuid); |
| 385 | 385 | }else{ |
| 386 | 386 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 387 | 387 | g.zTop, zUuid); |
| @@ -390,17 +390,17 @@ | ||
| 390 | 390 | #endif |
| 391 | 391 | pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0); |
| 392 | 392 | if( pAttach==0 ) fossil_redirect_home(); |
| 393 | 393 | zTarget = pAttach->zAttachTarget; |
| 394 | 394 | zSrc = pAttach->zAttachSrc; |
| 395 | - ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc); | |
| 395 | + ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc); | |
| 396 | 396 | zName = pAttach->zAttachName; |
| 397 | 397 | zDesc = pAttach->zComment; |
| 398 | 398 | zMime = mimetype_from_name(zName); |
| 399 | 399 | fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0; |
| 400 | 400 | if( validate16(zTarget, strlen(zTarget)) |
| 401 | - && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget) | |
| 401 | + && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget) | |
| 402 | 402 | ){ |
| 403 | 403 | zTktUuid = zTarget; |
| 404 | 404 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 405 | 405 | if( g.perm.WrTkt ){ |
| 406 | 406 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 407 | 407 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -40,31 +40,31 @@ | |
| 40 | Stmt q; |
| 41 | |
| 42 | if( zPage && zTkt ) zTkt = 0; |
| 43 | login_check_credentials(); |
| 44 | blob_zero(&sql); |
| 45 | blob_appendf(&sql, |
| 46 | "SELECT datetime(mtime%s), src, target, filename," |
| 47 | " comment, user," |
| 48 | " (SELECT uuid FROM blob WHERE rid=attachid), attachid" |
| 49 | " FROM attachment", |
| 50 | timeline_utc() |
| 51 | ); |
| 52 | if( zPage ){ |
| 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | style_header("Attachments To %h", zPage); |
| 55 | blob_appendf(&sql, " WHERE target=%Q", zPage); |
| 56 | }else if( zTkt ){ |
| 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | }else{ |
| 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | style_header("All Attachments"); |
| 63 | } |
| 64 | blob_appendf(&sql, " ORDER BY mtime DESC"); |
| 65 | db_prepare(&q, "%s", blob_str(&sql)); |
| 66 | @ <ol> |
| 67 | while( db_step(&q)==SQLITE_ROW ){ |
| 68 | const char *zDate = db_column_text(&q, 0); |
| 69 | const char *zSrc = db_column_text(&q, 1); |
| 70 | const char *zTarget = db_column_text(&q, 2); |
| @@ -377,11 +377,11 @@ | |
| 377 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 378 | #if 0 |
| 379 | /* Shunning here needs to get both the attachment control artifact and |
| 380 | ** the object that is attached. */ |
| 381 | if( g.perm.Admin ){ |
| 382 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 383 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 384 | g.zTop, zUuid); |
| 385 | }else{ |
| 386 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 387 | g.zTop, zUuid); |
| @@ -390,17 +390,17 @@ | |
| 390 | #endif |
| 391 | pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0); |
| 392 | if( pAttach==0 ) fossil_redirect_home(); |
| 393 | zTarget = pAttach->zAttachTarget; |
| 394 | zSrc = pAttach->zAttachSrc; |
| 395 | ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc); |
| 396 | zName = pAttach->zAttachName; |
| 397 | zDesc = pAttach->zComment; |
| 398 | zMime = mimetype_from_name(zName); |
| 399 | fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0; |
| 400 | if( validate16(zTarget, strlen(zTarget)) |
| 401 | && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget) |
| 402 | ){ |
| 403 | zTktUuid = zTarget; |
| 404 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 405 | if( g.perm.WrTkt ){ |
| 406 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 407 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -40,31 +40,31 @@ | |
| 40 | Stmt q; |
| 41 | |
| 42 | if( zPage && zTkt ) zTkt = 0; |
| 43 | login_check_credentials(); |
| 44 | blob_zero(&sql); |
| 45 | blob_append_sql(&sql, |
| 46 | "SELECT datetime(mtime%s), src, target, filename," |
| 47 | " comment, user," |
| 48 | " (SELECT uuid FROM blob WHERE rid=attachid), attachid" |
| 49 | " FROM attachment", |
| 50 | timeline_utc() |
| 51 | ); |
| 52 | if( zPage ){ |
| 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | style_header("Attachments To %h", zPage); |
| 55 | blob_append_sql(&sql, " WHERE target=%Q", zPage); |
| 56 | }else if( zTkt ){ |
| 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | }else{ |
| 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | style_header("All Attachments"); |
| 63 | } |
| 64 | blob_append_sql(&sql, " ORDER BY mtime DESC"); |
| 65 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 66 | @ <ol> |
| 67 | while( db_step(&q)==SQLITE_ROW ){ |
| 68 | const char *zDate = db_column_text(&q, 0); |
| 69 | const char *zSrc = db_column_text(&q, 1); |
| 70 | const char *zTarget = db_column_text(&q, 2); |
| @@ -377,11 +377,11 @@ | |
| 377 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 378 | #if 0 |
| 379 | /* Shunning here needs to get both the attachment control artifact and |
| 380 | ** the object that is attached. */ |
| 381 | if( g.perm.Admin ){ |
| 382 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){ |
| 383 | style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 384 | g.zTop, zUuid); |
| 385 | }else{ |
| 386 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 387 | g.zTop, zUuid); |
| @@ -390,17 +390,17 @@ | |
| 390 | #endif |
| 391 | pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0); |
| 392 | if( pAttach==0 ) fossil_redirect_home(); |
| 393 | zTarget = pAttach->zAttachTarget; |
| 394 | zSrc = pAttach->zAttachSrc; |
| 395 | ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc); |
| 396 | zName = pAttach->zAttachName; |
| 397 | zDesc = pAttach->zComment; |
| 398 | zMime = mimetype_from_name(zName); |
| 399 | fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0; |
| 400 | if( validate16(zTarget, strlen(zTarget)) |
| 401 | && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget) |
| 402 | ){ |
| 403 | zTktUuid = zTarget; |
| 404 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 405 | if( g.perm.WrTkt ){ |
| 406 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 407 |
+36
-1
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -34,14 +34,20 @@ | ||
| 34 | 34 | */ |
| 35 | 35 | struct Blob { |
| 36 | 36 | unsigned int nUsed; /* Number of bytes used in aData[] */ |
| 37 | 37 | unsigned int nAlloc; /* Number of bytes allocated for aData[] */ |
| 38 | 38 | unsigned int iCursor; /* Next character of input to parse */ |
| 39 | + unsigned int blobFlags; /* One or more BLOBFLAG_* bits */ | |
| 39 | 40 | char *aData; /* Where the information is stored */ |
| 40 | 41 | void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */ |
| 41 | 42 | }; |
| 42 | 43 | |
| 44 | +/* | |
| 45 | +** Allowed values for Blob.blobFlags | |
| 46 | +*/ | |
| 47 | +#define BLOBFLAG_NotSQL 0x0001 /* Non-SQL text */ | |
| 48 | + | |
| 43 | 49 | /* |
| 44 | 50 | ** The current size of a Blob |
| 45 | 51 | */ |
| 46 | 52 | #define blob_size(X) ((X)->nUsed) |
| 47 | 53 | |
| @@ -148,10 +154,11 @@ | ||
| 148 | 154 | free(pBlob->aData); |
| 149 | 155 | pBlob->aData = 0; |
| 150 | 156 | pBlob->nAlloc = 0; |
| 151 | 157 | pBlob->nUsed = 0; |
| 152 | 158 | pBlob->iCursor = 0; |
| 159 | + pBlob->blobFlags = 0; | |
| 153 | 160 | }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){ |
| 154 | 161 | char *pNew = fossil_realloc(pBlob->aData, newSize); |
| 155 | 162 | pBlob->aData = pNew; |
| 156 | 163 | pBlob->nAlloc = newSize; |
| 157 | 164 | if( pBlob->nUsed>pBlob->nAlloc ){ |
| @@ -162,11 +169,11 @@ | ||
| 162 | 169 | |
| 163 | 170 | /* |
| 164 | 171 | ** An initializer for Blobs |
| 165 | 172 | */ |
| 166 | 173 | #if INTERFACE |
| 167 | -#define BLOB_INITIALIZER {0,0,0,0,blobReallocMalloc} | |
| 174 | +#define BLOB_INITIALIZER {0,0,0,0,0,blobReallocMalloc} | |
| 168 | 175 | #endif |
| 169 | 176 | const Blob empty_blob = BLOB_INITIALIZER; |
| 170 | 177 | |
| 171 | 178 | /* |
| 172 | 179 | ** A reallocation function for when the initial string is in unmanaged |
| @@ -217,10 +224,11 @@ | ||
| 217 | 224 | }else{ |
| 218 | 225 | if( size<=0 ) size = strlen(zData); |
| 219 | 226 | pBlob->nUsed = pBlob->nAlloc = size; |
| 220 | 227 | pBlob->aData = (char*)zData; |
| 221 | 228 | pBlob->iCursor = 0; |
| 229 | + pBlob->blobFlags = 0; | |
| 222 | 230 | pBlob->xRealloc = blobReallocStatic; |
| 223 | 231 | } |
| 224 | 232 | } |
| 225 | 233 | |
| 226 | 234 | /* |
| @@ -248,10 +256,11 @@ | ||
| 248 | 256 | assert_blob_is_reset(pBlob); |
| 249 | 257 | pBlob->nUsed = 0; |
| 250 | 258 | pBlob->nAlloc = 1; |
| 251 | 259 | pBlob->aData = (char*)zEmpty; |
| 252 | 260 | pBlob->iCursor = 0; |
| 261 | + pBlob->blobFlags = 0; | |
| 253 | 262 | pBlob->xRealloc = blobReallocStatic; |
| 254 | 263 | } |
| 255 | 264 | |
| 256 | 265 | /* |
| 257 | 266 | ** Append text or data to the end of a blob. |
| @@ -292,10 +301,24 @@ | ||
| 292 | 301 | if( p->aData[p->nUsed]!=0 ){ |
| 293 | 302 | blob_materialize(p); |
| 294 | 303 | } |
| 295 | 304 | return p->aData; |
| 296 | 305 | } |
| 306 | + | |
| 307 | +/* | |
| 308 | +** Return a pointer to a null-terminated string for a blob that has | |
| 309 | +** been created using blob_append_sql() and not blob_appendf(). If | |
| 310 | +** text was ever added using blob_appendf() then throw an error. | |
| 311 | +*/ | |
| 312 | +char *blob_sql_text(Blob *p){ | |
| 313 | + blob_is_init(p); | |
| 314 | + if( (p->blobFlags & BLOBFLAG_NotSQL) ){ | |
| 315 | + fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text"); | |
| 316 | + } | |
| 317 | + return blob_str(p); | |
| 318 | +} | |
| 319 | + | |
| 297 | 320 | |
| 298 | 321 | /* |
| 299 | 322 | ** Return a pointer to a null-terminated string for a blob. |
| 300 | 323 | ** |
| 301 | 324 | ** WARNING: If the blob is ephemeral, it might cause a '\000' |
| @@ -671,13 +694,25 @@ | ||
| 671 | 694 | return i; |
| 672 | 695 | } |
| 673 | 696 | |
| 674 | 697 | /* |
| 675 | 698 | ** Do printf-style string rendering and append the results to a blob. |
| 699 | +** | |
| 700 | +** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags | |
| 701 | +** whereas blob_append_sql() does not. | |
| 676 | 702 | */ |
| 677 | 703 | void blob_appendf(Blob *pBlob, const char *zFormat, ...){ |
| 678 | 704 | if( pBlob ){ |
| 705 | + va_list ap; | |
| 706 | + va_start(ap, zFormat); | |
| 707 | + vxprintf(pBlob, zFormat, ap); | |
| 708 | + va_end(ap); | |
| 709 | + pBlob->blobFlags |= BLOBFLAG_NotSQL; | |
| 710 | + } | |
| 711 | +} | |
| 712 | +void blob_append_sql(Blob *pBlob, const char *zFormat, ...){ | |
| 713 | + if( pBlob ){ | |
| 679 | 714 | va_list ap; |
| 680 | 715 | va_start(ap, zFormat); |
| 681 | 716 | vxprintf(pBlob, zFormat, ap); |
| 682 | 717 | va_end(ap); |
| 683 | 718 | } |
| 684 | 719 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -34,14 +34,20 @@ | |
| 34 | */ |
| 35 | struct Blob { |
| 36 | unsigned int nUsed; /* Number of bytes used in aData[] */ |
| 37 | unsigned int nAlloc; /* Number of bytes allocated for aData[] */ |
| 38 | unsigned int iCursor; /* Next character of input to parse */ |
| 39 | char *aData; /* Where the information is stored */ |
| 40 | void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */ |
| 41 | }; |
| 42 | |
| 43 | /* |
| 44 | ** The current size of a Blob |
| 45 | */ |
| 46 | #define blob_size(X) ((X)->nUsed) |
| 47 | |
| @@ -148,10 +154,11 @@ | |
| 148 | free(pBlob->aData); |
| 149 | pBlob->aData = 0; |
| 150 | pBlob->nAlloc = 0; |
| 151 | pBlob->nUsed = 0; |
| 152 | pBlob->iCursor = 0; |
| 153 | }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){ |
| 154 | char *pNew = fossil_realloc(pBlob->aData, newSize); |
| 155 | pBlob->aData = pNew; |
| 156 | pBlob->nAlloc = newSize; |
| 157 | if( pBlob->nUsed>pBlob->nAlloc ){ |
| @@ -162,11 +169,11 @@ | |
| 162 | |
| 163 | /* |
| 164 | ** An initializer for Blobs |
| 165 | */ |
| 166 | #if INTERFACE |
| 167 | #define BLOB_INITIALIZER {0,0,0,0,blobReallocMalloc} |
| 168 | #endif |
| 169 | const Blob empty_blob = BLOB_INITIALIZER; |
| 170 | |
| 171 | /* |
| 172 | ** A reallocation function for when the initial string is in unmanaged |
| @@ -217,10 +224,11 @@ | |
| 217 | }else{ |
| 218 | if( size<=0 ) size = strlen(zData); |
| 219 | pBlob->nUsed = pBlob->nAlloc = size; |
| 220 | pBlob->aData = (char*)zData; |
| 221 | pBlob->iCursor = 0; |
| 222 | pBlob->xRealloc = blobReallocStatic; |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | /* |
| @@ -248,10 +256,11 @@ | |
| 248 | assert_blob_is_reset(pBlob); |
| 249 | pBlob->nUsed = 0; |
| 250 | pBlob->nAlloc = 1; |
| 251 | pBlob->aData = (char*)zEmpty; |
| 252 | pBlob->iCursor = 0; |
| 253 | pBlob->xRealloc = blobReallocStatic; |
| 254 | } |
| 255 | |
| 256 | /* |
| 257 | ** Append text or data to the end of a blob. |
| @@ -292,10 +301,24 @@ | |
| 292 | if( p->aData[p->nUsed]!=0 ){ |
| 293 | blob_materialize(p); |
| 294 | } |
| 295 | return p->aData; |
| 296 | } |
| 297 | |
| 298 | /* |
| 299 | ** Return a pointer to a null-terminated string for a blob. |
| 300 | ** |
| 301 | ** WARNING: If the blob is ephemeral, it might cause a '\000' |
| @@ -671,13 +694,25 @@ | |
| 671 | return i; |
| 672 | } |
| 673 | |
| 674 | /* |
| 675 | ** Do printf-style string rendering and append the results to a blob. |
| 676 | */ |
| 677 | void blob_appendf(Blob *pBlob, const char *zFormat, ...){ |
| 678 | if( pBlob ){ |
| 679 | va_list ap; |
| 680 | va_start(ap, zFormat); |
| 681 | vxprintf(pBlob, zFormat, ap); |
| 682 | va_end(ap); |
| 683 | } |
| 684 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -34,14 +34,20 @@ | |
| 34 | */ |
| 35 | struct Blob { |
| 36 | unsigned int nUsed; /* Number of bytes used in aData[] */ |
| 37 | unsigned int nAlloc; /* Number of bytes allocated for aData[] */ |
| 38 | unsigned int iCursor; /* Next character of input to parse */ |
| 39 | unsigned int blobFlags; /* One or more BLOBFLAG_* bits */ |
| 40 | char *aData; /* Where the information is stored */ |
| 41 | void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */ |
| 42 | }; |
| 43 | |
| 44 | /* |
| 45 | ** Allowed values for Blob.blobFlags |
| 46 | */ |
| 47 | #define BLOBFLAG_NotSQL 0x0001 /* Non-SQL text */ |
| 48 | |
| 49 | /* |
| 50 | ** The current size of a Blob |
| 51 | */ |
| 52 | #define blob_size(X) ((X)->nUsed) |
| 53 | |
| @@ -148,10 +154,11 @@ | |
| 154 | free(pBlob->aData); |
| 155 | pBlob->aData = 0; |
| 156 | pBlob->nAlloc = 0; |
| 157 | pBlob->nUsed = 0; |
| 158 | pBlob->iCursor = 0; |
| 159 | pBlob->blobFlags = 0; |
| 160 | }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){ |
| 161 | char *pNew = fossil_realloc(pBlob->aData, newSize); |
| 162 | pBlob->aData = pNew; |
| 163 | pBlob->nAlloc = newSize; |
| 164 | if( pBlob->nUsed>pBlob->nAlloc ){ |
| @@ -162,11 +169,11 @@ | |
| 169 | |
| 170 | /* |
| 171 | ** An initializer for Blobs |
| 172 | */ |
| 173 | #if INTERFACE |
| 174 | #define BLOB_INITIALIZER {0,0,0,0,0,blobReallocMalloc} |
| 175 | #endif |
| 176 | const Blob empty_blob = BLOB_INITIALIZER; |
| 177 | |
| 178 | /* |
| 179 | ** A reallocation function for when the initial string is in unmanaged |
| @@ -217,10 +224,11 @@ | |
| 224 | }else{ |
| 225 | if( size<=0 ) size = strlen(zData); |
| 226 | pBlob->nUsed = pBlob->nAlloc = size; |
| 227 | pBlob->aData = (char*)zData; |
| 228 | pBlob->iCursor = 0; |
| 229 | pBlob->blobFlags = 0; |
| 230 | pBlob->xRealloc = blobReallocStatic; |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | /* |
| @@ -248,10 +256,11 @@ | |
| 256 | assert_blob_is_reset(pBlob); |
| 257 | pBlob->nUsed = 0; |
| 258 | pBlob->nAlloc = 1; |
| 259 | pBlob->aData = (char*)zEmpty; |
| 260 | pBlob->iCursor = 0; |
| 261 | pBlob->blobFlags = 0; |
| 262 | pBlob->xRealloc = blobReallocStatic; |
| 263 | } |
| 264 | |
| 265 | /* |
| 266 | ** Append text or data to the end of a blob. |
| @@ -292,10 +301,24 @@ | |
| 301 | if( p->aData[p->nUsed]!=0 ){ |
| 302 | blob_materialize(p); |
| 303 | } |
| 304 | return p->aData; |
| 305 | } |
| 306 | |
| 307 | /* |
| 308 | ** Return a pointer to a null-terminated string for a blob that has |
| 309 | ** been created using blob_append_sql() and not blob_appendf(). If |
| 310 | ** text was ever added using blob_appendf() then throw an error. |
| 311 | */ |
| 312 | char *blob_sql_text(Blob *p){ |
| 313 | blob_is_init(p); |
| 314 | if( (p->blobFlags & BLOBFLAG_NotSQL) ){ |
| 315 | fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text"); |
| 316 | } |
| 317 | return blob_str(p); |
| 318 | } |
| 319 | |
| 320 | |
| 321 | /* |
| 322 | ** Return a pointer to a null-terminated string for a blob. |
| 323 | ** |
| 324 | ** WARNING: If the blob is ephemeral, it might cause a '\000' |
| @@ -671,13 +694,25 @@ | |
| 694 | return i; |
| 695 | } |
| 696 | |
| 697 | /* |
| 698 | ** Do printf-style string rendering and append the results to a blob. |
| 699 | ** |
| 700 | ** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags |
| 701 | ** whereas blob_append_sql() does not. |
| 702 | */ |
| 703 | void blob_appendf(Blob *pBlob, const char *zFormat, ...){ |
| 704 | if( pBlob ){ |
| 705 | va_list ap; |
| 706 | va_start(ap, zFormat); |
| 707 | vxprintf(pBlob, zFormat, ap); |
| 708 | va_end(ap); |
| 709 | pBlob->blobFlags |= BLOBFLAG_NotSQL; |
| 710 | } |
| 711 | } |
| 712 | void blob_append_sql(Blob *pBlob, const char *zFormat, ...){ |
| 713 | if( pBlob ){ |
| 714 | va_list ap; |
| 715 | va_start(ap, zFormat); |
| 716 | vxprintf(pBlob, zFormat, ap); |
| 717 | va_end(ap); |
| 718 | } |
| 719 |
+2
-2
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -300,12 +300,12 @@ | ||
| 300 | 300 | if( colorTest ){ |
| 301 | 301 | showClosed = 0; |
| 302 | 302 | showAll = 1; |
| 303 | 303 | } |
| 304 | 304 | |
| 305 | - style_header(showClosed ? "Closed Branches" : | |
| 306 | - showAll ? "All Branches" : "Open Branches"); | |
| 305 | + style_header("%s", showClosed ? "Closed Branches" : | |
| 306 | + showAll ? "All Branches" : "Open Branches"); | |
| 307 | 307 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 308 | 308 | if( showClosed ){ |
| 309 | 309 | style_submenu_element("All", "All", "brlist?all"); |
| 310 | 310 | style_submenu_element("Open","Open","brlist"); |
| 311 | 311 | }else if( showAll ){ |
| 312 | 312 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -300,12 +300,12 @@ | |
| 300 | if( colorTest ){ |
| 301 | showClosed = 0; |
| 302 | showAll = 1; |
| 303 | } |
| 304 | |
| 305 | style_header(showClosed ? "Closed Branches" : |
| 306 | showAll ? "All Branches" : "Open Branches"); |
| 307 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 308 | if( showClosed ){ |
| 309 | style_submenu_element("All", "All", "brlist?all"); |
| 310 | style_submenu_element("Open","Open","brlist"); |
| 311 | }else if( showAll ){ |
| 312 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -300,12 +300,12 @@ | |
| 300 | if( colorTest ){ |
| 301 | showClosed = 0; |
| 302 | showAll = 1; |
| 303 | } |
| 304 | |
| 305 | style_header("%s", showClosed ? "Closed Branches" : |
| 306 | showAll ? "All Branches" : "Open Branches"); |
| 307 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 308 | if( showClosed ){ |
| 309 | style_submenu_element("All", "All", "brlist?all"); |
| 310 | style_submenu_element("Open","Open","brlist"); |
| 311 | }else if( showAll ){ |
| 312 |
+2
-2
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -759,11 +759,11 @@ | ||
| 759 | 759 | db_prepare(&ins, |
| 760 | 760 | "INSERT INTO temp.fileage(fid, pathname)" |
| 761 | 761 | " SELECT rid, :path FROM blob WHERE uuid=:uuid" |
| 762 | 762 | ); |
| 763 | 763 | while( (pFile = manifest_file_next(pManifest, 0))!=0 ){ |
| 764 | - if(zGlob && !strglob(zGlob, pFile->zName)) continue; | |
| 764 | + if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue; | |
| 765 | 765 | db_bind_text(&ins, ":uuid", pFile->zUuid); |
| 766 | 766 | db_bind_text(&ins, ":path", pFile->zName); |
| 767 | 767 | db_step(&ins); |
| 768 | 768 | db_reset(&ins); |
| 769 | 769 | nFile++; |
| @@ -828,11 +828,11 @@ | ||
| 828 | 828 | rid = symbolic_name_to_rid(zName, "ci"); |
| 829 | 829 | if( rid==0 ){ |
| 830 | 830 | fossil_fatal("not a valid check-in: %s", zName); |
| 831 | 831 | } |
| 832 | 832 | style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName); |
| 833 | - style_header("File Ages", zName); | |
| 833 | + style_header("File Ages"); | |
| 834 | 834 | zGlob = P("glob"); |
| 835 | 835 | compute_fileage(rid,zGlob); |
| 836 | 836 | baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid); |
| 837 | 837 | zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc()); |
| 838 | 838 | @ <h2>File Ages For Check-in |
| 839 | 839 | |
| 840 | 840 | ADDED src/builtin.c |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -759,11 +759,11 @@ | |
| 759 | db_prepare(&ins, |
| 760 | "INSERT INTO temp.fileage(fid, pathname)" |
| 761 | " SELECT rid, :path FROM blob WHERE uuid=:uuid" |
| 762 | ); |
| 763 | while( (pFile = manifest_file_next(pManifest, 0))!=0 ){ |
| 764 | if(zGlob && !strglob(zGlob, pFile->zName)) continue; |
| 765 | db_bind_text(&ins, ":uuid", pFile->zUuid); |
| 766 | db_bind_text(&ins, ":path", pFile->zName); |
| 767 | db_step(&ins); |
| 768 | db_reset(&ins); |
| 769 | nFile++; |
| @@ -828,11 +828,11 @@ | |
| 828 | rid = symbolic_name_to_rid(zName, "ci"); |
| 829 | if( rid==0 ){ |
| 830 | fossil_fatal("not a valid check-in: %s", zName); |
| 831 | } |
| 832 | style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName); |
| 833 | style_header("File Ages", zName); |
| 834 | zGlob = P("glob"); |
| 835 | compute_fileage(rid,zGlob); |
| 836 | baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid); |
| 837 | zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc()); |
| 838 | @ <h2>File Ages For Check-in |
| 839 | |
| 840 | DDED src/builtin.c |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -759,11 +759,11 @@ | |
| 759 | db_prepare(&ins, |
| 760 | "INSERT INTO temp.fileage(fid, pathname)" |
| 761 | " SELECT rid, :path FROM blob WHERE uuid=:uuid" |
| 762 | ); |
| 763 | while( (pFile = manifest_file_next(pManifest, 0))!=0 ){ |
| 764 | if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue; |
| 765 | db_bind_text(&ins, ":uuid", pFile->zUuid); |
| 766 | db_bind_text(&ins, ":path", pFile->zName); |
| 767 | db_step(&ins); |
| 768 | db_reset(&ins); |
| 769 | nFile++; |
| @@ -828,11 +828,11 @@ | |
| 828 | rid = symbolic_name_to_rid(zName, "ci"); |
| 829 | if( rid==0 ){ |
| 830 | fossil_fatal("not a valid check-in: %s", zName); |
| 831 | } |
| 832 | style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName); |
| 833 | style_header("File Ages"); |
| 834 | zGlob = P("glob"); |
| 835 | compute_fileage(rid,zGlob); |
| 836 | baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid); |
| 837 | zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc()); |
| 838 | @ <h2>File Ages For Check-in |
| 839 | |
| 840 | DDED src/builtin.c |
+1
| --- a/src/builtin.c | ||
| +++ b/src/builtin.c | ||
| @@ -0,0 +1 @@ | ||
| 1 | +sizeof(aBuiltinFilesizeof(aBuiltinFil/if(==0 ) |
| --- a/src/builtin.c | |
| +++ b/src/builtin.c | |
| @@ -0,0 +1 @@ | |
| --- a/src/builtin.c | |
| +++ b/src/builtin.c | |
| @@ -0,0 +1 @@ | |
| 1 | sizeof(aBuiltinFilesizeof(aBuiltinFil/if(==0 ) |
+9
-9
| --- src/cache.c | ||
| +++ src/cache.c | ||
| @@ -61,11 +61,11 @@ | ||
| 61 | 61 | fossil_free(zDbName); |
| 62 | 62 | if( rc ){ |
| 63 | 63 | sqlite3_close(db); |
| 64 | 64 | return 0; |
| 65 | 65 | } |
| 66 | - rc = sqlite3_exec(db, | |
| 66 | + rc = sqlite3_exec(db, | |
| 67 | 67 | "PRAGMA page_size=8192;" |
| 68 | 68 | "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);" |
| 69 | 69 | "CREATE TABLE IF NOT EXISTS cache(" |
| 70 | 70 | "key TEXT PRIMARY KEY," /* Key used to access the cache */ |
| 71 | 71 | "id INT REFERENCES blob," /* The cache content */ |
| @@ -94,11 +94,11 @@ | ||
| 94 | 94 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| 95 | 95 | if( rc ){ |
| 96 | 96 | sqlite3_finalize(pStmt); |
| 97 | 97 | pStmt = 0; |
| 98 | 98 | } |
| 99 | - return pStmt; | |
| 99 | + return pStmt; | |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | /* |
| 103 | 103 | ** This routine implements an SQL function that renders a large integer |
| 104 | 104 | ** compactly: ex: 12.3MB |
| @@ -153,11 +153,11 @@ | ||
| 153 | 153 | if( pStmt==0 ) goto cache_write_end; |
| 154 | 154 | sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent), |
| 155 | 155 | SQLITE_STATIC); |
| 156 | 156 | if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end; |
| 157 | 157 | sqlite3_finalize(pStmt); |
| 158 | - pStmt = cacheStmt(db, | |
| 158 | + pStmt = cacheStmt(db, | |
| 159 | 159 | "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)" |
| 160 | 160 | "VALUES(?1,?2,strftime('%s','now'),1,?3)" |
| 161 | 161 | ); |
| 162 | 162 | if( pStmt==0 ) goto cache_write_end; |
| 163 | 163 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| @@ -202,27 +202,27 @@ | ||
| 202 | 202 | |
| 203 | 203 | db = cacheOpen(0); |
| 204 | 204 | if( db==0 ) return 0; |
| 205 | 205 | sqlite3_busy_timeout(db, 10000); |
| 206 | 206 | sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0); |
| 207 | - pStmt = cacheStmt(db, | |
| 207 | + pStmt = cacheStmt(db, | |
| 208 | 208 | "SELECT blob.data FROM cache, blob" |
| 209 | 209 | " WHERE cache.key=?1 AND cache.id=blob.id"); |
| 210 | 210 | if( pStmt==0 ) goto cache_read_done; |
| 211 | 211 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| 212 | 212 | if( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 213 | 213 | blob_append(pContent, sqlite3_column_blob(pStmt, 0), |
| 214 | 214 | sqlite3_column_bytes(pStmt, 0)); |
| 215 | 215 | rc = 1; |
| 216 | 216 | sqlite3_reset(pStmt); |
| 217 | - pStmt = cacheStmt(db, | |
| 217 | + pStmt = cacheStmt(db, | |
| 218 | 218 | "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')" |
| 219 | 219 | " WHERE key=?1"); |
| 220 | 220 | if( pStmt ){ |
| 221 | 221 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| 222 | 222 | sqlite3_step(pStmt); |
| 223 | - } | |
| 223 | + } | |
| 224 | 224 | } |
| 225 | 225 | sqlite3_finalize(pStmt); |
| 226 | 226 | cache_read_done: |
| 227 | 227 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 228 | 228 | sqlite3_close(db); |
| @@ -256,11 +256,11 @@ | ||
| 256 | 256 | sqlite3_stmt *pStmt; |
| 257 | 257 | |
| 258 | 258 | db_find_and_open_repository(0,0); |
| 259 | 259 | zCmd = g.argc>=3 ? g.argv[2] : ""; |
| 260 | 260 | nCmd = (int)strlen(zCmd); |
| 261 | - if( nCmd<=1 ){ | |
| 261 | + if( nCmd<=1 ){ | |
| 262 | 262 | fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]); |
| 263 | 263 | } |
| 264 | 264 | if( strncmp(zCmd, "init", nCmd)==0 ){ |
| 265 | 265 | db = cacheOpen(0); |
| 266 | 266 | sqlite3_close(db); |
| @@ -290,11 +290,11 @@ | ||
| 290 | 290 | fossil_print("cache does not exist\n"); |
| 291 | 291 | }else{ |
| 292 | 292 | int nEntry = 0; |
| 293 | 293 | char *zDbName = cacheName(); |
| 294 | 294 | cache_register_sizename(db); |
| 295 | - pStmt = cacheStmt(db, | |
| 295 | + pStmt = cacheStmt(db, | |
| 296 | 296 | "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')" |
| 297 | 297 | " FROM cache" |
| 298 | 298 | " ORDER BY tm DESC" |
| 299 | 299 | ); |
| 300 | 300 | if( pStmt ){ |
| @@ -338,11 +338,11 @@ | ||
| 338 | 338 | if( db==0 ){ |
| 339 | 339 | @ The web-page cache is disabled for this repository |
| 340 | 340 | }else{ |
| 341 | 341 | char *zDbName = cacheName(); |
| 342 | 342 | cache_register_sizename(db); |
| 343 | - pStmt = cacheStmt(db, | |
| 343 | + pStmt = cacheStmt(db, | |
| 344 | 344 | "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')" |
| 345 | 345 | " FROM cache" |
| 346 | 346 | " ORDER BY tm DESC" |
| 347 | 347 | ); |
| 348 | 348 | if( pStmt ){ |
| 349 | 349 |
| --- src/cache.c | |
| +++ src/cache.c | |
| @@ -61,11 +61,11 @@ | |
| 61 | fossil_free(zDbName); |
| 62 | if( rc ){ |
| 63 | sqlite3_close(db); |
| 64 | return 0; |
| 65 | } |
| 66 | rc = sqlite3_exec(db, |
| 67 | "PRAGMA page_size=8192;" |
| 68 | "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);" |
| 69 | "CREATE TABLE IF NOT EXISTS cache(" |
| 70 | "key TEXT PRIMARY KEY," /* Key used to access the cache */ |
| 71 | "id INT REFERENCES blob," /* The cache content */ |
| @@ -94,11 +94,11 @@ | |
| 94 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| 95 | if( rc ){ |
| 96 | sqlite3_finalize(pStmt); |
| 97 | pStmt = 0; |
| 98 | } |
| 99 | return pStmt; |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | ** This routine implements an SQL function that renders a large integer |
| 104 | ** compactly: ex: 12.3MB |
| @@ -153,11 +153,11 @@ | |
| 153 | if( pStmt==0 ) goto cache_write_end; |
| 154 | sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent), |
| 155 | SQLITE_STATIC); |
| 156 | if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end; |
| 157 | sqlite3_finalize(pStmt); |
| 158 | pStmt = cacheStmt(db, |
| 159 | "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)" |
| 160 | "VALUES(?1,?2,strftime('%s','now'),1,?3)" |
| 161 | ); |
| 162 | if( pStmt==0 ) goto cache_write_end; |
| 163 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| @@ -202,27 +202,27 @@ | |
| 202 | |
| 203 | db = cacheOpen(0); |
| 204 | if( db==0 ) return 0; |
| 205 | sqlite3_busy_timeout(db, 10000); |
| 206 | sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0); |
| 207 | pStmt = cacheStmt(db, |
| 208 | "SELECT blob.data FROM cache, blob" |
| 209 | " WHERE cache.key=?1 AND cache.id=blob.id"); |
| 210 | if( pStmt==0 ) goto cache_read_done; |
| 211 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| 212 | if( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 213 | blob_append(pContent, sqlite3_column_blob(pStmt, 0), |
| 214 | sqlite3_column_bytes(pStmt, 0)); |
| 215 | rc = 1; |
| 216 | sqlite3_reset(pStmt); |
| 217 | pStmt = cacheStmt(db, |
| 218 | "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')" |
| 219 | " WHERE key=?1"); |
| 220 | if( pStmt ){ |
| 221 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| 222 | sqlite3_step(pStmt); |
| 223 | } |
| 224 | } |
| 225 | sqlite3_finalize(pStmt); |
| 226 | cache_read_done: |
| 227 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 228 | sqlite3_close(db); |
| @@ -256,11 +256,11 @@ | |
| 256 | sqlite3_stmt *pStmt; |
| 257 | |
| 258 | db_find_and_open_repository(0,0); |
| 259 | zCmd = g.argc>=3 ? g.argv[2] : ""; |
| 260 | nCmd = (int)strlen(zCmd); |
| 261 | if( nCmd<=1 ){ |
| 262 | fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]); |
| 263 | } |
| 264 | if( strncmp(zCmd, "init", nCmd)==0 ){ |
| 265 | db = cacheOpen(0); |
| 266 | sqlite3_close(db); |
| @@ -290,11 +290,11 @@ | |
| 290 | fossil_print("cache does not exist\n"); |
| 291 | }else{ |
| 292 | int nEntry = 0; |
| 293 | char *zDbName = cacheName(); |
| 294 | cache_register_sizename(db); |
| 295 | pStmt = cacheStmt(db, |
| 296 | "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')" |
| 297 | " FROM cache" |
| 298 | " ORDER BY tm DESC" |
| 299 | ); |
| 300 | if( pStmt ){ |
| @@ -338,11 +338,11 @@ | |
| 338 | if( db==0 ){ |
| 339 | @ The web-page cache is disabled for this repository |
| 340 | }else{ |
| 341 | char *zDbName = cacheName(); |
| 342 | cache_register_sizename(db); |
| 343 | pStmt = cacheStmt(db, |
| 344 | "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')" |
| 345 | " FROM cache" |
| 346 | " ORDER BY tm DESC" |
| 347 | ); |
| 348 | if( pStmt ){ |
| 349 |
| --- src/cache.c | |
| +++ src/cache.c | |
| @@ -61,11 +61,11 @@ | |
| 61 | fossil_free(zDbName); |
| 62 | if( rc ){ |
| 63 | sqlite3_close(db); |
| 64 | return 0; |
| 65 | } |
| 66 | rc = sqlite3_exec(db, |
| 67 | "PRAGMA page_size=8192;" |
| 68 | "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);" |
| 69 | "CREATE TABLE IF NOT EXISTS cache(" |
| 70 | "key TEXT PRIMARY KEY," /* Key used to access the cache */ |
| 71 | "id INT REFERENCES blob," /* The cache content */ |
| @@ -94,11 +94,11 @@ | |
| 94 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| 95 | if( rc ){ |
| 96 | sqlite3_finalize(pStmt); |
| 97 | pStmt = 0; |
| 98 | } |
| 99 | return pStmt; |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | ** This routine implements an SQL function that renders a large integer |
| 104 | ** compactly: ex: 12.3MB |
| @@ -153,11 +153,11 @@ | |
| 153 | if( pStmt==0 ) goto cache_write_end; |
| 154 | sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent), |
| 155 | SQLITE_STATIC); |
| 156 | if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end; |
| 157 | sqlite3_finalize(pStmt); |
| 158 | pStmt = cacheStmt(db, |
| 159 | "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)" |
| 160 | "VALUES(?1,?2,strftime('%s','now'),1,?3)" |
| 161 | ); |
| 162 | if( pStmt==0 ) goto cache_write_end; |
| 163 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| @@ -202,27 +202,27 @@ | |
| 202 | |
| 203 | db = cacheOpen(0); |
| 204 | if( db==0 ) return 0; |
| 205 | sqlite3_busy_timeout(db, 10000); |
| 206 | sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0); |
| 207 | pStmt = cacheStmt(db, |
| 208 | "SELECT blob.data FROM cache, blob" |
| 209 | " WHERE cache.key=?1 AND cache.id=blob.id"); |
| 210 | if( pStmt==0 ) goto cache_read_done; |
| 211 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| 212 | if( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 213 | blob_append(pContent, sqlite3_column_blob(pStmt, 0), |
| 214 | sqlite3_column_bytes(pStmt, 0)); |
| 215 | rc = 1; |
| 216 | sqlite3_reset(pStmt); |
| 217 | pStmt = cacheStmt(db, |
| 218 | "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')" |
| 219 | " WHERE key=?1"); |
| 220 | if( pStmt ){ |
| 221 | sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC); |
| 222 | sqlite3_step(pStmt); |
| 223 | } |
| 224 | } |
| 225 | sqlite3_finalize(pStmt); |
| 226 | cache_read_done: |
| 227 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 228 | sqlite3_close(db); |
| @@ -256,11 +256,11 @@ | |
| 256 | sqlite3_stmt *pStmt; |
| 257 | |
| 258 | db_find_and_open_repository(0,0); |
| 259 | zCmd = g.argc>=3 ? g.argv[2] : ""; |
| 260 | nCmd = (int)strlen(zCmd); |
| 261 | if( nCmd<=1 ){ |
| 262 | fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]); |
| 263 | } |
| 264 | if( strncmp(zCmd, "init", nCmd)==0 ){ |
| 265 | db = cacheOpen(0); |
| 266 | sqlite3_close(db); |
| @@ -290,11 +290,11 @@ | |
| 290 | fossil_print("cache does not exist\n"); |
| 291 | }else{ |
| 292 | int nEntry = 0; |
| 293 | char *zDbName = cacheName(); |
| 294 | cache_register_sizename(db); |
| 295 | pStmt = cacheStmt(db, |
| 296 | "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')" |
| 297 | " FROM cache" |
| 298 | " ORDER BY tm DESC" |
| 299 | ); |
| 300 | if( pStmt ){ |
| @@ -338,11 +338,11 @@ | |
| 338 | if( db==0 ){ |
| 339 | @ The web-page cache is disabled for this repository |
| 340 | }else{ |
| 341 | char *zDbName = cacheName(); |
| 342 | cache_register_sizename(db); |
| 343 | pStmt = cacheStmt(db, |
| 344 | "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')" |
| 345 | " FROM cache" |
| 346 | " ORDER BY tm DESC" |
| 347 | ); |
| 348 | if( pStmt ){ |
| 349 |
+4
-3
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -277,12 +277,12 @@ | ||
| 277 | 277 | ** Return true if the response should be sent with Content-Encoding: gzip. |
| 278 | 278 | */ |
| 279 | 279 | static int is_gzippable(void){ |
| 280 | 280 | if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0; |
| 281 | 281 | return strncmp(zContentType, "text/", 5)==0 |
| 282 | - || strglob("application/*xml", zContentType) | |
| 283 | - || strglob("application/*javascript", zContentType); | |
| 282 | + || sqlite3_strglob("application/*xml", zContentType)==0 | |
| 283 | + || sqlite3_strglob("application/*javascript", zContentType)==0; | |
| 284 | 284 | } |
| 285 | 285 | |
| 286 | 286 | /* |
| 287 | 287 | ** Do a normal HTTP reply |
| 288 | 288 | */ |
| @@ -1712,11 +1712,12 @@ | ||
| 1712 | 1712 | listen(listener,10); |
| 1713 | 1713 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 1714 | 1714 | (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 1715 | 1715 | fflush(stdout); |
| 1716 | 1716 | if( zBrowser ){ |
| 1717 | - zBrowser = mprintf(zBrowser, iPort); | |
| 1717 | + assert( strstr(zBrowser,"%d")!=0 ); | |
| 1718 | + zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort); | |
| 1718 | 1719 | #if defined(__CYGWIN__) |
| 1719 | 1720 | /* On Cygwin, we can do better than "echo" */ |
| 1720 | 1721 | if( strncmp(zBrowser, "echo ", 5)==0 ){ |
| 1721 | 1722 | wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5); |
| 1722 | 1723 | wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */ |
| 1723 | 1724 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -277,12 +277,12 @@ | |
| 277 | ** Return true if the response should be sent with Content-Encoding: gzip. |
| 278 | */ |
| 279 | static int is_gzippable(void){ |
| 280 | if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0; |
| 281 | return strncmp(zContentType, "text/", 5)==0 |
| 282 | || strglob("application/*xml", zContentType) |
| 283 | || strglob("application/*javascript", zContentType); |
| 284 | } |
| 285 | |
| 286 | /* |
| 287 | ** Do a normal HTTP reply |
| 288 | */ |
| @@ -1712,11 +1712,12 @@ | |
| 1712 | listen(listener,10); |
| 1713 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 1714 | (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 1715 | fflush(stdout); |
| 1716 | if( zBrowser ){ |
| 1717 | zBrowser = mprintf(zBrowser, iPort); |
| 1718 | #if defined(__CYGWIN__) |
| 1719 | /* On Cygwin, we can do better than "echo" */ |
| 1720 | if( strncmp(zBrowser, "echo ", 5)==0 ){ |
| 1721 | wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5); |
| 1722 | wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */ |
| 1723 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -277,12 +277,12 @@ | |
| 277 | ** Return true if the response should be sent with Content-Encoding: gzip. |
| 278 | */ |
| 279 | static int is_gzippable(void){ |
| 280 | if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0; |
| 281 | return strncmp(zContentType, "text/", 5)==0 |
| 282 | || sqlite3_strglob("application/*xml", zContentType)==0 |
| 283 | || sqlite3_strglob("application/*javascript", zContentType)==0; |
| 284 | } |
| 285 | |
| 286 | /* |
| 287 | ** Do a normal HTTP reply |
| 288 | */ |
| @@ -1712,11 +1712,12 @@ | |
| 1712 | listen(listener,10); |
| 1713 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 1714 | (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 1715 | fflush(stdout); |
| 1716 | if( zBrowser ){ |
| 1717 | assert( strstr(zBrowser,"%d")!=0 ); |
| 1718 | zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort); |
| 1719 | #if defined(__CYGWIN__) |
| 1720 | /* On Cygwin, we can do better than "echo" */ |
| 1721 | if( strncmp(zBrowser, "echo ", 5)==0 ){ |
| 1722 | wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5); |
| 1723 | wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */ |
| 1724 |
+20
-17
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -52,23 +52,25 @@ | ||
| 52 | 52 | zName = blob_str(&fname); |
| 53 | 53 | if( fossil_strcmp(zName, ".")==0 ) { |
| 54 | 54 | blob_reset(&where); |
| 55 | 55 | break; |
| 56 | 56 | } |
| 57 | - blob_appendf(&where, " %s (pathname=%Q %s) " | |
| 58 | - "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", | |
| 59 | - (blob_size(&where)>0) ? "OR" : "AND", zName, | |
| 60 | - filename_collation(), zName, filename_collation(), | |
| 61 | - zName, filename_collation()); | |
| 57 | + blob_append_sql(&where, | |
| 58 | + " %s (pathname=%Q %s) " | |
| 59 | + "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", | |
| 60 | + (blob_size(&where)>0) ? "OR" : "AND", zName, | |
| 61 | + filename_collation(), zName, filename_collation(), | |
| 62 | + zName, filename_collation() | |
| 63 | + ); | |
| 62 | 64 | } |
| 63 | 65 | |
| 64 | 66 | db_prepare(&q, |
| 65 | 67 | "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)" |
| 66 | 68 | " FROM vfile " |
| 67 | 69 | " WHERE is_selected(id) %s" |
| 68 | 70 | " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1", |
| 69 | - blob_str(&where) | |
| 71 | + blob_sql_text(&where) | |
| 70 | 72 | ); |
| 71 | 73 | blob_zero(&rewrittenPathname); |
| 72 | 74 | while( db_step(&q)==SQLITE_ROW ){ |
| 73 | 75 | const char *zPathname = db_column_text(&q,0); |
| 74 | 76 | const char *zDisplayName = zPathname; |
| @@ -313,29 +315,32 @@ | ||
| 313 | 315 | zName = blob_str(&fname); |
| 314 | 316 | if( fossil_strcmp(zName, ".")==0 ) { |
| 315 | 317 | blob_reset(&where); |
| 316 | 318 | break; |
| 317 | 319 | } |
| 318 | - blob_appendf(&where, " %s (pathname=%Q %s) " | |
| 319 | - "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", | |
| 320 | - (blob_size(&where)>0) ? "OR" : "WHERE", zName, | |
| 321 | - filename_collation(), zName, filename_collation(), | |
| 322 | - zName, filename_collation()); | |
| 320 | + blob_append_sql(&where, | |
| 321 | + " %s (pathname=%Q %s) " | |
| 322 | + "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", | |
| 323 | + (blob_size(&where)>0) ? "OR" : "WHERE", zName, | |
| 324 | + filename_collation(), zName, filename_collation(), | |
| 325 | + zName, filename_collation() | |
| 326 | + ); | |
| 323 | 327 | } |
| 324 | 328 | vfile_check_signature(vid, 0); |
| 325 | 329 | if( showAge ){ |
| 326 | 330 | db_prepare(&q, |
| 327 | 331 | "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)," |
| 328 | 332 | " datetime(checkin_mtime(%d,rid),'unixepoch'%s)" |
| 329 | 333 | " FROM vfile %s" |
| 330 | - " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy | |
| 334 | + " ORDER BY %s", | |
| 335 | + vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/ | |
| 331 | 336 | ); |
| 332 | 337 | }else{ |
| 333 | 338 | db_prepare(&q, |
| 334 | 339 | "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)" |
| 335 | 340 | " FROM vfile %s" |
| 336 | - " ORDER BY %s", blob_str(&where), zOrderBy | |
| 341 | + " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/ | |
| 337 | 342 | ); |
| 338 | 343 | } |
| 339 | 344 | blob_reset(&where); |
| 340 | 345 | while( db_step(&q)==SQLITE_ROW ){ |
| 341 | 346 | const char *zPathname = db_column_text(&q,0); |
| @@ -908,14 +913,12 @@ | ||
| 908 | 913 | assert( g.aCommitFile==0 ); |
| 909 | 914 | if( g.argc>2 ){ |
| 910 | 915 | int ii, jj=0; |
| 911 | 916 | Blob fname; |
| 912 | 917 | Stmt q; |
| 913 | - const char *zCollate; | |
| 914 | 918 | Bag toCommit; |
| 915 | 919 | |
| 916 | - zCollate = filename_collation(); | |
| 917 | 920 | blob_zero(&fname); |
| 918 | 921 | bag_init(&toCommit); |
| 919 | 922 | for(ii=2; ii<g.argc; ii++){ |
| 920 | 923 | int cnt = 0; |
| 921 | 924 | file_tree_name(g.argv[ii], &fname, 1); |
| @@ -924,12 +927,12 @@ | ||
| 924 | 927 | return result; |
| 925 | 928 | } |
| 926 | 929 | db_prepare(&q, |
| 927 | 930 | "SELECT id FROM vfile WHERE pathname=%Q %s" |
| 928 | 931 | " OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 929 | - blob_str(&fname), zCollate, blob_str(&fname), | |
| 930 | - zCollate, blob_str(&fname), zCollate); | |
| 932 | + blob_str(&fname), filename_collation(), blob_str(&fname), | |
| 933 | + filename_collation(), blob_str(&fname), filename_collation()); | |
| 931 | 934 | while( db_step(&q)==SQLITE_ROW ){ |
| 932 | 935 | cnt++; |
| 933 | 936 | bag_insert(&toCommit, db_column_int(&q, 0)); |
| 934 | 937 | } |
| 935 | 938 | db_finalize(&q); |
| 936 | 939 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -52,23 +52,25 @@ | |
| 52 | zName = blob_str(&fname); |
| 53 | if( fossil_strcmp(zName, ".")==0 ) { |
| 54 | blob_reset(&where); |
| 55 | break; |
| 56 | } |
| 57 | blob_appendf(&where, " %s (pathname=%Q %s) " |
| 58 | "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 59 | (blob_size(&where)>0) ? "OR" : "AND", zName, |
| 60 | filename_collation(), zName, filename_collation(), |
| 61 | zName, filename_collation()); |
| 62 | } |
| 63 | |
| 64 | db_prepare(&q, |
| 65 | "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)" |
| 66 | " FROM vfile " |
| 67 | " WHERE is_selected(id) %s" |
| 68 | " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1", |
| 69 | blob_str(&where) |
| 70 | ); |
| 71 | blob_zero(&rewrittenPathname); |
| 72 | while( db_step(&q)==SQLITE_ROW ){ |
| 73 | const char *zPathname = db_column_text(&q,0); |
| 74 | const char *zDisplayName = zPathname; |
| @@ -313,29 +315,32 @@ | |
| 313 | zName = blob_str(&fname); |
| 314 | if( fossil_strcmp(zName, ".")==0 ) { |
| 315 | blob_reset(&where); |
| 316 | break; |
| 317 | } |
| 318 | blob_appendf(&where, " %s (pathname=%Q %s) " |
| 319 | "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 320 | (blob_size(&where)>0) ? "OR" : "WHERE", zName, |
| 321 | filename_collation(), zName, filename_collation(), |
| 322 | zName, filename_collation()); |
| 323 | } |
| 324 | vfile_check_signature(vid, 0); |
| 325 | if( showAge ){ |
| 326 | db_prepare(&q, |
| 327 | "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)," |
| 328 | " datetime(checkin_mtime(%d,rid),'unixepoch'%s)" |
| 329 | " FROM vfile %s" |
| 330 | " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy |
| 331 | ); |
| 332 | }else{ |
| 333 | db_prepare(&q, |
| 334 | "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)" |
| 335 | " FROM vfile %s" |
| 336 | " ORDER BY %s", blob_str(&where), zOrderBy |
| 337 | ); |
| 338 | } |
| 339 | blob_reset(&where); |
| 340 | while( db_step(&q)==SQLITE_ROW ){ |
| 341 | const char *zPathname = db_column_text(&q,0); |
| @@ -908,14 +913,12 @@ | |
| 908 | assert( g.aCommitFile==0 ); |
| 909 | if( g.argc>2 ){ |
| 910 | int ii, jj=0; |
| 911 | Blob fname; |
| 912 | Stmt q; |
| 913 | const char *zCollate; |
| 914 | Bag toCommit; |
| 915 | |
| 916 | zCollate = filename_collation(); |
| 917 | blob_zero(&fname); |
| 918 | bag_init(&toCommit); |
| 919 | for(ii=2; ii<g.argc; ii++){ |
| 920 | int cnt = 0; |
| 921 | file_tree_name(g.argv[ii], &fname, 1); |
| @@ -924,12 +927,12 @@ | |
| 924 | return result; |
| 925 | } |
| 926 | db_prepare(&q, |
| 927 | "SELECT id FROM vfile WHERE pathname=%Q %s" |
| 928 | " OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 929 | blob_str(&fname), zCollate, blob_str(&fname), |
| 930 | zCollate, blob_str(&fname), zCollate); |
| 931 | while( db_step(&q)==SQLITE_ROW ){ |
| 932 | cnt++; |
| 933 | bag_insert(&toCommit, db_column_int(&q, 0)); |
| 934 | } |
| 935 | db_finalize(&q); |
| 936 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -52,23 +52,25 @@ | |
| 52 | zName = blob_str(&fname); |
| 53 | if( fossil_strcmp(zName, ".")==0 ) { |
| 54 | blob_reset(&where); |
| 55 | break; |
| 56 | } |
| 57 | blob_append_sql(&where, |
| 58 | " %s (pathname=%Q %s) " |
| 59 | "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 60 | (blob_size(&where)>0) ? "OR" : "AND", zName, |
| 61 | filename_collation(), zName, filename_collation(), |
| 62 | zName, filename_collation() |
| 63 | ); |
| 64 | } |
| 65 | |
| 66 | db_prepare(&q, |
| 67 | "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)" |
| 68 | " FROM vfile " |
| 69 | " WHERE is_selected(id) %s" |
| 70 | " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1", |
| 71 | blob_sql_text(&where) |
| 72 | ); |
| 73 | blob_zero(&rewrittenPathname); |
| 74 | while( db_step(&q)==SQLITE_ROW ){ |
| 75 | const char *zPathname = db_column_text(&q,0); |
| 76 | const char *zDisplayName = zPathname; |
| @@ -313,29 +315,32 @@ | |
| 315 | zName = blob_str(&fname); |
| 316 | if( fossil_strcmp(zName, ".")==0 ) { |
| 317 | blob_reset(&where); |
| 318 | break; |
| 319 | } |
| 320 | blob_append_sql(&where, |
| 321 | " %s (pathname=%Q %s) " |
| 322 | "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 323 | (blob_size(&where)>0) ? "OR" : "WHERE", zName, |
| 324 | filename_collation(), zName, filename_collation(), |
| 325 | zName, filename_collation() |
| 326 | ); |
| 327 | } |
| 328 | vfile_check_signature(vid, 0); |
| 329 | if( showAge ){ |
| 330 | db_prepare(&q, |
| 331 | "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)," |
| 332 | " datetime(checkin_mtime(%d,rid),'unixepoch'%s)" |
| 333 | " FROM vfile %s" |
| 334 | " ORDER BY %s", |
| 335 | vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/ |
| 336 | ); |
| 337 | }else{ |
| 338 | db_prepare(&q, |
| 339 | "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)" |
| 340 | " FROM vfile %s" |
| 341 | " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/ |
| 342 | ); |
| 343 | } |
| 344 | blob_reset(&where); |
| 345 | while( db_step(&q)==SQLITE_ROW ){ |
| 346 | const char *zPathname = db_column_text(&q,0); |
| @@ -908,14 +913,12 @@ | |
| 913 | assert( g.aCommitFile==0 ); |
| 914 | if( g.argc>2 ){ |
| 915 | int ii, jj=0; |
| 916 | Blob fname; |
| 917 | Stmt q; |
| 918 | Bag toCommit; |
| 919 | |
| 920 | blob_zero(&fname); |
| 921 | bag_init(&toCommit); |
| 922 | for(ii=2; ii<g.argc; ii++){ |
| 923 | int cnt = 0; |
| 924 | file_tree_name(g.argv[ii], &fname, 1); |
| @@ -924,12 +927,12 @@ | |
| 927 | return result; |
| 928 | } |
| 929 | db_prepare(&q, |
| 930 | "SELECT id FROM vfile WHERE pathname=%Q %s" |
| 931 | " OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 932 | blob_str(&fname), filename_collation(), blob_str(&fname), |
| 933 | filename_collation(), blob_str(&fname), filename_collation()); |
| 934 | while( db_step(&q)==SQLITE_ROW ){ |
| 935 | cnt++; |
| 936 | bag_insert(&toCommit, db_column_int(&q, 0)); |
| 937 | } |
| 938 | db_finalize(&q); |
| 939 |
+1
-1
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -60,11 +60,11 @@ | ||
| 60 | 60 | Blob uuid; |
| 61 | 61 | int vid; |
| 62 | 62 | |
| 63 | 63 | blob_init(&uuid, zName, -1); |
| 64 | 64 | if( name_to_uuid(&uuid, 1, "ci") ){ |
| 65 | - fossil_fatal(g.zErrMsg); | |
| 65 | + fossil_fatal("%s", g.zErrMsg); | |
| 66 | 66 | } |
| 67 | 67 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 68 | 68 | if( vid==0 ){ |
| 69 | 69 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | ADDED src/codecheck1.c |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | Blob uuid; |
| 61 | int vid; |
| 62 | |
| 63 | blob_init(&uuid, zName, -1); |
| 64 | if( name_to_uuid(&uuid, 1, "ci") ){ |
| 65 | fossil_fatal(g.zErrMsg); |
| 66 | } |
| 67 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 68 | if( vid==0 ){ |
| 69 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 70 | } |
| 71 | |
| 72 | DDED src/codecheck1.c |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | Blob uuid; |
| 61 | int vid; |
| 62 | |
| 63 | blob_init(&uuid, zName, -1); |
| 64 | if( name_to_uuid(&uuid, 1, "ci") ){ |
| 65 | fossil_fatal("%s", g.zErrMsg); |
| 66 | } |
| 67 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 68 | if( vid==0 ){ |
| 69 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 70 | } |
| 71 | |
| 72 | DDED src/codecheck1.c |
+14
| --- a/src/codecheck1.c | ||
| +++ b/src/codecheck1.c | ||
| @@ -0,0 +1,14 @@ | ||
| 1 | +/* | |
| 2 | +** Copyright (c) 2014 D. Richard Hipp | |
| 3 | +** | |
| 4 | +** This program is free software; you can redistribute it and/or | |
| 5 | +** modify it under the terms of the Simplified BSD License (also | |
| 6 | +** known as the "2-Clause Licensetimeline_utc ** Copyright (c) 2014 D. Richard Hipp | |
| 7 | +** | |
| 8 | +** This program is free software; you can redistribute it and/or | |
| 9 | +** modify it under the terms of the Simplified BSD License (also | |
| 10 | +** known as the "2-Clause Licensetimeline_utc(c) 2014 D. Richard Hipp | |
| 11 | +** | |
| 12 | +** This program is free software; you can redistribute it and/or | |
| 13 | +** modify it under the terms of the Simplified BSD License (also | |
| 14 | +** known as the "2-Clause Licensetimeline_utc |
| --- a/src/codecheck1.c | |
| +++ b/src/codecheck1.c | |
| @@ -0,0 +1,14 @@ | |
| --- a/src/codecheck1.c | |
| +++ b/src/codecheck1.c | |
| @@ -0,0 +1,14 @@ | |
| 1 | /* |
| 2 | ** Copyright (c) 2014 D. Richard Hipp |
| 3 | ** |
| 4 | ** This program is free software; you can redistribute it and/or |
| 5 | ** modify it under the terms of the Simplified BSD License (also |
| 6 | ** known as the "2-Clause Licensetimeline_utc ** Copyright (c) 2014 D. Richard Hipp |
| 7 | ** |
| 8 | ** This program is free software; you can redistribute it and/or |
| 9 | ** modify it under the terms of the Simplified BSD License (also |
| 10 | ** known as the "2-Clause Licensetimeline_utc(c) 2014 D. Richard Hipp |
| 11 | ** |
| 12 | ** This program is free software; you can redistribute it and/or |
| 13 | ** modify it under the terms of the Simplified BSD License (also |
| 14 | ** known as the "2-Clause Licensetimeline_utc |
+2
-2
| --- src/comformat.c | ||
| +++ src/comformat.c | ||
| @@ -497,14 +497,14 @@ | ||
| 497 | 497 | zOrigText = mprintf("%s", blob_str(&fileData)); |
| 498 | 498 | blob_reset(&fileData); |
| 499 | 499 | } |
| 500 | 500 | } |
| 501 | 501 | if( decode ){ |
| 502 | - zText = mprintf(fromFile ? "%z" : "%s", zText); | |
| 502 | + zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText); | |
| 503 | 503 | defossilize(zText); |
| 504 | 504 | if( zOrigText ){ |
| 505 | - zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText); | |
| 505 | + zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText); | |
| 506 | 506 | defossilize(zOrigText); |
| 507 | 507 | } |
| 508 | 508 | } |
| 509 | 509 | if( indent<0 ){ |
| 510 | 510 | indent = strlen(zPrefix); |
| 511 | 511 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -497,14 +497,14 @@ | |
| 497 | zOrigText = mprintf("%s", blob_str(&fileData)); |
| 498 | blob_reset(&fileData); |
| 499 | } |
| 500 | } |
| 501 | if( decode ){ |
| 502 | zText = mprintf(fromFile ? "%z" : "%s", zText); |
| 503 | defossilize(zText); |
| 504 | if( zOrigText ){ |
| 505 | zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText); |
| 506 | defossilize(zOrigText); |
| 507 | } |
| 508 | } |
| 509 | if( indent<0 ){ |
| 510 | indent = strlen(zPrefix); |
| 511 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -497,14 +497,14 @@ | |
| 497 | zOrigText = mprintf("%s", blob_str(&fileData)); |
| 498 | blob_reset(&fileData); |
| 499 | } |
| 500 | } |
| 501 | if( decode ){ |
| 502 | zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText); |
| 503 | defossilize(zText); |
| 504 | if( zOrigText ){ |
| 505 | zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText); |
| 506 | defossilize(zOrigText); |
| 507 | } |
| 508 | } |
| 509 | if( indent<0 ){ |
| 510 | indent = strlen(zPrefix); |
| 511 |
+36
-28
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -194,19 +194,19 @@ | ||
| 194 | 194 | Blob x; |
| 195 | 195 | int i; |
| 196 | 196 | const char *zSep = ""; |
| 197 | 197 | |
| 198 | 198 | blob_zero(&x); |
| 199 | - blob_append(&x, "(", 1); | |
| 199 | + blob_append_sql(&x, "("); | |
| 200 | 200 | for(i=0; i<count(aConfig); i++){ |
| 201 | 201 | if( (aConfig[i].groupMask & iMask)==0 ) continue; |
| 202 | 202 | if( aConfig[i].zName[0]=='@' ) continue; |
| 203 | - blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName); | |
| 203 | + blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName); | |
| 204 | 204 | zSep = ","; |
| 205 | 205 | } |
| 206 | - blob_append(&x, ")", 1); | |
| 207 | - return blob_str(&x); | |
| 206 | + blob_append_sql(&x, ")"); | |
| 207 | + return blob_sql_text(&x); | |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | 210 | /* |
| 211 | 211 | ** Return the mask for the named configuration parameter if it can be |
| 212 | 212 | ** safely exported. Return 0 if the parameter is not safe to export. |
| @@ -361,11 +361,12 @@ | ||
| 361 | 361 | @ INSERT INTO _xfer_reportfmt |
| 362 | 362 | @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt; |
| 363 | 363 | @ INSERT INTO _xfer_user |
| 364 | 364 | @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user; |
| 365 | 365 | ; |
| 366 | - db_multi_exec(zSQL1); | |
| 366 | + assert( strchr(zSQL1,'%')==0 ); | |
| 367 | + db_multi_exec(zSQL1 /*works-like:""*/); | |
| 367 | 368 | |
| 368 | 369 | /* When the replace flag is set, add triggers that run the first time |
| 369 | 370 | ** that new data is seen. The triggers run only once and delete all the |
| 370 | 371 | ** existing data. |
| 371 | 372 | */ |
| @@ -390,11 +391,12 @@ | ||
| 390 | 391 | sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0, |
| 391 | 392 | config_is_reset_function, 0, 0); |
| 392 | 393 | sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0, |
| 393 | 394 | config_reset_function, 0, 0); |
| 394 | 395 | configHasBeenReset = 0; |
| 395 | - db_multi_exec(zSQL2); | |
| 396 | + assert( strchr(zSQL2,'%')==0 ); | |
| 397 | + db_multi_exec(zSQL2 /*works-like:""*/); | |
| 396 | 398 | } |
| 397 | 399 | } |
| 398 | 400 | |
| 399 | 401 | /* |
| 400 | 402 | ** After receiving configuration data, call this routine to transfer |
| @@ -407,11 +409,12 @@ | ||
| 407 | 409 | @ DELETE FROM reportfmt; |
| 408 | 410 | @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt; |
| 409 | 411 | @ DROP TABLE _xfer_user; |
| 410 | 412 | @ DROP TABLE _xfer_reportfmt; |
| 411 | 413 | ; |
| 412 | - db_multi_exec(zSQL); | |
| 414 | + assert( strchr(zSQL,'%')==0 ); | |
| 415 | + db_multi_exec(zSQL /*works-like:""*/); | |
| 413 | 416 | } |
| 414 | 417 | |
| 415 | 418 | /* |
| 416 | 419 | ** Mask of modified configuration sets |
| 417 | 420 | */ |
| @@ -563,35 +566,39 @@ | ||
| 563 | 566 | if( (thisMask & groupMask)==0 ) return; |
| 564 | 567 | |
| 565 | 568 | blob_zero(&sql); |
| 566 | 569 | if( groupMask & CONFIGSET_OVERWRITE ){ |
| 567 | 570 | if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){ |
| 568 | - db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]); | |
| 571 | + db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]); | |
| 569 | 572 | configHasBeenReset |= thisMask; |
| 570 | 573 | } |
| 571 | - blob_append(&sql, "REPLACE INTO ", -1); | |
| 572 | - }else{ | |
| 573 | - blob_append(&sql, "INSERT OR IGNORE INTO ", -1); | |
| 574 | - } | |
| 575 | - blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey); | |
| 576 | - for(jj=2; jj<nToken; jj+=2){ | |
| 577 | - blob_appendf(&sql, ",%s", azToken[jj]); | |
| 578 | - } | |
| 579 | - blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]); | |
| 580 | - for(jj=2; jj<nToken; jj+=2){ | |
| 581 | - blob_appendf(&sql, ",%s", azToken[jj+1]); | |
| 582 | - } | |
| 583 | - db_multi_exec("%s)", blob_str(&sql)); | |
| 574 | + blob_append_sql(&sql, "REPLACE INTO "); | |
| 575 | + }else{ | |
| 576 | + blob_append_sql(&sql, "INSERT OR IGNORE INTO "); | |
| 577 | + } | |
| 578 | + blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey); | |
| 579 | + for(jj=2; jj<nToken; jj+=2){ | |
| 580 | + blob_append_sql(&sql, ",\"%w\"", azToken[jj]); | |
| 581 | + } | |
| 582 | + blob_append_sql(&sql,") VALUES(%s,%s", | |
| 583 | + azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/); | |
| 584 | + for(jj=2; jj<nToken; jj+=2){ | |
| 585 | + blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/); | |
| 586 | + } | |
| 587 | + db_multi_exec("%s)", blob_sql_text(&sql)); | |
| 584 | 588 | if( db_changes()==0 ){ |
| 585 | 589 | blob_reset(&sql); |
| 586 | - blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]); | |
| 590 | + blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s", | |
| 591 | + &zName[1], azToken[0]/*safe-for-%s*/); | |
| 587 | 592 | for(jj=2; jj<nToken; jj+=2){ |
| 588 | - blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]); | |
| 593 | + blob_append_sql(&sql, ", \"%w\"=%s", | |
| 594 | + azToken[jj], azToken[jj+1]/*safe-for-%s*/); | |
| 589 | 595 | } |
| 590 | - blob_appendf(&sql, " WHERE %s=%s AND mtime<%s", | |
| 591 | - aType[ii].zPrimKey, azToken[1], azToken[0]); | |
| 592 | - db_multi_exec("%s", blob_str(&sql)); | |
| 596 | + blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s", | |
| 597 | + aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/, | |
| 598 | + azToken[0]/*safe-for-%s*/); | |
| 599 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 593 | 600 | } |
| 594 | 601 | blob_reset(&sql); |
| 595 | 602 | rebuildMask |= thisMask; |
| 596 | 603 | }else{ |
| 597 | 604 | /* Otherwise, the old format */ |
| @@ -609,11 +616,11 @@ | ||
| 609 | 616 | /* Notice that we are evaluating arbitrary SQL received from the |
| 610 | 617 | ** client. But this can only happen if the client has authenticated |
| 611 | 618 | ** as an administrator, so presumably we trust the client at this |
| 612 | 619 | ** point. |
| 613 | 620 | */ |
| 614 | - db_multi_exec("%s", blob_str(pContent)); | |
| 621 | + db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/); | |
| 615 | 622 | }else{ |
| 616 | 623 | db_multi_exec( |
| 617 | 624 | "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 618 | 625 | zName, blob_str(pContent) |
| 619 | 626 | ); |
| @@ -966,11 +973,12 @@ | ||
| 966 | 973 | db_multi_exec("DELETE FROM concealed"); |
| 967 | 974 | }else if( fossil_strcmp(zName,"@shun")==0 ){ |
| 968 | 975 | db_multi_exec("DELETE FROM shun"); |
| 969 | 976 | }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ |
| 970 | 977 | db_multi_exec("DELETE FROM reportfmt"); |
| 971 | - db_multi_exec(zRepositorySchemaDefaultReports); | |
| 978 | + assert( strchr(zRepositorySchemaDefaultReports,'%')==0 ); | |
| 979 | + db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/); | |
| 972 | 980 | } |
| 973 | 981 | } |
| 974 | 982 | db_end_transaction(0); |
| 975 | 983 | fossil_print("Configuration reset to factory defaults.\n"); |
| 976 | 984 | fossil_print("To recover, use: %s %s import %s\n", |
| 977 | 985 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -194,19 +194,19 @@ | |
| 194 | Blob x; |
| 195 | int i; |
| 196 | const char *zSep = ""; |
| 197 | |
| 198 | blob_zero(&x); |
| 199 | blob_append(&x, "(", 1); |
| 200 | for(i=0; i<count(aConfig); i++){ |
| 201 | if( (aConfig[i].groupMask & iMask)==0 ) continue; |
| 202 | if( aConfig[i].zName[0]=='@' ) continue; |
| 203 | blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName); |
| 204 | zSep = ","; |
| 205 | } |
| 206 | blob_append(&x, ")", 1); |
| 207 | return blob_str(&x); |
| 208 | } |
| 209 | |
| 210 | /* |
| 211 | ** Return the mask for the named configuration parameter if it can be |
| 212 | ** safely exported. Return 0 if the parameter is not safe to export. |
| @@ -361,11 +361,12 @@ | |
| 361 | @ INSERT INTO _xfer_reportfmt |
| 362 | @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt; |
| 363 | @ INSERT INTO _xfer_user |
| 364 | @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user; |
| 365 | ; |
| 366 | db_multi_exec(zSQL1); |
| 367 | |
| 368 | /* When the replace flag is set, add triggers that run the first time |
| 369 | ** that new data is seen. The triggers run only once and delete all the |
| 370 | ** existing data. |
| 371 | */ |
| @@ -390,11 +391,12 @@ | |
| 390 | sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0, |
| 391 | config_is_reset_function, 0, 0); |
| 392 | sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0, |
| 393 | config_reset_function, 0, 0); |
| 394 | configHasBeenReset = 0; |
| 395 | db_multi_exec(zSQL2); |
| 396 | } |
| 397 | } |
| 398 | |
| 399 | /* |
| 400 | ** After receiving configuration data, call this routine to transfer |
| @@ -407,11 +409,12 @@ | |
| 407 | @ DELETE FROM reportfmt; |
| 408 | @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt; |
| 409 | @ DROP TABLE _xfer_user; |
| 410 | @ DROP TABLE _xfer_reportfmt; |
| 411 | ; |
| 412 | db_multi_exec(zSQL); |
| 413 | } |
| 414 | |
| 415 | /* |
| 416 | ** Mask of modified configuration sets |
| 417 | */ |
| @@ -563,35 +566,39 @@ | |
| 563 | if( (thisMask & groupMask)==0 ) return; |
| 564 | |
| 565 | blob_zero(&sql); |
| 566 | if( groupMask & CONFIGSET_OVERWRITE ){ |
| 567 | if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){ |
| 568 | db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]); |
| 569 | configHasBeenReset |= thisMask; |
| 570 | } |
| 571 | blob_append(&sql, "REPLACE INTO ", -1); |
| 572 | }else{ |
| 573 | blob_append(&sql, "INSERT OR IGNORE INTO ", -1); |
| 574 | } |
| 575 | blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey); |
| 576 | for(jj=2; jj<nToken; jj+=2){ |
| 577 | blob_appendf(&sql, ",%s", azToken[jj]); |
| 578 | } |
| 579 | blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]); |
| 580 | for(jj=2; jj<nToken; jj+=2){ |
| 581 | blob_appendf(&sql, ",%s", azToken[jj+1]); |
| 582 | } |
| 583 | db_multi_exec("%s)", blob_str(&sql)); |
| 584 | if( db_changes()==0 ){ |
| 585 | blob_reset(&sql); |
| 586 | blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]); |
| 587 | for(jj=2; jj<nToken; jj+=2){ |
| 588 | blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]); |
| 589 | } |
| 590 | blob_appendf(&sql, " WHERE %s=%s AND mtime<%s", |
| 591 | aType[ii].zPrimKey, azToken[1], azToken[0]); |
| 592 | db_multi_exec("%s", blob_str(&sql)); |
| 593 | } |
| 594 | blob_reset(&sql); |
| 595 | rebuildMask |= thisMask; |
| 596 | }else{ |
| 597 | /* Otherwise, the old format */ |
| @@ -609,11 +616,11 @@ | |
| 609 | /* Notice that we are evaluating arbitrary SQL received from the |
| 610 | ** client. But this can only happen if the client has authenticated |
| 611 | ** as an administrator, so presumably we trust the client at this |
| 612 | ** point. |
| 613 | */ |
| 614 | db_multi_exec("%s", blob_str(pContent)); |
| 615 | }else{ |
| 616 | db_multi_exec( |
| 617 | "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 618 | zName, blob_str(pContent) |
| 619 | ); |
| @@ -966,11 +973,12 @@ | |
| 966 | db_multi_exec("DELETE FROM concealed"); |
| 967 | }else if( fossil_strcmp(zName,"@shun")==0 ){ |
| 968 | db_multi_exec("DELETE FROM shun"); |
| 969 | }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ |
| 970 | db_multi_exec("DELETE FROM reportfmt"); |
| 971 | db_multi_exec(zRepositorySchemaDefaultReports); |
| 972 | } |
| 973 | } |
| 974 | db_end_transaction(0); |
| 975 | fossil_print("Configuration reset to factory defaults.\n"); |
| 976 | fossil_print("To recover, use: %s %s import %s\n", |
| 977 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -194,19 +194,19 @@ | |
| 194 | Blob x; |
| 195 | int i; |
| 196 | const char *zSep = ""; |
| 197 | |
| 198 | blob_zero(&x); |
| 199 | blob_append_sql(&x, "("); |
| 200 | for(i=0; i<count(aConfig); i++){ |
| 201 | if( (aConfig[i].groupMask & iMask)==0 ) continue; |
| 202 | if( aConfig[i].zName[0]=='@' ) continue; |
| 203 | blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName); |
| 204 | zSep = ","; |
| 205 | } |
| 206 | blob_append_sql(&x, ")"); |
| 207 | return blob_sql_text(&x); |
| 208 | } |
| 209 | |
| 210 | /* |
| 211 | ** Return the mask for the named configuration parameter if it can be |
| 212 | ** safely exported. Return 0 if the parameter is not safe to export. |
| @@ -361,11 +361,12 @@ | |
| 361 | @ INSERT INTO _xfer_reportfmt |
| 362 | @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt; |
| 363 | @ INSERT INTO _xfer_user |
| 364 | @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user; |
| 365 | ; |
| 366 | assert( strchr(zSQL1,'%')==0 ); |
| 367 | db_multi_exec(zSQL1 /*works-like:""*/); |
| 368 | |
| 369 | /* When the replace flag is set, add triggers that run the first time |
| 370 | ** that new data is seen. The triggers run only once and delete all the |
| 371 | ** existing data. |
| 372 | */ |
| @@ -390,11 +391,12 @@ | |
| 391 | sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0, |
| 392 | config_is_reset_function, 0, 0); |
| 393 | sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0, |
| 394 | config_reset_function, 0, 0); |
| 395 | configHasBeenReset = 0; |
| 396 | assert( strchr(zSQL2,'%')==0 ); |
| 397 | db_multi_exec(zSQL2 /*works-like:""*/); |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | /* |
| 402 | ** After receiving configuration data, call this routine to transfer |
| @@ -407,11 +409,12 @@ | |
| 409 | @ DELETE FROM reportfmt; |
| 410 | @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt; |
| 411 | @ DROP TABLE _xfer_user; |
| 412 | @ DROP TABLE _xfer_reportfmt; |
| 413 | ; |
| 414 | assert( strchr(zSQL,'%')==0 ); |
| 415 | db_multi_exec(zSQL /*works-like:""*/); |
| 416 | } |
| 417 | |
| 418 | /* |
| 419 | ** Mask of modified configuration sets |
| 420 | */ |
| @@ -563,35 +566,39 @@ | |
| 566 | if( (thisMask & groupMask)==0 ) return; |
| 567 | |
| 568 | blob_zero(&sql); |
| 569 | if( groupMask & CONFIGSET_OVERWRITE ){ |
| 570 | if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){ |
| 571 | db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]); |
| 572 | configHasBeenReset |= thisMask; |
| 573 | } |
| 574 | blob_append_sql(&sql, "REPLACE INTO "); |
| 575 | }else{ |
| 576 | blob_append_sql(&sql, "INSERT OR IGNORE INTO "); |
| 577 | } |
| 578 | blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey); |
| 579 | for(jj=2; jj<nToken; jj+=2){ |
| 580 | blob_append_sql(&sql, ",\"%w\"", azToken[jj]); |
| 581 | } |
| 582 | blob_append_sql(&sql,") VALUES(%s,%s", |
| 583 | azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/); |
| 584 | for(jj=2; jj<nToken; jj+=2){ |
| 585 | blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/); |
| 586 | } |
| 587 | db_multi_exec("%s)", blob_sql_text(&sql)); |
| 588 | if( db_changes()==0 ){ |
| 589 | blob_reset(&sql); |
| 590 | blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s", |
| 591 | &zName[1], azToken[0]/*safe-for-%s*/); |
| 592 | for(jj=2; jj<nToken; jj+=2){ |
| 593 | blob_append_sql(&sql, ", \"%w\"=%s", |
| 594 | azToken[jj], azToken[jj+1]/*safe-for-%s*/); |
| 595 | } |
| 596 | blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s", |
| 597 | aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/, |
| 598 | azToken[0]/*safe-for-%s*/); |
| 599 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 600 | } |
| 601 | blob_reset(&sql); |
| 602 | rebuildMask |= thisMask; |
| 603 | }else{ |
| 604 | /* Otherwise, the old format */ |
| @@ -609,11 +616,11 @@ | |
| 616 | /* Notice that we are evaluating arbitrary SQL received from the |
| 617 | ** client. But this can only happen if the client has authenticated |
| 618 | ** as an administrator, so presumably we trust the client at this |
| 619 | ** point. |
| 620 | */ |
| 621 | db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/); |
| 622 | }else{ |
| 623 | db_multi_exec( |
| 624 | "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 625 | zName, blob_str(pContent) |
| 626 | ); |
| @@ -966,11 +973,12 @@ | |
| 973 | db_multi_exec("DELETE FROM concealed"); |
| 974 | }else if( fossil_strcmp(zName,"@shun")==0 ){ |
| 975 | db_multi_exec("DELETE FROM shun"); |
| 976 | }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ |
| 977 | db_multi_exec("DELETE FROM reportfmt"); |
| 978 | assert( strchr(zRepositorySchemaDefaultReports,'%')==0 ); |
| 979 | db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/); |
| 980 | } |
| 981 | } |
| 982 | db_end_transaction(0); |
| 983 | fossil_print("Configuration reset to factory defaults.\n"); |
| 984 | fossil_print("To recover, use: %s %s import %s\n", |
| 985 |
+2
-2
| --- src/content.c | ||
| +++ src/content.c | ||
| @@ -558,12 +558,12 @@ | ||
| 558 | 558 | } |
| 559 | 559 | }else{ |
| 560 | 560 | /* We are creating a new entry */ |
| 561 | 561 | db_prepare(&s1, |
| 562 | 562 | "INSERT INTO blob(rcvid,size,uuid,content)" |
| 563 | - "VALUES(%d,%d,'%b',:data)", | |
| 564 | - g.rcvid, size, &hash | |
| 563 | + "VALUES(%d,%d,'%q',:data)", | |
| 564 | + g.rcvid, size, blob_str(&hash) | |
| 565 | 565 | ); |
| 566 | 566 | db_bind_blob(&s1, ":data", &cmpr); |
| 567 | 567 | db_exec(&s1); |
| 568 | 568 | rid = db_last_insert_rowid(); |
| 569 | 569 | if( !pBlob ){ |
| 570 | 570 |
| --- src/content.c | |
| +++ src/content.c | |
| @@ -558,12 +558,12 @@ | |
| 558 | } |
| 559 | }else{ |
| 560 | /* We are creating a new entry */ |
| 561 | db_prepare(&s1, |
| 562 | "INSERT INTO blob(rcvid,size,uuid,content)" |
| 563 | "VALUES(%d,%d,'%b',:data)", |
| 564 | g.rcvid, size, &hash |
| 565 | ); |
| 566 | db_bind_blob(&s1, ":data", &cmpr); |
| 567 | db_exec(&s1); |
| 568 | rid = db_last_insert_rowid(); |
| 569 | if( !pBlob ){ |
| 570 |
| --- src/content.c | |
| +++ src/content.c | |
| @@ -558,12 +558,12 @@ | |
| 558 | } |
| 559 | }else{ |
| 560 | /* We are creating a new entry */ |
| 561 | db_prepare(&s1, |
| 562 | "INSERT INTO blob(rcvid,size,uuid,content)" |
| 563 | "VALUES(%d,%d,'%q',:data)", |
| 564 | g.rcvid, size, blob_str(&hash) |
| 565 | ); |
| 566 | db_bind_blob(&s1, ":data", &cmpr); |
| 567 | db_exec(&s1); |
| 568 | rid = db_last_insert_rowid(); |
| 569 | if( !pBlob ){ |
| 570 |
M
src/db.c
+32
-33
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -177,11 +177,11 @@ | ||
| 177 | 177 | db.doRollback |= db.aHook[i].xHook(); |
| 178 | 178 | } |
| 179 | 179 | while( db.pAllStmt ){ |
| 180 | 180 | db_finalize(db.pAllStmt); |
| 181 | 181 | } |
| 182 | - db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT"); | |
| 182 | + db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); | |
| 183 | 183 | db.doRollback = 0; |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | /* |
| @@ -664,17 +664,17 @@ | ||
| 664 | 664 | |
| 665 | 665 | db = db_open(zFileName); |
| 666 | 666 | sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0); |
| 667 | 667 | rc = sqlite3_exec(db, zSchema, 0, 0, 0); |
| 668 | 668 | if( rc!=SQLITE_OK ){ |
| 669 | - db_err(sqlite3_errmsg(db)); | |
| 669 | + db_err("%s", sqlite3_errmsg(db)); | |
| 670 | 670 | } |
| 671 | 671 | va_start(ap, zSchema); |
| 672 | 672 | while( (zSql = va_arg(ap, const char*))!=0 ){ |
| 673 | 673 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 674 | 674 | if( rc!=SQLITE_OK ){ |
| 675 | - db_err(sqlite3_errmsg(db)); | |
| 675 | + db_err("%s", sqlite3_errmsg(db)); | |
| 676 | 676 | } |
| 677 | 677 | } |
| 678 | 678 | va_end(ap); |
| 679 | 679 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 680 | 680 | sqlite3_close(db); |
| @@ -750,19 +750,19 @@ | ||
| 750 | 750 | |
| 751 | 751 | /* |
| 752 | 752 | ** Detaches the zLabel database. |
| 753 | 753 | */ |
| 754 | 754 | void db_detach(const char *zLabel){ |
| 755 | - db_multi_exec("DETACH DATABASE %s", zLabel); | |
| 755 | + db_multi_exec("DETACH DATABASE %Q", zLabel); | |
| 756 | 756 | } |
| 757 | 757 | |
| 758 | 758 | /* |
| 759 | 759 | ** zDbName is the name of a database file. Attach zDbName using |
| 760 | 760 | ** the name zLabel. |
| 761 | 761 | */ |
| 762 | 762 | void db_attach(const char *zDbName, const char *zLabel){ |
| 763 | - db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); | |
| 763 | + db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel); | |
| 764 | 764 | } |
| 765 | 765 | |
| 766 | 766 | /* |
| 767 | 767 | ** zDbName is the name of a database file. If no other database |
| 768 | 768 | ** file is open, then open this one. If another database file is |
| @@ -887,16 +887,16 @@ | ||
| 887 | 887 | static int db_local_table_exists_but_lacks_column( |
| 888 | 888 | const char *zTable, |
| 889 | 889 | const char *zColumn |
| 890 | 890 | ){ |
| 891 | 891 | char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master" |
| 892 | - " WHERE name=='%s' /*scan*/", | |
| 892 | + " WHERE name==%Q /*scan*/", | |
| 893 | 893 | db_name("localdb"), zTable); |
| 894 | 894 | int rc = 0; |
| 895 | 895 | if( zDef ){ |
| 896 | 896 | char *zPattern = mprintf("* %s *", zColumn); |
| 897 | - rc = strglob(zPattern, zDef)==0; | |
| 897 | + rc = sqlite3_strglob(zPattern, zDef)!=0; | |
| 898 | 898 | fossil_free(zPattern); |
| 899 | 899 | fossil_free(zDef); |
| 900 | 900 | } |
| 901 | 901 | return rc; |
| 902 | 902 | } |
| @@ -919,19 +919,19 @@ | ||
| 919 | 919 | |
| 920 | 920 | /* If the "isexe" column is missing from the vfile table, then |
| 921 | 921 | ** add it now. This code added on 2010-03-06. After all users have |
| 922 | 922 | ** upgraded, this code can be safely deleted. |
| 923 | 923 | */ |
| 924 | - if( !strglob("* isexe *", zVFileDef) ){ | |
| 924 | + if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){ | |
| 925 | 925 | db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0"); |
| 926 | 926 | } |
| 927 | 927 | |
| 928 | 928 | /* If "islink"/"isLink" columns are missing from tables, then |
| 929 | 929 | ** add them now. This code added on 2011-01-17 and 2011-08-27. |
| 930 | 930 | ** After all users have upgraded, this code can be safely deleted. |
| 931 | 931 | */ |
| 932 | - if( !strglob("* islink *", zVFileDef) ){ | |
| 932 | + if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){ | |
| 933 | 933 | db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0"); |
| 934 | 934 | if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){ |
| 935 | 935 | db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0"); |
| 936 | 936 | } |
| 937 | 937 | if( db_local_table_exists_but_lacks_column("undo", "isLink") ){ |
| @@ -1119,11 +1119,11 @@ | ||
| 1119 | 1119 | ** Return TRUE if the schema is out-of-date |
| 1120 | 1120 | */ |
| 1121 | 1121 | int db_schema_is_outofdate(void){ |
| 1122 | 1122 | return db_exists("SELECT 1 FROM config" |
| 1123 | 1123 | " WHERE name='aux-schema'" |
| 1124 | - " AND value<>'%s'", AUX_SCHEMA); | |
| 1124 | + " AND value<>%Q", AUX_SCHEMA); | |
| 1125 | 1125 | } |
| 1126 | 1126 | |
| 1127 | 1127 | /* |
| 1128 | 1128 | ** Return true if the database is writeable |
| 1129 | 1129 | */ |
| @@ -1349,17 +1349,17 @@ | ||
| 1349 | 1349 | Blob x; |
| 1350 | 1350 | int i; |
| 1351 | 1351 | const char *zSep = ""; |
| 1352 | 1352 | |
| 1353 | 1353 | blob_zero(&x); |
| 1354 | - blob_append(&x, "(", 1); | |
| 1354 | + blob_append_sql(&x, "("); | |
| 1355 | 1355 | for(i=0; ctrlSettings[i].name; i++){ |
| 1356 | - blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name); | |
| 1356 | + blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name); | |
| 1357 | 1357 | zSep = ","; |
| 1358 | 1358 | } |
| 1359 | - blob_append(&x, ")", 1); | |
| 1360 | - return blob_str(&x); | |
| 1359 | + blob_append_sql(&x, ")"); | |
| 1360 | + return blob_sql_text(&x); | |
| 1361 | 1361 | } |
| 1362 | 1362 | |
| 1363 | 1363 | /* |
| 1364 | 1364 | ** Fill an empty repository database with the basic information for a |
| 1365 | 1365 | ** repository. This function is shared between 'create_repository_cmd' |
| @@ -1997,53 +1997,52 @@ | ||
| 1997 | 1997 | ** ckout:%s |
| 1998 | 1998 | ** |
| 1999 | 1999 | ** Where %s is the checkout root. The value is the repository file. |
| 2000 | 2000 | */ |
| 2001 | 2001 | void db_record_repository_filename(const char *zName){ |
| 2002 | - const char *zCollation; | |
| 2003 | 2002 | char *zRepoSetting; |
| 2004 | 2003 | char *zCkoutSetting; |
| 2005 | 2004 | Blob full; |
| 2006 | 2005 | if( zName==0 ){ |
| 2007 | 2006 | if( !g.localOpen ) return; |
| 2008 | 2007 | zName = db_repository_filename(); |
| 2009 | 2008 | } |
| 2010 | 2009 | file_canonical_name(zName, &full, 0); |
| 2011 | - zCollation = filename_collation(); | |
| 2010 | + (void)filename_collation(); /* Initialize before connection swap */ | |
| 2012 | 2011 | db_swap_connections(); |
| 2013 | 2012 | zRepoSetting = mprintf("repo:%q", blob_str(&full)); |
| 2014 | 2013 | db_multi_exec( |
| 2015 | - "DELETE FROM global_config WHERE name %s = '%s';", | |
| 2016 | - zCollation, zRepoSetting | |
| 2014 | + "DELETE FROM global_config WHERE name %s = %Q;", | |
| 2015 | + filename_collation(), zRepoSetting | |
| 2017 | 2016 | ); |
| 2018 | 2017 | db_multi_exec( |
| 2019 | 2018 | "INSERT OR IGNORE INTO global_config(name,value)" |
| 2020 | - "VALUES('%s',1);", | |
| 2019 | + "VALUES(%Q,1);", | |
| 2021 | 2020 | zRepoSetting |
| 2022 | 2021 | ); |
| 2023 | 2022 | fossil_free(zRepoSetting); |
| 2024 | 2023 | if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){ |
| 2025 | 2024 | Blob localRoot; |
| 2026 | 2025 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 2027 | 2026 | zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot)); |
| 2028 | 2027 | db_multi_exec( |
| 2029 | - "DELETE FROM global_config WHERE name %s = '%s';", | |
| 2030 | - zCollation, zCkoutSetting | |
| 2028 | + "DELETE FROM global_config WHERE name %s = %Q;", | |
| 2029 | + filename_collation(), zCkoutSetting | |
| 2031 | 2030 | ); |
| 2032 | 2031 | db_multi_exec( |
| 2033 | 2032 | "REPLACE INTO global_config(name, value)" |
| 2034 | - "VALUES('%s','%q');", | |
| 2033 | + "VALUES(%Q,%Q);", | |
| 2035 | 2034 | zCkoutSetting, blob_str(&full) |
| 2036 | 2035 | ); |
| 2037 | 2036 | db_swap_connections(); |
| 2038 | 2037 | db_optional_sql("repository", |
| 2039 | - "DELETE FROM config WHERE name %s = '%s';", | |
| 2040 | - zCollation, zCkoutSetting | |
| 2038 | + "DELETE FROM config WHERE name %s = %Q;", | |
| 2039 | + filename_collation(), zCkoutSetting | |
| 2041 | 2040 | ); |
| 2042 | 2041 | db_optional_sql("repository", |
| 2043 | 2042 | "REPLACE INTO config(name,value,mtime)" |
| 2044 | - "VALUES('%s',1,now());", | |
| 2043 | + "VALUES(%Q,1,now());", | |
| 2045 | 2044 | zCkoutSetting |
| 2046 | 2045 | ); |
| 2047 | 2046 | fossil_free(zCkoutSetting); |
| 2048 | 2047 | blob_reset(&localRoot); |
| 2049 | 2048 | }else{ |
| @@ -2648,28 +2647,28 @@ | ||
| 2648 | 2647 | zOrigSql += j+6; |
| 2649 | 2648 | j = -1; |
| 2650 | 2649 | } |
| 2651 | 2650 | } |
| 2652 | 2651 | blob_append(&newSql, zOrigSql, -1); |
| 2653 | - blob_appendf(&allSql, | |
| 2654 | - "ALTER TABLE %s RENAME TO x_%s;\n" | |
| 2652 | + blob_append_sql(&allSql, | |
| 2653 | + "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n" | |
| 2655 | 2654 | "%s WITHOUT ROWID;\n" |
| 2656 | - "INSERT INTO %s SELECT * FROM x_%s;\n" | |
| 2657 | - "DROP TABLE x_%s;\n", | |
| 2658 | - zTName, zTName, blob_str(&newSql), zTName, zTName, zTName | |
| 2655 | + "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n" | |
| 2656 | + "DROP TABLE \"x_%w\";\n", | |
| 2657 | + zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName | |
| 2659 | 2658 | ); |
| 2660 | 2659 | fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]); |
| 2661 | 2660 | blob_reset(&newSql); |
| 2662 | 2661 | } |
| 2663 | - blob_appendf(&allSql, "COMMIT;\n"); | |
| 2662 | + blob_append_sql(&allSql, "COMMIT;\n"); | |
| 2664 | 2663 | db_finalize(&q); |
| 2665 | 2664 | if( dryRun ){ |
| 2666 | 2665 | fossil_print("SQL that would have been evaluated:\n"); |
| 2667 | 2666 | fossil_print("-------------------------------------------------------------\n"); |
| 2668 | - fossil_print("%s", blob_str(&allSql)); | |
| 2667 | + fossil_print("%s", blob_sql_text(&allSql)); | |
| 2669 | 2668 | }else{ |
| 2670 | - db_multi_exec("%s", blob_str(&allSql)); | |
| 2669 | + db_multi_exec("%s", blob_sql_text(&allSql)); | |
| 2671 | 2670 | } |
| 2672 | 2671 | blob_reset(&allSql); |
| 2673 | 2672 | db_close(1); |
| 2674 | 2673 | } |
| 2675 | 2674 | } |
| 2676 | 2675 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -177,11 +177,11 @@ | |
| 177 | db.doRollback |= db.aHook[i].xHook(); |
| 178 | } |
| 179 | while( db.pAllStmt ){ |
| 180 | db_finalize(db.pAllStmt); |
| 181 | } |
| 182 | db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 183 | db.doRollback = 0; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /* |
| @@ -664,17 +664,17 @@ | |
| 664 | |
| 665 | db = db_open(zFileName); |
| 666 | sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0); |
| 667 | rc = sqlite3_exec(db, zSchema, 0, 0, 0); |
| 668 | if( rc!=SQLITE_OK ){ |
| 669 | db_err(sqlite3_errmsg(db)); |
| 670 | } |
| 671 | va_start(ap, zSchema); |
| 672 | while( (zSql = va_arg(ap, const char*))!=0 ){ |
| 673 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 674 | if( rc!=SQLITE_OK ){ |
| 675 | db_err(sqlite3_errmsg(db)); |
| 676 | } |
| 677 | } |
| 678 | va_end(ap); |
| 679 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 680 | sqlite3_close(db); |
| @@ -750,19 +750,19 @@ | |
| 750 | |
| 751 | /* |
| 752 | ** Detaches the zLabel database. |
| 753 | */ |
| 754 | void db_detach(const char *zLabel){ |
| 755 | db_multi_exec("DETACH DATABASE %s", zLabel); |
| 756 | } |
| 757 | |
| 758 | /* |
| 759 | ** zDbName is the name of a database file. Attach zDbName using |
| 760 | ** the name zLabel. |
| 761 | */ |
| 762 | void db_attach(const char *zDbName, const char *zLabel){ |
| 763 | db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); |
| 764 | } |
| 765 | |
| 766 | /* |
| 767 | ** zDbName is the name of a database file. If no other database |
| 768 | ** file is open, then open this one. If another database file is |
| @@ -887,16 +887,16 @@ | |
| 887 | static int db_local_table_exists_but_lacks_column( |
| 888 | const char *zTable, |
| 889 | const char *zColumn |
| 890 | ){ |
| 891 | char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master" |
| 892 | " WHERE name=='%s' /*scan*/", |
| 893 | db_name("localdb"), zTable); |
| 894 | int rc = 0; |
| 895 | if( zDef ){ |
| 896 | char *zPattern = mprintf("* %s *", zColumn); |
| 897 | rc = strglob(zPattern, zDef)==0; |
| 898 | fossil_free(zPattern); |
| 899 | fossil_free(zDef); |
| 900 | } |
| 901 | return rc; |
| 902 | } |
| @@ -919,19 +919,19 @@ | |
| 919 | |
| 920 | /* If the "isexe" column is missing from the vfile table, then |
| 921 | ** add it now. This code added on 2010-03-06. After all users have |
| 922 | ** upgraded, this code can be safely deleted. |
| 923 | */ |
| 924 | if( !strglob("* isexe *", zVFileDef) ){ |
| 925 | db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0"); |
| 926 | } |
| 927 | |
| 928 | /* If "islink"/"isLink" columns are missing from tables, then |
| 929 | ** add them now. This code added on 2011-01-17 and 2011-08-27. |
| 930 | ** After all users have upgraded, this code can be safely deleted. |
| 931 | */ |
| 932 | if( !strglob("* islink *", zVFileDef) ){ |
| 933 | db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0"); |
| 934 | if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){ |
| 935 | db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0"); |
| 936 | } |
| 937 | if( db_local_table_exists_but_lacks_column("undo", "isLink") ){ |
| @@ -1119,11 +1119,11 @@ | |
| 1119 | ** Return TRUE if the schema is out-of-date |
| 1120 | */ |
| 1121 | int db_schema_is_outofdate(void){ |
| 1122 | return db_exists("SELECT 1 FROM config" |
| 1123 | " WHERE name='aux-schema'" |
| 1124 | " AND value<>'%s'", AUX_SCHEMA); |
| 1125 | } |
| 1126 | |
| 1127 | /* |
| 1128 | ** Return true if the database is writeable |
| 1129 | */ |
| @@ -1349,17 +1349,17 @@ | |
| 1349 | Blob x; |
| 1350 | int i; |
| 1351 | const char *zSep = ""; |
| 1352 | |
| 1353 | blob_zero(&x); |
| 1354 | blob_append(&x, "(", 1); |
| 1355 | for(i=0; ctrlSettings[i].name; i++){ |
| 1356 | blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name); |
| 1357 | zSep = ","; |
| 1358 | } |
| 1359 | blob_append(&x, ")", 1); |
| 1360 | return blob_str(&x); |
| 1361 | } |
| 1362 | |
| 1363 | /* |
| 1364 | ** Fill an empty repository database with the basic information for a |
| 1365 | ** repository. This function is shared between 'create_repository_cmd' |
| @@ -1997,53 +1997,52 @@ | |
| 1997 | ** ckout:%s |
| 1998 | ** |
| 1999 | ** Where %s is the checkout root. The value is the repository file. |
| 2000 | */ |
| 2001 | void db_record_repository_filename(const char *zName){ |
| 2002 | const char *zCollation; |
| 2003 | char *zRepoSetting; |
| 2004 | char *zCkoutSetting; |
| 2005 | Blob full; |
| 2006 | if( zName==0 ){ |
| 2007 | if( !g.localOpen ) return; |
| 2008 | zName = db_repository_filename(); |
| 2009 | } |
| 2010 | file_canonical_name(zName, &full, 0); |
| 2011 | zCollation = filename_collation(); |
| 2012 | db_swap_connections(); |
| 2013 | zRepoSetting = mprintf("repo:%q", blob_str(&full)); |
| 2014 | db_multi_exec( |
| 2015 | "DELETE FROM global_config WHERE name %s = '%s';", |
| 2016 | zCollation, zRepoSetting |
| 2017 | ); |
| 2018 | db_multi_exec( |
| 2019 | "INSERT OR IGNORE INTO global_config(name,value)" |
| 2020 | "VALUES('%s',1);", |
| 2021 | zRepoSetting |
| 2022 | ); |
| 2023 | fossil_free(zRepoSetting); |
| 2024 | if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){ |
| 2025 | Blob localRoot; |
| 2026 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 2027 | zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot)); |
| 2028 | db_multi_exec( |
| 2029 | "DELETE FROM global_config WHERE name %s = '%s';", |
| 2030 | zCollation, zCkoutSetting |
| 2031 | ); |
| 2032 | db_multi_exec( |
| 2033 | "REPLACE INTO global_config(name, value)" |
| 2034 | "VALUES('%s','%q');", |
| 2035 | zCkoutSetting, blob_str(&full) |
| 2036 | ); |
| 2037 | db_swap_connections(); |
| 2038 | db_optional_sql("repository", |
| 2039 | "DELETE FROM config WHERE name %s = '%s';", |
| 2040 | zCollation, zCkoutSetting |
| 2041 | ); |
| 2042 | db_optional_sql("repository", |
| 2043 | "REPLACE INTO config(name,value,mtime)" |
| 2044 | "VALUES('%s',1,now());", |
| 2045 | zCkoutSetting |
| 2046 | ); |
| 2047 | fossil_free(zCkoutSetting); |
| 2048 | blob_reset(&localRoot); |
| 2049 | }else{ |
| @@ -2648,28 +2647,28 @@ | |
| 2648 | zOrigSql += j+6; |
| 2649 | j = -1; |
| 2650 | } |
| 2651 | } |
| 2652 | blob_append(&newSql, zOrigSql, -1); |
| 2653 | blob_appendf(&allSql, |
| 2654 | "ALTER TABLE %s RENAME TO x_%s;\n" |
| 2655 | "%s WITHOUT ROWID;\n" |
| 2656 | "INSERT INTO %s SELECT * FROM x_%s;\n" |
| 2657 | "DROP TABLE x_%s;\n", |
| 2658 | zTName, zTName, blob_str(&newSql), zTName, zTName, zTName |
| 2659 | ); |
| 2660 | fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]); |
| 2661 | blob_reset(&newSql); |
| 2662 | } |
| 2663 | blob_appendf(&allSql, "COMMIT;\n"); |
| 2664 | db_finalize(&q); |
| 2665 | if( dryRun ){ |
| 2666 | fossil_print("SQL that would have been evaluated:\n"); |
| 2667 | fossil_print("-------------------------------------------------------------\n"); |
| 2668 | fossil_print("%s", blob_str(&allSql)); |
| 2669 | }else{ |
| 2670 | db_multi_exec("%s", blob_str(&allSql)); |
| 2671 | } |
| 2672 | blob_reset(&allSql); |
| 2673 | db_close(1); |
| 2674 | } |
| 2675 | } |
| 2676 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -177,11 +177,11 @@ | |
| 177 | db.doRollback |= db.aHook[i].xHook(); |
| 178 | } |
| 179 | while( db.pAllStmt ){ |
| 180 | db_finalize(db.pAllStmt); |
| 181 | } |
| 182 | db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 183 | db.doRollback = 0; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /* |
| @@ -664,17 +664,17 @@ | |
| 664 | |
| 665 | db = db_open(zFileName); |
| 666 | sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0); |
| 667 | rc = sqlite3_exec(db, zSchema, 0, 0, 0); |
| 668 | if( rc!=SQLITE_OK ){ |
| 669 | db_err("%s", sqlite3_errmsg(db)); |
| 670 | } |
| 671 | va_start(ap, zSchema); |
| 672 | while( (zSql = va_arg(ap, const char*))!=0 ){ |
| 673 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 674 | if( rc!=SQLITE_OK ){ |
| 675 | db_err("%s", sqlite3_errmsg(db)); |
| 676 | } |
| 677 | } |
| 678 | va_end(ap); |
| 679 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 680 | sqlite3_close(db); |
| @@ -750,19 +750,19 @@ | |
| 750 | |
| 751 | /* |
| 752 | ** Detaches the zLabel database. |
| 753 | */ |
| 754 | void db_detach(const char *zLabel){ |
| 755 | db_multi_exec("DETACH DATABASE %Q", zLabel); |
| 756 | } |
| 757 | |
| 758 | /* |
| 759 | ** zDbName is the name of a database file. Attach zDbName using |
| 760 | ** the name zLabel. |
| 761 | */ |
| 762 | void db_attach(const char *zDbName, const char *zLabel){ |
| 763 | db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel); |
| 764 | } |
| 765 | |
| 766 | /* |
| 767 | ** zDbName is the name of a database file. If no other database |
| 768 | ** file is open, then open this one. If another database file is |
| @@ -887,16 +887,16 @@ | |
| 887 | static int db_local_table_exists_but_lacks_column( |
| 888 | const char *zTable, |
| 889 | const char *zColumn |
| 890 | ){ |
| 891 | char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master" |
| 892 | " WHERE name==%Q /*scan*/", |
| 893 | db_name("localdb"), zTable); |
| 894 | int rc = 0; |
| 895 | if( zDef ){ |
| 896 | char *zPattern = mprintf("* %s *", zColumn); |
| 897 | rc = sqlite3_strglob(zPattern, zDef)!=0; |
| 898 | fossil_free(zPattern); |
| 899 | fossil_free(zDef); |
| 900 | } |
| 901 | return rc; |
| 902 | } |
| @@ -919,19 +919,19 @@ | |
| 919 | |
| 920 | /* If the "isexe" column is missing from the vfile table, then |
| 921 | ** add it now. This code added on 2010-03-06. After all users have |
| 922 | ** upgraded, this code can be safely deleted. |
| 923 | */ |
| 924 | if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){ |
| 925 | db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0"); |
| 926 | } |
| 927 | |
| 928 | /* If "islink"/"isLink" columns are missing from tables, then |
| 929 | ** add them now. This code added on 2011-01-17 and 2011-08-27. |
| 930 | ** After all users have upgraded, this code can be safely deleted. |
| 931 | */ |
| 932 | if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){ |
| 933 | db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0"); |
| 934 | if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){ |
| 935 | db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0"); |
| 936 | } |
| 937 | if( db_local_table_exists_but_lacks_column("undo", "isLink") ){ |
| @@ -1119,11 +1119,11 @@ | |
| 1119 | ** Return TRUE if the schema is out-of-date |
| 1120 | */ |
| 1121 | int db_schema_is_outofdate(void){ |
| 1122 | return db_exists("SELECT 1 FROM config" |
| 1123 | " WHERE name='aux-schema'" |
| 1124 | " AND value<>%Q", AUX_SCHEMA); |
| 1125 | } |
| 1126 | |
| 1127 | /* |
| 1128 | ** Return true if the database is writeable |
| 1129 | */ |
| @@ -1349,17 +1349,17 @@ | |
| 1349 | Blob x; |
| 1350 | int i; |
| 1351 | const char *zSep = ""; |
| 1352 | |
| 1353 | blob_zero(&x); |
| 1354 | blob_append_sql(&x, "("); |
| 1355 | for(i=0; ctrlSettings[i].name; i++){ |
| 1356 | blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name); |
| 1357 | zSep = ","; |
| 1358 | } |
| 1359 | blob_append_sql(&x, ")"); |
| 1360 | return blob_sql_text(&x); |
| 1361 | } |
| 1362 | |
| 1363 | /* |
| 1364 | ** Fill an empty repository database with the basic information for a |
| 1365 | ** repository. This function is shared between 'create_repository_cmd' |
| @@ -1997,53 +1997,52 @@ | |
| 1997 | ** ckout:%s |
| 1998 | ** |
| 1999 | ** Where %s is the checkout root. The value is the repository file. |
| 2000 | */ |
| 2001 | void db_record_repository_filename(const char *zName){ |
| 2002 | char *zRepoSetting; |
| 2003 | char *zCkoutSetting; |
| 2004 | Blob full; |
| 2005 | if( zName==0 ){ |
| 2006 | if( !g.localOpen ) return; |
| 2007 | zName = db_repository_filename(); |
| 2008 | } |
| 2009 | file_canonical_name(zName, &full, 0); |
| 2010 | (void)filename_collation(); /* Initialize before connection swap */ |
| 2011 | db_swap_connections(); |
| 2012 | zRepoSetting = mprintf("repo:%q", blob_str(&full)); |
| 2013 | db_multi_exec( |
| 2014 | "DELETE FROM global_config WHERE name %s = %Q;", |
| 2015 | filename_collation(), zRepoSetting |
| 2016 | ); |
| 2017 | db_multi_exec( |
| 2018 | "INSERT OR IGNORE INTO global_config(name,value)" |
| 2019 | "VALUES(%Q,1);", |
| 2020 | zRepoSetting |
| 2021 | ); |
| 2022 | fossil_free(zRepoSetting); |
| 2023 | if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){ |
| 2024 | Blob localRoot; |
| 2025 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 2026 | zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot)); |
| 2027 | db_multi_exec( |
| 2028 | "DELETE FROM global_config WHERE name %s = %Q;", |
| 2029 | filename_collation(), zCkoutSetting |
| 2030 | ); |
| 2031 | db_multi_exec( |
| 2032 | "REPLACE INTO global_config(name, value)" |
| 2033 | "VALUES(%Q,%Q);", |
| 2034 | zCkoutSetting, blob_str(&full) |
| 2035 | ); |
| 2036 | db_swap_connections(); |
| 2037 | db_optional_sql("repository", |
| 2038 | "DELETE FROM config WHERE name %s = %Q;", |
| 2039 | filename_collation(), zCkoutSetting |
| 2040 | ); |
| 2041 | db_optional_sql("repository", |
| 2042 | "REPLACE INTO config(name,value,mtime)" |
| 2043 | "VALUES(%Q,1,now());", |
| 2044 | zCkoutSetting |
| 2045 | ); |
| 2046 | fossil_free(zCkoutSetting); |
| 2047 | blob_reset(&localRoot); |
| 2048 | }else{ |
| @@ -2648,28 +2647,28 @@ | |
| 2647 | zOrigSql += j+6; |
| 2648 | j = -1; |
| 2649 | } |
| 2650 | } |
| 2651 | blob_append(&newSql, zOrigSql, -1); |
| 2652 | blob_append_sql(&allSql, |
| 2653 | "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n" |
| 2654 | "%s WITHOUT ROWID;\n" |
| 2655 | "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n" |
| 2656 | "DROP TABLE \"x_%w\";\n", |
| 2657 | zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName |
| 2658 | ); |
| 2659 | fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]); |
| 2660 | blob_reset(&newSql); |
| 2661 | } |
| 2662 | blob_append_sql(&allSql, "COMMIT;\n"); |
| 2663 | db_finalize(&q); |
| 2664 | if( dryRun ){ |
| 2665 | fossil_print("SQL that would have been evaluated:\n"); |
| 2666 | fossil_print("-------------------------------------------------------------\n"); |
| 2667 | fossil_print("%s", blob_sql_text(&allSql)); |
| 2668 | }else{ |
| 2669 | db_multi_exec("%s", blob_sql_text(&allSql)); |
| 2670 | } |
| 2671 | blob_reset(&allSql); |
| 2672 | db_close(1); |
| 2673 | } |
| 2674 | } |
| 2675 |
M
src/db.c
+32
-33
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -177,11 +177,11 @@ | ||
| 177 | 177 | db.doRollback |= db.aHook[i].xHook(); |
| 178 | 178 | } |
| 179 | 179 | while( db.pAllStmt ){ |
| 180 | 180 | db_finalize(db.pAllStmt); |
| 181 | 181 | } |
| 182 | - db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT"); | |
| 182 | + db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); | |
| 183 | 183 | db.doRollback = 0; |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | /* |
| @@ -664,17 +664,17 @@ | ||
| 664 | 664 | |
| 665 | 665 | db = db_open(zFileName); |
| 666 | 666 | sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0); |
| 667 | 667 | rc = sqlite3_exec(db, zSchema, 0, 0, 0); |
| 668 | 668 | if( rc!=SQLITE_OK ){ |
| 669 | - db_err(sqlite3_errmsg(db)); | |
| 669 | + db_err("%s", sqlite3_errmsg(db)); | |
| 670 | 670 | } |
| 671 | 671 | va_start(ap, zSchema); |
| 672 | 672 | while( (zSql = va_arg(ap, const char*))!=0 ){ |
| 673 | 673 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 674 | 674 | if( rc!=SQLITE_OK ){ |
| 675 | - db_err(sqlite3_errmsg(db)); | |
| 675 | + db_err("%s", sqlite3_errmsg(db)); | |
| 676 | 676 | } |
| 677 | 677 | } |
| 678 | 678 | va_end(ap); |
| 679 | 679 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 680 | 680 | sqlite3_close(db); |
| @@ -750,19 +750,19 @@ | ||
| 750 | 750 | |
| 751 | 751 | /* |
| 752 | 752 | ** Detaches the zLabel database. |
| 753 | 753 | */ |
| 754 | 754 | void db_detach(const char *zLabel){ |
| 755 | - db_multi_exec("DETACH DATABASE %s", zLabel); | |
| 755 | + db_multi_exec("DETACH DATABASE %Q", zLabel); | |
| 756 | 756 | } |
| 757 | 757 | |
| 758 | 758 | /* |
| 759 | 759 | ** zDbName is the name of a database file. Attach zDbName using |
| 760 | 760 | ** the name zLabel. |
| 761 | 761 | */ |
| 762 | 762 | void db_attach(const char *zDbName, const char *zLabel){ |
| 763 | - db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); | |
| 763 | + db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel); | |
| 764 | 764 | } |
| 765 | 765 | |
| 766 | 766 | /* |
| 767 | 767 | ** zDbName is the name of a database file. If no other database |
| 768 | 768 | ** file is open, then open this one. If another database file is |
| @@ -887,16 +887,16 @@ | ||
| 887 | 887 | static int db_local_table_exists_but_lacks_column( |
| 888 | 888 | const char *zTable, |
| 889 | 889 | const char *zColumn |
| 890 | 890 | ){ |
| 891 | 891 | char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master" |
| 892 | - " WHERE name=='%s' /*scan*/", | |
| 892 | + " WHERE name==%Q /*scan*/", | |
| 893 | 893 | db_name("localdb"), zTable); |
| 894 | 894 | int rc = 0; |
| 895 | 895 | if( zDef ){ |
| 896 | 896 | char *zPattern = mprintf("* %s *", zColumn); |
| 897 | - rc = strglob(zPattern, zDef)==0; | |
| 897 | + rc = sqlite3_strglob(zPattern, zDef)!=0; | |
| 898 | 898 | fossil_free(zPattern); |
| 899 | 899 | fossil_free(zDef); |
| 900 | 900 | } |
| 901 | 901 | return rc; |
| 902 | 902 | } |
| @@ -919,19 +919,19 @@ | ||
| 919 | 919 | |
| 920 | 920 | /* If the "isexe" column is missing from the vfile table, then |
| 921 | 921 | ** add it now. This code added on 2010-03-06. After all users have |
| 922 | 922 | ** upgraded, this code can be safely deleted. |
| 923 | 923 | */ |
| 924 | - if( !strglob("* isexe *", zVFileDef) ){ | |
| 924 | + if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){ | |
| 925 | 925 | db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0"); |
| 926 | 926 | } |
| 927 | 927 | |
| 928 | 928 | /* If "islink"/"isLink" columns are missing from tables, then |
| 929 | 929 | ** add them now. This code added on 2011-01-17 and 2011-08-27. |
| 930 | 930 | ** After all users have upgraded, this code can be safely deleted. |
| 931 | 931 | */ |
| 932 | - if( !strglob("* islink *", zVFileDef) ){ | |
| 932 | + if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){ | |
| 933 | 933 | db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0"); |
| 934 | 934 | if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){ |
| 935 | 935 | db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0"); |
| 936 | 936 | } |
| 937 | 937 | if( db_local_table_exists_but_lacks_column("undo", "isLink") ){ |
| @@ -1119,11 +1119,11 @@ | ||
| 1119 | 1119 | ** Return TRUE if the schema is out-of-date |
| 1120 | 1120 | */ |
| 1121 | 1121 | int db_schema_is_outofdate(void){ |
| 1122 | 1122 | return db_exists("SELECT 1 FROM config" |
| 1123 | 1123 | " WHERE name='aux-schema'" |
| 1124 | - " AND value<>'%s'", AUX_SCHEMA); | |
| 1124 | + " AND value<>%Q", AUX_SCHEMA); | |
| 1125 | 1125 | } |
| 1126 | 1126 | |
| 1127 | 1127 | /* |
| 1128 | 1128 | ** Return true if the database is writeable |
| 1129 | 1129 | */ |
| @@ -1349,17 +1349,17 @@ | ||
| 1349 | 1349 | Blob x; |
| 1350 | 1350 | int i; |
| 1351 | 1351 | const char *zSep = ""; |
| 1352 | 1352 | |
| 1353 | 1353 | blob_zero(&x); |
| 1354 | - blob_append(&x, "(", 1); | |
| 1354 | + blob_append_sql(&x, "("); | |
| 1355 | 1355 | for(i=0; ctrlSettings[i].name; i++){ |
| 1356 | - blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name); | |
| 1356 | + blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name); | |
| 1357 | 1357 | zSep = ","; |
| 1358 | 1358 | } |
| 1359 | - blob_append(&x, ")", 1); | |
| 1360 | - return blob_str(&x); | |
| 1359 | + blob_append_sql(&x, ")"); | |
| 1360 | + return blob_sql_text(&x); | |
| 1361 | 1361 | } |
| 1362 | 1362 | |
| 1363 | 1363 | /* |
| 1364 | 1364 | ** Fill an empty repository database with the basic information for a |
| 1365 | 1365 | ** repository. This function is shared between 'create_repository_cmd' |
| @@ -1997,53 +1997,52 @@ | ||
| 1997 | 1997 | ** ckout:%s |
| 1998 | 1998 | ** |
| 1999 | 1999 | ** Where %s is the checkout root. The value is the repository file. |
| 2000 | 2000 | */ |
| 2001 | 2001 | void db_record_repository_filename(const char *zName){ |
| 2002 | - const char *zCollation; | |
| 2003 | 2002 | char *zRepoSetting; |
| 2004 | 2003 | char *zCkoutSetting; |
| 2005 | 2004 | Blob full; |
| 2006 | 2005 | if( zName==0 ){ |
| 2007 | 2006 | if( !g.localOpen ) return; |
| 2008 | 2007 | zName = db_repository_filename(); |
| 2009 | 2008 | } |
| 2010 | 2009 | file_canonical_name(zName, &full, 0); |
| 2011 | - zCollation = filename_collation(); | |
| 2010 | + (void)filename_collation(); /* Initialize before connection swap */ | |
| 2012 | 2011 | db_swap_connections(); |
| 2013 | 2012 | zRepoSetting = mprintf("repo:%q", blob_str(&full)); |
| 2014 | 2013 | db_multi_exec( |
| 2015 | - "DELETE FROM global_config WHERE name %s = '%s';", | |
| 2016 | - zCollation, zRepoSetting | |
| 2014 | + "DELETE FROM global_config WHERE name %s = %Q;", | |
| 2015 | + filename_collation(), zRepoSetting | |
| 2017 | 2016 | ); |
| 2018 | 2017 | db_multi_exec( |
| 2019 | 2018 | "INSERT OR IGNORE INTO global_config(name,value)" |
| 2020 | - "VALUES('%s',1);", | |
| 2019 | + "VALUES(%Q,1);", | |
| 2021 | 2020 | zRepoSetting |
| 2022 | 2021 | ); |
| 2023 | 2022 | fossil_free(zRepoSetting); |
| 2024 | 2023 | if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){ |
| 2025 | 2024 | Blob localRoot; |
| 2026 | 2025 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 2027 | 2026 | zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot)); |
| 2028 | 2027 | db_multi_exec( |
| 2029 | - "DELETE FROM global_config WHERE name %s = '%s';", | |
| 2030 | - zCollation, zCkoutSetting | |
| 2028 | + "DELETE FROM global_config WHERE name %s = %Q;", | |
| 2029 | + filename_collation(), zCkoutSetting | |
| 2031 | 2030 | ); |
| 2032 | 2031 | db_multi_exec( |
| 2033 | 2032 | "REPLACE INTO global_config(name, value)" |
| 2034 | - "VALUES('%s','%q');", | |
| 2033 | + "VALUES(%Q,%Q);", | |
| 2035 | 2034 | zCkoutSetting, blob_str(&full) |
| 2036 | 2035 | ); |
| 2037 | 2036 | db_swap_connections(); |
| 2038 | 2037 | db_optional_sql("repository", |
| 2039 | - "DELETE FROM config WHERE name %s = '%s';", | |
| 2040 | - zCollation, zCkoutSetting | |
| 2038 | + "DELETE FROM config WHERE name %s = %Q;", | |
| 2039 | + filename_collation(), zCkoutSetting | |
| 2041 | 2040 | ); |
| 2042 | 2041 | db_optional_sql("repository", |
| 2043 | 2042 | "REPLACE INTO config(name,value,mtime)" |
| 2044 | - "VALUES('%s',1,now());", | |
| 2043 | + "VALUES(%Q,1,now());", | |
| 2045 | 2044 | zCkoutSetting |
| 2046 | 2045 | ); |
| 2047 | 2046 | fossil_free(zCkoutSetting); |
| 2048 | 2047 | blob_reset(&localRoot); |
| 2049 | 2048 | }else{ |
| @@ -2648,28 +2647,28 @@ | ||
| 2648 | 2647 | zOrigSql += j+6; |
| 2649 | 2648 | j = -1; |
| 2650 | 2649 | } |
| 2651 | 2650 | } |
| 2652 | 2651 | blob_append(&newSql, zOrigSql, -1); |
| 2653 | - blob_appendf(&allSql, | |
| 2654 | - "ALTER TABLE %s RENAME TO x_%s;\n" | |
| 2652 | + blob_append_sql(&allSql, | |
| 2653 | + "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n" | |
| 2655 | 2654 | "%s WITHOUT ROWID;\n" |
| 2656 | - "INSERT INTO %s SELECT * FROM x_%s;\n" | |
| 2657 | - "DROP TABLE x_%s;\n", | |
| 2658 | - zTName, zTName, blob_str(&newSql), zTName, zTName, zTName | |
| 2655 | + "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n" | |
| 2656 | + "DROP TABLE \"x_%w\";\n", | |
| 2657 | + zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName | |
| 2659 | 2658 | ); |
| 2660 | 2659 | fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]); |
| 2661 | 2660 | blob_reset(&newSql); |
| 2662 | 2661 | } |
| 2663 | - blob_appendf(&allSql, "COMMIT;\n"); | |
| 2662 | + blob_append_sql(&allSql, "COMMIT;\n"); | |
| 2664 | 2663 | db_finalize(&q); |
| 2665 | 2664 | if( dryRun ){ |
| 2666 | 2665 | fossil_print("SQL that would have been evaluated:\n"); |
| 2667 | 2666 | fossil_print("-------------------------------------------------------------\n"); |
| 2668 | - fossil_print("%s", blob_str(&allSql)); | |
| 2667 | + fossil_print("%s", blob_sql_text(&allSql)); | |
| 2669 | 2668 | }else{ |
| 2670 | - db_multi_exec("%s", blob_str(&allSql)); | |
| 2669 | + db_multi_exec("%s", blob_sql_text(&allSql)); | |
| 2671 | 2670 | } |
| 2672 | 2671 | blob_reset(&allSql); |
| 2673 | 2672 | db_close(1); |
| 2674 | 2673 | } |
| 2675 | 2674 | } |
| 2676 | 2675 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -177,11 +177,11 @@ | |
| 177 | db.doRollback |= db.aHook[i].xHook(); |
| 178 | } |
| 179 | while( db.pAllStmt ){ |
| 180 | db_finalize(db.pAllStmt); |
| 181 | } |
| 182 | db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 183 | db.doRollback = 0; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /* |
| @@ -664,17 +664,17 @@ | |
| 664 | |
| 665 | db = db_open(zFileName); |
| 666 | sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0); |
| 667 | rc = sqlite3_exec(db, zSchema, 0, 0, 0); |
| 668 | if( rc!=SQLITE_OK ){ |
| 669 | db_err(sqlite3_errmsg(db)); |
| 670 | } |
| 671 | va_start(ap, zSchema); |
| 672 | while( (zSql = va_arg(ap, const char*))!=0 ){ |
| 673 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 674 | if( rc!=SQLITE_OK ){ |
| 675 | db_err(sqlite3_errmsg(db)); |
| 676 | } |
| 677 | } |
| 678 | va_end(ap); |
| 679 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 680 | sqlite3_close(db); |
| @@ -750,19 +750,19 @@ | |
| 750 | |
| 751 | /* |
| 752 | ** Detaches the zLabel database. |
| 753 | */ |
| 754 | void db_detach(const char *zLabel){ |
| 755 | db_multi_exec("DETACH DATABASE %s", zLabel); |
| 756 | } |
| 757 | |
| 758 | /* |
| 759 | ** zDbName is the name of a database file. Attach zDbName using |
| 760 | ** the name zLabel. |
| 761 | */ |
| 762 | void db_attach(const char *zDbName, const char *zLabel){ |
| 763 | db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); |
| 764 | } |
| 765 | |
| 766 | /* |
| 767 | ** zDbName is the name of a database file. If no other database |
| 768 | ** file is open, then open this one. If another database file is |
| @@ -887,16 +887,16 @@ | |
| 887 | static int db_local_table_exists_but_lacks_column( |
| 888 | const char *zTable, |
| 889 | const char *zColumn |
| 890 | ){ |
| 891 | char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master" |
| 892 | " WHERE name=='%s' /*scan*/", |
| 893 | db_name("localdb"), zTable); |
| 894 | int rc = 0; |
| 895 | if( zDef ){ |
| 896 | char *zPattern = mprintf("* %s *", zColumn); |
| 897 | rc = strglob(zPattern, zDef)==0; |
| 898 | fossil_free(zPattern); |
| 899 | fossil_free(zDef); |
| 900 | } |
| 901 | return rc; |
| 902 | } |
| @@ -919,19 +919,19 @@ | |
| 919 | |
| 920 | /* If the "isexe" column is missing from the vfile table, then |
| 921 | ** add it now. This code added on 2010-03-06. After all users have |
| 922 | ** upgraded, this code can be safely deleted. |
| 923 | */ |
| 924 | if( !strglob("* isexe *", zVFileDef) ){ |
| 925 | db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0"); |
| 926 | } |
| 927 | |
| 928 | /* If "islink"/"isLink" columns are missing from tables, then |
| 929 | ** add them now. This code added on 2011-01-17 and 2011-08-27. |
| 930 | ** After all users have upgraded, this code can be safely deleted. |
| 931 | */ |
| 932 | if( !strglob("* islink *", zVFileDef) ){ |
| 933 | db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0"); |
| 934 | if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){ |
| 935 | db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0"); |
| 936 | } |
| 937 | if( db_local_table_exists_but_lacks_column("undo", "isLink") ){ |
| @@ -1119,11 +1119,11 @@ | |
| 1119 | ** Return TRUE if the schema is out-of-date |
| 1120 | */ |
| 1121 | int db_schema_is_outofdate(void){ |
| 1122 | return db_exists("SELECT 1 FROM config" |
| 1123 | " WHERE name='aux-schema'" |
| 1124 | " AND value<>'%s'", AUX_SCHEMA); |
| 1125 | } |
| 1126 | |
| 1127 | /* |
| 1128 | ** Return true if the database is writeable |
| 1129 | */ |
| @@ -1349,17 +1349,17 @@ | |
| 1349 | Blob x; |
| 1350 | int i; |
| 1351 | const char *zSep = ""; |
| 1352 | |
| 1353 | blob_zero(&x); |
| 1354 | blob_append(&x, "(", 1); |
| 1355 | for(i=0; ctrlSettings[i].name; i++){ |
| 1356 | blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name); |
| 1357 | zSep = ","; |
| 1358 | } |
| 1359 | blob_append(&x, ")", 1); |
| 1360 | return blob_str(&x); |
| 1361 | } |
| 1362 | |
| 1363 | /* |
| 1364 | ** Fill an empty repository database with the basic information for a |
| 1365 | ** repository. This function is shared between 'create_repository_cmd' |
| @@ -1997,53 +1997,52 @@ | |
| 1997 | ** ckout:%s |
| 1998 | ** |
| 1999 | ** Where %s is the checkout root. The value is the repository file. |
| 2000 | */ |
| 2001 | void db_record_repository_filename(const char *zName){ |
| 2002 | const char *zCollation; |
| 2003 | char *zRepoSetting; |
| 2004 | char *zCkoutSetting; |
| 2005 | Blob full; |
| 2006 | if( zName==0 ){ |
| 2007 | if( !g.localOpen ) return; |
| 2008 | zName = db_repository_filename(); |
| 2009 | } |
| 2010 | file_canonical_name(zName, &full, 0); |
| 2011 | zCollation = filename_collation(); |
| 2012 | db_swap_connections(); |
| 2013 | zRepoSetting = mprintf("repo:%q", blob_str(&full)); |
| 2014 | db_multi_exec( |
| 2015 | "DELETE FROM global_config WHERE name %s = '%s';", |
| 2016 | zCollation, zRepoSetting |
| 2017 | ); |
| 2018 | db_multi_exec( |
| 2019 | "INSERT OR IGNORE INTO global_config(name,value)" |
| 2020 | "VALUES('%s',1);", |
| 2021 | zRepoSetting |
| 2022 | ); |
| 2023 | fossil_free(zRepoSetting); |
| 2024 | if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){ |
| 2025 | Blob localRoot; |
| 2026 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 2027 | zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot)); |
| 2028 | db_multi_exec( |
| 2029 | "DELETE FROM global_config WHERE name %s = '%s';", |
| 2030 | zCollation, zCkoutSetting |
| 2031 | ); |
| 2032 | db_multi_exec( |
| 2033 | "REPLACE INTO global_config(name, value)" |
| 2034 | "VALUES('%s','%q');", |
| 2035 | zCkoutSetting, blob_str(&full) |
| 2036 | ); |
| 2037 | db_swap_connections(); |
| 2038 | db_optional_sql("repository", |
| 2039 | "DELETE FROM config WHERE name %s = '%s';", |
| 2040 | zCollation, zCkoutSetting |
| 2041 | ); |
| 2042 | db_optional_sql("repository", |
| 2043 | "REPLACE INTO config(name,value,mtime)" |
| 2044 | "VALUES('%s',1,now());", |
| 2045 | zCkoutSetting |
| 2046 | ); |
| 2047 | fossil_free(zCkoutSetting); |
| 2048 | blob_reset(&localRoot); |
| 2049 | }else{ |
| @@ -2648,28 +2647,28 @@ | |
| 2648 | zOrigSql += j+6; |
| 2649 | j = -1; |
| 2650 | } |
| 2651 | } |
| 2652 | blob_append(&newSql, zOrigSql, -1); |
| 2653 | blob_appendf(&allSql, |
| 2654 | "ALTER TABLE %s RENAME TO x_%s;\n" |
| 2655 | "%s WITHOUT ROWID;\n" |
| 2656 | "INSERT INTO %s SELECT * FROM x_%s;\n" |
| 2657 | "DROP TABLE x_%s;\n", |
| 2658 | zTName, zTName, blob_str(&newSql), zTName, zTName, zTName |
| 2659 | ); |
| 2660 | fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]); |
| 2661 | blob_reset(&newSql); |
| 2662 | } |
| 2663 | blob_appendf(&allSql, "COMMIT;\n"); |
| 2664 | db_finalize(&q); |
| 2665 | if( dryRun ){ |
| 2666 | fossil_print("SQL that would have been evaluated:\n"); |
| 2667 | fossil_print("-------------------------------------------------------------\n"); |
| 2668 | fossil_print("%s", blob_str(&allSql)); |
| 2669 | }else{ |
| 2670 | db_multi_exec("%s", blob_str(&allSql)); |
| 2671 | } |
| 2672 | blob_reset(&allSql); |
| 2673 | db_close(1); |
| 2674 | } |
| 2675 | } |
| 2676 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -177,11 +177,11 @@ | |
| 177 | db.doRollback |= db.aHook[i].xHook(); |
| 178 | } |
| 179 | while( db.pAllStmt ){ |
| 180 | db_finalize(db.pAllStmt); |
| 181 | } |
| 182 | db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 183 | db.doRollback = 0; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /* |
| @@ -664,17 +664,17 @@ | |
| 664 | |
| 665 | db = db_open(zFileName); |
| 666 | sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0); |
| 667 | rc = sqlite3_exec(db, zSchema, 0, 0, 0); |
| 668 | if( rc!=SQLITE_OK ){ |
| 669 | db_err("%s", sqlite3_errmsg(db)); |
| 670 | } |
| 671 | va_start(ap, zSchema); |
| 672 | while( (zSql = va_arg(ap, const char*))!=0 ){ |
| 673 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 674 | if( rc!=SQLITE_OK ){ |
| 675 | db_err("%s", sqlite3_errmsg(db)); |
| 676 | } |
| 677 | } |
| 678 | va_end(ap); |
| 679 | sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 680 | sqlite3_close(db); |
| @@ -750,19 +750,19 @@ | |
| 750 | |
| 751 | /* |
| 752 | ** Detaches the zLabel database. |
| 753 | */ |
| 754 | void db_detach(const char *zLabel){ |
| 755 | db_multi_exec("DETACH DATABASE %Q", zLabel); |
| 756 | } |
| 757 | |
| 758 | /* |
| 759 | ** zDbName is the name of a database file. Attach zDbName using |
| 760 | ** the name zLabel. |
| 761 | */ |
| 762 | void db_attach(const char *zDbName, const char *zLabel){ |
| 763 | db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel); |
| 764 | } |
| 765 | |
| 766 | /* |
| 767 | ** zDbName is the name of a database file. If no other database |
| 768 | ** file is open, then open this one. If another database file is |
| @@ -887,16 +887,16 @@ | |
| 887 | static int db_local_table_exists_but_lacks_column( |
| 888 | const char *zTable, |
| 889 | const char *zColumn |
| 890 | ){ |
| 891 | char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master" |
| 892 | " WHERE name==%Q /*scan*/", |
| 893 | db_name("localdb"), zTable); |
| 894 | int rc = 0; |
| 895 | if( zDef ){ |
| 896 | char *zPattern = mprintf("* %s *", zColumn); |
| 897 | rc = sqlite3_strglob(zPattern, zDef)!=0; |
| 898 | fossil_free(zPattern); |
| 899 | fossil_free(zDef); |
| 900 | } |
| 901 | return rc; |
| 902 | } |
| @@ -919,19 +919,19 @@ | |
| 919 | |
| 920 | /* If the "isexe" column is missing from the vfile table, then |
| 921 | ** add it now. This code added on 2010-03-06. After all users have |
| 922 | ** upgraded, this code can be safely deleted. |
| 923 | */ |
| 924 | if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){ |
| 925 | db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0"); |
| 926 | } |
| 927 | |
| 928 | /* If "islink"/"isLink" columns are missing from tables, then |
| 929 | ** add them now. This code added on 2011-01-17 and 2011-08-27. |
| 930 | ** After all users have upgraded, this code can be safely deleted. |
| 931 | */ |
| 932 | if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){ |
| 933 | db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0"); |
| 934 | if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){ |
| 935 | db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0"); |
| 936 | } |
| 937 | if( db_local_table_exists_but_lacks_column("undo", "isLink") ){ |
| @@ -1119,11 +1119,11 @@ | |
| 1119 | ** Return TRUE if the schema is out-of-date |
| 1120 | */ |
| 1121 | int db_schema_is_outofdate(void){ |
| 1122 | return db_exists("SELECT 1 FROM config" |
| 1123 | " WHERE name='aux-schema'" |
| 1124 | " AND value<>%Q", AUX_SCHEMA); |
| 1125 | } |
| 1126 | |
| 1127 | /* |
| 1128 | ** Return true if the database is writeable |
| 1129 | */ |
| @@ -1349,17 +1349,17 @@ | |
| 1349 | Blob x; |
| 1350 | int i; |
| 1351 | const char *zSep = ""; |
| 1352 | |
| 1353 | blob_zero(&x); |
| 1354 | blob_append_sql(&x, "("); |
| 1355 | for(i=0; ctrlSettings[i].name; i++){ |
| 1356 | blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name); |
| 1357 | zSep = ","; |
| 1358 | } |
| 1359 | blob_append_sql(&x, ")"); |
| 1360 | return blob_sql_text(&x); |
| 1361 | } |
| 1362 | |
| 1363 | /* |
| 1364 | ** Fill an empty repository database with the basic information for a |
| 1365 | ** repository. This function is shared between 'create_repository_cmd' |
| @@ -1997,53 +1997,52 @@ | |
| 1997 | ** ckout:%s |
| 1998 | ** |
| 1999 | ** Where %s is the checkout root. The value is the repository file. |
| 2000 | */ |
| 2001 | void db_record_repository_filename(const char *zName){ |
| 2002 | char *zRepoSetting; |
| 2003 | char *zCkoutSetting; |
| 2004 | Blob full; |
| 2005 | if( zName==0 ){ |
| 2006 | if( !g.localOpen ) return; |
| 2007 | zName = db_repository_filename(); |
| 2008 | } |
| 2009 | file_canonical_name(zName, &full, 0); |
| 2010 | (void)filename_collation(); /* Initialize before connection swap */ |
| 2011 | db_swap_connections(); |
| 2012 | zRepoSetting = mprintf("repo:%q", blob_str(&full)); |
| 2013 | db_multi_exec( |
| 2014 | "DELETE FROM global_config WHERE name %s = %Q;", |
| 2015 | filename_collation(), zRepoSetting |
| 2016 | ); |
| 2017 | db_multi_exec( |
| 2018 | "INSERT OR IGNORE INTO global_config(name,value)" |
| 2019 | "VALUES(%Q,1);", |
| 2020 | zRepoSetting |
| 2021 | ); |
| 2022 | fossil_free(zRepoSetting); |
| 2023 | if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){ |
| 2024 | Blob localRoot; |
| 2025 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 2026 | zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot)); |
| 2027 | db_multi_exec( |
| 2028 | "DELETE FROM global_config WHERE name %s = %Q;", |
| 2029 | filename_collation(), zCkoutSetting |
| 2030 | ); |
| 2031 | db_multi_exec( |
| 2032 | "REPLACE INTO global_config(name, value)" |
| 2033 | "VALUES(%Q,%Q);", |
| 2034 | zCkoutSetting, blob_str(&full) |
| 2035 | ); |
| 2036 | db_swap_connections(); |
| 2037 | db_optional_sql("repository", |
| 2038 | "DELETE FROM config WHERE name %s = %Q;", |
| 2039 | filename_collation(), zCkoutSetting |
| 2040 | ); |
| 2041 | db_optional_sql("repository", |
| 2042 | "REPLACE INTO config(name,value,mtime)" |
| 2043 | "VALUES(%Q,1,now());", |
| 2044 | zCkoutSetting |
| 2045 | ); |
| 2046 | fossil_free(zCkoutSetting); |
| 2047 | blob_reset(&localRoot); |
| 2048 | }else{ |
| @@ -2648,28 +2647,28 @@ | |
| 2647 | zOrigSql += j+6; |
| 2648 | j = -1; |
| 2649 | } |
| 2650 | } |
| 2651 | blob_append(&newSql, zOrigSql, -1); |
| 2652 | blob_append_sql(&allSql, |
| 2653 | "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n" |
| 2654 | "%s WITHOUT ROWID;\n" |
| 2655 | "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n" |
| 2656 | "DROP TABLE \"x_%w\";\n", |
| 2657 | zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName |
| 2658 | ); |
| 2659 | fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]); |
| 2660 | blob_reset(&newSql); |
| 2661 | } |
| 2662 | blob_append_sql(&allSql, "COMMIT;\n"); |
| 2663 | db_finalize(&q); |
| 2664 | if( dryRun ){ |
| 2665 | fossil_print("SQL that would have been evaluated:\n"); |
| 2666 | fossil_print("-------------------------------------------------------------\n"); |
| 2667 | fossil_print("%s", blob_sql_text(&allSql)); |
| 2668 | }else{ |
| 2669 | db_multi_exec("%s", blob_sql_text(&allSql)); |
| 2670 | } |
| 2671 | blob_reset(&allSql); |
| 2672 | db_close(1); |
| 2673 | } |
| 2674 | } |
| 2675 |
+10
-10
| --- src/delta.c | ||
| +++ src/delta.c | ||
| @@ -65,11 +65,11 @@ | ||
| 65 | 65 | ** The "u32" type must be an unsigned 32-bit integer. Adjust this |
| 66 | 66 | */ |
| 67 | 67 | typedef unsigned int u32; |
| 68 | 68 | |
| 69 | 69 | /* |
| 70 | -** Must be a 16-bit value | |
| 70 | +** Must be a 16-bit value | |
| 71 | 71 | */ |
| 72 | 72 | typedef short int s16; |
| 73 | 73 | typedef unsigned short int u16; |
| 74 | 74 | |
| 75 | 75 | #endif /* INTERFACE */ |
| @@ -82,11 +82,11 @@ | ||
| 82 | 82 | |
| 83 | 83 | /* |
| 84 | 84 | ** The current state of the rolling hash. |
| 85 | 85 | ** |
| 86 | 86 | ** z[] holds the values that have been hashed. z[] is a circular buffer. |
| 87 | -** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of | |
| 87 | +** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of | |
| 88 | 88 | ** the window. |
| 89 | 89 | ** |
| 90 | 90 | ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted |
| 91 | 91 | ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1. |
| 92 | 92 | ** (Each index for z[] should be module NHASH, of course. The %NHASH operator |
| @@ -135,11 +135,11 @@ | ||
| 135 | 135 | |
| 136 | 136 | /* |
| 137 | 137 | ** Write an base-64 integer into the given buffer. |
| 138 | 138 | */ |
| 139 | 139 | static void putInt(unsigned int v, char **pz){ |
| 140 | - static const char zDigits[] = | |
| 140 | + static const char zDigits[] = | |
| 141 | 141 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; |
| 142 | 142 | /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */ |
| 143 | 143 | int i, j; |
| 144 | 144 | char zBuf[20]; |
| 145 | 145 | if( v==0 ){ |
| @@ -229,11 +229,11 @@ | ||
| 229 | 229 | } |
| 230 | 230 | |
| 231 | 231 | /* |
| 232 | 232 | ** Create a new delta. |
| 233 | 233 | ** |
| 234 | -** The delta is written into a preallocated buffer, zDelta, which | |
| 234 | +** The delta is written into a preallocated buffer, zDelta, which | |
| 235 | 235 | ** should be at least 60 bytes longer than the target file, zOut. |
| 236 | 236 | ** The delta string will be NUL-terminated, but it might also contain |
| 237 | 237 | ** embedded NUL characters if either the zSrc or zOut files are |
| 238 | 238 | ** binary. This function returns the length of the delta string |
| 239 | 239 | ** in bytes, excluding the final NUL terminator character. |
| @@ -245,11 +245,11 @@ | ||
| 245 | 245 | ** delta file z, a program can compute the size of the output file |
| 246 | 246 | ** simply by reading the first line and decoding the base-64 number |
| 247 | 247 | ** found there. The delta_output_size() routine does exactly this. |
| 248 | 248 | ** |
| 249 | 249 | ** After the initial size number, the delta consists of a series of |
| 250 | -** literal text segments and commands to copy from the SOURCE file. | |
| 250 | +** literal text segments and commands to copy from the SOURCE file. | |
| 251 | 251 | ** A copy command looks like this: |
| 252 | 252 | ** |
| 253 | 253 | ** NNN@MMM, |
| 254 | 254 | ** |
| 255 | 255 | ** where NNN is the number of bytes to be copied and MMM is the offset |
| @@ -283,11 +283,11 @@ | ||
| 283 | 283 | ** search for a matching section in the source file. When a match |
| 284 | 284 | ** is found, a copy command is added to the delta. An effort is |
| 285 | 285 | ** made to extend the matching section to regions that come before |
| 286 | 286 | ** and after the 16-byte hash window. A copy command is only issued |
| 287 | 287 | ** if the result would use less space that just quoting the text |
| 288 | -** literally. Literal text is added to the delta for sections that | |
| 288 | +** literally. Literal text is added to the delta for sections that | |
| 289 | 289 | ** do not match or which can not be encoded efficiently using copy |
| 290 | 290 | ** commands. |
| 291 | 291 | */ |
| 292 | 292 | int delta_create( |
| 293 | 293 | const char *zSrc, /* The source or pattern file */ |
| @@ -356,13 +356,13 @@ | ||
| 356 | 356 | hv = hash_32bit(&h) % nHash; |
| 357 | 357 | DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); ) |
| 358 | 358 | iBlock = landmark[hv]; |
| 359 | 359 | while( iBlock>=0 && (limit--)>0 ){ |
| 360 | 360 | /* |
| 361 | - ** The hash window has identified a potential match against | |
| 361 | + ** The hash window has identified a potential match against | |
| 362 | 362 | ** landmark block iBlock. But we need to investigate further. |
| 363 | - ** | |
| 363 | + ** | |
| 364 | 364 | ** Look for a region in zOut that matches zSrc. Anchor the search |
| 365 | 365 | ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to |
| 366 | 366 | ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen]. |
| 367 | 367 | ** |
| 368 | 368 | ** Set cnt equal to the length of the match and set ofst so that |
| @@ -468,16 +468,16 @@ | ||
| 468 | 468 | } |
| 469 | 469 | /* Output the final checksum record. */ |
| 470 | 470 | putInt(checksum(zOut, lenOut), &zDelta); |
| 471 | 471 | *(zDelta++) = ';'; |
| 472 | 472 | fossil_free(collide); |
| 473 | - return zDelta - zOrigDelta; | |
| 473 | + return zDelta - zOrigDelta; | |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | /* |
| 477 | 477 | ** Return the size (in bytes) of the output from applying |
| 478 | -** a delta. | |
| 478 | +** a delta. | |
| 479 | 479 | ** |
| 480 | 480 | ** This routine is provided so that an procedure that is able |
| 481 | 481 | ** to call delta_apply() can learn how much space is required |
| 482 | 482 | ** for the output and hence allocate nor more space that is really |
| 483 | 483 | ** needed. |
| 484 | 484 |
| --- src/delta.c | |
| +++ src/delta.c | |
| @@ -65,11 +65,11 @@ | |
| 65 | ** The "u32" type must be an unsigned 32-bit integer. Adjust this |
| 66 | */ |
| 67 | typedef unsigned int u32; |
| 68 | |
| 69 | /* |
| 70 | ** Must be a 16-bit value |
| 71 | */ |
| 72 | typedef short int s16; |
| 73 | typedef unsigned short int u16; |
| 74 | |
| 75 | #endif /* INTERFACE */ |
| @@ -82,11 +82,11 @@ | |
| 82 | |
| 83 | /* |
| 84 | ** The current state of the rolling hash. |
| 85 | ** |
| 86 | ** z[] holds the values that have been hashed. z[] is a circular buffer. |
| 87 | ** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of |
| 88 | ** the window. |
| 89 | ** |
| 90 | ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted |
| 91 | ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1. |
| 92 | ** (Each index for z[] should be module NHASH, of course. The %NHASH operator |
| @@ -135,11 +135,11 @@ | |
| 135 | |
| 136 | /* |
| 137 | ** Write an base-64 integer into the given buffer. |
| 138 | */ |
| 139 | static void putInt(unsigned int v, char **pz){ |
| 140 | static const char zDigits[] = |
| 141 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; |
| 142 | /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */ |
| 143 | int i, j; |
| 144 | char zBuf[20]; |
| 145 | if( v==0 ){ |
| @@ -229,11 +229,11 @@ | |
| 229 | } |
| 230 | |
| 231 | /* |
| 232 | ** Create a new delta. |
| 233 | ** |
| 234 | ** The delta is written into a preallocated buffer, zDelta, which |
| 235 | ** should be at least 60 bytes longer than the target file, zOut. |
| 236 | ** The delta string will be NUL-terminated, but it might also contain |
| 237 | ** embedded NUL characters if either the zSrc or zOut files are |
| 238 | ** binary. This function returns the length of the delta string |
| 239 | ** in bytes, excluding the final NUL terminator character. |
| @@ -245,11 +245,11 @@ | |
| 245 | ** delta file z, a program can compute the size of the output file |
| 246 | ** simply by reading the first line and decoding the base-64 number |
| 247 | ** found there. The delta_output_size() routine does exactly this. |
| 248 | ** |
| 249 | ** After the initial size number, the delta consists of a series of |
| 250 | ** literal text segments and commands to copy from the SOURCE file. |
| 251 | ** A copy command looks like this: |
| 252 | ** |
| 253 | ** NNN@MMM, |
| 254 | ** |
| 255 | ** where NNN is the number of bytes to be copied and MMM is the offset |
| @@ -283,11 +283,11 @@ | |
| 283 | ** search for a matching section in the source file. When a match |
| 284 | ** is found, a copy command is added to the delta. An effort is |
| 285 | ** made to extend the matching section to regions that come before |
| 286 | ** and after the 16-byte hash window. A copy command is only issued |
| 287 | ** if the result would use less space that just quoting the text |
| 288 | ** literally. Literal text is added to the delta for sections that |
| 289 | ** do not match or which can not be encoded efficiently using copy |
| 290 | ** commands. |
| 291 | */ |
| 292 | int delta_create( |
| 293 | const char *zSrc, /* The source or pattern file */ |
| @@ -356,13 +356,13 @@ | |
| 356 | hv = hash_32bit(&h) % nHash; |
| 357 | DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); ) |
| 358 | iBlock = landmark[hv]; |
| 359 | while( iBlock>=0 && (limit--)>0 ){ |
| 360 | /* |
| 361 | ** The hash window has identified a potential match against |
| 362 | ** landmark block iBlock. But we need to investigate further. |
| 363 | ** |
| 364 | ** Look for a region in zOut that matches zSrc. Anchor the search |
| 365 | ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to |
| 366 | ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen]. |
| 367 | ** |
| 368 | ** Set cnt equal to the length of the match and set ofst so that |
| @@ -468,16 +468,16 @@ | |
| 468 | } |
| 469 | /* Output the final checksum record. */ |
| 470 | putInt(checksum(zOut, lenOut), &zDelta); |
| 471 | *(zDelta++) = ';'; |
| 472 | fossil_free(collide); |
| 473 | return zDelta - zOrigDelta; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | ** Return the size (in bytes) of the output from applying |
| 478 | ** a delta. |
| 479 | ** |
| 480 | ** This routine is provided so that an procedure that is able |
| 481 | ** to call delta_apply() can learn how much space is required |
| 482 | ** for the output and hence allocate nor more space that is really |
| 483 | ** needed. |
| 484 |
| --- src/delta.c | |
| +++ src/delta.c | |
| @@ -65,11 +65,11 @@ | |
| 65 | ** The "u32" type must be an unsigned 32-bit integer. Adjust this |
| 66 | */ |
| 67 | typedef unsigned int u32; |
| 68 | |
| 69 | /* |
| 70 | ** Must be a 16-bit value |
| 71 | */ |
| 72 | typedef short int s16; |
| 73 | typedef unsigned short int u16; |
| 74 | |
| 75 | #endif /* INTERFACE */ |
| @@ -82,11 +82,11 @@ | |
| 82 | |
| 83 | /* |
| 84 | ** The current state of the rolling hash. |
| 85 | ** |
| 86 | ** z[] holds the values that have been hashed. z[] is a circular buffer. |
| 87 | ** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of |
| 88 | ** the window. |
| 89 | ** |
| 90 | ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted |
| 91 | ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1. |
| 92 | ** (Each index for z[] should be module NHASH, of course. The %NHASH operator |
| @@ -135,11 +135,11 @@ | |
| 135 | |
| 136 | /* |
| 137 | ** Write an base-64 integer into the given buffer. |
| 138 | */ |
| 139 | static void putInt(unsigned int v, char **pz){ |
| 140 | static const char zDigits[] = |
| 141 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; |
| 142 | /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */ |
| 143 | int i, j; |
| 144 | char zBuf[20]; |
| 145 | if( v==0 ){ |
| @@ -229,11 +229,11 @@ | |
| 229 | } |
| 230 | |
| 231 | /* |
| 232 | ** Create a new delta. |
| 233 | ** |
| 234 | ** The delta is written into a preallocated buffer, zDelta, which |
| 235 | ** should be at least 60 bytes longer than the target file, zOut. |
| 236 | ** The delta string will be NUL-terminated, but it might also contain |
| 237 | ** embedded NUL characters if either the zSrc or zOut files are |
| 238 | ** binary. This function returns the length of the delta string |
| 239 | ** in bytes, excluding the final NUL terminator character. |
| @@ -245,11 +245,11 @@ | |
| 245 | ** delta file z, a program can compute the size of the output file |
| 246 | ** simply by reading the first line and decoding the base-64 number |
| 247 | ** found there. The delta_output_size() routine does exactly this. |
| 248 | ** |
| 249 | ** After the initial size number, the delta consists of a series of |
| 250 | ** literal text segments and commands to copy from the SOURCE file. |
| 251 | ** A copy command looks like this: |
| 252 | ** |
| 253 | ** NNN@MMM, |
| 254 | ** |
| 255 | ** where NNN is the number of bytes to be copied and MMM is the offset |
| @@ -283,11 +283,11 @@ | |
| 283 | ** search for a matching section in the source file. When a match |
| 284 | ** is found, a copy command is added to the delta. An effort is |
| 285 | ** made to extend the matching section to regions that come before |
| 286 | ** and after the 16-byte hash window. A copy command is only issued |
| 287 | ** if the result would use less space that just quoting the text |
| 288 | ** literally. Literal text is added to the delta for sections that |
| 289 | ** do not match or which can not be encoded efficiently using copy |
| 290 | ** commands. |
| 291 | */ |
| 292 | int delta_create( |
| 293 | const char *zSrc, /* The source or pattern file */ |
| @@ -356,13 +356,13 @@ | |
| 356 | hv = hash_32bit(&h) % nHash; |
| 357 | DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); ) |
| 358 | iBlock = landmark[hv]; |
| 359 | while( iBlock>=0 && (limit--)>0 ){ |
| 360 | /* |
| 361 | ** The hash window has identified a potential match against |
| 362 | ** landmark block iBlock. But we need to investigate further. |
| 363 | ** |
| 364 | ** Look for a region in zOut that matches zSrc. Anchor the search |
| 365 | ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to |
| 366 | ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen]. |
| 367 | ** |
| 368 | ** Set cnt equal to the length of the match and set ofst so that |
| @@ -468,16 +468,16 @@ | |
| 468 | } |
| 469 | /* Output the final checksum record. */ |
| 470 | putInt(checksum(zOut, lenOut), &zDelta); |
| 471 | *(zDelta++) = ';'; |
| 472 | fossil_free(collide); |
| 473 | return zDelta - zOrigDelta; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | ** Return the size (in bytes) of the output from applying |
| 478 | ** a delta. |
| 479 | ** |
| 480 | ** This routine is provided so that an procedure that is able |
| 481 | ** to call delta_apply() can learn how much space is required |
| 482 | ** for the output and hence allocate nor more space that is really |
| 483 | ** needed. |
| 484 |
+10
-10
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -389,22 +389,22 @@ | ||
| 389 | 389 | verify_all_options(); |
| 390 | 390 | |
| 391 | 391 | if( recomputeFlag ) leaf_rebuild(); |
| 392 | 392 | blob_zero(&sql); |
| 393 | 393 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 394 | - blob_appendf(&sql, " AND blob.rid IN leaf"); | |
| 394 | + blob_append_sql(&sql, " AND blob.rid IN leaf"); | |
| 395 | 395 | if( showClosed ){ |
| 396 | - blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid")); | |
| 396 | + blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid")); | |
| 397 | 397 | }else if( !showAll ){ |
| 398 | - blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); | |
| 398 | + blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); | |
| 399 | 399 | } |
| 400 | 400 | if( byBranch ){ |
| 401 | 401 | db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase," |
| 402 | 402 | " event.mtime DESC", |
| 403 | - blob_str(&sql)); | |
| 403 | + blob_sql_text(&sql)); | |
| 404 | 404 | }else{ |
| 405 | - db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql)); | |
| 405 | + db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql)); | |
| 406 | 406 | } |
| 407 | 407 | blob_reset(&sql); |
| 408 | 408 | n = 0; |
| 409 | 409 | while( db_step(&q)==SQLITE_ROW ){ |
| 410 | 410 | const char *zId = db_column_text(&q, 1); |
| @@ -474,17 +474,17 @@ | ||
| 474 | 474 | }else{ |
| 475 | 475 | @ <h1>Open leaves:</h1> |
| 476 | 476 | } |
| 477 | 477 | blob_zero(&sql); |
| 478 | 478 | blob_append(&sql, timeline_query_for_www(), -1); |
| 479 | - blob_appendf(&sql, " AND blob.rid IN leaf"); | |
| 479 | + blob_append_sql(&sql, " AND blob.rid IN leaf"); | |
| 480 | 480 | if( showClosed ){ |
| 481 | - blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid")); | |
| 481 | + blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid")); | |
| 482 | 482 | }else if( !showAll ){ |
| 483 | - blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); | |
| 483 | + blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); | |
| 484 | 484 | } |
| 485 | - db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql)); | |
| 485 | + db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql)); | |
| 486 | 486 | blob_reset(&sql); |
| 487 | 487 | www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0); |
| 488 | 488 | db_finalize(&q); |
| 489 | 489 | @ <br /> |
| 490 | 490 | style_footer(); |
| @@ -508,11 +508,11 @@ | ||
| 508 | 508 | Stmt q; |
| 509 | 509 | int rid; |
| 510 | 510 | |
| 511 | 511 | bag_init(&seen); |
| 512 | 512 | bag_init(&pending); |
| 513 | - db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab); | |
| 513 | + db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab); | |
| 514 | 514 | db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid); |
| 515 | 515 | while( db_step(&q)==SQLITE_ROW ){ |
| 516 | 516 | int mid = db_column_int(&q, 0); |
| 517 | 517 | bag_insert(&pending, mid); |
| 518 | 518 | bag_insert(&seen, mid); |
| 519 | 519 | |
| 520 | 520 | ADDED src/diff.tcl |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -389,22 +389,22 @@ | |
| 389 | verify_all_options(); |
| 390 | |
| 391 | if( recomputeFlag ) leaf_rebuild(); |
| 392 | blob_zero(&sql); |
| 393 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 394 | blob_appendf(&sql, " AND blob.rid IN leaf"); |
| 395 | if( showClosed ){ |
| 396 | blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid")); |
| 397 | }else if( !showAll ){ |
| 398 | blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); |
| 399 | } |
| 400 | if( byBranch ){ |
| 401 | db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase," |
| 402 | " event.mtime DESC", |
| 403 | blob_str(&sql)); |
| 404 | }else{ |
| 405 | db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql)); |
| 406 | } |
| 407 | blob_reset(&sql); |
| 408 | n = 0; |
| 409 | while( db_step(&q)==SQLITE_ROW ){ |
| 410 | const char *zId = db_column_text(&q, 1); |
| @@ -474,17 +474,17 @@ | |
| 474 | }else{ |
| 475 | @ <h1>Open leaves:</h1> |
| 476 | } |
| 477 | blob_zero(&sql); |
| 478 | blob_append(&sql, timeline_query_for_www(), -1); |
| 479 | blob_appendf(&sql, " AND blob.rid IN leaf"); |
| 480 | if( showClosed ){ |
| 481 | blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid")); |
| 482 | }else if( !showAll ){ |
| 483 | blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); |
| 484 | } |
| 485 | db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql)); |
| 486 | blob_reset(&sql); |
| 487 | www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0); |
| 488 | db_finalize(&q); |
| 489 | @ <br /> |
| 490 | style_footer(); |
| @@ -508,11 +508,11 @@ | |
| 508 | Stmt q; |
| 509 | int rid; |
| 510 | |
| 511 | bag_init(&seen); |
| 512 | bag_init(&pending); |
| 513 | db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab); |
| 514 | db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid); |
| 515 | while( db_step(&q)==SQLITE_ROW ){ |
| 516 | int mid = db_column_int(&q, 0); |
| 517 | bag_insert(&pending, mid); |
| 518 | bag_insert(&seen, mid); |
| 519 | |
| 520 | DDED src/diff.tcl |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -389,22 +389,22 @@ | |
| 389 | verify_all_options(); |
| 390 | |
| 391 | if( recomputeFlag ) leaf_rebuild(); |
| 392 | blob_zero(&sql); |
| 393 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 394 | blob_append_sql(&sql, " AND blob.rid IN leaf"); |
| 395 | if( showClosed ){ |
| 396 | blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid")); |
| 397 | }else if( !showAll ){ |
| 398 | blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); |
| 399 | } |
| 400 | if( byBranch ){ |
| 401 | db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase," |
| 402 | " event.mtime DESC", |
| 403 | blob_sql_text(&sql)); |
| 404 | }else{ |
| 405 | db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql)); |
| 406 | } |
| 407 | blob_reset(&sql); |
| 408 | n = 0; |
| 409 | while( db_step(&q)==SQLITE_ROW ){ |
| 410 | const char *zId = db_column_text(&q, 1); |
| @@ -474,17 +474,17 @@ | |
| 474 | }else{ |
| 475 | @ <h1>Open leaves:</h1> |
| 476 | } |
| 477 | blob_zero(&sql); |
| 478 | blob_append(&sql, timeline_query_for_www(), -1); |
| 479 | blob_append_sql(&sql, " AND blob.rid IN leaf"); |
| 480 | if( showClosed ){ |
| 481 | blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid")); |
| 482 | }else if( !showAll ){ |
| 483 | blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid")); |
| 484 | } |
| 485 | db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql)); |
| 486 | blob_reset(&sql); |
| 487 | www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0); |
| 488 | db_finalize(&q); |
| 489 | @ <br /> |
| 490 | style_footer(); |
| @@ -508,11 +508,11 @@ | |
| 508 | Stmt q; |
| 509 | int rid; |
| 510 | |
| 511 | bag_init(&seen); |
| 512 | bag_init(&pending); |
| 513 | db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab); |
| 514 | db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid); |
| 515 | while( db_step(&q)==SQLITE_ROW ){ |
| 516 | int mid = db_column_int(&q, 0); |
| 517 | bag_insert(&pending, mid); |
| 518 | bag_insert(&seen, mid); |
| 519 | |
| 520 | DDED src/diff.tcl |
No diff available
+12
-398
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -142,17 +142,17 @@ | ||
| 142 | 142 | Blob cmd; /* Text of command to run */ |
| 143 | 143 | |
| 144 | 144 | if( !fIncludeBinary ){ |
| 145 | 145 | Blob file2; |
| 146 | 146 | if( isBin1 ){ |
| 147 | - fossil_print(DIFF_CANNOT_COMPUTE_BINARY); | |
| 147 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); | |
| 148 | 148 | return; |
| 149 | 149 | } |
| 150 | 150 | if( zBinGlob ){ |
| 151 | 151 | Glob *pBinary = glob_create(zBinGlob); |
| 152 | 152 | if( glob_match(pBinary, zName) ){ |
| 153 | - fossil_print(DIFF_CANNOT_COMPUTE_BINARY); | |
| 153 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); | |
| 154 | 154 | glob_free(pBinary); |
| 155 | 155 | return; |
| 156 | 156 | } |
| 157 | 157 | glob_free(pBinary); |
| 158 | 158 | } |
| @@ -163,11 +163,11 @@ | ||
| 163 | 163 | }else{ |
| 164 | 164 | blob_read_from_file(&file2, zFile2); |
| 165 | 165 | } |
| 166 | 166 | } |
| 167 | 167 | if( looks_like_binary(&file2) ){ |
| 168 | - fossil_print(DIFF_CANNOT_COMPUTE_BINARY); | |
| 168 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); | |
| 169 | 169 | blob_reset(&file2); |
| 170 | 170 | return; |
| 171 | 171 | } |
| 172 | 172 | blob_reset(&file2); |
| 173 | 173 | } |
| @@ -238,17 +238,17 @@ | ||
| 238 | 238 | char zTemp1[300]; |
| 239 | 239 | char zTemp2[300]; |
| 240 | 240 | |
| 241 | 241 | if( !fIncludeBinary ){ |
| 242 | 242 | if( isBin1 || isBin2 ){ |
| 243 | - fossil_print(DIFF_CANNOT_COMPUTE_BINARY); | |
| 243 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); | |
| 244 | 244 | return; |
| 245 | 245 | } |
| 246 | 246 | if( zBinGlob ){ |
| 247 | 247 | Glob *pBinary = glob_create(zBinGlob); |
| 248 | 248 | if( glob_match(pBinary, zName) ){ |
| 249 | - fossil_print(DIFF_CANNOT_COMPUTE_BINARY); | |
| 249 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); | |
| 250 | 250 | glob_free(pBinary); |
| 251 | 251 | return; |
| 252 | 252 | } |
| 253 | 253 | glob_free(pBinary); |
| 254 | 254 | } |
| @@ -302,11 +302,11 @@ | ||
| 302 | 302 | int isBin; |
| 303 | 303 | file_tree_name(zFileTreeName, &fname, 1); |
| 304 | 304 | historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, |
| 305 | 305 | fIncludeBinary ? 0 : &isBin, 0); |
| 306 | 306 | if( !isLink != !file_wd_islink(zFrom) ){ |
| 307 | - fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); | |
| 307 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); | |
| 308 | 308 | }else{ |
| 309 | 309 | diff_file(&content, isBin, zFileTreeName, zFileTreeName, |
| 310 | 310 | zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); |
| 311 | 311 | } |
| 312 | 312 | blob_reset(&content); |
| @@ -346,11 +346,11 @@ | ||
| 346 | 346 | int rid = name_to_typed_rid(zFrom, "ci"); |
| 347 | 347 | if( !is_a_version(rid) ){ |
| 348 | 348 | fossil_fatal("no such check-in: %s", zFrom); |
| 349 | 349 | } |
| 350 | 350 | load_vfile_from_rid(rid); |
| 351 | - blob_appendf(&sql, | |
| 351 | + blob_append_sql(&sql, | |
| 352 | 352 | "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink" |
| 353 | 353 | " FROM vfile v1, vfile v2 " |
| 354 | 354 | " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d" |
| 355 | 355 | " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)" |
| 356 | 356 | "UNION " |
| @@ -367,20 +367,20 @@ | ||
| 367 | 367 | " WHERE v1.vid=%d AND v1.pathname=v2.pathname)" |
| 368 | 368 | " ORDER BY 1", |
| 369 | 369 | rid, vid, rid, vid, vid, rid |
| 370 | 370 | ); |
| 371 | 371 | }else{ |
| 372 | - blob_appendf(&sql, | |
| 372 | + blob_append_sql(&sql, | |
| 373 | 373 | "SELECT pathname, deleted, chnged , rid==0, rid, islink" |
| 374 | 374 | " FROM vfile" |
| 375 | 375 | " WHERE vid=%d" |
| 376 | 376 | " AND (deleted OR chnged OR rid==0)" |
| 377 | 377 | " ORDER BY pathname", |
| 378 | 378 | vid |
| 379 | 379 | ); |
| 380 | 380 | } |
| 381 | - db_prepare(&q, blob_str(&sql)); | |
| 381 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 382 | 382 | while( db_step(&q)==SQLITE_ROW ){ |
| 383 | 383 | const char *zPathname = db_column_text(&q,0); |
| 384 | 384 | int isDeleted = db_column_int(&q, 1); |
| 385 | 385 | int isChnged = db_column_int(&q,2); |
| 386 | 386 | int isNew = db_column_int(&q,3); |
| @@ -408,11 +408,11 @@ | ||
| 408 | 408 | Blob content; |
| 409 | 409 | int isBin; |
| 410 | 410 | if( !isLink != !file_wd_islink(zFullName) ){ |
| 411 | 411 | diff_print_index(zPathname, diffFlags); |
| 412 | 412 | diff_print_filenames(zPathname, zPathname, diffFlags); |
| 413 | - fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); | |
| 413 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); | |
| 414 | 414 | continue; |
| 415 | 415 | } |
| 416 | 416 | if( srcid>0 ){ |
| 417 | 417 | content_get(srcid, &content); |
| 418 | 418 | }else{ |
| @@ -462,11 +462,11 @@ | ||
| 462 | 462 | fIncludeBinary ? 0 : &isBin1, 0); |
| 463 | 463 | historical_version_of_file(zTo, zName, &v2, &isLink2, 0, |
| 464 | 464 | fIncludeBinary ? 0 : &isBin2, 0); |
| 465 | 465 | if( isLink1 != isLink2 ){ |
| 466 | 466 | diff_print_filenames(zName, zName, diffFlags); |
| 467 | - fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); | |
| 467 | + fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); | |
| 468 | 468 | }else{ |
| 469 | 469 | diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd, |
| 470 | 470 | zBinGlob, fIncludeBinary, diffFlags); |
| 471 | 471 | } |
| 472 | 472 | blob_reset(&v1); |
| @@ -617,396 +617,10 @@ | ||
| 617 | 617 | zName = "diff-command"; |
| 618 | 618 | } |
| 619 | 619 | return db_get(zName, zDefault); |
| 620 | 620 | } |
| 621 | 621 | |
| 622 | -/* A Tcl/Tk script used to render diff output. | |
| 623 | -*/ | |
| 624 | -static const char zDiffScript[] = | |
| 625 | -@ set prog { | |
| 626 | -@ package require Tk | |
| 627 | -@ | |
| 628 | -@ array set CFG { | |
| 629 | -@ TITLE {Fossil Diff} | |
| 630 | -@ LN_COL_BG #dddddd | |
| 631 | -@ LN_COL_FG #444444 | |
| 632 | -@ TXT_COL_BG #ffffff | |
| 633 | -@ TXT_COL_FG #000000 | |
| 634 | -@ MKR_COL_BG #444444 | |
| 635 | -@ MKR_COL_FG #dddddd | |
| 636 | -@ CHNG_BG #d0d0ff | |
| 637 | -@ ADD_BG #c0ffc0 | |
| 638 | -@ RM_BG #ffc0c0 | |
| 639 | -@ HR_FG #888888 | |
| 640 | -@ HR_PAD_TOP 4 | |
| 641 | -@ HR_PAD_BTM 8 | |
| 642 | -@ FN_BG #444444 | |
| 643 | -@ FN_FG #ffffff | |
| 644 | -@ FN_PAD 5 | |
| 645 | -@ ERR_FG #ee0000 | |
| 646 | -@ PADX 5 | |
| 647 | -@ WIDTH 80 | |
| 648 | -@ HEIGHT 45 | |
| 649 | -@ LB_HEIGHT 25 | |
| 650 | -@ } | |
| 651 | -@ | |
| 652 | -@ if {![namespace exists ttk]} { | |
| 653 | -@ interp alias {} ::ttk::scrollbar {} ::scrollbar | |
| 654 | -@ interp alias {} ::ttk::menubutton {} ::menubutton | |
| 655 | -@ } | |
| 656 | -@ | |
| 657 | -@ proc dehtml {x} { | |
| 658 | -@ set x [regsub -all {<[^>]*>} $x {}] | |
| 659 | -@ return [string map {& & < < > > ' ' " \"} $x] | |
| 660 | -@ } | |
| 661 | -@ | |
| 662 | -@ proc cols {} { | |
| 663 | -@ return [list .lnA .txtA .mkr .lnB .txtB] | |
| 664 | -@ } | |
| 665 | -@ | |
| 666 | -@ proc colType {c} { | |
| 667 | -@ regexp {[a-z]+} $c type | |
| 668 | -@ return $type | |
| 669 | -@ } | |
| 670 | -@ | |
| 671 | -@ proc getLine {difftxt N iivar} { | |
| 672 | -@ upvar $iivar ii | |
| 673 | -@ if {$ii>=$N} {return -1} | |
| 674 | -@ set x [lindex $difftxt $ii] | |
| 675 | -@ incr ii | |
| 676 | -@ return $x | |
| 677 | -@ } | |
| 678 | -@ | |
| 679 | -@ proc readDiffs {fossilcmd} { | |
| 680 | -@ global difftxt | |
| 681 | -@ if {![info exists difftxt]} { | |
| 682 | -@ set in [open $fossilcmd r] | |
| 683 | -@ fconfigure $in -encoding utf-8 | |
| 684 | -@ set difftxt [split [read $in] \n] | |
| 685 | -@ close $in | |
| 686 | -@ } | |
| 687 | -@ set N [llength $difftxt] | |
| 688 | -@ set ii 0 | |
| 689 | -@ set nDiffs 0 | |
| 690 | -@ array set widths {txt 0 ln 0 mkr 0} | |
| 691 | -@ while {[set line [getLine $difftxt $N ii]] != -1} { | |
| 692 | -@ set fn2 {} | |
| 693 | -@ if {![regexp {^=+ (.*?) =+ versus =+ (.*?) =+$} $line all fn fn2] | |
| 694 | -@ && ![regexp {^=+ (.*?) =+$} $line all fn] | |
| 695 | -@ } { | |
| 696 | -@ continue | |
| 697 | -@ } | |
| 698 | -@ set errMsg "" | |
| 699 | -@ set line [getLine $difftxt $N ii] | |
| 700 | -@ if {[string compare -length 6 $line "<table"] | |
| 701 | -@ && ![regexp {<p[^>]*>(.+)} $line - errMsg]} { | |
| 702 | -@ continue | |
| 703 | -@ } | |
| 704 | -@ incr nDiffs | |
| 705 | -@ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}] | |
| 706 | -@ .wfiles.lb insert end $fn | |
| 707 | -@ | |
| 708 | -@ foreach c [cols] { | |
| 709 | -@ if {$nDiffs > 1} { | |
| 710 | -@ $c insert end \n - | |
| 711 | -@ } | |
| 712 | -@ if {[colType $c] eq "txt"} { | |
| 713 | -@ $c insert end $fn\n fn | |
| 714 | -@ if {$fn2!=""} {set fn $fn2} | |
| 715 | -@ } else { | |
| 716 | -@ $c insert end \n fn | |
| 717 | -@ } | |
| 718 | -@ $c insert end \n - | |
| 719 | -@ | |
| 720 | -@ if {$errMsg ne ""} continue | |
| 721 | -@ while {[getLine $difftxt $N ii] ne "<pre>"} continue | |
| 722 | -@ set type [colType $c] | |
| 723 | -@ set str {} | |
| 724 | -@ while {[set line [getLine $difftxt $N ii]] ne "</pre>"} { | |
| 725 | -@ set len [string length [dehtml $line]] | |
| 726 | -@ if {$len > $widths($type)} { | |
| 727 | -@ set widths($type) $len | |
| 728 | -@ } | |
| 729 | -@ append str $line\n | |
| 730 | -@ } | |
| 731 | -@ | |
| 732 | -@ set re {<span class="diff([a-z]+)">([^<]*)</span>} | |
| 733 | -@ # Use \r as separator since it can't appear in the diff output (it gets | |
| 734 | -@ # converted to a space). | |
| 735 | -@ set str [regsub -all $re $str "\r\\1\r\\2\r"] | |
| 736 | -@ foreach {pre class mid} [split $str \r] { | |
| 737 | -@ if {$class ne ""} { | |
| 738 | -@ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -] | |
| 739 | -@ } else { | |
| 740 | -@ $c insert end [dehtml $pre] - | |
| 741 | -@ } | |
| 742 | -@ } | |
| 743 | -@ } | |
| 744 | -@ | |
| 745 | -@ if {$errMsg ne ""} { | |
| 746 | -@ foreach c {.txtA .txtB} {$c insert end [string trim $errMsg] err} | |
| 747 | -@ foreach c [cols] {$c insert end \n -} | |
| 748 | -@ } | |
| 749 | -@ } | |
| 750 | -@ | |
| 751 | -@ foreach c [cols] { | |
| 752 | -@ set type [colType $c] | |
| 753 | -@ if {$type ne "txt"} { | |
| 754 | -@ $c config -width $widths($type) | |
| 755 | -@ } | |
| 756 | -@ $c config -state disabled | |
| 757 | -@ } | |
| 758 | -@ if {$nDiffs <= [.wfiles.lb cget -height]} { | |
| 759 | -@ .wfiles.lb config -height $nDiffs | |
| 760 | -@ grid remove .wfiles.sb | |
| 761 | -@ } | |
| 762 | -@ | |
| 763 | -@ return $nDiffs | |
| 764 | -@ } | |
| 765 | -@ | |
| 766 | -@ proc viewDiff {idx} { | |
| 767 | -@ .txtA yview $idx | |
| 768 | -@ .txtA xview moveto 0 | |
| 769 | -@ } | |
| 770 | -@ | |
| 771 | -@ proc cycleDiffs {{reverse 0}} { | |
| 772 | -@ if {$reverse} { | |
| 773 | -@ set range [.txtA tag prevrange fn @0,0 1.0] | |
| 774 | -@ if {$range eq ""} { | |
| 775 | -@ viewDiff {fn.last -1c} | |
| 776 | -@ } else { | |
| 777 | -@ viewDiff [lindex $range 0] | |
| 778 | -@ } | |
| 779 | -@ } else { | |
| 780 | -@ set range [.txtA tag nextrange fn {@0,0 +1c} end] | |
| 781 | -@ if {$range eq "" || [lindex [.txtA yview] 1] == 1} { | |
| 782 | -@ viewDiff fn.first | |
| 783 | -@ } else { | |
| 784 | -@ viewDiff [lindex $range 0] | |
| 785 | -@ } | |
| 786 | -@ } | |
| 787 | -@ } | |
| 788 | -@ | |
| 789 | -@ proc xvis {col} { | |
| 790 | -@ set view [$col xview] | |
| 791 | -@ return [expr {[lindex $view 1]-[lindex $view 0]}] | |
| 792 | -@ } | |
| 793 | -@ | |
| 794 | -@ proc scroll-x {args} { | |
| 795 | -@ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}] | |
| 796 | -@ eval $c xview $args | |
| 797 | -@ } | |
| 798 | -@ | |
| 799 | -@ interp alias {} scroll-y {} .txtA yview | |
| 800 | -@ | |
| 801 | -@ proc noop {args} {} | |
| 802 | -@ | |
| 803 | -@ proc enableSync {axis} { | |
| 804 | -@ update idletasks | |
| 805 | -@ interp alias {} sync-$axis {} | |
| 806 | -@ rename _sync-$axis sync-$axis | |
| 807 | -@ } | |
| 808 | -@ | |
| 809 | -@ proc disableSync {axis} { | |
| 810 | -@ rename sync-$axis _sync-$axis | |
| 811 | -@ interp alias {} sync-$axis {} noop | |
| 812 | -@ } | |
| 813 | -@ | |
| 814 | -@ proc sync-x {col first last} { | |
| 815 | -@ disableSync x | |
| 816 | -@ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}] | |
| 817 | -@ foreach side {A B} { | |
| 818 | -@ set sb .sbx$side | |
| 819 | -@ set xview [.txt$side xview] | |
| 820 | -@ if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} { | |
| 821 | -@ grid $sb | |
| 822 | -@ eval $sb set $xview | |
| 823 | -@ } else { | |
| 824 | -@ grid remove $sb | |
| 825 | -@ } | |
| 826 | -@ } | |
| 827 | -@ enableSync x | |
| 828 | -@ } | |
| 829 | -@ | |
| 830 | -@ proc sync-y {first last} { | |
| 831 | -@ disableSync y | |
| 832 | -@ foreach c [cols] { | |
| 833 | -@ $c yview moveto $first | |
| 834 | -@ } | |
| 835 | -@ if {$first > 0 || $last < 1} { | |
| 836 | -@ grid .sby | |
| 837 | -@ .sby set $first $last | |
| 838 | -@ } else { | |
| 839 | -@ grid remove .sby | |
| 840 | -@ } | |
| 841 | -@ enableSync y | |
| 842 | -@ } | |
| 843 | -@ | |
| 844 | -@ wm withdraw . | |
| 845 | -@ wm title . $CFG(TITLE) | |
| 846 | -@ wm iconname . $CFG(TITLE) | |
| 847 | -@ bind . <q> exit | |
| 848 | -@ bind . <Destroy> {after 0 exit} | |
| 849 | -@ bind . <Tab> {cycleDiffs; break} | |
| 850 | -@ bind . <<PrevWindow>> {cycleDiffs 1; break} | |
| 851 | -@ bind . <Return> { | |
| 852 | -@ event generate .bb.files <1> | |
| 853 | -@ event generate .bb.files <ButtonRelease-1> | |
| 854 | -@ break | |
| 855 | -@ } | |
| 856 | -@ foreach {key axis args} { | |
| 857 | -@ Up y {scroll -5 units} | |
| 858 | -@ Down y {scroll 5 units} | |
| 859 | -@ Left x {scroll -5 units} | |
| 860 | -@ Right x {scroll 5 units} | |
| 861 | -@ Prior y {scroll -1 page} | |
| 862 | -@ Next y {scroll 1 page} | |
| 863 | -@ Home y {moveto 0} | |
| 864 | -@ End y {moveto 1} | |
| 865 | -@ } { | |
| 866 | -@ bind . <$key> "scroll-$axis $args; break" | |
| 867 | -@ bind . <Shift-$key> continue | |
| 868 | -@ } | |
| 869 | -@ | |
| 870 | -@ frame .bb | |
| 871 | -@ ::ttk::menubutton .bb.files -text "Files" | |
| 872 | -@ toplevel .wfiles | |
| 873 | -@ wm withdraw .wfiles | |
| 874 | -@ update idletasks | |
| 875 | -@ wm transient .wfiles . | |
| 876 | -@ wm overrideredirect .wfiles 1 | |
| 877 | -@ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \ | |
| 878 | -@ -yscroll {.wfiles.sb set} | |
| 879 | -@ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview} | |
| 880 | -@ grid .wfiles.lb .wfiles.sb -sticky ns | |
| 881 | -@ bind .bb.files <1> { | |
| 882 | -@ set x [winfo rootx %W] | |
| 883 | -@ set y [expr {[winfo rooty %W]+[winfo height %W]}] | |
| 884 | -@ wm geometry .wfiles +$x+$y | |
| 885 | -@ wm deiconify .wfiles | |
| 886 | -@ focus .wfiles.lb | |
| 887 | -@ } | |
| 888 | -@ bind .wfiles <FocusOut> {wm withdraw .wfiles} | |
| 889 | -@ bind .wfiles <Escape> {focus .} | |
| 890 | -@ foreach evt {1 Return} { | |
| 891 | -@ bind .wfiles.lb <$evt> { | |
| 892 | -@ catch { | |
| 893 | -@ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]] | |
| 894 | -@ viewDiff $idx | |
| 895 | -@ } | |
| 896 | -@ focus . | |
| 897 | -@ break | |
| 898 | -@ } | |
| 899 | -@ } | |
| 900 | -@ bind .wfiles.lb <Motion> { | |
| 901 | -@ %W selection clear 0 end | |
| 902 | -@ %W selection set @%x,%y | |
| 903 | -@ } | |
| 904 | -@ | |
| 905 | -@ foreach {side syncCol} {A .txtB B .txtA} { | |
| 906 | -@ set ln .ln$side | |
| 907 | -@ text $ln | |
| 908 | -@ $ln tag config - -justify right | |
| 909 | -@ | |
| 910 | -@ set txt .txt$side | |
| 911 | -@ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \ | |
| 912 | -@ -xscroll "sync-x $syncCol" | |
| 913 | -@ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5 | |
| 914 | -@ foreach tag {add rm chng} { | |
| 915 | -@ $txt tag config $tag -background $CFG([string toupper $tag]_BG) | |
| 916 | -@ $txt tag lower $tag | |
| 917 | -@ } | |
| 918 | -@ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \ | |
| 919 | -@ -justify center | |
| 920 | -@ $txt tag config err -foreground $CFG(ERR_FG) | |
| 921 | -@ } | |
| 922 | -@ text .mkr | |
| 923 | -@ | |
| 924 | -@ foreach c [cols] { | |
| 925 | -@ set keyPrefix [string toupper [colType $c]]_COL_ | |
| 926 | -@ if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}} | |
| 927 | -@ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \ | |
| 928 | -@ -padx $CFG(PADX) -yscroll sync-y | |
| 929 | -@ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \ | |
| 930 | -@ -foreground $CFG(HR_FG) | |
| 931 | -@ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD) | |
| 932 | -@ bindtags $c ". $c Text all" | |
| 933 | -@ bind $c <1> {focus %W} | |
| 934 | -@ } | |
| 935 | -@ | |
| 936 | -@ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical | |
| 937 | -@ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal | |
| 938 | -@ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal | |
| 939 | -@ frame .spacer | |
| 940 | -@ | |
| 941 | -@ if {[readDiffs $fossilcmd] == 0} { | |
| 942 | -@ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes" | |
| 943 | -@ exit | |
| 944 | -@ } | |
| 945 | -@ update idletasks | |
| 946 | -@ | |
| 947 | -@ proc saveDiff {} { | |
| 948 | -@ set fn [tk_getSaveFile] | |
| 949 | -@ if {$fn==""} return | |
| 950 | -@ set out [open $fn wb] | |
| 951 | -@ puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'" | |
| 952 | -@ puts $out "# to see the graphical diff.\n#" | |
| 953 | -@ puts $out "set fossilcmd {}" | |
| 954 | -@ puts $out "set prog [list $::prog]" | |
| 955 | -@ puts $out "set difftxt \173" | |
| 956 | -@ foreach e $::difftxt {puts $out [list $e]} | |
| 957 | -@ puts $out "\175" | |
| 958 | -@ puts $out "eval \$prog" | |
| 959 | -@ close $out | |
| 960 | -@ } | |
| 961 | -@ proc invertDiff {} { | |
| 962 | -@ global CFG | |
| 963 | -@ array set x [grid info .txtA] | |
| 964 | -@ if {$x(-column)==1} { | |
| 965 | -@ grid config .lnB -column 0 | |
| 966 | -@ grid config .txtB -column 1 | |
| 967 | -@ .txtB tag config add -background $CFG(RM_BG) | |
| 968 | -@ grid config .lnA -column 3 | |
| 969 | -@ grid config .txtA -column 4 | |
| 970 | -@ .txtA tag config rm -background $CFG(ADD_BG) | |
| 971 | -@ } else { | |
| 972 | -@ grid config .lnA -column 0 | |
| 973 | -@ grid config .txtA -column 1 | |
| 974 | -@ .txtA tag config rm -background $CFG(RM_BG) | |
| 975 | -@ grid config .lnB -column 3 | |
| 976 | -@ grid config .txtB -column 4 | |
| 977 | -@ .txtB tag config add -background $CFG(ADD_BG) | |
| 978 | -@ } | |
| 979 | -@ .mkr config -state normal | |
| 980 | -@ set clt [.mkr search -all < 1.0 end] | |
| 981 | -@ set cgt [.mkr search -all > 1.0 end] | |
| 982 | -@ foreach c $clt {.mkr replace $c "$c +1 chars" >} | |
| 983 | -@ foreach c $cgt {.mkr replace $c "$c +1 chars" <} | |
| 984 | -@ .mkr config -state disabled | |
| 985 | -@ } | |
| 986 | -@ ::ttk::button .bb.quit -text {Quit} -command exit | |
| 987 | -@ ::ttk::button .bb.invert -text {Invert} -command invertDiff | |
| 988 | -@ ::ttk::button .bb.save -text {Save As...} -command saveDiff | |
| 989 | -@ pack .bb.quit .bb.invert -side left | |
| 990 | -@ if {$fossilcmd!=""} {pack .bb.save -side left} | |
| 991 | -@ pack .bb.files -side left | |
| 992 | -@ grid rowconfigure . 1 -weight 1 | |
| 993 | -@ grid columnconfigure . 1 -weight 1 | |
| 994 | -@ grid columnconfigure . 4 -weight 1 | |
| 995 | -@ grid .bb -row 0 -columnspan 6 | |
| 996 | -@ eval grid [cols] -row 1 -sticky nsew | |
| 997 | -@ grid .sby -row 1 -column 5 -sticky ns | |
| 998 | -@ grid .sbxA -row 2 -columnspan 2 -sticky ew | |
| 999 | -@ grid .spacer -row 2 -column 2 | |
| 1000 | -@ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew | |
| 1001 | -@ | |
| 1002 | -@ .spacer config -height [winfo height .sbxA] | |
| 1003 | -@ wm deiconify . | |
| 1004 | -@ } | |
| 1005 | -@ eval $prog | |
| 1006 | -; | |
| 1007 | - | |
| 1008 | 622 | /* |
| 1009 | 623 | ** Show diff output in a Tcl/Tk window, in response to the --tk option |
| 1010 | 624 | ** to the diff command. |
| 1011 | 625 | ** |
| 1012 | 626 | ** If fossil has direct access to a Tcl interpreter (either loaded |
| @@ -1040,11 +654,11 @@ | ||
| 1040 | 654 | int j; |
| 1041 | 655 | blob_append(&script, " ", 1); |
| 1042 | 656 | for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]); |
| 1043 | 657 | } |
| 1044 | 658 | } |
| 1045 | - blob_appendf(&script, "}\n%s", zDiffScript); | |
| 659 | + blob_appendf(&script, "}\n%s", builtin_file("diff.tcl", 0)); | |
| 1046 | 660 | if( zTempFile ){ |
| 1047 | 661 | blob_write_to_file(&script, zTempFile); |
| 1048 | 662 | fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile); |
| 1049 | 663 | }else{ |
| 1050 | 664 | #if defined(FOSSIL_ENABLE_TCL) |
| 1051 | 665 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -142,17 +142,17 @@ | |
| 142 | Blob cmd; /* Text of command to run */ |
| 143 | |
| 144 | if( !fIncludeBinary ){ |
| 145 | Blob file2; |
| 146 | if( isBin1 ){ |
| 147 | fossil_print(DIFF_CANNOT_COMPUTE_BINARY); |
| 148 | return; |
| 149 | } |
| 150 | if( zBinGlob ){ |
| 151 | Glob *pBinary = glob_create(zBinGlob); |
| 152 | if( glob_match(pBinary, zName) ){ |
| 153 | fossil_print(DIFF_CANNOT_COMPUTE_BINARY); |
| 154 | glob_free(pBinary); |
| 155 | return; |
| 156 | } |
| 157 | glob_free(pBinary); |
| 158 | } |
| @@ -163,11 +163,11 @@ | |
| 163 | }else{ |
| 164 | blob_read_from_file(&file2, zFile2); |
| 165 | } |
| 166 | } |
| 167 | if( looks_like_binary(&file2) ){ |
| 168 | fossil_print(DIFF_CANNOT_COMPUTE_BINARY); |
| 169 | blob_reset(&file2); |
| 170 | return; |
| 171 | } |
| 172 | blob_reset(&file2); |
| 173 | } |
| @@ -238,17 +238,17 @@ | |
| 238 | char zTemp1[300]; |
| 239 | char zTemp2[300]; |
| 240 | |
| 241 | if( !fIncludeBinary ){ |
| 242 | if( isBin1 || isBin2 ){ |
| 243 | fossil_print(DIFF_CANNOT_COMPUTE_BINARY); |
| 244 | return; |
| 245 | } |
| 246 | if( zBinGlob ){ |
| 247 | Glob *pBinary = glob_create(zBinGlob); |
| 248 | if( glob_match(pBinary, zName) ){ |
| 249 | fossil_print(DIFF_CANNOT_COMPUTE_BINARY); |
| 250 | glob_free(pBinary); |
| 251 | return; |
| 252 | } |
| 253 | glob_free(pBinary); |
| 254 | } |
| @@ -302,11 +302,11 @@ | |
| 302 | int isBin; |
| 303 | file_tree_name(zFileTreeName, &fname, 1); |
| 304 | historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, |
| 305 | fIncludeBinary ? 0 : &isBin, 0); |
| 306 | if( !isLink != !file_wd_islink(zFrom) ){ |
| 307 | fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); |
| 308 | }else{ |
| 309 | diff_file(&content, isBin, zFileTreeName, zFileTreeName, |
| 310 | zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); |
| 311 | } |
| 312 | blob_reset(&content); |
| @@ -346,11 +346,11 @@ | |
| 346 | int rid = name_to_typed_rid(zFrom, "ci"); |
| 347 | if( !is_a_version(rid) ){ |
| 348 | fossil_fatal("no such check-in: %s", zFrom); |
| 349 | } |
| 350 | load_vfile_from_rid(rid); |
| 351 | blob_appendf(&sql, |
| 352 | "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink" |
| 353 | " FROM vfile v1, vfile v2 " |
| 354 | " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d" |
| 355 | " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)" |
| 356 | "UNION " |
| @@ -367,20 +367,20 @@ | |
| 367 | " WHERE v1.vid=%d AND v1.pathname=v2.pathname)" |
| 368 | " ORDER BY 1", |
| 369 | rid, vid, rid, vid, vid, rid |
| 370 | ); |
| 371 | }else{ |
| 372 | blob_appendf(&sql, |
| 373 | "SELECT pathname, deleted, chnged , rid==0, rid, islink" |
| 374 | " FROM vfile" |
| 375 | " WHERE vid=%d" |
| 376 | " AND (deleted OR chnged OR rid==0)" |
| 377 | " ORDER BY pathname", |
| 378 | vid |
| 379 | ); |
| 380 | } |
| 381 | db_prepare(&q, blob_str(&sql)); |
| 382 | while( db_step(&q)==SQLITE_ROW ){ |
| 383 | const char *zPathname = db_column_text(&q,0); |
| 384 | int isDeleted = db_column_int(&q, 1); |
| 385 | int isChnged = db_column_int(&q,2); |
| 386 | int isNew = db_column_int(&q,3); |
| @@ -408,11 +408,11 @@ | |
| 408 | Blob content; |
| 409 | int isBin; |
| 410 | if( !isLink != !file_wd_islink(zFullName) ){ |
| 411 | diff_print_index(zPathname, diffFlags); |
| 412 | diff_print_filenames(zPathname, zPathname, diffFlags); |
| 413 | fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); |
| 414 | continue; |
| 415 | } |
| 416 | if( srcid>0 ){ |
| 417 | content_get(srcid, &content); |
| 418 | }else{ |
| @@ -462,11 +462,11 @@ | |
| 462 | fIncludeBinary ? 0 : &isBin1, 0); |
| 463 | historical_version_of_file(zTo, zName, &v2, &isLink2, 0, |
| 464 | fIncludeBinary ? 0 : &isBin2, 0); |
| 465 | if( isLink1 != isLink2 ){ |
| 466 | diff_print_filenames(zName, zName, diffFlags); |
| 467 | fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); |
| 468 | }else{ |
| 469 | diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd, |
| 470 | zBinGlob, fIncludeBinary, diffFlags); |
| 471 | } |
| 472 | blob_reset(&v1); |
| @@ -617,396 +617,10 @@ | |
| 617 | zName = "diff-command"; |
| 618 | } |
| 619 | return db_get(zName, zDefault); |
| 620 | } |
| 621 | |
| 622 | /* A Tcl/Tk script used to render diff output. |
| 623 | */ |
| 624 | static const char zDiffScript[] = |
| 625 | @ set prog { |
| 626 | @ package require Tk |
| 627 | @ |
| 628 | @ array set CFG { |
| 629 | @ TITLE {Fossil Diff} |
| 630 | @ LN_COL_BG #dddddd |
| 631 | @ LN_COL_FG #444444 |
| 632 | @ TXT_COL_BG #ffffff |
| 633 | @ TXT_COL_FG #000000 |
| 634 | @ MKR_COL_BG #444444 |
| 635 | @ MKR_COL_FG #dddddd |
| 636 | @ CHNG_BG #d0d0ff |
| 637 | @ ADD_BG #c0ffc0 |
| 638 | @ RM_BG #ffc0c0 |
| 639 | @ HR_FG #888888 |
| 640 | @ HR_PAD_TOP 4 |
| 641 | @ HR_PAD_BTM 8 |
| 642 | @ FN_BG #444444 |
| 643 | @ FN_FG #ffffff |
| 644 | @ FN_PAD 5 |
| 645 | @ ERR_FG #ee0000 |
| 646 | @ PADX 5 |
| 647 | @ WIDTH 80 |
| 648 | @ HEIGHT 45 |
| 649 | @ LB_HEIGHT 25 |
| 650 | @ } |
| 651 | @ |
| 652 | @ if {![namespace exists ttk]} { |
| 653 | @ interp alias {} ::ttk::scrollbar {} ::scrollbar |
| 654 | @ interp alias {} ::ttk::menubutton {} ::menubutton |
| 655 | @ } |
| 656 | @ |
| 657 | @ proc dehtml {x} { |
| 658 | @ set x [regsub -all {<[^>]*>} $x {}] |
| 659 | @ return [string map {& & < < > > ' ' " \"} $x] |
| 660 | @ } |
| 661 | @ |
| 662 | @ proc cols {} { |
| 663 | @ return [list .lnA .txtA .mkr .lnB .txtB] |
| 664 | @ } |
| 665 | @ |
| 666 | @ proc colType {c} { |
| 667 | @ regexp {[a-z]+} $c type |
| 668 | @ return $type |
| 669 | @ } |
| 670 | @ |
| 671 | @ proc getLine {difftxt N iivar} { |
| 672 | @ upvar $iivar ii |
| 673 | @ if {$ii>=$N} {return -1} |
| 674 | @ set x [lindex $difftxt $ii] |
| 675 | @ incr ii |
| 676 | @ return $x |
| 677 | @ } |
| 678 | @ |
| 679 | @ proc readDiffs {fossilcmd} { |
| 680 | @ global difftxt |
| 681 | @ if {![info exists difftxt]} { |
| 682 | @ set in [open $fossilcmd r] |
| 683 | @ fconfigure $in -encoding utf-8 |
| 684 | @ set difftxt [split [read $in] \n] |
| 685 | @ close $in |
| 686 | @ } |
| 687 | @ set N [llength $difftxt] |
| 688 | @ set ii 0 |
| 689 | @ set nDiffs 0 |
| 690 | @ array set widths {txt 0 ln 0 mkr 0} |
| 691 | @ while {[set line [getLine $difftxt $N ii]] != -1} { |
| 692 | @ set fn2 {} |
| 693 | @ if {![regexp {^=+ (.*?) =+ versus =+ (.*?) =+$} $line all fn fn2] |
| 694 | @ && ![regexp {^=+ (.*?) =+$} $line all fn] |
| 695 | @ } { |
| 696 | @ continue |
| 697 | @ } |
| 698 | @ set errMsg "" |
| 699 | @ set line [getLine $difftxt $N ii] |
| 700 | @ if {[string compare -length 6 $line "<table"] |
| 701 | @ && ![regexp {<p[^>]*>(.+)} $line - errMsg]} { |
| 702 | @ continue |
| 703 | @ } |
| 704 | @ incr nDiffs |
| 705 | @ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}] |
| 706 | @ .wfiles.lb insert end $fn |
| 707 | @ |
| 708 | @ foreach c [cols] { |
| 709 | @ if {$nDiffs > 1} { |
| 710 | @ $c insert end \n - |
| 711 | @ } |
| 712 | @ if {[colType $c] eq "txt"} { |
| 713 | @ $c insert end $fn\n fn |
| 714 | @ if {$fn2!=""} {set fn $fn2} |
| 715 | @ } else { |
| 716 | @ $c insert end \n fn |
| 717 | @ } |
| 718 | @ $c insert end \n - |
| 719 | @ |
| 720 | @ if {$errMsg ne ""} continue |
| 721 | @ while {[getLine $difftxt $N ii] ne "<pre>"} continue |
| 722 | @ set type [colType $c] |
| 723 | @ set str {} |
| 724 | @ while {[set line [getLine $difftxt $N ii]] ne "</pre>"} { |
| 725 | @ set len [string length [dehtml $line]] |
| 726 | @ if {$len > $widths($type)} { |
| 727 | @ set widths($type) $len |
| 728 | @ } |
| 729 | @ append str $line\n |
| 730 | @ } |
| 731 | @ |
| 732 | @ set re {<span class="diff([a-z]+)">([^<]*)</span>} |
| 733 | @ # Use \r as separator since it can't appear in the diff output (it gets |
| 734 | @ # converted to a space). |
| 735 | @ set str [regsub -all $re $str "\r\\1\r\\2\r"] |
| 736 | @ foreach {pre class mid} [split $str \r] { |
| 737 | @ if {$class ne ""} { |
| 738 | @ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -] |
| 739 | @ } else { |
| 740 | @ $c insert end [dehtml $pre] - |
| 741 | @ } |
| 742 | @ } |
| 743 | @ } |
| 744 | @ |
| 745 | @ if {$errMsg ne ""} { |
| 746 | @ foreach c {.txtA .txtB} {$c insert end [string trim $errMsg] err} |
| 747 | @ foreach c [cols] {$c insert end \n -} |
| 748 | @ } |
| 749 | @ } |
| 750 | @ |
| 751 | @ foreach c [cols] { |
| 752 | @ set type [colType $c] |
| 753 | @ if {$type ne "txt"} { |
| 754 | @ $c config -width $widths($type) |
| 755 | @ } |
| 756 | @ $c config -state disabled |
| 757 | @ } |
| 758 | @ if {$nDiffs <= [.wfiles.lb cget -height]} { |
| 759 | @ .wfiles.lb config -height $nDiffs |
| 760 | @ grid remove .wfiles.sb |
| 761 | @ } |
| 762 | @ |
| 763 | @ return $nDiffs |
| 764 | @ } |
| 765 | @ |
| 766 | @ proc viewDiff {idx} { |
| 767 | @ .txtA yview $idx |
| 768 | @ .txtA xview moveto 0 |
| 769 | @ } |
| 770 | @ |
| 771 | @ proc cycleDiffs {{reverse 0}} { |
| 772 | @ if {$reverse} { |
| 773 | @ set range [.txtA tag prevrange fn @0,0 1.0] |
| 774 | @ if {$range eq ""} { |
| 775 | @ viewDiff {fn.last -1c} |
| 776 | @ } else { |
| 777 | @ viewDiff [lindex $range 0] |
| 778 | @ } |
| 779 | @ } else { |
| 780 | @ set range [.txtA tag nextrange fn {@0,0 +1c} end] |
| 781 | @ if {$range eq "" || [lindex [.txtA yview] 1] == 1} { |
| 782 | @ viewDiff fn.first |
| 783 | @ } else { |
| 784 | @ viewDiff [lindex $range 0] |
| 785 | @ } |
| 786 | @ } |
| 787 | @ } |
| 788 | @ |
| 789 | @ proc xvis {col} { |
| 790 | @ set view [$col xview] |
| 791 | @ return [expr {[lindex $view 1]-[lindex $view 0]}] |
| 792 | @ } |
| 793 | @ |
| 794 | @ proc scroll-x {args} { |
| 795 | @ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}] |
| 796 | @ eval $c xview $args |
| 797 | @ } |
| 798 | @ |
| 799 | @ interp alias {} scroll-y {} .txtA yview |
| 800 | @ |
| 801 | @ proc noop {args} {} |
| 802 | @ |
| 803 | @ proc enableSync {axis} { |
| 804 | @ update idletasks |
| 805 | @ interp alias {} sync-$axis {} |
| 806 | @ rename _sync-$axis sync-$axis |
| 807 | @ } |
| 808 | @ |
| 809 | @ proc disableSync {axis} { |
| 810 | @ rename sync-$axis _sync-$axis |
| 811 | @ interp alias {} sync-$axis {} noop |
| 812 | @ } |
| 813 | @ |
| 814 | @ proc sync-x {col first last} { |
| 815 | @ disableSync x |
| 816 | @ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}] |
| 817 | @ foreach side {A B} { |
| 818 | @ set sb .sbx$side |
| 819 | @ set xview [.txt$side xview] |
| 820 | @ if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} { |
| 821 | @ grid $sb |
| 822 | @ eval $sb set $xview |
| 823 | @ } else { |
| 824 | @ grid remove $sb |
| 825 | @ } |
| 826 | @ } |
| 827 | @ enableSync x |
| 828 | @ } |
| 829 | @ |
| 830 | @ proc sync-y {first last} { |
| 831 | @ disableSync y |
| 832 | @ foreach c [cols] { |
| 833 | @ $c yview moveto $first |
| 834 | @ } |
| 835 | @ if {$first > 0 || $last < 1} { |
| 836 | @ grid .sby |
| 837 | @ .sby set $first $last |
| 838 | @ } else { |
| 839 | @ grid remove .sby |
| 840 | @ } |
| 841 | @ enableSync y |
| 842 | @ } |
| 843 | @ |
| 844 | @ wm withdraw . |
| 845 | @ wm title . $CFG(TITLE) |
| 846 | @ wm iconname . $CFG(TITLE) |
| 847 | @ bind . <q> exit |
| 848 | @ bind . <Destroy> {after 0 exit} |
| 849 | @ bind . <Tab> {cycleDiffs; break} |
| 850 | @ bind . <<PrevWindow>> {cycleDiffs 1; break} |
| 851 | @ bind . <Return> { |
| 852 | @ event generate .bb.files <1> |
| 853 | @ event generate .bb.files <ButtonRelease-1> |
| 854 | @ break |
| 855 | @ } |
| 856 | @ foreach {key axis args} { |
| 857 | @ Up y {scroll -5 units} |
| 858 | @ Down y {scroll 5 units} |
| 859 | @ Left x {scroll -5 units} |
| 860 | @ Right x {scroll 5 units} |
| 861 | @ Prior y {scroll -1 page} |
| 862 | @ Next y {scroll 1 page} |
| 863 | @ Home y {moveto 0} |
| 864 | @ End y {moveto 1} |
| 865 | @ } { |
| 866 | @ bind . <$key> "scroll-$axis $args; break" |
| 867 | @ bind . <Shift-$key> continue |
| 868 | @ } |
| 869 | @ |
| 870 | @ frame .bb |
| 871 | @ ::ttk::menubutton .bb.files -text "Files" |
| 872 | @ toplevel .wfiles |
| 873 | @ wm withdraw .wfiles |
| 874 | @ update idletasks |
| 875 | @ wm transient .wfiles . |
| 876 | @ wm overrideredirect .wfiles 1 |
| 877 | @ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \ |
| 878 | @ -yscroll {.wfiles.sb set} |
| 879 | @ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview} |
| 880 | @ grid .wfiles.lb .wfiles.sb -sticky ns |
| 881 | @ bind .bb.files <1> { |
| 882 | @ set x [winfo rootx %W] |
| 883 | @ set y [expr {[winfo rooty %W]+[winfo height %W]}] |
| 884 | @ wm geometry .wfiles +$x+$y |
| 885 | @ wm deiconify .wfiles |
| 886 | @ focus .wfiles.lb |
| 887 | @ } |
| 888 | @ bind .wfiles <FocusOut> {wm withdraw .wfiles} |
| 889 | @ bind .wfiles <Escape> {focus .} |
| 890 | @ foreach evt {1 Return} { |
| 891 | @ bind .wfiles.lb <$evt> { |
| 892 | @ catch { |
| 893 | @ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]] |
| 894 | @ viewDiff $idx |
| 895 | @ } |
| 896 | @ focus . |
| 897 | @ break |
| 898 | @ } |
| 899 | @ } |
| 900 | @ bind .wfiles.lb <Motion> { |
| 901 | @ %W selection clear 0 end |
| 902 | @ %W selection set @%x,%y |
| 903 | @ } |
| 904 | @ |
| 905 | @ foreach {side syncCol} {A .txtB B .txtA} { |
| 906 | @ set ln .ln$side |
| 907 | @ text $ln |
| 908 | @ $ln tag config - -justify right |
| 909 | @ |
| 910 | @ set txt .txt$side |
| 911 | @ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \ |
| 912 | @ -xscroll "sync-x $syncCol" |
| 913 | @ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5 |
| 914 | @ foreach tag {add rm chng} { |
| 915 | @ $txt tag config $tag -background $CFG([string toupper $tag]_BG) |
| 916 | @ $txt tag lower $tag |
| 917 | @ } |
| 918 | @ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \ |
| 919 | @ -justify center |
| 920 | @ $txt tag config err -foreground $CFG(ERR_FG) |
| 921 | @ } |
| 922 | @ text .mkr |
| 923 | @ |
| 924 | @ foreach c [cols] { |
| 925 | @ set keyPrefix [string toupper [colType $c]]_COL_ |
| 926 | @ if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}} |
| 927 | @ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \ |
| 928 | @ -padx $CFG(PADX) -yscroll sync-y |
| 929 | @ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \ |
| 930 | @ -foreground $CFG(HR_FG) |
| 931 | @ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD) |
| 932 | @ bindtags $c ". $c Text all" |
| 933 | @ bind $c <1> {focus %W} |
| 934 | @ } |
| 935 | @ |
| 936 | @ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical |
| 937 | @ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal |
| 938 | @ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal |
| 939 | @ frame .spacer |
| 940 | @ |
| 941 | @ if {[readDiffs $fossilcmd] == 0} { |
| 942 | @ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes" |
| 943 | @ exit |
| 944 | @ } |
| 945 | @ update idletasks |
| 946 | @ |
| 947 | @ proc saveDiff {} { |
| 948 | @ set fn [tk_getSaveFile] |
| 949 | @ if {$fn==""} return |
| 950 | @ set out [open $fn wb] |
| 951 | @ puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'" |
| 952 | @ puts $out "# to see the graphical diff.\n#" |
| 953 | @ puts $out "set fossilcmd {}" |
| 954 | @ puts $out "set prog [list $::prog]" |
| 955 | @ puts $out "set difftxt \173" |
| 956 | @ foreach e $::difftxt {puts $out [list $e]} |
| 957 | @ puts $out "\175" |
| 958 | @ puts $out "eval \$prog" |
| 959 | @ close $out |
| 960 | @ } |
| 961 | @ proc invertDiff {} { |
| 962 | @ global CFG |
| 963 | @ array set x [grid info .txtA] |
| 964 | @ if {$x(-column)==1} { |
| 965 | @ grid config .lnB -column 0 |
| 966 | @ grid config .txtB -column 1 |
| 967 | @ .txtB tag config add -background $CFG(RM_BG) |
| 968 | @ grid config .lnA -column 3 |
| 969 | @ grid config .txtA -column 4 |
| 970 | @ .txtA tag config rm -background $CFG(ADD_BG) |
| 971 | @ } else { |
| 972 | @ grid config .lnA -column 0 |
| 973 | @ grid config .txtA -column 1 |
| 974 | @ .txtA tag config rm -background $CFG(RM_BG) |
| 975 | @ grid config .lnB -column 3 |
| 976 | @ grid config .txtB -column 4 |
| 977 | @ .txtB tag config add -background $CFG(ADD_BG) |
| 978 | @ } |
| 979 | @ .mkr config -state normal |
| 980 | @ set clt [.mkr search -all < 1.0 end] |
| 981 | @ set cgt [.mkr search -all > 1.0 end] |
| 982 | @ foreach c $clt {.mkr replace $c "$c +1 chars" >} |
| 983 | @ foreach c $cgt {.mkr replace $c "$c +1 chars" <} |
| 984 | @ .mkr config -state disabled |
| 985 | @ } |
| 986 | @ ::ttk::button .bb.quit -text {Quit} -command exit |
| 987 | @ ::ttk::button .bb.invert -text {Invert} -command invertDiff |
| 988 | @ ::ttk::button .bb.save -text {Save As...} -command saveDiff |
| 989 | @ pack .bb.quit .bb.invert -side left |
| 990 | @ if {$fossilcmd!=""} {pack .bb.save -side left} |
| 991 | @ pack .bb.files -side left |
| 992 | @ grid rowconfigure . 1 -weight 1 |
| 993 | @ grid columnconfigure . 1 -weight 1 |
| 994 | @ grid columnconfigure . 4 -weight 1 |
| 995 | @ grid .bb -row 0 -columnspan 6 |
| 996 | @ eval grid [cols] -row 1 -sticky nsew |
| 997 | @ grid .sby -row 1 -column 5 -sticky ns |
| 998 | @ grid .sbxA -row 2 -columnspan 2 -sticky ew |
| 999 | @ grid .spacer -row 2 -column 2 |
| 1000 | @ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew |
| 1001 | @ |
| 1002 | @ .spacer config -height [winfo height .sbxA] |
| 1003 | @ wm deiconify . |
| 1004 | @ } |
| 1005 | @ eval $prog |
| 1006 | ; |
| 1007 | |
| 1008 | /* |
| 1009 | ** Show diff output in a Tcl/Tk window, in response to the --tk option |
| 1010 | ** to the diff command. |
| 1011 | ** |
| 1012 | ** If fossil has direct access to a Tcl interpreter (either loaded |
| @@ -1040,11 +654,11 @@ | |
| 1040 | int j; |
| 1041 | blob_append(&script, " ", 1); |
| 1042 | for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]); |
| 1043 | } |
| 1044 | } |
| 1045 | blob_appendf(&script, "}\n%s", zDiffScript); |
| 1046 | if( zTempFile ){ |
| 1047 | blob_write_to_file(&script, zTempFile); |
| 1048 | fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile); |
| 1049 | }else{ |
| 1050 | #if defined(FOSSIL_ENABLE_TCL) |
| 1051 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -142,17 +142,17 @@ | |
| 142 | Blob cmd; /* Text of command to run */ |
| 143 | |
| 144 | if( !fIncludeBinary ){ |
| 145 | Blob file2; |
| 146 | if( isBin1 ){ |
| 147 | fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); |
| 148 | return; |
| 149 | } |
| 150 | if( zBinGlob ){ |
| 151 | Glob *pBinary = glob_create(zBinGlob); |
| 152 | if( glob_match(pBinary, zName) ){ |
| 153 | fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); |
| 154 | glob_free(pBinary); |
| 155 | return; |
| 156 | } |
| 157 | glob_free(pBinary); |
| 158 | } |
| @@ -163,11 +163,11 @@ | |
| 163 | }else{ |
| 164 | blob_read_from_file(&file2, zFile2); |
| 165 | } |
| 166 | } |
| 167 | if( looks_like_binary(&file2) ){ |
| 168 | fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); |
| 169 | blob_reset(&file2); |
| 170 | return; |
| 171 | } |
| 172 | blob_reset(&file2); |
| 173 | } |
| @@ -238,17 +238,17 @@ | |
| 238 | char zTemp1[300]; |
| 239 | char zTemp2[300]; |
| 240 | |
| 241 | if( !fIncludeBinary ){ |
| 242 | if( isBin1 || isBin2 ){ |
| 243 | fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); |
| 244 | return; |
| 245 | } |
| 246 | if( zBinGlob ){ |
| 247 | Glob *pBinary = glob_create(zBinGlob); |
| 248 | if( glob_match(pBinary, zName) ){ |
| 249 | fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY); |
| 250 | glob_free(pBinary); |
| 251 | return; |
| 252 | } |
| 253 | glob_free(pBinary); |
| 254 | } |
| @@ -302,11 +302,11 @@ | |
| 302 | int isBin; |
| 303 | file_tree_name(zFileTreeName, &fname, 1); |
| 304 | historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, |
| 305 | fIncludeBinary ? 0 : &isBin, 0); |
| 306 | if( !isLink != !file_wd_islink(zFrom) ){ |
| 307 | fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); |
| 308 | }else{ |
| 309 | diff_file(&content, isBin, zFileTreeName, zFileTreeName, |
| 310 | zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); |
| 311 | } |
| 312 | blob_reset(&content); |
| @@ -346,11 +346,11 @@ | |
| 346 | int rid = name_to_typed_rid(zFrom, "ci"); |
| 347 | if( !is_a_version(rid) ){ |
| 348 | fossil_fatal("no such check-in: %s", zFrom); |
| 349 | } |
| 350 | load_vfile_from_rid(rid); |
| 351 | blob_append_sql(&sql, |
| 352 | "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink" |
| 353 | " FROM vfile v1, vfile v2 " |
| 354 | " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d" |
| 355 | " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)" |
| 356 | "UNION " |
| @@ -367,20 +367,20 @@ | |
| 367 | " WHERE v1.vid=%d AND v1.pathname=v2.pathname)" |
| 368 | " ORDER BY 1", |
| 369 | rid, vid, rid, vid, vid, rid |
| 370 | ); |
| 371 | }else{ |
| 372 | blob_append_sql(&sql, |
| 373 | "SELECT pathname, deleted, chnged , rid==0, rid, islink" |
| 374 | " FROM vfile" |
| 375 | " WHERE vid=%d" |
| 376 | " AND (deleted OR chnged OR rid==0)" |
| 377 | " ORDER BY pathname", |
| 378 | vid |
| 379 | ); |
| 380 | } |
| 381 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 382 | while( db_step(&q)==SQLITE_ROW ){ |
| 383 | const char *zPathname = db_column_text(&q,0); |
| 384 | int isDeleted = db_column_int(&q, 1); |
| 385 | int isChnged = db_column_int(&q,2); |
| 386 | int isNew = db_column_int(&q,3); |
| @@ -408,11 +408,11 @@ | |
| 408 | Blob content; |
| 409 | int isBin; |
| 410 | if( !isLink != !file_wd_islink(zFullName) ){ |
| 411 | diff_print_index(zPathname, diffFlags); |
| 412 | diff_print_filenames(zPathname, zPathname, diffFlags); |
| 413 | fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); |
| 414 | continue; |
| 415 | } |
| 416 | if( srcid>0 ){ |
| 417 | content_get(srcid, &content); |
| 418 | }else{ |
| @@ -462,11 +462,11 @@ | |
| 462 | fIncludeBinary ? 0 : &isBin1, 0); |
| 463 | historical_version_of_file(zTo, zName, &v2, &isLink2, 0, |
| 464 | fIncludeBinary ? 0 : &isBin2, 0); |
| 465 | if( isLink1 != isLink2 ){ |
| 466 | diff_print_filenames(zName, zName, diffFlags); |
| 467 | fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); |
| 468 | }else{ |
| 469 | diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd, |
| 470 | zBinGlob, fIncludeBinary, diffFlags); |
| 471 | } |
| 472 | blob_reset(&v1); |
| @@ -617,396 +617,10 @@ | |
| 617 | zName = "diff-command"; |
| 618 | } |
| 619 | return db_get(zName, zDefault); |
| 620 | } |
| 621 | |
| 622 | /* |
| 623 | ** Show diff output in a Tcl/Tk window, in response to the --tk option |
| 624 | ** to the diff command. |
| 625 | ** |
| 626 | ** If fossil has direct access to a Tcl interpreter (either loaded |
| @@ -1040,11 +654,11 @@ | |
| 654 | int j; |
| 655 | blob_append(&script, " ", 1); |
| 656 | for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]); |
| 657 | } |
| 658 | } |
| 659 | blob_appendf(&script, "}\n%s", builtin_file("diff.tcl", 0)); |
| 660 | if( zTempFile ){ |
| 661 | blob_write_to_file(&script, zTempFile); |
| 662 | fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile); |
| 663 | }else{ |
| 664 | #if defined(FOSSIL_ENABLE_TCL) |
| 665 |
+69
-71
| --- src/doc.c | ||
| +++ src/doc.c | ||
| @@ -26,11 +26,11 @@ | ||
| 26 | 26 | ** Try to guess the mimetype from content. |
| 27 | 27 | ** |
| 28 | 28 | ** If the content is pure text, return NULL. |
| 29 | 29 | ** |
| 30 | 30 | ** For image types, attempt to return an appropriate mimetype |
| 31 | -** name like "image/gif" or "image/jpeg". | |
| 31 | +** name like "image/gif" or "image/jpeg". | |
| 32 | 32 | ** |
| 33 | 33 | ** For any other binary type, return "unknown/unknown". |
| 34 | 34 | */ |
| 35 | 35 | const char *mimetype_from_content(Blob *pBlob){ |
| 36 | 36 | int i; |
| @@ -83,11 +83,11 @@ | ||
| 83 | 83 | int i; |
| 84 | 84 | int first, last; |
| 85 | 85 | int len; |
| 86 | 86 | char zSuffix[20]; |
| 87 | 87 | |
| 88 | - /* A table of mimetypes based on file suffixes. | |
| 88 | + /* A table of mimetypes based on file suffixes. | |
| 89 | 89 | ** Suffixes must be in sorted order so that we can do a binary |
| 90 | 90 | ** search to find the mime-type |
| 91 | 91 | */ |
| 92 | 92 | static const struct { |
| 93 | 93 | const char *zSuffix; /* The file suffix */ |
| @@ -487,11 +487,11 @@ | ||
| 487 | 487 | db_end_transaction(0); |
| 488 | 488 | } |
| 489 | 489 | blob_to_utf8_no_bom(&filebody, 0); |
| 490 | 490 | |
| 491 | 491 | /* The file is now contained in the filebody blob. Deliver the |
| 492 | - ** file to the user | |
| 492 | + ** file to the user | |
| 493 | 493 | */ |
| 494 | 494 | zMime = P("mimetype"); |
| 495 | 495 | if( zMime==0 ){ |
| 496 | 496 | zMime = mimetype_from_name(zName); |
| 497 | 497 | } |
| @@ -501,11 +501,11 @@ | ||
| 501 | 501 | Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event" |
| 502 | 502 | " WHERE objid=%d AND type='ci'", vid)); |
| 503 | 503 | if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){ |
| 504 | 504 | Blob title, tail; |
| 505 | 505 | if( wiki_find_title(&filebody, &title, &tail) ){ |
| 506 | - style_header(blob_str(&title)); | |
| 506 | + style_header("%s", blob_str(&title)); | |
| 507 | 507 | wiki_convert(&tail, 0, WIKI_BUTTONS); |
| 508 | 508 | }else{ |
| 509 | 509 | style_header("Documentation"); |
| 510 | 510 | wiki_convert(&filebody, 0, WIKI_BUTTONS); |
| 511 | 511 | } |
| @@ -513,11 +513,11 @@ | ||
| 513 | 513 | }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){ |
| 514 | 514 | Blob title = BLOB_INITIALIZER; |
| 515 | 515 | Blob tail = BLOB_INITIALIZER; |
| 516 | 516 | markdown_to_html(&filebody, &title, &tail); |
| 517 | 517 | if( blob_size(&title)>0 ){ |
| 518 | - style_header(blob_str(&title)); | |
| 518 | + style_header("%s", blob_str(&title)); | |
| 519 | 519 | }else{ |
| 520 | 520 | style_header("Documentation"); |
| 521 | 521 | } |
| 522 | 522 | blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail)); |
| 523 | 523 | style_footer(); |
| @@ -528,15 +528,13 @@ | ||
| 528 | 528 | @ </pre></blockquote> |
| 529 | 529 | style_footer(); |
| 530 | 530 | #ifdef FOSSIL_ENABLE_TH1_DOCS |
| 531 | 531 | }else if( db_get_boolean("th1-docs", 0) && |
| 532 | 532 | fossil_strcmp(zMime, "application/x-th1")==0 ){ |
| 533 | - char *zHtml = htmlize(zName, -1); | |
| 534 | - style_header(zHtml); | |
| 533 | + style_header("%h", zName); | |
| 535 | 534 | Th_Render(blob_str(&filebody)); |
| 536 | 535 | style_footer(); |
| 537 | - fossil_free(zHtml); | |
| 538 | 536 | #endif |
| 539 | 537 | }else{ |
| 540 | 538 | cgi_set_content_type(zMime); |
| 541 | 539 | cgi_set_content(&filebody); |
| 542 | 540 | } |
| @@ -546,79 +544,79 @@ | ||
| 546 | 544 | /* Jump here when unable to locate the document */ |
| 547 | 545 | db_end_transaction(0); |
| 548 | 546 | style_header("Document Not Found"); |
| 549 | 547 | @ <p>No such document: %h(zName)</p> |
| 550 | 548 | style_footer(); |
| 551 | - return; | |
| 549 | + return; | |
| 552 | 550 | } |
| 553 | 551 | |
| 554 | 552 | /* |
| 555 | 553 | ** The default logo. |
| 556 | 554 | */ |
| 557 | 555 | static const unsigned char aLogo[] = { |
| 558 | - 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85, | |
| 559 | - 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166, | |
| 560 | - 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184, | |
| 561 | - 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201, | |
| 562 | - 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237, | |
| 563 | - 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0, | |
| 564 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 565 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, | |
| 566 | - 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105, | |
| 567 | - 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56, | |
| 568 | - 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161, | |
| 569 | - 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102, | |
| 570 | - 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242, | |
| 571 | - 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233, | |
| 572 | - 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8, | |
| 573 | - 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6, | |
| 574 | - 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5, | |
| 575 | - 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40, | |
| 576 | - 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40, | |
| 577 | - 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201, | |
| 578 | - 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19, | |
| 579 | - 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100, | |
| 580 | - 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195, | |
| 581 | - 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158, | |
| 582 | - 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176, | |
| 583 | - 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194, | |
| 584 | - 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244, | |
| 585 | - 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182, | |
| 586 | - 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130, | |
| 587 | - 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137, | |
| 588 | - 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224, | |
| 589 | - 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40, | |
| 590 | - 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96, | |
| 591 | - 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250, | |
| 592 | - 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170, | |
| 593 | - 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91, | |
| 594 | - 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219, | |
| 595 | - 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189, | |
| 596 | - 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10, | |
| 597 | - 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17, | |
| 598 | - 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203, | |
| 599 | - 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241, | |
| 600 | - 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141, | |
| 601 | - 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188, | |
| 602 | - 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24, | |
| 603 | - 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2, | |
| 604 | - 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128, | |
| 605 | - 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129, | |
| 606 | - 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196, | |
| 607 | - 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196, | |
| 608 | - 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143, | |
| 609 | - 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131, | |
| 610 | - 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224, | |
| 611 | - 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16, | |
| 612 | - 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66, | |
| 613 | - 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154, | |
| 614 | - 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94, | |
| 615 | - 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197, | |
| 616 | - 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86, | |
| 617 | - 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159, | |
| 618 | - 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13, | |
| 619 | - 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59, | |
| 556 | + 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85, | |
| 557 | + 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166, | |
| 558 | + 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184, | |
| 559 | + 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201, | |
| 560 | + 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237, | |
| 561 | + 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0, | |
| 562 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 563 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, | |
| 564 | + 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105, | |
| 565 | + 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56, | |
| 566 | + 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161, | |
| 567 | + 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102, | |
| 568 | + 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242, | |
| 569 | + 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233, | |
| 570 | + 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8, | |
| 571 | + 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6, | |
| 572 | + 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5, | |
| 573 | + 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40, | |
| 574 | + 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40, | |
| 575 | + 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201, | |
| 576 | + 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19, | |
| 577 | + 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100, | |
| 578 | + 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195, | |
| 579 | + 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158, | |
| 580 | + 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176, | |
| 581 | + 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194, | |
| 582 | + 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244, | |
| 583 | + 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182, | |
| 584 | + 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130, | |
| 585 | + 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137, | |
| 586 | + 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224, | |
| 587 | + 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40, | |
| 588 | + 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96, | |
| 589 | + 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250, | |
| 590 | + 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170, | |
| 591 | + 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91, | |
| 592 | + 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219, | |
| 593 | + 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189, | |
| 594 | + 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10, | |
| 595 | + 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17, | |
| 596 | + 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203, | |
| 597 | + 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241, | |
| 598 | + 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141, | |
| 599 | + 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188, | |
| 600 | + 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24, | |
| 601 | + 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2, | |
| 602 | + 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128, | |
| 603 | + 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129, | |
| 604 | + 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196, | |
| 605 | + 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196, | |
| 606 | + 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143, | |
| 607 | + 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131, | |
| 608 | + 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224, | |
| 609 | + 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16, | |
| 610 | + 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66, | |
| 611 | + 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154, | |
| 612 | + 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94, | |
| 613 | + 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197, | |
| 614 | + 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86, | |
| 615 | + 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159, | |
| 616 | + 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13, | |
| 617 | + 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59, | |
| 620 | 618 | }; |
| 621 | 619 | |
| 622 | 620 | /* |
| 623 | 621 | ** WEBPAGE: logo |
| 624 | 622 | ** |
| 625 | 623 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -26,11 +26,11 @@ | |
| 26 | ** Try to guess the mimetype from content. |
| 27 | ** |
| 28 | ** If the content is pure text, return NULL. |
| 29 | ** |
| 30 | ** For image types, attempt to return an appropriate mimetype |
| 31 | ** name like "image/gif" or "image/jpeg". |
| 32 | ** |
| 33 | ** For any other binary type, return "unknown/unknown". |
| 34 | */ |
| 35 | const char *mimetype_from_content(Blob *pBlob){ |
| 36 | int i; |
| @@ -83,11 +83,11 @@ | |
| 83 | int i; |
| 84 | int first, last; |
| 85 | int len; |
| 86 | char zSuffix[20]; |
| 87 | |
| 88 | /* A table of mimetypes based on file suffixes. |
| 89 | ** Suffixes must be in sorted order so that we can do a binary |
| 90 | ** search to find the mime-type |
| 91 | */ |
| 92 | static const struct { |
| 93 | const char *zSuffix; /* The file suffix */ |
| @@ -487,11 +487,11 @@ | |
| 487 | db_end_transaction(0); |
| 488 | } |
| 489 | blob_to_utf8_no_bom(&filebody, 0); |
| 490 | |
| 491 | /* The file is now contained in the filebody blob. Deliver the |
| 492 | ** file to the user |
| 493 | */ |
| 494 | zMime = P("mimetype"); |
| 495 | if( zMime==0 ){ |
| 496 | zMime = mimetype_from_name(zName); |
| 497 | } |
| @@ -501,11 +501,11 @@ | |
| 501 | Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event" |
| 502 | " WHERE objid=%d AND type='ci'", vid)); |
| 503 | if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){ |
| 504 | Blob title, tail; |
| 505 | if( wiki_find_title(&filebody, &title, &tail) ){ |
| 506 | style_header(blob_str(&title)); |
| 507 | wiki_convert(&tail, 0, WIKI_BUTTONS); |
| 508 | }else{ |
| 509 | style_header("Documentation"); |
| 510 | wiki_convert(&filebody, 0, WIKI_BUTTONS); |
| 511 | } |
| @@ -513,11 +513,11 @@ | |
| 513 | }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){ |
| 514 | Blob title = BLOB_INITIALIZER; |
| 515 | Blob tail = BLOB_INITIALIZER; |
| 516 | markdown_to_html(&filebody, &title, &tail); |
| 517 | if( blob_size(&title)>0 ){ |
| 518 | style_header(blob_str(&title)); |
| 519 | }else{ |
| 520 | style_header("Documentation"); |
| 521 | } |
| 522 | blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail)); |
| 523 | style_footer(); |
| @@ -528,15 +528,13 @@ | |
| 528 | @ </pre></blockquote> |
| 529 | style_footer(); |
| 530 | #ifdef FOSSIL_ENABLE_TH1_DOCS |
| 531 | }else if( db_get_boolean("th1-docs", 0) && |
| 532 | fossil_strcmp(zMime, "application/x-th1")==0 ){ |
| 533 | char *zHtml = htmlize(zName, -1); |
| 534 | style_header(zHtml); |
| 535 | Th_Render(blob_str(&filebody)); |
| 536 | style_footer(); |
| 537 | fossil_free(zHtml); |
| 538 | #endif |
| 539 | }else{ |
| 540 | cgi_set_content_type(zMime); |
| 541 | cgi_set_content(&filebody); |
| 542 | } |
| @@ -546,79 +544,79 @@ | |
| 546 | /* Jump here when unable to locate the document */ |
| 547 | db_end_transaction(0); |
| 548 | style_header("Document Not Found"); |
| 549 | @ <p>No such document: %h(zName)</p> |
| 550 | style_footer(); |
| 551 | return; |
| 552 | } |
| 553 | |
| 554 | /* |
| 555 | ** The default logo. |
| 556 | */ |
| 557 | static const unsigned char aLogo[] = { |
| 558 | 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85, |
| 559 | 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166, |
| 560 | 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184, |
| 561 | 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201, |
| 562 | 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237, |
| 563 | 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0, |
| 564 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 565 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, |
| 566 | 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105, |
| 567 | 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56, |
| 568 | 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161, |
| 569 | 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102, |
| 570 | 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242, |
| 571 | 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233, |
| 572 | 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8, |
| 573 | 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6, |
| 574 | 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5, |
| 575 | 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40, |
| 576 | 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40, |
| 577 | 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201, |
| 578 | 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19, |
| 579 | 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100, |
| 580 | 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195, |
| 581 | 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158, |
| 582 | 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176, |
| 583 | 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194, |
| 584 | 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244, |
| 585 | 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182, |
| 586 | 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130, |
| 587 | 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137, |
| 588 | 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224, |
| 589 | 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40, |
| 590 | 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96, |
| 591 | 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250, |
| 592 | 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170, |
| 593 | 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91, |
| 594 | 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219, |
| 595 | 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189, |
| 596 | 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10, |
| 597 | 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17, |
| 598 | 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203, |
| 599 | 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241, |
| 600 | 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141, |
| 601 | 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188, |
| 602 | 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24, |
| 603 | 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2, |
| 604 | 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128, |
| 605 | 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129, |
| 606 | 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196, |
| 607 | 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196, |
| 608 | 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143, |
| 609 | 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131, |
| 610 | 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224, |
| 611 | 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16, |
| 612 | 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66, |
| 613 | 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154, |
| 614 | 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94, |
| 615 | 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197, |
| 616 | 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86, |
| 617 | 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159, |
| 618 | 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13, |
| 619 | 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59, |
| 620 | }; |
| 621 | |
| 622 | /* |
| 623 | ** WEBPAGE: logo |
| 624 | ** |
| 625 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -26,11 +26,11 @@ | |
| 26 | ** Try to guess the mimetype from content. |
| 27 | ** |
| 28 | ** If the content is pure text, return NULL. |
| 29 | ** |
| 30 | ** For image types, attempt to return an appropriate mimetype |
| 31 | ** name like "image/gif" or "image/jpeg". |
| 32 | ** |
| 33 | ** For any other binary type, return "unknown/unknown". |
| 34 | */ |
| 35 | const char *mimetype_from_content(Blob *pBlob){ |
| 36 | int i; |
| @@ -83,11 +83,11 @@ | |
| 83 | int i; |
| 84 | int first, last; |
| 85 | int len; |
| 86 | char zSuffix[20]; |
| 87 | |
| 88 | /* A table of mimetypes based on file suffixes. |
| 89 | ** Suffixes must be in sorted order so that we can do a binary |
| 90 | ** search to find the mime-type |
| 91 | */ |
| 92 | static const struct { |
| 93 | const char *zSuffix; /* The file suffix */ |
| @@ -487,11 +487,11 @@ | |
| 487 | db_end_transaction(0); |
| 488 | } |
| 489 | blob_to_utf8_no_bom(&filebody, 0); |
| 490 | |
| 491 | /* The file is now contained in the filebody blob. Deliver the |
| 492 | ** file to the user |
| 493 | */ |
| 494 | zMime = P("mimetype"); |
| 495 | if( zMime==0 ){ |
| 496 | zMime = mimetype_from_name(zName); |
| 497 | } |
| @@ -501,11 +501,11 @@ | |
| 501 | Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event" |
| 502 | " WHERE objid=%d AND type='ci'", vid)); |
| 503 | if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){ |
| 504 | Blob title, tail; |
| 505 | if( wiki_find_title(&filebody, &title, &tail) ){ |
| 506 | style_header("%s", blob_str(&title)); |
| 507 | wiki_convert(&tail, 0, WIKI_BUTTONS); |
| 508 | }else{ |
| 509 | style_header("Documentation"); |
| 510 | wiki_convert(&filebody, 0, WIKI_BUTTONS); |
| 511 | } |
| @@ -513,11 +513,11 @@ | |
| 513 | }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){ |
| 514 | Blob title = BLOB_INITIALIZER; |
| 515 | Blob tail = BLOB_INITIALIZER; |
| 516 | markdown_to_html(&filebody, &title, &tail); |
| 517 | if( blob_size(&title)>0 ){ |
| 518 | style_header("%s", blob_str(&title)); |
| 519 | }else{ |
| 520 | style_header("Documentation"); |
| 521 | } |
| 522 | blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail)); |
| 523 | style_footer(); |
| @@ -528,15 +528,13 @@ | |
| 528 | @ </pre></blockquote> |
| 529 | style_footer(); |
| 530 | #ifdef FOSSIL_ENABLE_TH1_DOCS |
| 531 | }else if( db_get_boolean("th1-docs", 0) && |
| 532 | fossil_strcmp(zMime, "application/x-th1")==0 ){ |
| 533 | style_header("%h", zName); |
| 534 | Th_Render(blob_str(&filebody)); |
| 535 | style_footer(); |
| 536 | #endif |
| 537 | }else{ |
| 538 | cgi_set_content_type(zMime); |
| 539 | cgi_set_content(&filebody); |
| 540 | } |
| @@ -546,79 +544,79 @@ | |
| 544 | /* Jump here when unable to locate the document */ |
| 545 | db_end_transaction(0); |
| 546 | style_header("Document Not Found"); |
| 547 | @ <p>No such document: %h(zName)</p> |
| 548 | style_footer(); |
| 549 | return; |
| 550 | } |
| 551 | |
| 552 | /* |
| 553 | ** The default logo. |
| 554 | */ |
| 555 | static const unsigned char aLogo[] = { |
| 556 | 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85, |
| 557 | 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166, |
| 558 | 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184, |
| 559 | 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201, |
| 560 | 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237, |
| 561 | 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0, |
| 562 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 563 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, |
| 564 | 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105, |
| 565 | 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56, |
| 566 | 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161, |
| 567 | 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102, |
| 568 | 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242, |
| 569 | 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233, |
| 570 | 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8, |
| 571 | 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6, |
| 572 | 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5, |
| 573 | 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40, |
| 574 | 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40, |
| 575 | 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201, |
| 576 | 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19, |
| 577 | 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100, |
| 578 | 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195, |
| 579 | 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158, |
| 580 | 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176, |
| 581 | 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194, |
| 582 | 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244, |
| 583 | 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182, |
| 584 | 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130, |
| 585 | 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137, |
| 586 | 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224, |
| 587 | 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40, |
| 588 | 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96, |
| 589 | 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250, |
| 590 | 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170, |
| 591 | 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91, |
| 592 | 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219, |
| 593 | 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189, |
| 594 | 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10, |
| 595 | 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17, |
| 596 | 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203, |
| 597 | 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241, |
| 598 | 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141, |
| 599 | 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188, |
| 600 | 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24, |
| 601 | 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2, |
| 602 | 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128, |
| 603 | 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129, |
| 604 | 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196, |
| 605 | 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196, |
| 606 | 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143, |
| 607 | 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131, |
| 608 | 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224, |
| 609 | 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16, |
| 610 | 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66, |
| 611 | 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154, |
| 612 | 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94, |
| 613 | 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197, |
| 614 | 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86, |
| 615 | 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159, |
| 616 | 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13, |
| 617 | 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59, |
| 618 | }; |
| 619 | |
| 620 | /* |
| 621 | ** WEBPAGE: logo |
| 622 | ** |
| 623 |
+27
-27
| --- src/encode.c | ||
| +++ src/encode.c | ||
| @@ -47,30 +47,30 @@ | ||
| 47 | 47 | } |
| 48 | 48 | i = 0; |
| 49 | 49 | zOut = fossil_malloc( count+1 ); |
| 50 | 50 | while( n-->0 && (c = *zIn)!=0 ){ |
| 51 | 51 | switch( c ){ |
| 52 | - case '<': | |
| 52 | + case '<': | |
| 53 | 53 | zOut[i++] = '&'; |
| 54 | 54 | zOut[i++] = 'l'; |
| 55 | 55 | zOut[i++] = 't'; |
| 56 | 56 | zOut[i++] = ';'; |
| 57 | 57 | break; |
| 58 | - case '>': | |
| 58 | + case '>': | |
| 59 | 59 | zOut[i++] = '&'; |
| 60 | 60 | zOut[i++] = 'g'; |
| 61 | 61 | zOut[i++] = 't'; |
| 62 | 62 | zOut[i++] = ';'; |
| 63 | 63 | break; |
| 64 | - case '&': | |
| 64 | + case '&': | |
| 65 | 65 | zOut[i++] = '&'; |
| 66 | 66 | zOut[i++] = 'a'; |
| 67 | 67 | zOut[i++] = 'm'; |
| 68 | 68 | zOut[i++] = 'p'; |
| 69 | 69 | zOut[i++] = ';'; |
| 70 | 70 | break; |
| 71 | - case '"': | |
| 71 | + case '"': | |
| 72 | 72 | zOut[i++] = '&'; |
| 73 | 73 | zOut[i++] = 'q'; |
| 74 | 74 | zOut[i++] = 'u'; |
| 75 | 75 | zOut[i++] = 'o'; |
| 76 | 76 | zOut[i++] = 't'; |
| @@ -181,11 +181,11 @@ | ||
| 181 | 181 | /* |
| 182 | 182 | ** Convert the input string into a form that is suitable for use as |
| 183 | 183 | ** a token in the HTTP protocol. Spaces are encoded as '+' and special |
| 184 | 184 | ** characters are encoded as "%HH" where HH is a two-digit hexidecimal |
| 185 | 185 | ** representation of the character. The "/" character is not encoded |
| 186 | -** by this routine. | |
| 186 | +** by this routine. | |
| 187 | 187 | */ |
| 188 | 188 | char *urlize(const char *z, int n){ |
| 189 | 189 | return EncodeHttp(z, n, 0); |
| 190 | 190 | } |
| 191 | 191 | |
| @@ -327,11 +327,11 @@ | ||
| 327 | 327 | |
| 328 | 328 | |
| 329 | 329 | /* |
| 330 | 330 | ** The characters used for HTTP base64 encoding. |
| 331 | 331 | */ |
| 332 | -static unsigned char zBase[] = | |
| 332 | +static unsigned char zBase[] = | |
| 333 | 333 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 334 | 334 | |
| 335 | 335 | /* |
| 336 | 336 | ** Encode a string using a base-64 encoding. |
| 337 | 337 | ** The encoding can be reversed using the <b>decode64</b> function. |
| @@ -366,11 +366,11 @@ | ||
| 366 | 366 | z64[n] = 0; |
| 367 | 367 | return z64; |
| 368 | 368 | } |
| 369 | 369 | |
| 370 | 370 | /* |
| 371 | -** COMMAND: test-encode64 | |
| 371 | +** COMMAND: test-encode64 | |
| 372 | 372 | ** Usage: %fossil test-encode64 STRING |
| 373 | 373 | */ |
| 374 | 374 | void test_encode64_cmd(void){ |
| 375 | 375 | char *z; |
| 376 | 376 | int i; |
| @@ -431,11 +431,11 @@ | ||
| 431 | 431 | *pnByte = j; |
| 432 | 432 | return zData; |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | /* |
| 436 | -** COMMAND: test-decode64 | |
| 436 | +** COMMAND: test-decode64 | |
| 437 | 437 | ** Usage: %fossil test-decode64 STRING |
| 438 | 438 | */ |
| 439 | 439 | void test_decode64_cmd(void){ |
| 440 | 440 | char *z; |
| 441 | 441 | int i, n; |
| @@ -454,11 +454,11 @@ | ||
| 454 | 454 | */ |
| 455 | 455 | |
| 456 | 456 | /* |
| 457 | 457 | ** The array used for encoding |
| 458 | 458 | */ /* 123456789 12345 */ |
| 459 | -static const char zEncode[] = "0123456789abcdef"; | |
| 459 | +static const char zEncode[] = "0123456789abcdef"; | |
| 460 | 460 | |
| 461 | 461 | /* |
| 462 | 462 | ** Encode a N-digit base-256 in base-16. Return zero on success |
| 463 | 463 | ** and non-zero if there is an error. |
| 464 | 464 | */ |
| @@ -473,33 +473,33 @@ | ||
| 473 | 473 | } |
| 474 | 474 | |
| 475 | 475 | /* |
| 476 | 476 | ** An array for translating single base-16 characters into a value. |
| 477 | 477 | ** Disallowed input characters have a value of 64. Upper and lower |
| 478 | -** case is the same. | |
| 478 | +** case is the same. | |
| 479 | 479 | */ |
| 480 | 480 | static const char zDecode[] = { |
| 481 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 482 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 483 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 484 | - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64, | |
| 481 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 482 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 483 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 484 | + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64, | |
| 485 | 485 | 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 486 | 486 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 487 | 487 | 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 488 | 488 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 489 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 490 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 491 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 492 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 493 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 494 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 495 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 496 | - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 489 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 490 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 491 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 492 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 493 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 494 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 495 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 496 | + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
| 497 | 497 | }; |
| 498 | 498 | |
| 499 | 499 | /* |
| 500 | -** Decode a N-character base-16 number into base-256. N must be a | |
| 500 | +** Decode a N-character base-16 number into base-256. N must be a | |
| 501 | 501 | ** multiple of 2. The output buffer must be at least N/2 characters |
| 502 | 502 | ** in length |
| 503 | 503 | */ |
| 504 | 504 | int decode16(const unsigned char *zIn, unsigned char *pOut, int N){ |
| 505 | 505 | int i, j; |
| @@ -545,11 +545,11 @@ | ||
| 545 | 545 | /* Randomness used for XOR-ing by the obscure() and unobscure() routines */ |
| 546 | 546 | static const unsigned char aObscurer[16] = { |
| 547 | 547 | 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86, |
| 548 | 548 | 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85 |
| 549 | 549 | }; |
| 550 | - | |
| 550 | + | |
| 551 | 551 | |
| 552 | 552 | /* |
| 553 | 553 | ** Obscure plain text so that it is not easily readable. |
| 554 | 554 | ** |
| 555 | 555 | ** This is used for storing sensitive information (such as passwords) in a |
| @@ -562,11 +562,11 @@ | ||
| 562 | 562 | */ |
| 563 | 563 | char *obscure(const char *zIn){ |
| 564 | 564 | int n, i; |
| 565 | 565 | unsigned char salt; |
| 566 | 566 | char *zOut; |
| 567 | - | |
| 567 | + | |
| 568 | 568 | if( zIn==0 ) return 0; |
| 569 | 569 | n = strlen(zIn); |
| 570 | 570 | zOut = fossil_malloc( n*2+3 ); |
| 571 | 571 | sqlite3_randomness(1, &salt); |
| 572 | 572 | zOut[n+1] = (char)salt; |
| @@ -578,17 +578,17 @@ | ||
| 578 | 578 | /* |
| 579 | 579 | ** Undo the obscuring of text performed by obscure(). Or, if the input is |
| 580 | 580 | ** not hexadecimal (meaning the input is not the output of obscure()) then |
| 581 | 581 | ** do the equivalent of strdup(). |
| 582 | 582 | ** |
| 583 | -** The result is memory obtained from malloc that should be freed by the caller. | |
| 583 | +** The result is memory obtained from malloc that should be freed by the caller. | |
| 584 | 584 | */ |
| 585 | 585 | char *unobscure(const char *zIn){ |
| 586 | 586 | int n, i; |
| 587 | 587 | unsigned char salt; |
| 588 | 588 | char *zOut; |
| 589 | - | |
| 589 | + | |
| 590 | 590 | if( zIn==0 ) return 0; |
| 591 | 591 | n = strlen(zIn); |
| 592 | 592 | zOut = fossil_malloc( n + 1 ); |
| 593 | 593 | if( n<2 |
| 594 | 594 | || decode16((unsigned char*)zIn, &salt, 2) |
| 595 | 595 |
| --- src/encode.c | |
| +++ src/encode.c | |
| @@ -47,30 +47,30 @@ | |
| 47 | } |
| 48 | i = 0; |
| 49 | zOut = fossil_malloc( count+1 ); |
| 50 | while( n-->0 && (c = *zIn)!=0 ){ |
| 51 | switch( c ){ |
| 52 | case '<': |
| 53 | zOut[i++] = '&'; |
| 54 | zOut[i++] = 'l'; |
| 55 | zOut[i++] = 't'; |
| 56 | zOut[i++] = ';'; |
| 57 | break; |
| 58 | case '>': |
| 59 | zOut[i++] = '&'; |
| 60 | zOut[i++] = 'g'; |
| 61 | zOut[i++] = 't'; |
| 62 | zOut[i++] = ';'; |
| 63 | break; |
| 64 | case '&': |
| 65 | zOut[i++] = '&'; |
| 66 | zOut[i++] = 'a'; |
| 67 | zOut[i++] = 'm'; |
| 68 | zOut[i++] = 'p'; |
| 69 | zOut[i++] = ';'; |
| 70 | break; |
| 71 | case '"': |
| 72 | zOut[i++] = '&'; |
| 73 | zOut[i++] = 'q'; |
| 74 | zOut[i++] = 'u'; |
| 75 | zOut[i++] = 'o'; |
| 76 | zOut[i++] = 't'; |
| @@ -181,11 +181,11 @@ | |
| 181 | /* |
| 182 | ** Convert the input string into a form that is suitable for use as |
| 183 | ** a token in the HTTP protocol. Spaces are encoded as '+' and special |
| 184 | ** characters are encoded as "%HH" where HH is a two-digit hexidecimal |
| 185 | ** representation of the character. The "/" character is not encoded |
| 186 | ** by this routine. |
| 187 | */ |
| 188 | char *urlize(const char *z, int n){ |
| 189 | return EncodeHttp(z, n, 0); |
| 190 | } |
| 191 | |
| @@ -327,11 +327,11 @@ | |
| 327 | |
| 328 | |
| 329 | /* |
| 330 | ** The characters used for HTTP base64 encoding. |
| 331 | */ |
| 332 | static unsigned char zBase[] = |
| 333 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 334 | |
| 335 | /* |
| 336 | ** Encode a string using a base-64 encoding. |
| 337 | ** The encoding can be reversed using the <b>decode64</b> function. |
| @@ -366,11 +366,11 @@ | |
| 366 | z64[n] = 0; |
| 367 | return z64; |
| 368 | } |
| 369 | |
| 370 | /* |
| 371 | ** COMMAND: test-encode64 |
| 372 | ** Usage: %fossil test-encode64 STRING |
| 373 | */ |
| 374 | void test_encode64_cmd(void){ |
| 375 | char *z; |
| 376 | int i; |
| @@ -431,11 +431,11 @@ | |
| 431 | *pnByte = j; |
| 432 | return zData; |
| 433 | } |
| 434 | |
| 435 | /* |
| 436 | ** COMMAND: test-decode64 |
| 437 | ** Usage: %fossil test-decode64 STRING |
| 438 | */ |
| 439 | void test_decode64_cmd(void){ |
| 440 | char *z; |
| 441 | int i, n; |
| @@ -454,11 +454,11 @@ | |
| 454 | */ |
| 455 | |
| 456 | /* |
| 457 | ** The array used for encoding |
| 458 | */ /* 123456789 12345 */ |
| 459 | static const char zEncode[] = "0123456789abcdef"; |
| 460 | |
| 461 | /* |
| 462 | ** Encode a N-digit base-256 in base-16. Return zero on success |
| 463 | ** and non-zero if there is an error. |
| 464 | */ |
| @@ -473,33 +473,33 @@ | |
| 473 | } |
| 474 | |
| 475 | /* |
| 476 | ** An array for translating single base-16 characters into a value. |
| 477 | ** Disallowed input characters have a value of 64. Upper and lower |
| 478 | ** case is the same. |
| 479 | */ |
| 480 | static const char zDecode[] = { |
| 481 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 482 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 483 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 484 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64, |
| 485 | 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 486 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 487 | 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 488 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 489 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 490 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 491 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 492 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 493 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 494 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 495 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 496 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 497 | }; |
| 498 | |
| 499 | /* |
| 500 | ** Decode a N-character base-16 number into base-256. N must be a |
| 501 | ** multiple of 2. The output buffer must be at least N/2 characters |
| 502 | ** in length |
| 503 | */ |
| 504 | int decode16(const unsigned char *zIn, unsigned char *pOut, int N){ |
| 505 | int i, j; |
| @@ -545,11 +545,11 @@ | |
| 545 | /* Randomness used for XOR-ing by the obscure() and unobscure() routines */ |
| 546 | static const unsigned char aObscurer[16] = { |
| 547 | 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86, |
| 548 | 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85 |
| 549 | }; |
| 550 | |
| 551 | |
| 552 | /* |
| 553 | ** Obscure plain text so that it is not easily readable. |
| 554 | ** |
| 555 | ** This is used for storing sensitive information (such as passwords) in a |
| @@ -562,11 +562,11 @@ | |
| 562 | */ |
| 563 | char *obscure(const char *zIn){ |
| 564 | int n, i; |
| 565 | unsigned char salt; |
| 566 | char *zOut; |
| 567 | |
| 568 | if( zIn==0 ) return 0; |
| 569 | n = strlen(zIn); |
| 570 | zOut = fossil_malloc( n*2+3 ); |
| 571 | sqlite3_randomness(1, &salt); |
| 572 | zOut[n+1] = (char)salt; |
| @@ -578,17 +578,17 @@ | |
| 578 | /* |
| 579 | ** Undo the obscuring of text performed by obscure(). Or, if the input is |
| 580 | ** not hexadecimal (meaning the input is not the output of obscure()) then |
| 581 | ** do the equivalent of strdup(). |
| 582 | ** |
| 583 | ** The result is memory obtained from malloc that should be freed by the caller. |
| 584 | */ |
| 585 | char *unobscure(const char *zIn){ |
| 586 | int n, i; |
| 587 | unsigned char salt; |
| 588 | char *zOut; |
| 589 | |
| 590 | if( zIn==0 ) return 0; |
| 591 | n = strlen(zIn); |
| 592 | zOut = fossil_malloc( n + 1 ); |
| 593 | if( n<2 |
| 594 | || decode16((unsigned char*)zIn, &salt, 2) |
| 595 |
| --- src/encode.c | |
| +++ src/encode.c | |
| @@ -47,30 +47,30 @@ | |
| 47 | } |
| 48 | i = 0; |
| 49 | zOut = fossil_malloc( count+1 ); |
| 50 | while( n-->0 && (c = *zIn)!=0 ){ |
| 51 | switch( c ){ |
| 52 | case '<': |
| 53 | zOut[i++] = '&'; |
| 54 | zOut[i++] = 'l'; |
| 55 | zOut[i++] = 't'; |
| 56 | zOut[i++] = ';'; |
| 57 | break; |
| 58 | case '>': |
| 59 | zOut[i++] = '&'; |
| 60 | zOut[i++] = 'g'; |
| 61 | zOut[i++] = 't'; |
| 62 | zOut[i++] = ';'; |
| 63 | break; |
| 64 | case '&': |
| 65 | zOut[i++] = '&'; |
| 66 | zOut[i++] = 'a'; |
| 67 | zOut[i++] = 'm'; |
| 68 | zOut[i++] = 'p'; |
| 69 | zOut[i++] = ';'; |
| 70 | break; |
| 71 | case '"': |
| 72 | zOut[i++] = '&'; |
| 73 | zOut[i++] = 'q'; |
| 74 | zOut[i++] = 'u'; |
| 75 | zOut[i++] = 'o'; |
| 76 | zOut[i++] = 't'; |
| @@ -181,11 +181,11 @@ | |
| 181 | /* |
| 182 | ** Convert the input string into a form that is suitable for use as |
| 183 | ** a token in the HTTP protocol. Spaces are encoded as '+' and special |
| 184 | ** characters are encoded as "%HH" where HH is a two-digit hexidecimal |
| 185 | ** representation of the character. The "/" character is not encoded |
| 186 | ** by this routine. |
| 187 | */ |
| 188 | char *urlize(const char *z, int n){ |
| 189 | return EncodeHttp(z, n, 0); |
| 190 | } |
| 191 | |
| @@ -327,11 +327,11 @@ | |
| 327 | |
| 328 | |
| 329 | /* |
| 330 | ** The characters used for HTTP base64 encoding. |
| 331 | */ |
| 332 | static unsigned char zBase[] = |
| 333 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 334 | |
| 335 | /* |
| 336 | ** Encode a string using a base-64 encoding. |
| 337 | ** The encoding can be reversed using the <b>decode64</b> function. |
| @@ -366,11 +366,11 @@ | |
| 366 | z64[n] = 0; |
| 367 | return z64; |
| 368 | } |
| 369 | |
| 370 | /* |
| 371 | ** COMMAND: test-encode64 |
| 372 | ** Usage: %fossil test-encode64 STRING |
| 373 | */ |
| 374 | void test_encode64_cmd(void){ |
| 375 | char *z; |
| 376 | int i; |
| @@ -431,11 +431,11 @@ | |
| 431 | *pnByte = j; |
| 432 | return zData; |
| 433 | } |
| 434 | |
| 435 | /* |
| 436 | ** COMMAND: test-decode64 |
| 437 | ** Usage: %fossil test-decode64 STRING |
| 438 | */ |
| 439 | void test_decode64_cmd(void){ |
| 440 | char *z; |
| 441 | int i, n; |
| @@ -454,11 +454,11 @@ | |
| 454 | */ |
| 455 | |
| 456 | /* |
| 457 | ** The array used for encoding |
| 458 | */ /* 123456789 12345 */ |
| 459 | static const char zEncode[] = "0123456789abcdef"; |
| 460 | |
| 461 | /* |
| 462 | ** Encode a N-digit base-256 in base-16. Return zero on success |
| 463 | ** and non-zero if there is an error. |
| 464 | */ |
| @@ -473,33 +473,33 @@ | |
| 473 | } |
| 474 | |
| 475 | /* |
| 476 | ** An array for translating single base-16 characters into a value. |
| 477 | ** Disallowed input characters have a value of 64. Upper and lower |
| 478 | ** case is the same. |
| 479 | */ |
| 480 | static const char zDecode[] = { |
| 481 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 482 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 483 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 484 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64, |
| 485 | 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 486 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 487 | 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 488 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 489 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 490 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 491 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 492 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 493 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 494 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 495 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 496 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 497 | }; |
| 498 | |
| 499 | /* |
| 500 | ** Decode a N-character base-16 number into base-256. N must be a |
| 501 | ** multiple of 2. The output buffer must be at least N/2 characters |
| 502 | ** in length |
| 503 | */ |
| 504 | int decode16(const unsigned char *zIn, unsigned char *pOut, int N){ |
| 505 | int i, j; |
| @@ -545,11 +545,11 @@ | |
| 545 | /* Randomness used for XOR-ing by the obscure() and unobscure() routines */ |
| 546 | static const unsigned char aObscurer[16] = { |
| 547 | 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86, |
| 548 | 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85 |
| 549 | }; |
| 550 | |
| 551 | |
| 552 | /* |
| 553 | ** Obscure plain text so that it is not easily readable. |
| 554 | ** |
| 555 | ** This is used for storing sensitive information (such as passwords) in a |
| @@ -562,11 +562,11 @@ | |
| 562 | */ |
| 563 | char *obscure(const char *zIn){ |
| 564 | int n, i; |
| 565 | unsigned char salt; |
| 566 | char *zOut; |
| 567 | |
| 568 | if( zIn==0 ) return 0; |
| 569 | n = strlen(zIn); |
| 570 | zOut = fossil_malloc( n*2+3 ); |
| 571 | sqlite3_randomness(1, &salt); |
| 572 | zOut[n+1] = (char)salt; |
| @@ -578,17 +578,17 @@ | |
| 578 | /* |
| 579 | ** Undo the obscuring of text performed by obscure(). Or, if the input is |
| 580 | ** not hexadecimal (meaning the input is not the output of obscure()) then |
| 581 | ** do the equivalent of strdup(). |
| 582 | ** |
| 583 | ** The result is memory obtained from malloc that should be freed by the caller. |
| 584 | */ |
| 585 | char *unobscure(const char *zIn){ |
| 586 | int n, i; |
| 587 | unsigned char salt; |
| 588 | char *zOut; |
| 589 | |
| 590 | if( zIn==0 ) return 0; |
| 591 | n = strlen(zIn); |
| 592 | zOut = fossil_malloc( n + 1 ); |
| 593 | if( n<2 |
| 594 | || decode16((unsigned char*)zIn, &salt, 2) |
| 595 |
+2
-4
| --- src/event.c | ||
| +++ src/event.c | ||
| @@ -119,11 +119,11 @@ | ||
| 119 | 119 | if( pEvent==0 ){ |
| 120 | 120 | fossil_fatal("Object #%d is not an event", rid); |
| 121 | 121 | } |
| 122 | 122 | blob_init(&fullbody, pEvent->zWiki, -1); |
| 123 | 123 | if( wiki_find_title(&fullbody, &title, &tail) ){ |
| 124 | - style_header(blob_str(&title)); | |
| 124 | + style_header("%s", blob_str(&title)); | |
| 125 | 125 | }else{ |
| 126 | 126 | style_header("Event %S", zEventId); |
| 127 | 127 | tail = fullbody; |
| 128 | 128 | } |
| 129 | 129 | if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){ |
| @@ -203,11 +203,10 @@ | ||
| 203 | 203 | void eventedit_page(void){ |
| 204 | 204 | char *zTag; |
| 205 | 205 | int rid = 0; |
| 206 | 206 | Blob event; |
| 207 | 207 | const char *zEventId; |
| 208 | - char *zHtmlPageName; | |
| 209 | 208 | int n; |
| 210 | 209 | const char *z; |
| 211 | 210 | char *zBody = (char*)P("w"); |
| 212 | 211 | char *zETime = (char*)P("t"); |
| 213 | 212 | const char *zComment = P("c"); |
| @@ -364,12 +363,11 @@ | ||
| 364 | 363 | return; |
| 365 | 364 | } |
| 366 | 365 | if( zBody==0 ){ |
| 367 | 366 | zBody = mprintf("<i>Event Text</i>"); |
| 368 | 367 | } |
| 369 | - zHtmlPageName = mprintf("Edit Event %S", zEventId); | |
| 370 | - style_header(zHtmlPageName); | |
| 368 | + style_header("Edit Event %S", zEventId); | |
| 371 | 369 | if( P("preview")!=0 ){ |
| 372 | 370 | Blob title, tail, com; |
| 373 | 371 | @ <p><b>Timeline comment preview:</b></p> |
| 374 | 372 | @ <blockquote> |
| 375 | 373 | @ <table border="0"> |
| 376 | 374 |
| --- src/event.c | |
| +++ src/event.c | |
| @@ -119,11 +119,11 @@ | |
| 119 | if( pEvent==0 ){ |
| 120 | fossil_fatal("Object #%d is not an event", rid); |
| 121 | } |
| 122 | blob_init(&fullbody, pEvent->zWiki, -1); |
| 123 | if( wiki_find_title(&fullbody, &title, &tail) ){ |
| 124 | style_header(blob_str(&title)); |
| 125 | }else{ |
| 126 | style_header("Event %S", zEventId); |
| 127 | tail = fullbody; |
| 128 | } |
| 129 | if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){ |
| @@ -203,11 +203,10 @@ | |
| 203 | void eventedit_page(void){ |
| 204 | char *zTag; |
| 205 | int rid = 0; |
| 206 | Blob event; |
| 207 | const char *zEventId; |
| 208 | char *zHtmlPageName; |
| 209 | int n; |
| 210 | const char *z; |
| 211 | char *zBody = (char*)P("w"); |
| 212 | char *zETime = (char*)P("t"); |
| 213 | const char *zComment = P("c"); |
| @@ -364,12 +363,11 @@ | |
| 364 | return; |
| 365 | } |
| 366 | if( zBody==0 ){ |
| 367 | zBody = mprintf("<i>Event Text</i>"); |
| 368 | } |
| 369 | zHtmlPageName = mprintf("Edit Event %S", zEventId); |
| 370 | style_header(zHtmlPageName); |
| 371 | if( P("preview")!=0 ){ |
| 372 | Blob title, tail, com; |
| 373 | @ <p><b>Timeline comment preview:</b></p> |
| 374 | @ <blockquote> |
| 375 | @ <table border="0"> |
| 376 |
| --- src/event.c | |
| +++ src/event.c | |
| @@ -119,11 +119,11 @@ | |
| 119 | if( pEvent==0 ){ |
| 120 | fossil_fatal("Object #%d is not an event", rid); |
| 121 | } |
| 122 | blob_init(&fullbody, pEvent->zWiki, -1); |
| 123 | if( wiki_find_title(&fullbody, &title, &tail) ){ |
| 124 | style_header("%s", blob_str(&title)); |
| 125 | }else{ |
| 126 | style_header("Event %S", zEventId); |
| 127 | tail = fullbody; |
| 128 | } |
| 129 | if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){ |
| @@ -203,11 +203,10 @@ | |
| 203 | void eventedit_page(void){ |
| 204 | char *zTag; |
| 205 | int rid = 0; |
| 206 | Blob event; |
| 207 | const char *zEventId; |
| 208 | int n; |
| 209 | const char *z; |
| 210 | char *zBody = (char*)P("w"); |
| 211 | char *zETime = (char*)P("t"); |
| 212 | const char *zComment = P("c"); |
| @@ -364,12 +363,11 @@ | |
| 363 | return; |
| 364 | } |
| 365 | if( zBody==0 ){ |
| 366 | zBody = mprintf("<i>Event Text</i>"); |
| 367 | } |
| 368 | style_header("Edit Event %S", zEventId); |
| 369 | if( P("preview")!=0 ){ |
| 370 | Blob title, tail, com; |
| 371 | @ <p><b>Timeline comment preview:</b></p> |
| 372 | @ <blockquote> |
| 373 | @ <table border="0"> |
| 374 |
+2
-2
| --- src/export.c | ||
| +++ src/export.c | ||
| @@ -71,12 +71,12 @@ | ||
| 71 | 71 | /* |
| 72 | 72 | ** Found beginning of email address. Look for the end and extract |
| 73 | 73 | ** the part. |
| 74 | 74 | */ |
| 75 | 75 | zEmail = mprintf("%s", &zContact[i]); |
| 76 | - for(i=0; zEmail[i] && zEmail[i]!='>'; i++){} | |
| 77 | - if( zEmail[i]=='>' ) zEmail[i+1] = 0; | |
| 76 | + for(j=0; zEmail[j] && zEmail[j]!='>'; j++){} | |
| 77 | + if( zEmail[j]=='>' ) zEmail[j+1] = 0; | |
| 78 | 78 | }else{ |
| 79 | 79 | /* |
| 80 | 80 | ** Found an end marker for email, but nothing else. |
| 81 | 81 | */ |
| 82 | 82 | zEmail = mprintf("<%s>", zUser); |
| 83 | 83 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -71,12 +71,12 @@ | |
| 71 | /* |
| 72 | ** Found beginning of email address. Look for the end and extract |
| 73 | ** the part. |
| 74 | */ |
| 75 | zEmail = mprintf("%s", &zContact[i]); |
| 76 | for(i=0; zEmail[i] && zEmail[i]!='>'; i++){} |
| 77 | if( zEmail[i]=='>' ) zEmail[i+1] = 0; |
| 78 | }else{ |
| 79 | /* |
| 80 | ** Found an end marker for email, but nothing else. |
| 81 | */ |
| 82 | zEmail = mprintf("<%s>", zUser); |
| 83 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -71,12 +71,12 @@ | |
| 71 | /* |
| 72 | ** Found beginning of email address. Look for the end and extract |
| 73 | ** the part. |
| 74 | */ |
| 75 | zEmail = mprintf("%s", &zContact[i]); |
| 76 | for(j=0; zEmail[j] && zEmail[j]!='>'; j++){} |
| 77 | if( zEmail[j]=='>' ) zEmail[j+1] = 0; |
| 78 | }else{ |
| 79 | /* |
| 80 | ** Found an end marker for email, but nothing else. |
| 81 | */ |
| 82 | zEmail = mprintf("<%s>", zUser); |
| 83 |
+12
-12
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -319,11 +319,11 @@ | ||
| 319 | 319 | |
| 320 | 320 | zPrevDate[0] = 0; |
| 321 | 321 | zFilename = PD("name",""); |
| 322 | 322 | url_add_parameter(&url, "name", zFilename); |
| 323 | 323 | blob_zero(&sql); |
| 324 | - blob_appendf(&sql, | |
| 324 | + blob_append_sql(&sql, | |
| 325 | 325 | "SELECT" |
| 326 | 326 | " datetime(event.mtime%s)," /* Date of change */ |
| 327 | 327 | " coalesce(event.ecomment, event.comment)," /* Check-in comment */ |
| 328 | 328 | " coalesce(event.euser, event.user)," /* User who made chng */ |
| 329 | 329 | " mlink.pid," /* Parent file rid */ |
| @@ -338,44 +338,44 @@ | ||
| 338 | 338 | " mlink.pfnid", /* Previous filename */ |
| 339 | 339 | timeline_utc(), TAG_BRANCH |
| 340 | 340 | ); |
| 341 | 341 | if( firstChngOnly ){ |
| 342 | 342 | #if 0 |
| 343 | - blob_appendf(&sql, ", min(event.mtime)"); | |
| 343 | + blob_append_sql(&sql, ", min(event.mtime)"); | |
| 344 | 344 | #else |
| 345 | - blob_appendf(&sql, | |
| 345 | + blob_append_sql(&sql, | |
| 346 | 346 | ", min(CASE (SELECT value FROM tagxref" |
| 347 | 347 | " WHERE tagtype>0 AND tagid=%d" |
| 348 | 348 | " AND tagxref.rid=mlink.mid)" |
| 349 | 349 | " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)", |
| 350 | 350 | TAG_BRANCH); |
| 351 | 351 | #endif |
| 352 | 352 | } |
| 353 | - blob_appendf(&sql, | |
| 353 | + blob_append_sql(&sql, | |
| 354 | 354 | " FROM mlink, event" |
| 355 | 355 | " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)" |
| 356 | 356 | " AND event.objid=mlink.mid", |
| 357 | 357 | zFilename |
| 358 | 358 | ); |
| 359 | 359 | if( baseCheckin ){ |
| 360 | 360 | compute_direct_ancestors(baseCheckin, 10000000); |
| 361 | - blob_appendf(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)"); | |
| 361 | + blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)"); | |
| 362 | 362 | } |
| 363 | 363 | if( (zA = P("a"))!=0 ){ |
| 364 | - blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA); | |
| 364 | + blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); | |
| 365 | 365 | url_add_parameter(&url, "a", zA); |
| 366 | 366 | } |
| 367 | 367 | if( (zB = P("b"))!=0 ){ |
| 368 | - blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB); | |
| 368 | + blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB); | |
| 369 | 369 | url_add_parameter(&url, "b", zB); |
| 370 | 370 | } |
| 371 | 371 | if( firstChngOnly ){ |
| 372 | - blob_appendf(&sql, " GROUP BY mlink.fid"); | |
| 372 | + blob_append_sql(&sql, " GROUP BY mlink.fid"); | |
| 373 | 373 | } |
| 374 | - blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); | |
| 374 | + blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/"); | |
| 375 | 375 | if( (n = atoi(PD("n","0")))>0 ){ |
| 376 | - blob_appendf(&sql, " LIMIT %d", n); | |
| 376 | + blob_append_sql(&sql, " LIMIT %d", n); | |
| 377 | 377 | url_add_parameter(&url, "n", P("n")); |
| 378 | 378 | } |
| 379 | 379 | if( baseCheckin==0 ){ |
| 380 | 380 | if( firstChngOnly ){ |
| 381 | 381 | style_submenu_element("Full", "Show all changes","%s", |
| @@ -384,11 +384,11 @@ | ||
| 384 | 384 | style_submenu_element("Simplified", |
| 385 | 385 | "Show only first use of a change","%s", |
| 386 | 386 | url_render(&url, "fco", 0, 0, 0)); |
| 387 | 387 | } |
| 388 | 388 | } |
| 389 | - db_prepare(&q, blob_str(&sql)); | |
| 389 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 390 | 390 | if( P("showsql")!=0 ){ |
| 391 | 391 | @ <p>SQL: %h(blob_str(&sql))</p> |
| 392 | 392 | } |
| 393 | 393 | blob_reset(&sql); |
| 394 | 394 | blob_zero(&title); |
| @@ -473,11 +473,11 @@ | ||
| 473 | 473 | }else{ |
| 474 | 474 | @ <b>Deleted</b> by check-in |
| 475 | 475 | } |
| 476 | 476 | } |
| 477 | 477 | hyperlink_to_uuid(zCkin); |
| 478 | - @ %w(zCom) (user: | |
| 478 | + @ %W(zCom) (user: | |
| 479 | 479 | hyperlink_to_user(zUser, zDate, ""); |
| 480 | 480 | @ branch: %h(zBr)) |
| 481 | 481 | if( g.perm.Hyperlink && zUuid ){ |
| 482 | 482 | const char *z = zFilename; |
| 483 | 483 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 484 | 484 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -319,11 +319,11 @@ | |
| 319 | |
| 320 | zPrevDate[0] = 0; |
| 321 | zFilename = PD("name",""); |
| 322 | url_add_parameter(&url, "name", zFilename); |
| 323 | blob_zero(&sql); |
| 324 | blob_appendf(&sql, |
| 325 | "SELECT" |
| 326 | " datetime(event.mtime%s)," /* Date of change */ |
| 327 | " coalesce(event.ecomment, event.comment)," /* Check-in comment */ |
| 328 | " coalesce(event.euser, event.user)," /* User who made chng */ |
| 329 | " mlink.pid," /* Parent file rid */ |
| @@ -338,44 +338,44 @@ | |
| 338 | " mlink.pfnid", /* Previous filename */ |
| 339 | timeline_utc(), TAG_BRANCH |
| 340 | ); |
| 341 | if( firstChngOnly ){ |
| 342 | #if 0 |
| 343 | blob_appendf(&sql, ", min(event.mtime)"); |
| 344 | #else |
| 345 | blob_appendf(&sql, |
| 346 | ", min(CASE (SELECT value FROM tagxref" |
| 347 | " WHERE tagtype>0 AND tagid=%d" |
| 348 | " AND tagxref.rid=mlink.mid)" |
| 349 | " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)", |
| 350 | TAG_BRANCH); |
| 351 | #endif |
| 352 | } |
| 353 | blob_appendf(&sql, |
| 354 | " FROM mlink, event" |
| 355 | " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)" |
| 356 | " AND event.objid=mlink.mid", |
| 357 | zFilename |
| 358 | ); |
| 359 | if( baseCheckin ){ |
| 360 | compute_direct_ancestors(baseCheckin, 10000000); |
| 361 | blob_appendf(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)"); |
| 362 | } |
| 363 | if( (zA = P("a"))!=0 ){ |
| 364 | blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA); |
| 365 | url_add_parameter(&url, "a", zA); |
| 366 | } |
| 367 | if( (zB = P("b"))!=0 ){ |
| 368 | blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB); |
| 369 | url_add_parameter(&url, "b", zB); |
| 370 | } |
| 371 | if( firstChngOnly ){ |
| 372 | blob_appendf(&sql, " GROUP BY mlink.fid"); |
| 373 | } |
| 374 | blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); |
| 375 | if( (n = atoi(PD("n","0")))>0 ){ |
| 376 | blob_appendf(&sql, " LIMIT %d", n); |
| 377 | url_add_parameter(&url, "n", P("n")); |
| 378 | } |
| 379 | if( baseCheckin==0 ){ |
| 380 | if( firstChngOnly ){ |
| 381 | style_submenu_element("Full", "Show all changes","%s", |
| @@ -384,11 +384,11 @@ | |
| 384 | style_submenu_element("Simplified", |
| 385 | "Show only first use of a change","%s", |
| 386 | url_render(&url, "fco", 0, 0, 0)); |
| 387 | } |
| 388 | } |
| 389 | db_prepare(&q, blob_str(&sql)); |
| 390 | if( P("showsql")!=0 ){ |
| 391 | @ <p>SQL: %h(blob_str(&sql))</p> |
| 392 | } |
| 393 | blob_reset(&sql); |
| 394 | blob_zero(&title); |
| @@ -473,11 +473,11 @@ | |
| 473 | }else{ |
| 474 | @ <b>Deleted</b> by check-in |
| 475 | } |
| 476 | } |
| 477 | hyperlink_to_uuid(zCkin); |
| 478 | @ %w(zCom) (user: |
| 479 | hyperlink_to_user(zUser, zDate, ""); |
| 480 | @ branch: %h(zBr)) |
| 481 | if( g.perm.Hyperlink && zUuid ){ |
| 482 | const char *z = zFilename; |
| 483 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 484 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -319,11 +319,11 @@ | |
| 319 | |
| 320 | zPrevDate[0] = 0; |
| 321 | zFilename = PD("name",""); |
| 322 | url_add_parameter(&url, "name", zFilename); |
| 323 | blob_zero(&sql); |
| 324 | blob_append_sql(&sql, |
| 325 | "SELECT" |
| 326 | " datetime(event.mtime%s)," /* Date of change */ |
| 327 | " coalesce(event.ecomment, event.comment)," /* Check-in comment */ |
| 328 | " coalesce(event.euser, event.user)," /* User who made chng */ |
| 329 | " mlink.pid," /* Parent file rid */ |
| @@ -338,44 +338,44 @@ | |
| 338 | " mlink.pfnid", /* Previous filename */ |
| 339 | timeline_utc(), TAG_BRANCH |
| 340 | ); |
| 341 | if( firstChngOnly ){ |
| 342 | #if 0 |
| 343 | blob_append_sql(&sql, ", min(event.mtime)"); |
| 344 | #else |
| 345 | blob_append_sql(&sql, |
| 346 | ", min(CASE (SELECT value FROM tagxref" |
| 347 | " WHERE tagtype>0 AND tagid=%d" |
| 348 | " AND tagxref.rid=mlink.mid)" |
| 349 | " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)", |
| 350 | TAG_BRANCH); |
| 351 | #endif |
| 352 | } |
| 353 | blob_append_sql(&sql, |
| 354 | " FROM mlink, event" |
| 355 | " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)" |
| 356 | " AND event.objid=mlink.mid", |
| 357 | zFilename |
| 358 | ); |
| 359 | if( baseCheckin ){ |
| 360 | compute_direct_ancestors(baseCheckin, 10000000); |
| 361 | blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)"); |
| 362 | } |
| 363 | if( (zA = P("a"))!=0 ){ |
| 364 | blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); |
| 365 | url_add_parameter(&url, "a", zA); |
| 366 | } |
| 367 | if( (zB = P("b"))!=0 ){ |
| 368 | blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB); |
| 369 | url_add_parameter(&url, "b", zB); |
| 370 | } |
| 371 | if( firstChngOnly ){ |
| 372 | blob_append_sql(&sql, " GROUP BY mlink.fid"); |
| 373 | } |
| 374 | blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/"); |
| 375 | if( (n = atoi(PD("n","0")))>0 ){ |
| 376 | blob_append_sql(&sql, " LIMIT %d", n); |
| 377 | url_add_parameter(&url, "n", P("n")); |
| 378 | } |
| 379 | if( baseCheckin==0 ){ |
| 380 | if( firstChngOnly ){ |
| 381 | style_submenu_element("Full", "Show all changes","%s", |
| @@ -384,11 +384,11 @@ | |
| 384 | style_submenu_element("Simplified", |
| 385 | "Show only first use of a change","%s", |
| 386 | url_render(&url, "fco", 0, 0, 0)); |
| 387 | } |
| 388 | } |
| 389 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 390 | if( P("showsql")!=0 ){ |
| 391 | @ <p>SQL: %h(blob_str(&sql))</p> |
| 392 | } |
| 393 | blob_reset(&sql); |
| 394 | blob_zero(&title); |
| @@ -473,11 +473,11 @@ | |
| 473 | }else{ |
| 474 | @ <b>Deleted</b> by check-in |
| 475 | } |
| 476 | } |
| 477 | hyperlink_to_uuid(zCkin); |
| 478 | @ %W(zCom) (user: |
| 479 | hyperlink_to_user(zUser, zDate, ""); |
| 480 | @ branch: %h(zBr)) |
| 481 | if( g.perm.Hyperlink && zUuid ){ |
| 482 | const char *z = zFilename; |
| 483 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 484 |
+2
-2
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -167,11 +167,11 @@ | ||
| 167 | 167 | char *zPrompt; |
| 168 | 168 | char *zHttpAuth = 0; |
| 169 | 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | 171 | g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); |
| 172 | - fossil_print(zPrompt); | |
| 172 | + fossil_print("%s", zPrompt); | |
| 173 | 173 | free(zPrompt); |
| 174 | 174 | if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | 175 | zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 176 | 176 | }else{ |
| 177 | 177 | prompt_user("Basic Authorization user: ", &x); |
| @@ -214,11 +214,11 @@ | ||
| 214 | 214 | int i; /* Loop counter */ |
| 215 | 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | 217 | |
| 218 | 218 | if( transport_open(&g.url) ){ |
| 219 | - fossil_warning(transport_errmsg(&g.url)); | |
| 219 | + fossil_warning("%s", transport_errmsg(&g.url)); | |
| 220 | 220 | return 1; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | 224 | blob_zero(&login); |
| 225 | 225 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -167,11 +167,11 @@ | |
| 167 | char *zPrompt; |
| 168 | char *zHttpAuth = 0; |
| 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); |
| 172 | fossil_print(zPrompt); |
| 173 | free(zPrompt); |
| 174 | if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 176 | }else{ |
| 177 | prompt_user("Basic Authorization user: ", &x); |
| @@ -214,11 +214,11 @@ | |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | |
| 218 | if( transport_open(&g.url) ){ |
| 219 | fossil_warning(transport_errmsg(&g.url)); |
| 220 | return 1; |
| 221 | } |
| 222 | |
| 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | blob_zero(&login); |
| 225 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -167,11 +167,11 @@ | |
| 167 | char *zPrompt; |
| 168 | char *zHttpAuth = 0; |
| 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); |
| 172 | fossil_print("%s", zPrompt); |
| 173 | free(zPrompt); |
| 174 | if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 176 | }else{ |
| 177 | prompt_user("Basic Authorization user: ", &x); |
| @@ -214,11 +214,11 @@ | |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | |
| 218 | if( transport_open(&g.url) ){ |
| 219 | fossil_warning("%s", transport_errmsg(&g.url)); |
| 220 | return 1; |
| 221 | } |
| 222 | |
| 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | blob_zero(&login); |
| 225 |
+6
-8
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -535,20 +535,18 @@ | ||
| 535 | 535 | timeline_utc(), timeline_utc(), rid, rid |
| 536 | 536 | ); |
| 537 | 537 | sideBySide = !is_false(PD("sbs","1")); |
| 538 | 538 | if( db_step(&q1)==SQLITE_ROW ){ |
| 539 | 539 | const char *zUuid = db_column_text(&q1, 0); |
| 540 | - char *zTitle = mprintf("Check-in [%S]", zUuid); | |
| 541 | 540 | char *zEUser, *zEComment; |
| 542 | 541 | const char *zUser; |
| 543 | 542 | const char *zComment; |
| 544 | 543 | const char *zDate; |
| 545 | 544 | const char *zOrigDate; |
| 546 | 545 | |
| 547 | - style_header(zTitle); | |
| 546 | + style_header("Check-in [%S]", zUuid); | |
| 548 | 547 | login_anonymous_available(); |
| 549 | - free(zTitle); | |
| 550 | 548 | zEUser = db_text(0, |
| 551 | 549 | "SELECT value FROM tagxref" |
| 552 | 550 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 553 | 551 | TAG_USER, rid); |
| 554 | 552 | zEComment = db_text(0, |
| @@ -1582,11 +1580,11 @@ | ||
| 1582 | 1580 | login_check_credentials(); |
| 1583 | 1581 | if( !g.perm.Read ){ login_needed(); return; } |
| 1584 | 1582 | if( rid==0 ) fossil_redirect_home(); |
| 1585 | 1583 | if( g.perm.Admin ){ |
| 1586 | 1584 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1587 | - if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ | |
| 1585 | + if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ | |
| 1588 | 1586 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun", |
| 1589 | 1587 | g.zTop, zUuid); |
| 1590 | 1588 | }else{ |
| 1591 | 1589 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1592 | 1590 | g.zTop, zUuid); |
| @@ -1768,20 +1766,20 @@ | ||
| 1768 | 1766 | login_check_credentials(); |
| 1769 | 1767 | if( !g.perm.Read ){ login_needed(); return; } |
| 1770 | 1768 | if( rid==0 ) fossil_redirect_home(); |
| 1771 | 1769 | if( g.perm.Admin ){ |
| 1772 | 1770 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1773 | - if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ | |
| 1771 | + if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ | |
| 1774 | 1772 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| 1775 | 1773 | g.zTop, zUuid); |
| 1776 | 1774 | }else{ |
| 1777 | 1775 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1778 | 1776 | g.zTop, zUuid); |
| 1779 | 1777 | } |
| 1780 | 1778 | } |
| 1781 | 1779 | if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL; |
| 1782 | - style_header(descOnly ? "Artifact Description" : "Artifact Content"); | |
| 1780 | + style_header("%s", descOnly ? "Artifact Description" : "Artifact Content"); | |
| 1783 | 1781 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1784 | 1782 | if( g.perm.Setup ){ |
| 1785 | 1783 | @ <h2>Artifact %s(zUuid) (%d(rid)):</h2> |
| 1786 | 1784 | }else{ |
| 1787 | 1785 | @ <h2>Artifact %s(zUuid):</h2> |
| @@ -1884,11 +1882,11 @@ | ||
| 1884 | 1882 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 1885 | 1883 | rid = name_to_rid_www("name"); |
| 1886 | 1884 | if( rid==0 ){ fossil_redirect_home(); } |
| 1887 | 1885 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1888 | 1886 | if( g.perm.Admin ){ |
| 1889 | - if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ | |
| 1887 | + if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ | |
| 1890 | 1888 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| 1891 | 1889 | g.zTop, zUuid); |
| 1892 | 1890 | }else{ |
| 1893 | 1891 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1894 | 1892 | g.zTop, zUuid); |
| @@ -2029,11 +2027,11 @@ | ||
| 2029 | 2027 | cgi_set_parameter("src","info"); |
| 2030 | 2028 | ambiguous_page(); |
| 2031 | 2029 | return; |
| 2032 | 2030 | } |
| 2033 | 2031 | zName = blob_str(&uuid); |
| 2034 | - rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName); | |
| 2032 | + rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName); | |
| 2035 | 2033 | if( rid==0 ){ |
| 2036 | 2034 | style_header("Broken Link"); |
| 2037 | 2035 | @ <p>No such object: %h(zName)</p> |
| 2038 | 2036 | style_footer(); |
| 2039 | 2037 | return; |
| 2040 | 2038 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -535,20 +535,18 @@ | |
| 535 | timeline_utc(), timeline_utc(), rid, rid |
| 536 | ); |
| 537 | sideBySide = !is_false(PD("sbs","1")); |
| 538 | if( db_step(&q1)==SQLITE_ROW ){ |
| 539 | const char *zUuid = db_column_text(&q1, 0); |
| 540 | char *zTitle = mprintf("Check-in [%S]", zUuid); |
| 541 | char *zEUser, *zEComment; |
| 542 | const char *zUser; |
| 543 | const char *zComment; |
| 544 | const char *zDate; |
| 545 | const char *zOrigDate; |
| 546 | |
| 547 | style_header(zTitle); |
| 548 | login_anonymous_available(); |
| 549 | free(zTitle); |
| 550 | zEUser = db_text(0, |
| 551 | "SELECT value FROM tagxref" |
| 552 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 553 | TAG_USER, rid); |
| 554 | zEComment = db_text(0, |
| @@ -1582,11 +1580,11 @@ | |
| 1582 | login_check_credentials(); |
| 1583 | if( !g.perm.Read ){ login_needed(); return; } |
| 1584 | if( rid==0 ) fossil_redirect_home(); |
| 1585 | if( g.perm.Admin ){ |
| 1586 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1587 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1588 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun", |
| 1589 | g.zTop, zUuid); |
| 1590 | }else{ |
| 1591 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1592 | g.zTop, zUuid); |
| @@ -1768,20 +1766,20 @@ | |
| 1768 | login_check_credentials(); |
| 1769 | if( !g.perm.Read ){ login_needed(); return; } |
| 1770 | if( rid==0 ) fossil_redirect_home(); |
| 1771 | if( g.perm.Admin ){ |
| 1772 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1773 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1774 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| 1775 | g.zTop, zUuid); |
| 1776 | }else{ |
| 1777 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1778 | g.zTop, zUuid); |
| 1779 | } |
| 1780 | } |
| 1781 | if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL; |
| 1782 | style_header(descOnly ? "Artifact Description" : "Artifact Content"); |
| 1783 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1784 | if( g.perm.Setup ){ |
| 1785 | @ <h2>Artifact %s(zUuid) (%d(rid)):</h2> |
| 1786 | }else{ |
| 1787 | @ <h2>Artifact %s(zUuid):</h2> |
| @@ -1884,11 +1882,11 @@ | |
| 1884 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 1885 | rid = name_to_rid_www("name"); |
| 1886 | if( rid==0 ){ fossil_redirect_home(); } |
| 1887 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1888 | if( g.perm.Admin ){ |
| 1889 | if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 1890 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| 1891 | g.zTop, zUuid); |
| 1892 | }else{ |
| 1893 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1894 | g.zTop, zUuid); |
| @@ -2029,11 +2027,11 @@ | |
| 2029 | cgi_set_parameter("src","info"); |
| 2030 | ambiguous_page(); |
| 2031 | return; |
| 2032 | } |
| 2033 | zName = blob_str(&uuid); |
| 2034 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName); |
| 2035 | if( rid==0 ){ |
| 2036 | style_header("Broken Link"); |
| 2037 | @ <p>No such object: %h(zName)</p> |
| 2038 | style_footer(); |
| 2039 | return; |
| 2040 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -535,20 +535,18 @@ | |
| 535 | timeline_utc(), timeline_utc(), rid, rid |
| 536 | ); |
| 537 | sideBySide = !is_false(PD("sbs","1")); |
| 538 | if( db_step(&q1)==SQLITE_ROW ){ |
| 539 | const char *zUuid = db_column_text(&q1, 0); |
| 540 | char *zEUser, *zEComment; |
| 541 | const char *zUser; |
| 542 | const char *zComment; |
| 543 | const char *zDate; |
| 544 | const char *zOrigDate; |
| 545 | |
| 546 | style_header("Check-in [%S]", zUuid); |
| 547 | login_anonymous_available(); |
| 548 | zEUser = db_text(0, |
| 549 | "SELECT value FROM tagxref" |
| 550 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 551 | TAG_USER, rid); |
| 552 | zEComment = db_text(0, |
| @@ -1582,11 +1580,11 @@ | |
| 1580 | login_check_credentials(); |
| 1581 | if( !g.perm.Read ){ login_needed(); return; } |
| 1582 | if( rid==0 ) fossil_redirect_home(); |
| 1583 | if( g.perm.Admin ){ |
| 1584 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1585 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1586 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun", |
| 1587 | g.zTop, zUuid); |
| 1588 | }else{ |
| 1589 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1590 | g.zTop, zUuid); |
| @@ -1768,20 +1766,20 @@ | |
| 1766 | login_check_credentials(); |
| 1767 | if( !g.perm.Read ){ login_needed(); return; } |
| 1768 | if( rid==0 ) fossil_redirect_home(); |
| 1769 | if( g.perm.Admin ){ |
| 1770 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1771 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1772 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| 1773 | g.zTop, zUuid); |
| 1774 | }else{ |
| 1775 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1776 | g.zTop, zUuid); |
| 1777 | } |
| 1778 | } |
| 1779 | if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL; |
| 1780 | style_header("%s", descOnly ? "Artifact Description" : "Artifact Content"); |
| 1781 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1782 | if( g.perm.Setup ){ |
| 1783 | @ <h2>Artifact %s(zUuid) (%d(rid)):</h2> |
| 1784 | }else{ |
| 1785 | @ <h2>Artifact %s(zUuid):</h2> |
| @@ -1884,11 +1882,11 @@ | |
| 1882 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 1883 | rid = name_to_rid_www("name"); |
| 1884 | if( rid==0 ){ fossil_redirect_home(); } |
| 1885 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1886 | if( g.perm.Admin ){ |
| 1887 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1888 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| 1889 | g.zTop, zUuid); |
| 1890 | }else{ |
| 1891 | style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 1892 | g.zTop, zUuid); |
| @@ -2029,11 +2027,11 @@ | |
| 2027 | cgi_set_parameter("src","info"); |
| 2028 | ambiguous_page(); |
| 2029 | return; |
| 2030 | } |
| 2031 | zName = blob_str(&uuid); |
| 2032 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName); |
| 2033 | if( rid==0 ){ |
| 2034 | style_header("Broken Link"); |
| 2035 | @ <p>No such object: %h(zName)</p> |
| 2036 | style_footer(); |
| 2037 | return; |
| 2038 |
+7
-7
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -1665,11 +1665,11 @@ | ||
| 1665 | 1665 | cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt, |
| 1666 | 1666 | char resetBlob){ |
| 1667 | 1667 | Stmt q = empty_Stmt; |
| 1668 | 1668 | cson_value * pay = NULL; |
| 1669 | 1669 | assert( blob_size(pSql) > 0 ); |
| 1670 | - db_prepare(&q, "%s", blob_str(pSql)); | |
| 1670 | + db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/); | |
| 1671 | 1671 | if(resetBlob){ |
| 1672 | 1672 | blob_reset(pSql); |
| 1673 | 1673 | } |
| 1674 | 1674 | pay = json_stmt_to_array_of_obj(&q, pTgt); |
| 1675 | 1675 | db_finalize(&q); |
| @@ -1983,16 +1983,16 @@ | ||
| 1983 | 1983 | cson_object_set(jo, "sqlite", jv2); |
| 1984 | 1984 | sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)", |
| 1985 | 1985 | sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion()); |
| 1986 | 1986 | SETBUF(jo2, "version"); |
| 1987 | 1987 | zDb = db_name("repository"); |
| 1988 | - cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb))); | |
| 1989 | - cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb))); | |
| 1990 | - cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb))); | |
| 1991 | - sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb)); | |
| 1988 | + cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb))); | |
| 1989 | + cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb))); | |
| 1990 | + cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb))); | |
| 1991 | + sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb)); | |
| 1992 | 1992 | SETBUF(jo2, "encoding"); |
| 1993 | - sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb)); | |
| 1993 | + sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb)); | |
| 1994 | 1994 | cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null()); |
| 1995 | 1995 | return jv; |
| 1996 | 1996 | #undef SETBUF |
| 1997 | 1997 | } |
| 1998 | 1998 | |
| @@ -2016,11 +2016,11 @@ | ||
| 2016 | 2016 | for( ; zPages->name; ++zPages, ++i ){ |
| 2017 | 2017 | if(filterByMode){ |
| 2018 | 2018 | if(g.isHTTP && zPages->runMode < 0) continue; |
| 2019 | 2019 | else if(zPages->runMode > 0) continue; |
| 2020 | 2020 | } |
| 2021 | - blob_appendf(pOut, zPages->name, -1); | |
| 2021 | + blob_append(pOut, zPages->name, -1); | |
| 2022 | 2022 | if((zPages+1)->name){ |
| 2023 | 2023 | blob_append(pOut, ", ",2); |
| 2024 | 2024 | } |
| 2025 | 2025 | } |
| 2026 | 2026 | return i; |
| 2027 | 2027 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1665,11 +1665,11 @@ | |
| 1665 | cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt, |
| 1666 | char resetBlob){ |
| 1667 | Stmt q = empty_Stmt; |
| 1668 | cson_value * pay = NULL; |
| 1669 | assert( blob_size(pSql) > 0 ); |
| 1670 | db_prepare(&q, "%s", blob_str(pSql)); |
| 1671 | if(resetBlob){ |
| 1672 | blob_reset(pSql); |
| 1673 | } |
| 1674 | pay = json_stmt_to_array_of_obj(&q, pTgt); |
| 1675 | db_finalize(&q); |
| @@ -1983,16 +1983,16 @@ | |
| 1983 | cson_object_set(jo, "sqlite", jv2); |
| 1984 | sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)", |
| 1985 | sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion()); |
| 1986 | SETBUF(jo2, "version"); |
| 1987 | zDb = db_name("repository"); |
| 1988 | cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb))); |
| 1989 | cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb))); |
| 1990 | cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb))); |
| 1991 | sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb)); |
| 1992 | SETBUF(jo2, "encoding"); |
| 1993 | sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb)); |
| 1994 | cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null()); |
| 1995 | return jv; |
| 1996 | #undef SETBUF |
| 1997 | } |
| 1998 | |
| @@ -2016,11 +2016,11 @@ | |
| 2016 | for( ; zPages->name; ++zPages, ++i ){ |
| 2017 | if(filterByMode){ |
| 2018 | if(g.isHTTP && zPages->runMode < 0) continue; |
| 2019 | else if(zPages->runMode > 0) continue; |
| 2020 | } |
| 2021 | blob_appendf(pOut, zPages->name, -1); |
| 2022 | if((zPages+1)->name){ |
| 2023 | blob_append(pOut, ", ",2); |
| 2024 | } |
| 2025 | } |
| 2026 | return i; |
| 2027 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1665,11 +1665,11 @@ | |
| 1665 | cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt, |
| 1666 | char resetBlob){ |
| 1667 | Stmt q = empty_Stmt; |
| 1668 | cson_value * pay = NULL; |
| 1669 | assert( blob_size(pSql) > 0 ); |
| 1670 | db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/); |
| 1671 | if(resetBlob){ |
| 1672 | blob_reset(pSql); |
| 1673 | } |
| 1674 | pay = json_stmt_to_array_of_obj(&q, pTgt); |
| 1675 | db_finalize(&q); |
| @@ -1983,16 +1983,16 @@ | |
| 1983 | cson_object_set(jo, "sqlite", jv2); |
| 1984 | sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)", |
| 1985 | sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion()); |
| 1986 | SETBUF(jo2, "version"); |
| 1987 | zDb = db_name("repository"); |
| 1988 | cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb))); |
| 1989 | cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb))); |
| 1990 | cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb))); |
| 1991 | sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb)); |
| 1992 | SETBUF(jo2, "encoding"); |
| 1993 | sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb)); |
| 1994 | cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null()); |
| 1995 | return jv; |
| 1996 | #undef SETBUF |
| 1997 | } |
| 1998 | |
| @@ -2016,11 +2016,11 @@ | |
| 2016 | for( ; zPages->name; ++zPages, ++i ){ |
| 2017 | if(filterByMode){ |
| 2018 | if(g.isHTTP && zPages->runMode < 0) continue; |
| 2019 | else if(zPages->runMode > 0) continue; |
| 2020 | } |
| 2021 | blob_append(pOut, zPages->name, -1); |
| 2022 | if((zPages+1)->name){ |
| 2023 | blob_append(pOut, ", ",2); |
| 2024 | } |
| 2025 | } |
| 2026 | return i; |
| 2027 |
+2
-2
| --- src/json_config.c | ||
| +++ src/json_config.c | ||
| @@ -145,11 +145,11 @@ | ||
| 145 | 145 | for( i = 0; prop->name; ++prop ){ |
| 146 | 146 | if(prop->groupMask & confMask){ |
| 147 | 147 | if( i++ ){ |
| 148 | 148 | blob_append(&sql,",",1); |
| 149 | 149 | } |
| 150 | - blob_appendf(&sql, "%Q", prop->name); | |
| 150 | + blob_append_sql(&sql, "%Q", prop->name); | |
| 151 | 151 | } |
| 152 | 152 | } |
| 153 | 153 | blob_append(&sql,") ", -1); |
| 154 | 154 | } |
| 155 | 155 | |
| @@ -156,11 +156,11 @@ | ||
| 156 | 156 | |
| 157 | 157 | if( optSkinBackups ){ |
| 158 | 158 | blob_append(&sql, " OR name GLOB 'skin:*'", -1); |
| 159 | 159 | } |
| 160 | 160 | blob_append(&sql," ORDER BY name", -1); |
| 161 | - db_prepare(&q, blob_str(&sql)); | |
| 161 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 162 | 162 | blob_reset(&sql); |
| 163 | 163 | pay = cson_new_object(); |
| 164 | 164 | while( (SQLITE_ROW==db_step(&q)) ){ |
| 165 | 165 | cson_object_set(pay, |
| 166 | 166 | db_column_text(&q,0), |
| 167 | 167 |
| --- src/json_config.c | |
| +++ src/json_config.c | |
| @@ -145,11 +145,11 @@ | |
| 145 | for( i = 0; prop->name; ++prop ){ |
| 146 | if(prop->groupMask & confMask){ |
| 147 | if( i++ ){ |
| 148 | blob_append(&sql,",",1); |
| 149 | } |
| 150 | blob_appendf(&sql, "%Q", prop->name); |
| 151 | } |
| 152 | } |
| 153 | blob_append(&sql,") ", -1); |
| 154 | } |
| 155 | |
| @@ -156,11 +156,11 @@ | |
| 156 | |
| 157 | if( optSkinBackups ){ |
| 158 | blob_append(&sql, " OR name GLOB 'skin:*'", -1); |
| 159 | } |
| 160 | blob_append(&sql," ORDER BY name", -1); |
| 161 | db_prepare(&q, blob_str(&sql)); |
| 162 | blob_reset(&sql); |
| 163 | pay = cson_new_object(); |
| 164 | while( (SQLITE_ROW==db_step(&q)) ){ |
| 165 | cson_object_set(pay, |
| 166 | db_column_text(&q,0), |
| 167 |
| --- src/json_config.c | |
| +++ src/json_config.c | |
| @@ -145,11 +145,11 @@ | |
| 145 | for( i = 0; prop->name; ++prop ){ |
| 146 | if(prop->groupMask & confMask){ |
| 147 | if( i++ ){ |
| 148 | blob_append(&sql,",",1); |
| 149 | } |
| 150 | blob_append_sql(&sql, "%Q", prop->name); |
| 151 | } |
| 152 | } |
| 153 | blob_append(&sql,") ", -1); |
| 154 | } |
| 155 | |
| @@ -156,11 +156,11 @@ | |
| 156 | |
| 157 | if( optSkinBackups ){ |
| 158 | blob_append(&sql, " OR name GLOB 'skin:*'", -1); |
| 159 | } |
| 160 | blob_append(&sql," ORDER BY name", -1); |
| 161 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 162 | blob_reset(&sql); |
| 163 | pay = cson_new_object(); |
| 164 | while( (SQLITE_ROW==db_step(&q)) ){ |
| 165 | cson_object_set(pay, |
| 166 | db_column_text(&q,0), |
| 167 |
+6
-7
| --- src/json_finfo.c | ||
| +++ src/json_finfo.c | ||
| @@ -62,11 +62,11 @@ | ||
| 62 | 62 | zBefore = json_find_option_cstr("before",NULL,"b"); |
| 63 | 63 | zAfter = json_find_option_cstr("after",NULL,"a"); |
| 64 | 64 | limit = json_find_option_int("limit",NULL,"n", -1); |
| 65 | 65 | zCheckin = json_find_option_cstr("checkin",NULL,"ci"); |
| 66 | 66 | |
| 67 | - blob_appendf(&sql, | |
| 67 | + blob_append_sql(&sql, | |
| 68 | 68 | /*0*/ "SELECT b.uuid," |
| 69 | 69 | /*1*/ " ci.uuid," |
| 70 | 70 | /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| 71 | 71 | /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER)," |
| 72 | 72 | /*4*/ " coalesce(event.euser, event.user)," |
| @@ -93,25 +93,24 @@ | ||
| 93 | 93 | json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 94 | 94 | "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found"); |
| 95 | 95 | blob_reset(&sql); |
| 96 | 96 | return NULL; |
| 97 | 97 | } |
| 98 | - blob_appendf(&sql, " AND ci.uuid='%q'", zU); | |
| 98 | + blob_append_sql(&sql, " AND ci.uuid='%q'", zU); | |
| 99 | 99 | free(zU); |
| 100 | 100 | }else{ |
| 101 | 101 | if( zAfter && *zAfter ){ |
| 102 | - blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter); | |
| 102 | + blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter); | |
| 103 | 103 | sort = 1; |
| 104 | 104 | }else if( zBefore && *zBefore ){ |
| 105 | - blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore); | |
| 105 | + blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore); | |
| 106 | 106 | } |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | - blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC")); | |
| 109 | + blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC")); | |
| 110 | 110 | /*printf("SQL=\n%s\n",blob_str(&sql));*/ |
| 111 | - db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding | |
| 112 | - SQL escapes*/); | |
| 111 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 113 | 112 | blob_reset(&sql); |
| 114 | 113 | |
| 115 | 114 | pay = cson_new_object(); |
| 116 | 115 | cson_object_set(pay, "name", json_new_string(zFilename)); |
| 117 | 116 | if( limit > 0 ){ |
| 118 | 117 |
| --- src/json_finfo.c | |
| +++ src/json_finfo.c | |
| @@ -62,11 +62,11 @@ | |
| 62 | zBefore = json_find_option_cstr("before",NULL,"b"); |
| 63 | zAfter = json_find_option_cstr("after",NULL,"a"); |
| 64 | limit = json_find_option_int("limit",NULL,"n", -1); |
| 65 | zCheckin = json_find_option_cstr("checkin",NULL,"ci"); |
| 66 | |
| 67 | blob_appendf(&sql, |
| 68 | /*0*/ "SELECT b.uuid," |
| 69 | /*1*/ " ci.uuid," |
| 70 | /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| 71 | /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER)," |
| 72 | /*4*/ " coalesce(event.euser, event.user)," |
| @@ -93,25 +93,24 @@ | |
| 93 | json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 94 | "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found"); |
| 95 | blob_reset(&sql); |
| 96 | return NULL; |
| 97 | } |
| 98 | blob_appendf(&sql, " AND ci.uuid='%q'", zU); |
| 99 | free(zU); |
| 100 | }else{ |
| 101 | if( zAfter && *zAfter ){ |
| 102 | blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter); |
| 103 | sort = 1; |
| 104 | }else if( zBefore && *zBefore ){ |
| 105 | blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore); |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC")); |
| 110 | /*printf("SQL=\n%s\n",blob_str(&sql));*/ |
| 111 | db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding |
| 112 | SQL escapes*/); |
| 113 | blob_reset(&sql); |
| 114 | |
| 115 | pay = cson_new_object(); |
| 116 | cson_object_set(pay, "name", json_new_string(zFilename)); |
| 117 | if( limit > 0 ){ |
| 118 |
| --- src/json_finfo.c | |
| +++ src/json_finfo.c | |
| @@ -62,11 +62,11 @@ | |
| 62 | zBefore = json_find_option_cstr("before",NULL,"b"); |
| 63 | zAfter = json_find_option_cstr("after",NULL,"a"); |
| 64 | limit = json_find_option_int("limit",NULL,"n", -1); |
| 65 | zCheckin = json_find_option_cstr("checkin",NULL,"ci"); |
| 66 | |
| 67 | blob_append_sql(&sql, |
| 68 | /*0*/ "SELECT b.uuid," |
| 69 | /*1*/ " ci.uuid," |
| 70 | /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| 71 | /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER)," |
| 72 | /*4*/ " coalesce(event.euser, event.user)," |
| @@ -93,25 +93,24 @@ | |
| 93 | json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 94 | "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found"); |
| 95 | blob_reset(&sql); |
| 96 | return NULL; |
| 97 | } |
| 98 | blob_append_sql(&sql, " AND ci.uuid='%q'", zU); |
| 99 | free(zU); |
| 100 | }else{ |
| 101 | if( zAfter && *zAfter ){ |
| 102 | blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter); |
| 103 | sort = 1; |
| 104 | }else if( zBefore && *zBefore ){ |
| 105 | blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore); |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC")); |
| 110 | /*printf("SQL=\n%s\n",blob_str(&sql));*/ |
| 111 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 112 | blob_reset(&sql); |
| 113 | |
| 114 | pay = cson_new_object(); |
| 115 | cson_object_set(pay, "name", json_new_string(zFilename)); |
| 116 | if( limit > 0 ){ |
| 117 |
+1
-1
| --- src/json_query.c | ||
| +++ src/json_query.c | ||
| @@ -64,11 +64,11 @@ | ||
| 64 | 64 | return NULL; |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | zFmt = json_find_option_cstr2("format",NULL,"f",3); |
| 68 | 68 | if(!zFmt) zFmt = "o"; |
| 69 | - db_prepare(&q,"%s", zSql); | |
| 69 | + db_prepare(&q,"%s", zSql/*safe-for-%s*/); | |
| 70 | 70 | if( 0 == sqlite3_column_count( q.pStmt ) ){ |
| 71 | 71 | json_set_err(FSL_JSON_E_USAGE, |
| 72 | 72 | "Input query has no result columns. " |
| 73 | 73 | "Only SELECT-like queries are supported."); |
| 74 | 74 | db_finalize(&q); |
| 75 | 75 |
| --- src/json_query.c | |
| +++ src/json_query.c | |
| @@ -64,11 +64,11 @@ | |
| 64 | return NULL; |
| 65 | } |
| 66 | |
| 67 | zFmt = json_find_option_cstr2("format",NULL,"f",3); |
| 68 | if(!zFmt) zFmt = "o"; |
| 69 | db_prepare(&q,"%s", zSql); |
| 70 | if( 0 == sqlite3_column_count( q.pStmt ) ){ |
| 71 | json_set_err(FSL_JSON_E_USAGE, |
| 72 | "Input query has no result columns. " |
| 73 | "Only SELECT-like queries are supported."); |
| 74 | db_finalize(&q); |
| 75 |
| --- src/json_query.c | |
| +++ src/json_query.c | |
| @@ -64,11 +64,11 @@ | |
| 64 | return NULL; |
| 65 | } |
| 66 | |
| 67 | zFmt = json_find_option_cstr2("format",NULL,"f",3); |
| 68 | if(!zFmt) zFmt = "o"; |
| 69 | db_prepare(&q,"%s", zSql/*safe-for-%s*/); |
| 70 | if( 0 == sqlite3_column_count( q.pStmt ) ){ |
| 71 | json_set_err(FSL_JSON_E_USAGE, |
| 72 | "Input query has no result columns. " |
| 73 | "Only SELECT-like queries are supported."); |
| 74 | db_finalize(&q); |
| 75 |
+1
-1
| --- src/json_report.c | ||
| +++ src/json_report.c | ||
| @@ -204,11 +204,11 @@ | ||
| 204 | 204 | |
| 205 | 205 | /* Copy over report's SQL...*/ |
| 206 | 206 | blob_append(&sql, db_column_text(&q,0), -1); |
| 207 | 207 | zTitle = mprintf("%s", db_column_text(&q,1)); |
| 208 | 208 | db_finalize(&q); |
| 209 | - db_prepare(&q, "%s", blob_str(&sql)); | |
| 209 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 210 | 210 | |
| 211 | 211 | /** Build the response... */ |
| 212 | 212 | pay = cson_new_object(); |
| 213 | 213 | |
| 214 | 214 | cson_object_set(pay, "report", json_new_int(nReport)); |
| 215 | 215 |
| --- src/json_report.c | |
| +++ src/json_report.c | |
| @@ -204,11 +204,11 @@ | |
| 204 | |
| 205 | /* Copy over report's SQL...*/ |
| 206 | blob_append(&sql, db_column_text(&q,0), -1); |
| 207 | zTitle = mprintf("%s", db_column_text(&q,1)); |
| 208 | db_finalize(&q); |
| 209 | db_prepare(&q, "%s", blob_str(&sql)); |
| 210 | |
| 211 | /** Build the response... */ |
| 212 | pay = cson_new_object(); |
| 213 | |
| 214 | cson_object_set(pay, "report", json_new_int(nReport)); |
| 215 |
| --- src/json_report.c | |
| +++ src/json_report.c | |
| @@ -204,11 +204,11 @@ | |
| 204 | |
| 205 | /* Copy over report's SQL...*/ |
| 206 | blob_append(&sql, db_column_text(&q,0), -1); |
| 207 | zTitle = mprintf("%s", db_column_text(&q,1)); |
| 208 | db_finalize(&q); |
| 209 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 210 | |
| 211 | /** Build the response... */ |
| 212 | pay = cson_new_object(); |
| 213 | |
| 214 | cson_object_set(pay, "report", json_new_int(nReport)); |
| 215 |
+2
-2
| --- src/json_tag.c | ||
| +++ src/json_tag.c | ||
| @@ -301,11 +301,11 @@ | ||
| 301 | 301 | " SELECT rid FROM tagxref" |
| 302 | 302 | " WHERE tagtype>0 AND tagid=%d" |
| 303 | 303 | " )" |
| 304 | 304 | " ORDER BY event.mtime DESC" |
| 305 | 305 | "%s LIMIT %d", |
| 306 | - zSqlBase, zType, tagid, | |
| 306 | + zSqlBase /*safe-for-%s*/, zType, tagid, | |
| 307 | 307 | (limit>0)?"":"--", limit |
| 308 | 308 | ); |
| 309 | 309 | listV = json_stmt_to_array_of_obj(&q, NULL); |
| 310 | 310 | db_finalize(&q); |
| 311 | 311 | } |
| @@ -442,11 +442,11 @@ | ||
| 442 | 442 | if(!fTicket){ |
| 443 | 443 | blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1); |
| 444 | 444 | } |
| 445 | 445 | blob_append(&sql, |
| 446 | 446 | " ORDER BY tagname", -1); |
| 447 | - db_prepare(&q, blob_buffer(&sql)); | |
| 447 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 448 | 448 | blob_reset(&sql); |
| 449 | 449 | cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) ); |
| 450 | 450 | while( SQLITE_ROW == db_step(&q) ){ |
| 451 | 451 | const char *zName = db_column_text(&q, 0); |
| 452 | 452 | if(NULL==arV){ |
| 453 | 453 |
| --- src/json_tag.c | |
| +++ src/json_tag.c | |
| @@ -301,11 +301,11 @@ | |
| 301 | " SELECT rid FROM tagxref" |
| 302 | " WHERE tagtype>0 AND tagid=%d" |
| 303 | " )" |
| 304 | " ORDER BY event.mtime DESC" |
| 305 | "%s LIMIT %d", |
| 306 | zSqlBase, zType, tagid, |
| 307 | (limit>0)?"":"--", limit |
| 308 | ); |
| 309 | listV = json_stmt_to_array_of_obj(&q, NULL); |
| 310 | db_finalize(&q); |
| 311 | } |
| @@ -442,11 +442,11 @@ | |
| 442 | if(!fTicket){ |
| 443 | blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1); |
| 444 | } |
| 445 | blob_append(&sql, |
| 446 | " ORDER BY tagname", -1); |
| 447 | db_prepare(&q, blob_buffer(&sql)); |
| 448 | blob_reset(&sql); |
| 449 | cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) ); |
| 450 | while( SQLITE_ROW == db_step(&q) ){ |
| 451 | const char *zName = db_column_text(&q, 0); |
| 452 | if(NULL==arV){ |
| 453 |
| --- src/json_tag.c | |
| +++ src/json_tag.c | |
| @@ -301,11 +301,11 @@ | |
| 301 | " SELECT rid FROM tagxref" |
| 302 | " WHERE tagtype>0 AND tagid=%d" |
| 303 | " )" |
| 304 | " ORDER BY event.mtime DESC" |
| 305 | "%s LIMIT %d", |
| 306 | zSqlBase /*safe-for-%s*/, zType, tagid, |
| 307 | (limit>0)?"":"--", limit |
| 308 | ); |
| 309 | listV = json_stmt_to_array_of_obj(&q, NULL); |
| 310 | db_finalize(&q); |
| 311 | } |
| @@ -442,11 +442,11 @@ | |
| 442 | if(!fTicket){ |
| 443 | blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1); |
| 444 | } |
| 445 | blob_append(&sql, |
| 446 | " ORDER BY tagname", -1); |
| 447 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 448 | blob_reset(&sql); |
| 449 | cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) ); |
| 450 | while( SQLITE_ROW == db_step(&q) ){ |
| 451 | const char *zName = db_column_text(&q, 0); |
| 452 | if(NULL==arV){ |
| 453 |
+9
-11
| --- src/json_timeline.c | ||
| +++ src/json_timeline.c | ||
| @@ -83,11 +83,11 @@ | ||
| 83 | 83 | @ tags TEXT, |
| 84 | 84 | @ tagId INTEGER, |
| 85 | 85 | @ brief TEXT |
| 86 | 86 | @ ) |
| 87 | 87 | ; |
| 88 | - db_multi_exec(zSql); | |
| 88 | + db_multi_exec("%s", zSql /*safe-for-%s*/); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | /* |
| 92 | 92 | ** Return a pointer to a constant string that forms the basis |
| 93 | 93 | ** for a timeline query for the JSON interface. |
| @@ -384,21 +384,21 @@ | ||
| 384 | 384 | " bgcolor as bgColor" |
| 385 | 385 | " FROM event JOIN blob" |
| 386 | 386 | " WHERE blob.rid=event.objid", |
| 387 | 387 | -1); |
| 388 | 388 | |
| 389 | - blob_appendf(&sql, | |
| 389 | + blob_append_sql(&sql, | |
| 390 | 390 | " AND event.type='ci'" |
| 391 | 391 | " AND blob.rid IN (SELECT rid FROM tagxref" |
| 392 | 392 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)" |
| 393 | 393 | " ORDER BY event.mtime DESC", |
| 394 | 394 | TAG_BRANCH); |
| 395 | 395 | limit = json_timeline_limit(20); |
| 396 | 396 | if(limit>0){ |
| 397 | - blob_appendf(&sql," LIMIT %d ",limit); | |
| 397 | + blob_append_sql(&sql," LIMIT %d ",limit); | |
| 398 | 398 | } |
| 399 | - db_prepare(&q,"%s", blob_str(&sql)); | |
| 399 | + db_prepare(&q,"%s", blob_sql_text(&sql)); | |
| 400 | 400 | blob_reset(&sql); |
| 401 | 401 | pay = json_stmt_to_array_of_obj(&q, NULL); |
| 402 | 402 | db_finalize(&q); |
| 403 | 403 | assert(NULL != pay); |
| 404 | 404 | if(pay){ |
| @@ -482,11 +482,11 @@ | ||
| 482 | 482 | #if 0 |
| 483 | 483 | /* only for testing! */ |
| 484 | 484 | tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))); |
| 485 | 485 | SET("timelineSql"); |
| 486 | 486 | #endif |
| 487 | - db_multi_exec(blob_buffer(&sql)); | |
| 487 | + db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/); | |
| 488 | 488 | blob_reset(&sql); |
| 489 | 489 | db_prepare(&q, "SELECT " |
| 490 | 490 | " rid AS rid" |
| 491 | 491 | " FROM json_timeline" |
| 492 | 492 | " ORDER BY rowid"); |
| @@ -547,11 +547,11 @@ | ||
| 547 | 547 | #if 0 |
| 548 | 548 | /* only for testing! */ |
| 549 | 549 | tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))); |
| 550 | 550 | SET("timelineSql"); |
| 551 | 551 | #endif |
| 552 | - db_multi_exec(blob_buffer(&sql)); | |
| 552 | + db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/); | |
| 553 | 553 | blob_reset(&sql); |
| 554 | 554 | db_prepare(&q, "SELECT" |
| 555 | 555 | " uuid AS uuid," |
| 556 | 556 | " mtime AS timestamp," |
| 557 | 557 | #if 0 |
| @@ -565,12 +565,11 @@ | ||
| 565 | 565 | " tags AS tags," /*FIXME: split this into |
| 566 | 566 | a JSON array*/ |
| 567 | 567 | " tagId AS tagId," |
| 568 | 568 | #endif |
| 569 | 569 | " FROM json_timeline" |
| 570 | - " ORDER BY rowid", | |
| 571 | - -1); | |
| 570 | + " ORDER BY rowid"); | |
| 572 | 571 | list = cson_new_array(); |
| 573 | 572 | json_stmt_to_array_of_obj(&q, list); |
| 574 | 573 | cson_object_set(pay, "timeline", cson_array_value(list)); |
| 575 | 574 | goto ok; |
| 576 | 575 | error: |
| @@ -607,11 +606,11 @@ | ||
| 607 | 606 | if(check){ |
| 608 | 607 | json_set_err(check, "Query initialization failed."); |
| 609 | 608 | goto error; |
| 610 | 609 | } |
| 611 | 610 | |
| 612 | - db_multi_exec(blob_buffer(&sql)); | |
| 611 | + db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/); | |
| 613 | 612 | #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \ |
| 614 | 613 | json_set_err((cson_rc.AllocError==check) \ |
| 615 | 614 | ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \ |
| 616 | 615 | "Object property insertion failed."); \ |
| 617 | 616 | goto error;\ |
| @@ -638,12 +637,11 @@ | ||
| 638 | 637 | " user AS user," |
| 639 | 638 | " eventType AS eventType," |
| 640 | 639 | " comment AS comment," |
| 641 | 640 | " brief AS briefComment" |
| 642 | 641 | " FROM json_timeline" |
| 643 | - " ORDER BY rowid", | |
| 644 | - -1); | |
| 642 | + " ORDER BY rowid"); | |
| 645 | 643 | listV = cson_value_new_array(); |
| 646 | 644 | list = cson_value_get_array(listV); |
| 647 | 645 | tmp = listV; |
| 648 | 646 | SET("timeline"); |
| 649 | 647 | while( (SQLITE_ROW == db_step(&q) )){ |
| 650 | 648 |
| --- src/json_timeline.c | |
| +++ src/json_timeline.c | |
| @@ -83,11 +83,11 @@ | |
| 83 | @ tags TEXT, |
| 84 | @ tagId INTEGER, |
| 85 | @ brief TEXT |
| 86 | @ ) |
| 87 | ; |
| 88 | db_multi_exec(zSql); |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Return a pointer to a constant string that forms the basis |
| 93 | ** for a timeline query for the JSON interface. |
| @@ -384,21 +384,21 @@ | |
| 384 | " bgcolor as bgColor" |
| 385 | " FROM event JOIN blob" |
| 386 | " WHERE blob.rid=event.objid", |
| 387 | -1); |
| 388 | |
| 389 | blob_appendf(&sql, |
| 390 | " AND event.type='ci'" |
| 391 | " AND blob.rid IN (SELECT rid FROM tagxref" |
| 392 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)" |
| 393 | " ORDER BY event.mtime DESC", |
| 394 | TAG_BRANCH); |
| 395 | limit = json_timeline_limit(20); |
| 396 | if(limit>0){ |
| 397 | blob_appendf(&sql," LIMIT %d ",limit); |
| 398 | } |
| 399 | db_prepare(&q,"%s", blob_str(&sql)); |
| 400 | blob_reset(&sql); |
| 401 | pay = json_stmt_to_array_of_obj(&q, NULL); |
| 402 | db_finalize(&q); |
| 403 | assert(NULL != pay); |
| 404 | if(pay){ |
| @@ -482,11 +482,11 @@ | |
| 482 | #if 0 |
| 483 | /* only for testing! */ |
| 484 | tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))); |
| 485 | SET("timelineSql"); |
| 486 | #endif |
| 487 | db_multi_exec(blob_buffer(&sql)); |
| 488 | blob_reset(&sql); |
| 489 | db_prepare(&q, "SELECT " |
| 490 | " rid AS rid" |
| 491 | " FROM json_timeline" |
| 492 | " ORDER BY rowid"); |
| @@ -547,11 +547,11 @@ | |
| 547 | #if 0 |
| 548 | /* only for testing! */ |
| 549 | tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))); |
| 550 | SET("timelineSql"); |
| 551 | #endif |
| 552 | db_multi_exec(blob_buffer(&sql)); |
| 553 | blob_reset(&sql); |
| 554 | db_prepare(&q, "SELECT" |
| 555 | " uuid AS uuid," |
| 556 | " mtime AS timestamp," |
| 557 | #if 0 |
| @@ -565,12 +565,11 @@ | |
| 565 | " tags AS tags," /*FIXME: split this into |
| 566 | a JSON array*/ |
| 567 | " tagId AS tagId," |
| 568 | #endif |
| 569 | " FROM json_timeline" |
| 570 | " ORDER BY rowid", |
| 571 | -1); |
| 572 | list = cson_new_array(); |
| 573 | json_stmt_to_array_of_obj(&q, list); |
| 574 | cson_object_set(pay, "timeline", cson_array_value(list)); |
| 575 | goto ok; |
| 576 | error: |
| @@ -607,11 +606,11 @@ | |
| 607 | if(check){ |
| 608 | json_set_err(check, "Query initialization failed."); |
| 609 | goto error; |
| 610 | } |
| 611 | |
| 612 | db_multi_exec(blob_buffer(&sql)); |
| 613 | #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \ |
| 614 | json_set_err((cson_rc.AllocError==check) \ |
| 615 | ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \ |
| 616 | "Object property insertion failed."); \ |
| 617 | goto error;\ |
| @@ -638,12 +637,11 @@ | |
| 638 | " user AS user," |
| 639 | " eventType AS eventType," |
| 640 | " comment AS comment," |
| 641 | " brief AS briefComment" |
| 642 | " FROM json_timeline" |
| 643 | " ORDER BY rowid", |
| 644 | -1); |
| 645 | listV = cson_value_new_array(); |
| 646 | list = cson_value_get_array(listV); |
| 647 | tmp = listV; |
| 648 | SET("timeline"); |
| 649 | while( (SQLITE_ROW == db_step(&q) )){ |
| 650 |
| --- src/json_timeline.c | |
| +++ src/json_timeline.c | |
| @@ -83,11 +83,11 @@ | |
| 83 | @ tags TEXT, |
| 84 | @ tagId INTEGER, |
| 85 | @ brief TEXT |
| 86 | @ ) |
| 87 | ; |
| 88 | db_multi_exec("%s", zSql /*safe-for-%s*/); |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Return a pointer to a constant string that forms the basis |
| 93 | ** for a timeline query for the JSON interface. |
| @@ -384,21 +384,21 @@ | |
| 384 | " bgcolor as bgColor" |
| 385 | " FROM event JOIN blob" |
| 386 | " WHERE blob.rid=event.objid", |
| 387 | -1); |
| 388 | |
| 389 | blob_append_sql(&sql, |
| 390 | " AND event.type='ci'" |
| 391 | " AND blob.rid IN (SELECT rid FROM tagxref" |
| 392 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)" |
| 393 | " ORDER BY event.mtime DESC", |
| 394 | TAG_BRANCH); |
| 395 | limit = json_timeline_limit(20); |
| 396 | if(limit>0){ |
| 397 | blob_append_sql(&sql," LIMIT %d ",limit); |
| 398 | } |
| 399 | db_prepare(&q,"%s", blob_sql_text(&sql)); |
| 400 | blob_reset(&sql); |
| 401 | pay = json_stmt_to_array_of_obj(&q, NULL); |
| 402 | db_finalize(&q); |
| 403 | assert(NULL != pay); |
| 404 | if(pay){ |
| @@ -482,11 +482,11 @@ | |
| 482 | #if 0 |
| 483 | /* only for testing! */ |
| 484 | tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))); |
| 485 | SET("timelineSql"); |
| 486 | #endif |
| 487 | db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/); |
| 488 | blob_reset(&sql); |
| 489 | db_prepare(&q, "SELECT " |
| 490 | " rid AS rid" |
| 491 | " FROM json_timeline" |
| 492 | " ORDER BY rowid"); |
| @@ -547,11 +547,11 @@ | |
| 547 | #if 0 |
| 548 | /* only for testing! */ |
| 549 | tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))); |
| 550 | SET("timelineSql"); |
| 551 | #endif |
| 552 | db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/); |
| 553 | blob_reset(&sql); |
| 554 | db_prepare(&q, "SELECT" |
| 555 | " uuid AS uuid," |
| 556 | " mtime AS timestamp," |
| 557 | #if 0 |
| @@ -565,12 +565,11 @@ | |
| 565 | " tags AS tags," /*FIXME: split this into |
| 566 | a JSON array*/ |
| 567 | " tagId AS tagId," |
| 568 | #endif |
| 569 | " FROM json_timeline" |
| 570 | " ORDER BY rowid"); |
| 571 | list = cson_new_array(); |
| 572 | json_stmt_to_array_of_obj(&q, list); |
| 573 | cson_object_set(pay, "timeline", cson_array_value(list)); |
| 574 | goto ok; |
| 575 | error: |
| @@ -607,11 +606,11 @@ | |
| 606 | if(check){ |
| 607 | json_set_err(check, "Query initialization failed."); |
| 608 | goto error; |
| 609 | } |
| 610 | |
| 611 | db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/); |
| 612 | #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \ |
| 613 | json_set_err((cson_rc.AllocError==check) \ |
| 614 | ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \ |
| 615 | "Object property insertion failed."); \ |
| 616 | goto error;\ |
| @@ -638,12 +637,11 @@ | |
| 637 | " user AS user," |
| 638 | " eventType AS eventType," |
| 639 | " comment AS comment," |
| 640 | " brief AS briefComment" |
| 641 | " FROM json_timeline" |
| 642 | " ORDER BY rowid"); |
| 643 | listV = cson_value_new_array(); |
| 644 | list = cson_value_get_array(listV); |
| 645 | tmp = listV; |
| 646 | SET("timeline"); |
| 647 | while( (SQLITE_ROW == db_step(&q) )){ |
| 648 |
+9
-9
| --- src/json_user.c | ||
| +++ src/json_user.c | ||
| @@ -286,11 +286,11 @@ | ||
| 286 | 286 | /* reminders: 1) does not allocate. |
| 287 | 287 | 2) we do this because changing a name |
| 288 | 288 | invalidates any login token because the old name |
| 289 | 289 | is part of the token hash. |
| 290 | 290 | */; |
| 291 | - blob_appendf(&sql, ", login=%Q", zNameNew); | |
| 291 | + blob_append_sql(&sql, ", login=%Q", zNameNew); | |
| 292 | 292 | ++gotFields; |
| 293 | 293 | } |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | if( zCap && *zCap ){ |
| @@ -298,11 +298,11 @@ | ||
| 298 | 298 | /* we "could" arguably silently ignore cap in this case. */ |
| 299 | 299 | json_set_err(FSL_JSON_E_DENIED, |
| 300 | 300 | "Changing capabilities requires 'a' or 's' privileges."); |
| 301 | 301 | goto error; |
| 302 | 302 | } |
| 303 | - blob_appendf(&sql, ", cap=%Q", zCap); | |
| 303 | + blob_append_sql(&sql, ", cap=%Q", zCap); | |
| 304 | 304 | ++gotFields; |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | 307 | if( zPW && *zPW ){ |
| 308 | 308 | if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){ |
| @@ -314,24 +314,24 @@ | ||
| 314 | 314 | #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */ |
| 315 | 315 | #if !TRY_LOGIN_GROUP |
| 316 | 316 | char * zPWHash = NULL; |
| 317 | 317 | ++gotFields; |
| 318 | 318 | zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL); |
| 319 | - blob_appendf(&sql, ", pw=%Q", zPWHash); | |
| 319 | + blob_append_sql(&sql, ", pw=%Q", zPWHash); | |
| 320 | 320 | free(zPWHash); |
| 321 | 321 | #else |
| 322 | 322 | ++gotFields; |
| 323 | - blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q," | |
| 323 | + blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q," | |
| 324 | 324 | "(SELECT value FROM config WHERE name='project-code')))", |
| 325 | 325 | zPW, zNameNew ? zNameNew : zName); |
| 326 | 326 | /* shared_secret() func is undefined? */ |
| 327 | 327 | #endif |
| 328 | 328 | } |
| 329 | 329 | } |
| 330 | 330 | |
| 331 | 331 | if( zInfo ){ |
| 332 | - blob_appendf(&sql, ", info=%Q", zInfo); | |
| 332 | + blob_append_sql(&sql, ", info=%Q", zInfo); | |
| 333 | 333 | ++gotFields; |
| 334 | 334 | } |
| 335 | 335 | |
| 336 | 336 | if((g.perm.Admin || g.perm.Setup) |
| 337 | 337 | && forceLogout && cson_value_get_bool(forceLogout)){ |
| @@ -344,26 +344,26 @@ | ||
| 344 | 344 | "Required user data are missing."); |
| 345 | 345 | goto error; |
| 346 | 346 | } |
| 347 | 347 | assert(uid>0); |
| 348 | 348 | #if !TRY_LOGIN_GROUP |
| 349 | - blob_appendf(&sql, " WHERE uid=%d", uid); | |
| 349 | + blob_append_sql(&sql, " WHERE uid=%d", uid); | |
| 350 | 350 | #else /* need name for login group support :/ */ |
| 351 | - blob_appendf(&sql, " WHERE login=%Q", zName); | |
| 351 | + blob_append_sql(&sql, " WHERE login=%Q", zName); | |
| 352 | 352 | #endif |
| 353 | 353 | #if 0 |
| 354 | 354 | puts(blob_str(&sql)); |
| 355 | 355 | cson_output_FILE( cson_object_value(pUser), stdout, NULL ); |
| 356 | 356 | #endif |
| 357 | - db_prepare(&q, "%s", blob_str(&sql)); | |
| 357 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 358 | 358 | db_exec(&q); |
| 359 | 359 | db_finalize(&q); |
| 360 | 360 | #if TRY_LOGIN_GROUP |
| 361 | 361 | if( zPW || cson_value_get_bool(forceLogout) ){ |
| 362 | 362 | Blob groupSql = empty_blob; |
| 363 | 363 | char * zErr = NULL; |
| 364 | - blob_appendf(&groupSql, | |
| 364 | + blob_append_sql(&groupSql, | |
| 365 | 365 | "INSERT INTO user(login)" |
| 366 | 366 | " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);", |
| 367 | 367 | zName, zName |
| 368 | 368 | ); |
| 369 | 369 | blob_append(&groupSql, blob_str(&sql), blob_size(&sql)); |
| 370 | 370 |
| --- src/json_user.c | |
| +++ src/json_user.c | |
| @@ -286,11 +286,11 @@ | |
| 286 | /* reminders: 1) does not allocate. |
| 287 | 2) we do this because changing a name |
| 288 | invalidates any login token because the old name |
| 289 | is part of the token hash. |
| 290 | */; |
| 291 | blob_appendf(&sql, ", login=%Q", zNameNew); |
| 292 | ++gotFields; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | if( zCap && *zCap ){ |
| @@ -298,11 +298,11 @@ | |
| 298 | /* we "could" arguably silently ignore cap in this case. */ |
| 299 | json_set_err(FSL_JSON_E_DENIED, |
| 300 | "Changing capabilities requires 'a' or 's' privileges."); |
| 301 | goto error; |
| 302 | } |
| 303 | blob_appendf(&sql, ", cap=%Q", zCap); |
| 304 | ++gotFields; |
| 305 | } |
| 306 | |
| 307 | if( zPW && *zPW ){ |
| 308 | if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){ |
| @@ -314,24 +314,24 @@ | |
| 314 | #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */ |
| 315 | #if !TRY_LOGIN_GROUP |
| 316 | char * zPWHash = NULL; |
| 317 | ++gotFields; |
| 318 | zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL); |
| 319 | blob_appendf(&sql, ", pw=%Q", zPWHash); |
| 320 | free(zPWHash); |
| 321 | #else |
| 322 | ++gotFields; |
| 323 | blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q," |
| 324 | "(SELECT value FROM config WHERE name='project-code')))", |
| 325 | zPW, zNameNew ? zNameNew : zName); |
| 326 | /* shared_secret() func is undefined? */ |
| 327 | #endif |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | if( zInfo ){ |
| 332 | blob_appendf(&sql, ", info=%Q", zInfo); |
| 333 | ++gotFields; |
| 334 | } |
| 335 | |
| 336 | if((g.perm.Admin || g.perm.Setup) |
| 337 | && forceLogout && cson_value_get_bool(forceLogout)){ |
| @@ -344,26 +344,26 @@ | |
| 344 | "Required user data are missing."); |
| 345 | goto error; |
| 346 | } |
| 347 | assert(uid>0); |
| 348 | #if !TRY_LOGIN_GROUP |
| 349 | blob_appendf(&sql, " WHERE uid=%d", uid); |
| 350 | #else /* need name for login group support :/ */ |
| 351 | blob_appendf(&sql, " WHERE login=%Q", zName); |
| 352 | #endif |
| 353 | #if 0 |
| 354 | puts(blob_str(&sql)); |
| 355 | cson_output_FILE( cson_object_value(pUser), stdout, NULL ); |
| 356 | #endif |
| 357 | db_prepare(&q, "%s", blob_str(&sql)); |
| 358 | db_exec(&q); |
| 359 | db_finalize(&q); |
| 360 | #if TRY_LOGIN_GROUP |
| 361 | if( zPW || cson_value_get_bool(forceLogout) ){ |
| 362 | Blob groupSql = empty_blob; |
| 363 | char * zErr = NULL; |
| 364 | blob_appendf(&groupSql, |
| 365 | "INSERT INTO user(login)" |
| 366 | " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);", |
| 367 | zName, zName |
| 368 | ); |
| 369 | blob_append(&groupSql, blob_str(&sql), blob_size(&sql)); |
| 370 |
| --- src/json_user.c | |
| +++ src/json_user.c | |
| @@ -286,11 +286,11 @@ | |
| 286 | /* reminders: 1) does not allocate. |
| 287 | 2) we do this because changing a name |
| 288 | invalidates any login token because the old name |
| 289 | is part of the token hash. |
| 290 | */; |
| 291 | blob_append_sql(&sql, ", login=%Q", zNameNew); |
| 292 | ++gotFields; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | if( zCap && *zCap ){ |
| @@ -298,11 +298,11 @@ | |
| 298 | /* we "could" arguably silently ignore cap in this case. */ |
| 299 | json_set_err(FSL_JSON_E_DENIED, |
| 300 | "Changing capabilities requires 'a' or 's' privileges."); |
| 301 | goto error; |
| 302 | } |
| 303 | blob_append_sql(&sql, ", cap=%Q", zCap); |
| 304 | ++gotFields; |
| 305 | } |
| 306 | |
| 307 | if( zPW && *zPW ){ |
| 308 | if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){ |
| @@ -314,24 +314,24 @@ | |
| 314 | #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */ |
| 315 | #if !TRY_LOGIN_GROUP |
| 316 | char * zPWHash = NULL; |
| 317 | ++gotFields; |
| 318 | zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL); |
| 319 | blob_append_sql(&sql, ", pw=%Q", zPWHash); |
| 320 | free(zPWHash); |
| 321 | #else |
| 322 | ++gotFields; |
| 323 | blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q," |
| 324 | "(SELECT value FROM config WHERE name='project-code')))", |
| 325 | zPW, zNameNew ? zNameNew : zName); |
| 326 | /* shared_secret() func is undefined? */ |
| 327 | #endif |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | if( zInfo ){ |
| 332 | blob_append_sql(&sql, ", info=%Q", zInfo); |
| 333 | ++gotFields; |
| 334 | } |
| 335 | |
| 336 | if((g.perm.Admin || g.perm.Setup) |
| 337 | && forceLogout && cson_value_get_bool(forceLogout)){ |
| @@ -344,26 +344,26 @@ | |
| 344 | "Required user data are missing."); |
| 345 | goto error; |
| 346 | } |
| 347 | assert(uid>0); |
| 348 | #if !TRY_LOGIN_GROUP |
| 349 | blob_append_sql(&sql, " WHERE uid=%d", uid); |
| 350 | #else /* need name for login group support :/ */ |
| 351 | blob_append_sql(&sql, " WHERE login=%Q", zName); |
| 352 | #endif |
| 353 | #if 0 |
| 354 | puts(blob_str(&sql)); |
| 355 | cson_output_FILE( cson_object_value(pUser), stdout, NULL ); |
| 356 | #endif |
| 357 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 358 | db_exec(&q); |
| 359 | db_finalize(&q); |
| 360 | #if TRY_LOGIN_GROUP |
| 361 | if( zPW || cson_value_get_bool(forceLogout) ){ |
| 362 | Blob groupSql = empty_blob; |
| 363 | char * zErr = NULL; |
| 364 | blob_append_sql(&groupSql, |
| 365 | "INSERT INTO user(login)" |
| 366 | " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);", |
| 367 | zName, zName |
| 368 | ); |
| 369 | blob_append(&groupSql, blob_str(&sql), blob_size(&sql)); |
| 370 |
+5
-6
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -444,22 +444,21 @@ | ||
| 444 | 444 | " substr(tagname,6) as name" |
| 445 | 445 | " FROM tag WHERE tagname GLOB 'wiki-*'", |
| 446 | 446 | -1); |
| 447 | 447 | zGlob = json_find_option_cstr("glob",NULL,"g"); |
| 448 | 448 | if(zGlob && *zGlob){ |
| 449 | - blob_appendf(&sql," AND name %s GLOB %Q", | |
| 450 | - fInvert ? "NOT" : "", zGlob); | |
| 449 | + blob_append_sql(&sql," AND name %s GLOB %Q", | |
| 450 | + fInvert ? "NOT" : "", zGlob); | |
| 451 | 451 | }else{ |
| 452 | 452 | zGlob = json_find_option_cstr("like",NULL,"l"); |
| 453 | 453 | if(zGlob && *zGlob){ |
| 454 | - blob_appendf(&sql," AND name %s LIKE %Q", | |
| 455 | - fInvert ? "NOT" : "", | |
| 456 | - zGlob); | |
| 454 | + blob_append_sql(&sql," AND name %s LIKE %Q", | |
| 455 | + fInvert ? "NOT" : "", zGlob); | |
| 457 | 456 | } |
| 458 | 457 | } |
| 459 | 458 | blob_append(&sql," ORDER BY lower(name)", -1); |
| 460 | - db_prepare(&q,"%s", blob_str(&sql)); | |
| 459 | + db_prepare(&q,"%s", blob_sql_text(&sql)); | |
| 461 | 460 | blob_reset(&sql); |
| 462 | 461 | listV = cson_value_new_array(); |
| 463 | 462 | list = cson_value_get_array(listV); |
| 464 | 463 | while( SQLITE_ROW == db_step(&q) ){ |
| 465 | 464 | cson_value * v; |
| 466 | 465 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -444,22 +444,21 @@ | |
| 444 | " substr(tagname,6) as name" |
| 445 | " FROM tag WHERE tagname GLOB 'wiki-*'", |
| 446 | -1); |
| 447 | zGlob = json_find_option_cstr("glob",NULL,"g"); |
| 448 | if(zGlob && *zGlob){ |
| 449 | blob_appendf(&sql," AND name %s GLOB %Q", |
| 450 | fInvert ? "NOT" : "", zGlob); |
| 451 | }else{ |
| 452 | zGlob = json_find_option_cstr("like",NULL,"l"); |
| 453 | if(zGlob && *zGlob){ |
| 454 | blob_appendf(&sql," AND name %s LIKE %Q", |
| 455 | fInvert ? "NOT" : "", |
| 456 | zGlob); |
| 457 | } |
| 458 | } |
| 459 | blob_append(&sql," ORDER BY lower(name)", -1); |
| 460 | db_prepare(&q,"%s", blob_str(&sql)); |
| 461 | blob_reset(&sql); |
| 462 | listV = cson_value_new_array(); |
| 463 | list = cson_value_get_array(listV); |
| 464 | while( SQLITE_ROW == db_step(&q) ){ |
| 465 | cson_value * v; |
| 466 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -444,22 +444,21 @@ | |
| 444 | " substr(tagname,6) as name" |
| 445 | " FROM tag WHERE tagname GLOB 'wiki-*'", |
| 446 | -1); |
| 447 | zGlob = json_find_option_cstr("glob",NULL,"g"); |
| 448 | if(zGlob && *zGlob){ |
| 449 | blob_append_sql(&sql," AND name %s GLOB %Q", |
| 450 | fInvert ? "NOT" : "", zGlob); |
| 451 | }else{ |
| 452 | zGlob = json_find_option_cstr("like",NULL,"l"); |
| 453 | if(zGlob && *zGlob){ |
| 454 | blob_append_sql(&sql," AND name %s LIKE %Q", |
| 455 | fInvert ? "NOT" : "", zGlob); |
| 456 | } |
| 457 | } |
| 458 | blob_append(&sql," ORDER BY lower(name)", -1); |
| 459 | db_prepare(&q,"%s", blob_sql_text(&sql)); |
| 460 | blob_reset(&sql); |
| 461 | listV = cson_value_new_array(); |
| 462 | list = cson_value_get_array(listV); |
| 463 | while( SQLITE_ROW == db_step(&q) ){ |
| 464 | cson_value * v; |
| 465 |
+3
-2
| --- src/leaf.c | ||
| +++ src/leaf.c | ||
| @@ -39,11 +39,12 @@ | ||
| 39 | 39 | @ AND coalesce((SELECT value FROM tagxref |
| 40 | 40 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 41 | 41 | @ =coalesce((SELECT value FROM tagxref |
| 42 | 42 | @ WHERE tagid=%d AND rid=plink.cid), 'trunk') |
| 43 | 43 | ; |
| 44 | - rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH); | |
| 44 | + rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/, | |
| 45 | + rid, TAG_BRANCH, TAG_BRANCH); | |
| 45 | 46 | return rc==0; |
| 46 | 47 | } |
| 47 | 48 | |
| 48 | 49 | /* |
| 49 | 50 | ** Count the number of primary non-branch children for the given check-in. |
| @@ -63,11 +64,11 @@ | ||
| 63 | 64 | @ AND coalesce((SELECT value FROM tagxref |
| 64 | 65 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 65 | 66 | @ =coalesce((SELECT value FROM tagxref |
| 66 | 67 | @ WHERE tagid=%d AND rid=plink.cid), 'trunk') |
| 67 | 68 | ; |
| 68 | - db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH); | |
| 69 | + db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH); | |
| 69 | 70 | db_bind_int(&q, ":pid", pid); |
| 70 | 71 | if( db_step(&q)==SQLITE_ROW ){ |
| 71 | 72 | nNonBranch = db_column_int(&q, 0); |
| 72 | 73 | } |
| 73 | 74 | db_reset(&q); |
| 74 | 75 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -39,11 +39,12 @@ | |
| 39 | @ AND coalesce((SELECT value FROM tagxref |
| 40 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 41 | @ =coalesce((SELECT value FROM tagxref |
| 42 | @ WHERE tagid=%d AND rid=plink.cid), 'trunk') |
| 43 | ; |
| 44 | rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH); |
| 45 | return rc==0; |
| 46 | } |
| 47 | |
| 48 | /* |
| 49 | ** Count the number of primary non-branch children for the given check-in. |
| @@ -63,11 +64,11 @@ | |
| 63 | @ AND coalesce((SELECT value FROM tagxref |
| 64 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 65 | @ =coalesce((SELECT value FROM tagxref |
| 66 | @ WHERE tagid=%d AND rid=plink.cid), 'trunk') |
| 67 | ; |
| 68 | db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH); |
| 69 | db_bind_int(&q, ":pid", pid); |
| 70 | if( db_step(&q)==SQLITE_ROW ){ |
| 71 | nNonBranch = db_column_int(&q, 0); |
| 72 | } |
| 73 | db_reset(&q); |
| 74 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -39,11 +39,12 @@ | |
| 39 | @ AND coalesce((SELECT value FROM tagxref |
| 40 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 41 | @ =coalesce((SELECT value FROM tagxref |
| 42 | @ WHERE tagid=%d AND rid=plink.cid), 'trunk') |
| 43 | ; |
| 44 | rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/, |
| 45 | rid, TAG_BRANCH, TAG_BRANCH); |
| 46 | return rc==0; |
| 47 | } |
| 48 | |
| 49 | /* |
| 50 | ** Count the number of primary non-branch children for the given check-in. |
| @@ -63,11 +64,11 @@ | |
| 64 | @ AND coalesce((SELECT value FROM tagxref |
| 65 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 66 | @ =coalesce((SELECT value FROM tagxref |
| 67 | @ WHERE tagid=%d AND rid=plink.cid), 'trunk') |
| 68 | ; |
| 69 | db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH); |
| 70 | db_bind_int(&q, ":pid", pid); |
| 71 | if( db_step(&q)==SQLITE_ROW ){ |
| 72 | nNonBranch = db_column_int(&q, 0); |
| 73 | } |
| 74 | db_reset(&q); |
| 75 |
+14
-17
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -93,15 +93,12 @@ | ||
| 93 | 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | 94 | " FROM config" |
| 95 | 95 | " WHERE name IN ('project-code','login-group-code')" |
| 96 | 96 | " ORDER BY name /*sort*/" |
| 97 | 97 | ); |
| 98 | - if( zCookieName==0 ){ | |
| 99 | - zCookieName = mprintf("fossil-0123456789abcdef"); | |
| 100 | - } | |
| 101 | 98 | } |
| 102 | - return zCookieName; | |
| 99 | + return zCookieName ? zCookieName : "unknown"; | |
| 103 | 100 | } |
| 104 | 101 | |
| 105 | 102 | /* |
| 106 | 103 | ** Redirect to the page specified by the "g" query parameter. |
| 107 | 104 | ** Or if there is no "g" query parameter, redirect to the homepage. |
| @@ -403,15 +400,15 @@ | ||
| 403 | 400 | /* If a URI appears in the User-Agent, it is probably a bot */ |
| 404 | 401 | if( strncmp("http", zAgent+i,4)==0 ) return 0; |
| 405 | 402 | } |
| 406 | 403 | if( strncmp(zAgent, "Mozilla/", 8)==0 ){ |
| 407 | 404 | if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */ |
| 408 | - if( strglob("*Firefox/[1-9]*", zAgent) ) return 1; | |
| 409 | - if( strglob("*Chrome/[1-9]*", zAgent) ) return 1; | |
| 410 | - if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1; | |
| 411 | - if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */ | |
| 412 | - if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1; | |
| 405 | + if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1; | |
| 406 | + if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1; | |
| 407 | + if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1; | |
| 408 | + if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */ | |
| 409 | + if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1; | |
| 413 | 410 | return 0; |
| 414 | 411 | } |
| 415 | 412 | if( strncmp(zAgent, "Opera/", 6)==0 ) return 1; |
| 416 | 413 | if( strncmp(zAgent, "Safari/", 7)==0 ) return 1; |
| 417 | 414 | if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1; |
| @@ -1302,11 +1299,11 @@ | ||
| 1302 | 1299 | }else{ |
| 1303 | 1300 | char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0); |
| 1304 | 1301 | int uid; |
| 1305 | 1302 | db_multi_exec( |
| 1306 | 1303 | "INSERT INTO user(login,pw,cap,info,mtime)" |
| 1307 | - "VALUES(%B,%Q,%B,%B,strftime('%s','now'))", | |
| 1304 | + "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))", | |
| 1308 | 1305 | &login, zPw, &caps, &contact |
| 1309 | 1306 | ); |
| 1310 | 1307 | free(zPw); |
| 1311 | 1308 | |
| 1312 | 1309 | /* The user is registered, now just log him in. */ |
| @@ -1477,17 +1474,17 @@ | ||
| 1477 | 1474 | *pzErrMsg = 0; /* Default to no errors */ |
| 1478 | 1475 | zSelf = db_name("repository"); |
| 1479 | 1476 | |
| 1480 | 1477 | /* Get the full pathname of the other repository */ |
| 1481 | 1478 | file_canonical_name(zRepo, &fullName, 0); |
| 1482 | - zRepo = mprintf(blob_str(&fullName)); | |
| 1479 | + zRepo = fossil_strdup(blob_str(&fullName)); | |
| 1483 | 1480 | blob_reset(&fullName); |
| 1484 | 1481 | |
| 1485 | 1482 | /* Get the full pathname for our repository. Also the project code |
| 1486 | 1483 | ** and project name for ourself. */ |
| 1487 | 1484 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1488 | - zSelfRepo = mprintf(blob_str(&fullName)); | |
| 1485 | + zSelfRepo = fossil_strdup(blob_str(&fullName)); | |
| 1489 | 1486 | blob_reset(&fullName); |
| 1490 | 1487 | zSelfProjCode = db_get("project-code", "unknown"); |
| 1491 | 1488 | zSelfLabel = db_get("project-name", 0); |
| 1492 | 1489 | if( zSelfLabel==0 ){ |
| 1493 | 1490 | zSelfLabel = zSelfProjCode; |
| @@ -1508,11 +1505,11 @@ | ||
| 1508 | 1505 | zRepo, &pOther, |
| 1509 | 1506 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1510 | 1507 | g.zVfsName |
| 1511 | 1508 | ); |
| 1512 | 1509 | if( rc!=SQLITE_OK ){ |
| 1513 | - *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); | |
| 1510 | + *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther)); | |
| 1514 | 1511 | }else{ |
| 1515 | 1512 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1516 | 1513 | } |
| 1517 | 1514 | sqlite3_close(pOther); |
| 1518 | 1515 | if( rc ) return; |
| @@ -1541,13 +1538,13 @@ | ||
| 1541 | 1538 | */ |
| 1542 | 1539 | zSelfProjCode = abbreviated_project_code(zSelfProjCode); |
| 1543 | 1540 | zOtherProjCode = abbreviated_project_code(zOtherProjCode); |
| 1544 | 1541 | db_begin_transaction(); |
| 1545 | 1542 | db_multi_exec( |
| 1546 | - "DELETE FROM %s.config WHERE name GLOB 'peer-*';" | |
| 1547 | - "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);" | |
| 1548 | - "INSERT INTO %s.config(name,value) " | |
| 1543 | + "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';" | |
| 1544 | + "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);" | |
| 1545 | + "INSERT INTO \"%w\".config(name,value) " | |
| 1549 | 1546 | " SELECT 'peer-name-%q', value FROM other.config" |
| 1550 | 1547 | " WHERE name='project-name';", |
| 1551 | 1548 | zSelf, |
| 1552 | 1549 | zSelf, zOtherProjCode, zRepo, |
| 1553 | 1550 | zSelf, zOtherProjCode |
| @@ -1558,11 +1555,11 @@ | ||
| 1558 | 1555 | "INSERT OR IGNORE INTO other.config(name,value)" |
| 1559 | 1556 | " VALUES('login-group-code',lower(hex(randomblob(8))));", |
| 1560 | 1557 | zNewName |
| 1561 | 1558 | ); |
| 1562 | 1559 | db_multi_exec( |
| 1563 | - "REPLACE INTO %s.config(name,value)" | |
| 1560 | + "REPLACE INTO \"%w\".config(name,value)" | |
| 1564 | 1561 | " SELECT name, value FROM other.config" |
| 1565 | 1562 | " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'", |
| 1566 | 1563 | zSelf |
| 1567 | 1564 | ); |
| 1568 | 1565 | db_end_transaction(0); |
| 1569 | 1566 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -93,15 +93,12 @@ | |
| 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | " FROM config" |
| 95 | " WHERE name IN ('project-code','login-group-code')" |
| 96 | " ORDER BY name /*sort*/" |
| 97 | ); |
| 98 | if( zCookieName==0 ){ |
| 99 | zCookieName = mprintf("fossil-0123456789abcdef"); |
| 100 | } |
| 101 | } |
| 102 | return zCookieName; |
| 103 | } |
| 104 | |
| 105 | /* |
| 106 | ** Redirect to the page specified by the "g" query parameter. |
| 107 | ** Or if there is no "g" query parameter, redirect to the homepage. |
| @@ -403,15 +400,15 @@ | |
| 403 | /* If a URI appears in the User-Agent, it is probably a bot */ |
| 404 | if( strncmp("http", zAgent+i,4)==0 ) return 0; |
| 405 | } |
| 406 | if( strncmp(zAgent, "Mozilla/", 8)==0 ){ |
| 407 | if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */ |
| 408 | if( strglob("*Firefox/[1-9]*", zAgent) ) return 1; |
| 409 | if( strglob("*Chrome/[1-9]*", zAgent) ) return 1; |
| 410 | if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1; |
| 411 | if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */ |
| 412 | if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1; |
| 413 | return 0; |
| 414 | } |
| 415 | if( strncmp(zAgent, "Opera/", 6)==0 ) return 1; |
| 416 | if( strncmp(zAgent, "Safari/", 7)==0 ) return 1; |
| 417 | if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1; |
| @@ -1302,11 +1299,11 @@ | |
| 1302 | }else{ |
| 1303 | char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0); |
| 1304 | int uid; |
| 1305 | db_multi_exec( |
| 1306 | "INSERT INTO user(login,pw,cap,info,mtime)" |
| 1307 | "VALUES(%B,%Q,%B,%B,strftime('%s','now'))", |
| 1308 | &login, zPw, &caps, &contact |
| 1309 | ); |
| 1310 | free(zPw); |
| 1311 | |
| 1312 | /* The user is registered, now just log him in. */ |
| @@ -1477,17 +1474,17 @@ | |
| 1477 | *pzErrMsg = 0; /* Default to no errors */ |
| 1478 | zSelf = db_name("repository"); |
| 1479 | |
| 1480 | /* Get the full pathname of the other repository */ |
| 1481 | file_canonical_name(zRepo, &fullName, 0); |
| 1482 | zRepo = mprintf(blob_str(&fullName)); |
| 1483 | blob_reset(&fullName); |
| 1484 | |
| 1485 | /* Get the full pathname for our repository. Also the project code |
| 1486 | ** and project name for ourself. */ |
| 1487 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1488 | zSelfRepo = mprintf(blob_str(&fullName)); |
| 1489 | blob_reset(&fullName); |
| 1490 | zSelfProjCode = db_get("project-code", "unknown"); |
| 1491 | zSelfLabel = db_get("project-name", 0); |
| 1492 | if( zSelfLabel==0 ){ |
| 1493 | zSelfLabel = zSelfProjCode; |
| @@ -1508,11 +1505,11 @@ | |
| 1508 | zRepo, &pOther, |
| 1509 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1510 | g.zVfsName |
| 1511 | ); |
| 1512 | if( rc!=SQLITE_OK ){ |
| 1513 | *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); |
| 1514 | }else{ |
| 1515 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1516 | } |
| 1517 | sqlite3_close(pOther); |
| 1518 | if( rc ) return; |
| @@ -1541,13 +1538,13 @@ | |
| 1541 | */ |
| 1542 | zSelfProjCode = abbreviated_project_code(zSelfProjCode); |
| 1543 | zOtherProjCode = abbreviated_project_code(zOtherProjCode); |
| 1544 | db_begin_transaction(); |
| 1545 | db_multi_exec( |
| 1546 | "DELETE FROM %s.config WHERE name GLOB 'peer-*';" |
| 1547 | "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);" |
| 1548 | "INSERT INTO %s.config(name,value) " |
| 1549 | " SELECT 'peer-name-%q', value FROM other.config" |
| 1550 | " WHERE name='project-name';", |
| 1551 | zSelf, |
| 1552 | zSelf, zOtherProjCode, zRepo, |
| 1553 | zSelf, zOtherProjCode |
| @@ -1558,11 +1555,11 @@ | |
| 1558 | "INSERT OR IGNORE INTO other.config(name,value)" |
| 1559 | " VALUES('login-group-code',lower(hex(randomblob(8))));", |
| 1560 | zNewName |
| 1561 | ); |
| 1562 | db_multi_exec( |
| 1563 | "REPLACE INTO %s.config(name,value)" |
| 1564 | " SELECT name, value FROM other.config" |
| 1565 | " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'", |
| 1566 | zSelf |
| 1567 | ); |
| 1568 | db_end_transaction(0); |
| 1569 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -93,15 +93,12 @@ | |
| 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | " FROM config" |
| 95 | " WHERE name IN ('project-code','login-group-code')" |
| 96 | " ORDER BY name /*sort*/" |
| 97 | ); |
| 98 | } |
| 99 | return zCookieName ? zCookieName : "unknown"; |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | ** Redirect to the page specified by the "g" query parameter. |
| 104 | ** Or if there is no "g" query parameter, redirect to the homepage. |
| @@ -403,15 +400,15 @@ | |
| 400 | /* If a URI appears in the User-Agent, it is probably a bot */ |
| 401 | if( strncmp("http", zAgent+i,4)==0 ) return 0; |
| 402 | } |
| 403 | if( strncmp(zAgent, "Mozilla/", 8)==0 ){ |
| 404 | if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */ |
| 405 | if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1; |
| 406 | if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1; |
| 407 | if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1; |
| 408 | if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */ |
| 409 | if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1; |
| 410 | return 0; |
| 411 | } |
| 412 | if( strncmp(zAgent, "Opera/", 6)==0 ) return 1; |
| 413 | if( strncmp(zAgent, "Safari/", 7)==0 ) return 1; |
| 414 | if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1; |
| @@ -1302,11 +1299,11 @@ | |
| 1299 | }else{ |
| 1300 | char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0); |
| 1301 | int uid; |
| 1302 | db_multi_exec( |
| 1303 | "INSERT INTO user(login,pw,cap,info,mtime)" |
| 1304 | "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))", |
| 1305 | &login, zPw, &caps, &contact |
| 1306 | ); |
| 1307 | free(zPw); |
| 1308 | |
| 1309 | /* The user is registered, now just log him in. */ |
| @@ -1477,17 +1474,17 @@ | |
| 1474 | *pzErrMsg = 0; /* Default to no errors */ |
| 1475 | zSelf = db_name("repository"); |
| 1476 | |
| 1477 | /* Get the full pathname of the other repository */ |
| 1478 | file_canonical_name(zRepo, &fullName, 0); |
| 1479 | zRepo = fossil_strdup(blob_str(&fullName)); |
| 1480 | blob_reset(&fullName); |
| 1481 | |
| 1482 | /* Get the full pathname for our repository. Also the project code |
| 1483 | ** and project name for ourself. */ |
| 1484 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1485 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 1486 | blob_reset(&fullName); |
| 1487 | zSelfProjCode = db_get("project-code", "unknown"); |
| 1488 | zSelfLabel = db_get("project-name", 0); |
| 1489 | if( zSelfLabel==0 ){ |
| 1490 | zSelfLabel = zSelfProjCode; |
| @@ -1508,11 +1505,11 @@ | |
| 1505 | zRepo, &pOther, |
| 1506 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1507 | g.zVfsName |
| 1508 | ); |
| 1509 | if( rc!=SQLITE_OK ){ |
| 1510 | *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther)); |
| 1511 | }else{ |
| 1512 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1513 | } |
| 1514 | sqlite3_close(pOther); |
| 1515 | if( rc ) return; |
| @@ -1541,13 +1538,13 @@ | |
| 1538 | */ |
| 1539 | zSelfProjCode = abbreviated_project_code(zSelfProjCode); |
| 1540 | zOtherProjCode = abbreviated_project_code(zOtherProjCode); |
| 1541 | db_begin_transaction(); |
| 1542 | db_multi_exec( |
| 1543 | "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';" |
| 1544 | "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);" |
| 1545 | "INSERT INTO \"%w\".config(name,value) " |
| 1546 | " SELECT 'peer-name-%q', value FROM other.config" |
| 1547 | " WHERE name='project-name';", |
| 1548 | zSelf, |
| 1549 | zSelf, zOtherProjCode, zRepo, |
| 1550 | zSelf, zOtherProjCode |
| @@ -1558,11 +1555,11 @@ | |
| 1555 | "INSERT OR IGNORE INTO other.config(name,value)" |
| 1556 | " VALUES('login-group-code',lower(hex(randomblob(8))));", |
| 1557 | zNewName |
| 1558 | ); |
| 1559 | db_multi_exec( |
| 1560 | "REPLACE INTO \"%w\".config(name,value)" |
| 1561 | " SELECT name, value FROM other.config" |
| 1562 | " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'", |
| 1563 | zSelf |
| 1564 | ); |
| 1565 | db_end_transaction(0); |
| 1566 |
+14
-17
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -93,15 +93,12 @@ | ||
| 93 | 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | 94 | " FROM config" |
| 95 | 95 | " WHERE name IN ('project-code','login-group-code')" |
| 96 | 96 | " ORDER BY name /*sort*/" |
| 97 | 97 | ); |
| 98 | - if( zCookieName==0 ){ | |
| 99 | - zCookieName = mprintf("fossil-0123456789abcdef"); | |
| 100 | - } | |
| 101 | 98 | } |
| 102 | - return zCookieName; | |
| 99 | + return zCookieName ? zCookieName : "unknown"; | |
| 103 | 100 | } |
| 104 | 101 | |
| 105 | 102 | /* |
| 106 | 103 | ** Redirect to the page specified by the "g" query parameter. |
| 107 | 104 | ** Or if there is no "g" query parameter, redirect to the homepage. |
| @@ -403,15 +400,15 @@ | ||
| 403 | 400 | /* If a URI appears in the User-Agent, it is probably a bot */ |
| 404 | 401 | if( strncmp("http", zAgent+i,4)==0 ) return 0; |
| 405 | 402 | } |
| 406 | 403 | if( strncmp(zAgent, "Mozilla/", 8)==0 ){ |
| 407 | 404 | if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */ |
| 408 | - if( strglob("*Firefox/[1-9]*", zAgent) ) return 1; | |
| 409 | - if( strglob("*Chrome/[1-9]*", zAgent) ) return 1; | |
| 410 | - if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1; | |
| 411 | - if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */ | |
| 412 | - if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1; | |
| 405 | + if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1; | |
| 406 | + if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1; | |
| 407 | + if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1; | |
| 408 | + if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */ | |
| 409 | + if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1; | |
| 413 | 410 | return 0; |
| 414 | 411 | } |
| 415 | 412 | if( strncmp(zAgent, "Opera/", 6)==0 ) return 1; |
| 416 | 413 | if( strncmp(zAgent, "Safari/", 7)==0 ) return 1; |
| 417 | 414 | if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1; |
| @@ -1302,11 +1299,11 @@ | ||
| 1302 | 1299 | }else{ |
| 1303 | 1300 | char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0); |
| 1304 | 1301 | int uid; |
| 1305 | 1302 | db_multi_exec( |
| 1306 | 1303 | "INSERT INTO user(login,pw,cap,info,mtime)" |
| 1307 | - "VALUES(%B,%Q,%B,%B,strftime('%s','now'))", | |
| 1304 | + "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))", | |
| 1308 | 1305 | &login, zPw, &caps, &contact |
| 1309 | 1306 | ); |
| 1310 | 1307 | free(zPw); |
| 1311 | 1308 | |
| 1312 | 1309 | /* The user is registered, now just log him in. */ |
| @@ -1477,17 +1474,17 @@ | ||
| 1477 | 1474 | *pzErrMsg = 0; /* Default to no errors */ |
| 1478 | 1475 | zSelf = db_name("repository"); |
| 1479 | 1476 | |
| 1480 | 1477 | /* Get the full pathname of the other repository */ |
| 1481 | 1478 | file_canonical_name(zRepo, &fullName, 0); |
| 1482 | - zRepo = mprintf(blob_str(&fullName)); | |
| 1479 | + zRepo = fossil_strdup(blob_str(&fullName)); | |
| 1483 | 1480 | blob_reset(&fullName); |
| 1484 | 1481 | |
| 1485 | 1482 | /* Get the full pathname for our repository. Also the project code |
| 1486 | 1483 | ** and project name for ourself. */ |
| 1487 | 1484 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1488 | - zSelfRepo = mprintf(blob_str(&fullName)); | |
| 1485 | + zSelfRepo = fossil_strdup(blob_str(&fullName)); | |
| 1489 | 1486 | blob_reset(&fullName); |
| 1490 | 1487 | zSelfProjCode = db_get("project-code", "unknown"); |
| 1491 | 1488 | zSelfLabel = db_get("project-name", 0); |
| 1492 | 1489 | if( zSelfLabel==0 ){ |
| 1493 | 1490 | zSelfLabel = zSelfProjCode; |
| @@ -1508,11 +1505,11 @@ | ||
| 1508 | 1505 | zRepo, &pOther, |
| 1509 | 1506 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1510 | 1507 | g.zVfsName |
| 1511 | 1508 | ); |
| 1512 | 1509 | if( rc!=SQLITE_OK ){ |
| 1513 | - *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); | |
| 1510 | + *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther)); | |
| 1514 | 1511 | }else{ |
| 1515 | 1512 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1516 | 1513 | } |
| 1517 | 1514 | sqlite3_close(pOther); |
| 1518 | 1515 | if( rc ) return; |
| @@ -1541,13 +1538,13 @@ | ||
| 1541 | 1538 | */ |
| 1542 | 1539 | zSelfProjCode = abbreviated_project_code(zSelfProjCode); |
| 1543 | 1540 | zOtherProjCode = abbreviated_project_code(zOtherProjCode); |
| 1544 | 1541 | db_begin_transaction(); |
| 1545 | 1542 | db_multi_exec( |
| 1546 | - "DELETE FROM %s.config WHERE name GLOB 'peer-*';" | |
| 1547 | - "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);" | |
| 1548 | - "INSERT INTO %s.config(name,value) " | |
| 1543 | + "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';" | |
| 1544 | + "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);" | |
| 1545 | + "INSERT INTO \"%w\".config(name,value) " | |
| 1549 | 1546 | " SELECT 'peer-name-%q', value FROM other.config" |
| 1550 | 1547 | " WHERE name='project-name';", |
| 1551 | 1548 | zSelf, |
| 1552 | 1549 | zSelf, zOtherProjCode, zRepo, |
| 1553 | 1550 | zSelf, zOtherProjCode |
| @@ -1558,11 +1555,11 @@ | ||
| 1558 | 1555 | "INSERT OR IGNORE INTO other.config(name,value)" |
| 1559 | 1556 | " VALUES('login-group-code',lower(hex(randomblob(8))));", |
| 1560 | 1557 | zNewName |
| 1561 | 1558 | ); |
| 1562 | 1559 | db_multi_exec( |
| 1563 | - "REPLACE INTO %s.config(name,value)" | |
| 1560 | + "REPLACE INTO \"%w\".config(name,value)" | |
| 1564 | 1561 | " SELECT name, value FROM other.config" |
| 1565 | 1562 | " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'", |
| 1566 | 1563 | zSelf |
| 1567 | 1564 | ); |
| 1568 | 1565 | db_end_transaction(0); |
| 1569 | 1566 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -93,15 +93,12 @@ | |
| 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | " FROM config" |
| 95 | " WHERE name IN ('project-code','login-group-code')" |
| 96 | " ORDER BY name /*sort*/" |
| 97 | ); |
| 98 | if( zCookieName==0 ){ |
| 99 | zCookieName = mprintf("fossil-0123456789abcdef"); |
| 100 | } |
| 101 | } |
| 102 | return zCookieName; |
| 103 | } |
| 104 | |
| 105 | /* |
| 106 | ** Redirect to the page specified by the "g" query parameter. |
| 107 | ** Or if there is no "g" query parameter, redirect to the homepage. |
| @@ -403,15 +400,15 @@ | |
| 403 | /* If a URI appears in the User-Agent, it is probably a bot */ |
| 404 | if( strncmp("http", zAgent+i,4)==0 ) return 0; |
| 405 | } |
| 406 | if( strncmp(zAgent, "Mozilla/", 8)==0 ){ |
| 407 | if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */ |
| 408 | if( strglob("*Firefox/[1-9]*", zAgent) ) return 1; |
| 409 | if( strglob("*Chrome/[1-9]*", zAgent) ) return 1; |
| 410 | if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1; |
| 411 | if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */ |
| 412 | if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1; |
| 413 | return 0; |
| 414 | } |
| 415 | if( strncmp(zAgent, "Opera/", 6)==0 ) return 1; |
| 416 | if( strncmp(zAgent, "Safari/", 7)==0 ) return 1; |
| 417 | if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1; |
| @@ -1302,11 +1299,11 @@ | |
| 1302 | }else{ |
| 1303 | char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0); |
| 1304 | int uid; |
| 1305 | db_multi_exec( |
| 1306 | "INSERT INTO user(login,pw,cap,info,mtime)" |
| 1307 | "VALUES(%B,%Q,%B,%B,strftime('%s','now'))", |
| 1308 | &login, zPw, &caps, &contact |
| 1309 | ); |
| 1310 | free(zPw); |
| 1311 | |
| 1312 | /* The user is registered, now just log him in. */ |
| @@ -1477,17 +1474,17 @@ | |
| 1477 | *pzErrMsg = 0; /* Default to no errors */ |
| 1478 | zSelf = db_name("repository"); |
| 1479 | |
| 1480 | /* Get the full pathname of the other repository */ |
| 1481 | file_canonical_name(zRepo, &fullName, 0); |
| 1482 | zRepo = mprintf(blob_str(&fullName)); |
| 1483 | blob_reset(&fullName); |
| 1484 | |
| 1485 | /* Get the full pathname for our repository. Also the project code |
| 1486 | ** and project name for ourself. */ |
| 1487 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1488 | zSelfRepo = mprintf(blob_str(&fullName)); |
| 1489 | blob_reset(&fullName); |
| 1490 | zSelfProjCode = db_get("project-code", "unknown"); |
| 1491 | zSelfLabel = db_get("project-name", 0); |
| 1492 | if( zSelfLabel==0 ){ |
| 1493 | zSelfLabel = zSelfProjCode; |
| @@ -1508,11 +1505,11 @@ | |
| 1508 | zRepo, &pOther, |
| 1509 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1510 | g.zVfsName |
| 1511 | ); |
| 1512 | if( rc!=SQLITE_OK ){ |
| 1513 | *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); |
| 1514 | }else{ |
| 1515 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1516 | } |
| 1517 | sqlite3_close(pOther); |
| 1518 | if( rc ) return; |
| @@ -1541,13 +1538,13 @@ | |
| 1541 | */ |
| 1542 | zSelfProjCode = abbreviated_project_code(zSelfProjCode); |
| 1543 | zOtherProjCode = abbreviated_project_code(zOtherProjCode); |
| 1544 | db_begin_transaction(); |
| 1545 | db_multi_exec( |
| 1546 | "DELETE FROM %s.config WHERE name GLOB 'peer-*';" |
| 1547 | "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);" |
| 1548 | "INSERT INTO %s.config(name,value) " |
| 1549 | " SELECT 'peer-name-%q', value FROM other.config" |
| 1550 | " WHERE name='project-name';", |
| 1551 | zSelf, |
| 1552 | zSelf, zOtherProjCode, zRepo, |
| 1553 | zSelf, zOtherProjCode |
| @@ -1558,11 +1555,11 @@ | |
| 1558 | "INSERT OR IGNORE INTO other.config(name,value)" |
| 1559 | " VALUES('login-group-code',lower(hex(randomblob(8))));", |
| 1560 | zNewName |
| 1561 | ); |
| 1562 | db_multi_exec( |
| 1563 | "REPLACE INTO %s.config(name,value)" |
| 1564 | " SELECT name, value FROM other.config" |
| 1565 | " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'", |
| 1566 | zSelf |
| 1567 | ); |
| 1568 | db_end_transaction(0); |
| 1569 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -93,15 +93,12 @@ | |
| 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | " FROM config" |
| 95 | " WHERE name IN ('project-code','login-group-code')" |
| 96 | " ORDER BY name /*sort*/" |
| 97 | ); |
| 98 | } |
| 99 | return zCookieName ? zCookieName : "unknown"; |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | ** Redirect to the page specified by the "g" query parameter. |
| 104 | ** Or if there is no "g" query parameter, redirect to the homepage. |
| @@ -403,15 +400,15 @@ | |
| 400 | /* If a URI appears in the User-Agent, it is probably a bot */ |
| 401 | if( strncmp("http", zAgent+i,4)==0 ) return 0; |
| 402 | } |
| 403 | if( strncmp(zAgent, "Mozilla/", 8)==0 ){ |
| 404 | if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */ |
| 405 | if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1; |
| 406 | if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1; |
| 407 | if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1; |
| 408 | if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */ |
| 409 | if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1; |
| 410 | return 0; |
| 411 | } |
| 412 | if( strncmp(zAgent, "Opera/", 6)==0 ) return 1; |
| 413 | if( strncmp(zAgent, "Safari/", 7)==0 ) return 1; |
| 414 | if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1; |
| @@ -1302,11 +1299,11 @@ | |
| 1299 | }else{ |
| 1300 | char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0); |
| 1301 | int uid; |
| 1302 | db_multi_exec( |
| 1303 | "INSERT INTO user(login,pw,cap,info,mtime)" |
| 1304 | "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))", |
| 1305 | &login, zPw, &caps, &contact |
| 1306 | ); |
| 1307 | free(zPw); |
| 1308 | |
| 1309 | /* The user is registered, now just log him in. */ |
| @@ -1477,17 +1474,17 @@ | |
| 1474 | *pzErrMsg = 0; /* Default to no errors */ |
| 1475 | zSelf = db_name("repository"); |
| 1476 | |
| 1477 | /* Get the full pathname of the other repository */ |
| 1478 | file_canonical_name(zRepo, &fullName, 0); |
| 1479 | zRepo = fossil_strdup(blob_str(&fullName)); |
| 1480 | blob_reset(&fullName); |
| 1481 | |
| 1482 | /* Get the full pathname for our repository. Also the project code |
| 1483 | ** and project name for ourself. */ |
| 1484 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1485 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 1486 | blob_reset(&fullName); |
| 1487 | zSelfProjCode = db_get("project-code", "unknown"); |
| 1488 | zSelfLabel = db_get("project-name", 0); |
| 1489 | if( zSelfLabel==0 ){ |
| 1490 | zSelfLabel = zSelfProjCode; |
| @@ -1508,11 +1505,11 @@ | |
| 1505 | zRepo, &pOther, |
| 1506 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1507 | g.zVfsName |
| 1508 | ); |
| 1509 | if( rc!=SQLITE_OK ){ |
| 1510 | *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther)); |
| 1511 | }else{ |
| 1512 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1513 | } |
| 1514 | sqlite3_close(pOther); |
| 1515 | if( rc ) return; |
| @@ -1541,13 +1538,13 @@ | |
| 1538 | */ |
| 1539 | zSelfProjCode = abbreviated_project_code(zSelfProjCode); |
| 1540 | zOtherProjCode = abbreviated_project_code(zOtherProjCode); |
| 1541 | db_begin_transaction(); |
| 1542 | db_multi_exec( |
| 1543 | "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';" |
| 1544 | "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);" |
| 1545 | "INSERT INTO \"%w\".config(name,value) " |
| 1546 | " SELECT 'peer-name-%q', value FROM other.config" |
| 1547 | " WHERE name='project-name';", |
| 1548 | zSelf, |
| 1549 | zSelf, zOtherProjCode, zRepo, |
| 1550 | zSelf, zOtherProjCode |
| @@ -1558,11 +1555,11 @@ | |
| 1555 | "INSERT OR IGNORE INTO other.config(name,value)" |
| 1556 | " VALUES('login-group-code',lower(hex(randomblob(8))));", |
| 1557 | zNewName |
| 1558 | ); |
| 1559 | db_multi_exec( |
| 1560 | "REPLACE INTO \"%w\".config(name,value)" |
| 1561 | " SELECT name, value FROM other.config" |
| 1562 | " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'", |
| 1563 | zSelf |
| 1564 | ); |
| 1565 | db_end_transaction(0); |
| 1566 |
+9
-8
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -169,11 +169,11 @@ | ||
| 169 | 169 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 170 | 170 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 171 | 171 | int *aCommitFile; /* Array of files to be committed */ |
| 172 | 172 | int markPrivate; /* All new artifacts are private if true */ |
| 173 | 173 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 174 | - int wikiFlags; /* Wiki conversion flags applied to %w and %W */ | |
| 174 | + int wikiFlags; /* Wiki conversion flags applied to %W */ | |
| 175 | 175 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 176 | 176 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 177 | 177 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 178 | 178 | UrlData url; /* Information about current URL */ |
| 179 | 179 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| @@ -1694,13 +1694,13 @@ | ||
| 1694 | 1694 | /* If the CGI program contains one or more lines of the form |
| 1695 | 1695 | ** |
| 1696 | 1696 | ** redirect: repository-filename http://hostname/path/%s |
| 1697 | 1697 | ** |
| 1698 | 1698 | ** then control jumps here. Search each repository for an artifact ID |
| 1699 | -** that matches the "name" CGI parameter and for the first match, | |
| 1700 | -** redirect to the corresponding URL with the "name" CGI parameter | |
| 1701 | -** inserted. Paint an error page if no match is found. | |
| 1699 | +** or ticket ID that matches the "name" CGI parameter and for the | |
| 1700 | +** first match, redirect to the corresponding URL with the "name" CGI | |
| 1701 | +** parameter inserted. Paint an error page if no match is found. | |
| 1702 | 1702 | ** |
| 1703 | 1703 | ** If there is a line of the form: |
| 1704 | 1704 | ** |
| 1705 | 1705 | ** redirect: * URL |
| 1706 | 1706 | ** |
| @@ -1721,19 +1721,20 @@ | ||
| 1721 | 1721 | if( fossil_strcmp(azRedirect[i*2],"*")==0 ){ |
| 1722 | 1722 | zNotFound = azRedirect[i*2+1]; |
| 1723 | 1723 | continue; |
| 1724 | 1724 | } |
| 1725 | 1725 | db_open_repository(azRedirect[i*2]); |
| 1726 | - if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){ | |
| 1727 | - cgi_redirectf(azRedirect[i*2+1], zName); | |
| 1726 | + if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) || | |
| 1727 | + db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){ | |
| 1728 | + cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName); | |
| 1728 | 1729 | return; |
| 1729 | 1730 | } |
| 1730 | 1731 | db_close(1); |
| 1731 | 1732 | } |
| 1732 | 1733 | } |
| 1733 | 1734 | if( zNotFound ){ |
| 1734 | - cgi_redirectf(zNotFound, zName); | |
| 1735 | + cgi_redirectf(zNotFound /*works-like:"%s"*/, zName); | |
| 1735 | 1736 | }else{ |
| 1736 | 1737 | @ <html> |
| 1737 | 1738 | @ <head><title>No Such Object</title></head> |
| 1738 | 1739 | @ <body> |
| 1739 | 1740 | @ <p>No such object: <b>%h(zName)</b></p> |
| @@ -2199,11 +2200,11 @@ | ||
| 2199 | 2200 | }else{ |
| 2200 | 2201 | zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser); |
| 2201 | 2202 | } |
| 2202 | 2203 | if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; |
| 2203 | 2204 | if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; |
| 2204 | - }else{ | |
| 2205 | + }else if( g.db ){ | |
| 2205 | 2206 | db_setup_server_and_project_codes(1); |
| 2206 | 2207 | } |
| 2207 | 2208 | db_close(1); |
| 2208 | 2209 | if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){ |
| 2209 | 2210 | fossil_fatal("unable to listen on TCP socket %d", iPort); |
| 2210 | 2211 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -169,11 +169,11 @@ | |
| 169 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 170 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 171 | int *aCommitFile; /* Array of files to be committed */ |
| 172 | int markPrivate; /* All new artifacts are private if true */ |
| 173 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 174 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 175 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 176 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 177 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 178 | UrlData url; /* Information about current URL */ |
| 179 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| @@ -1694,13 +1694,13 @@ | |
| 1694 | /* If the CGI program contains one or more lines of the form |
| 1695 | ** |
| 1696 | ** redirect: repository-filename http://hostname/path/%s |
| 1697 | ** |
| 1698 | ** then control jumps here. Search each repository for an artifact ID |
| 1699 | ** that matches the "name" CGI parameter and for the first match, |
| 1700 | ** redirect to the corresponding URL with the "name" CGI parameter |
| 1701 | ** inserted. Paint an error page if no match is found. |
| 1702 | ** |
| 1703 | ** If there is a line of the form: |
| 1704 | ** |
| 1705 | ** redirect: * URL |
| 1706 | ** |
| @@ -1721,19 +1721,20 @@ | |
| 1721 | if( fossil_strcmp(azRedirect[i*2],"*")==0 ){ |
| 1722 | zNotFound = azRedirect[i*2+1]; |
| 1723 | continue; |
| 1724 | } |
| 1725 | db_open_repository(azRedirect[i*2]); |
| 1726 | if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){ |
| 1727 | cgi_redirectf(azRedirect[i*2+1], zName); |
| 1728 | return; |
| 1729 | } |
| 1730 | db_close(1); |
| 1731 | } |
| 1732 | } |
| 1733 | if( zNotFound ){ |
| 1734 | cgi_redirectf(zNotFound, zName); |
| 1735 | }else{ |
| 1736 | @ <html> |
| 1737 | @ <head><title>No Such Object</title></head> |
| 1738 | @ <body> |
| 1739 | @ <p>No such object: <b>%h(zName)</b></p> |
| @@ -2199,11 +2200,11 @@ | |
| 2199 | }else{ |
| 2200 | zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser); |
| 2201 | } |
| 2202 | if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; |
| 2203 | if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; |
| 2204 | }else{ |
| 2205 | db_setup_server_and_project_codes(1); |
| 2206 | } |
| 2207 | db_close(1); |
| 2208 | if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){ |
| 2209 | fossil_fatal("unable to listen on TCP socket %d", iPort); |
| 2210 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -169,11 +169,11 @@ | |
| 169 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 170 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 171 | int *aCommitFile; /* Array of files to be committed */ |
| 172 | int markPrivate; /* All new artifacts are private if true */ |
| 173 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 174 | int wikiFlags; /* Wiki conversion flags applied to %W */ |
| 175 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 176 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 177 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 178 | UrlData url; /* Information about current URL */ |
| 179 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| @@ -1694,13 +1694,13 @@ | |
| 1694 | /* If the CGI program contains one or more lines of the form |
| 1695 | ** |
| 1696 | ** redirect: repository-filename http://hostname/path/%s |
| 1697 | ** |
| 1698 | ** then control jumps here. Search each repository for an artifact ID |
| 1699 | ** or ticket ID that matches the "name" CGI parameter and for the |
| 1700 | ** first match, redirect to the corresponding URL with the "name" CGI |
| 1701 | ** parameter inserted. Paint an error page if no match is found. |
| 1702 | ** |
| 1703 | ** If there is a line of the form: |
| 1704 | ** |
| 1705 | ** redirect: * URL |
| 1706 | ** |
| @@ -1721,19 +1721,20 @@ | |
| 1721 | if( fossil_strcmp(azRedirect[i*2],"*")==0 ){ |
| 1722 | zNotFound = azRedirect[i*2+1]; |
| 1723 | continue; |
| 1724 | } |
| 1725 | db_open_repository(azRedirect[i*2]); |
| 1726 | if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) || |
| 1727 | db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){ |
| 1728 | cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName); |
| 1729 | return; |
| 1730 | } |
| 1731 | db_close(1); |
| 1732 | } |
| 1733 | } |
| 1734 | if( zNotFound ){ |
| 1735 | cgi_redirectf(zNotFound /*works-like:"%s"*/, zName); |
| 1736 | }else{ |
| 1737 | @ <html> |
| 1738 | @ <head><title>No Such Object</title></head> |
| 1739 | @ <body> |
| 1740 | @ <p>No such object: <b>%h(zName)</b></p> |
| @@ -2199,11 +2200,11 @@ | |
| 2200 | }else{ |
| 2201 | zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser); |
| 2202 | } |
| 2203 | if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; |
| 2204 | if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; |
| 2205 | }else if( g.db ){ |
| 2206 | db_setup_server_and_project_codes(1); |
| 2207 | } |
| 2208 | db_close(1); |
| 2209 | if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){ |
| 2210 | fossil_fatal("unable to listen on TCP socket %d", iPort); |
| 2211 |
+30
-2
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -20,10 +20,11 @@ | ||
| 20 | 20 | $(SRCDIR)/bag.c \ |
| 21 | 21 | $(SRCDIR)/bisect.c \ |
| 22 | 22 | $(SRCDIR)/blob.c \ |
| 23 | 23 | $(SRCDIR)/branch.c \ |
| 24 | 24 | $(SRCDIR)/browse.c \ |
| 25 | + $(SRCDIR)/builtin.c \ | |
| 25 | 26 | $(SRCDIR)/cache.c \ |
| 26 | 27 | $(SRCDIR)/captcha.c \ |
| 27 | 28 | $(SRCDIR)/cgi.c \ |
| 28 | 29 | $(SRCDIR)/checkin.c \ |
| 29 | 30 | $(SRCDIR)/checkout.c \ |
| @@ -124,19 +125,23 @@ | ||
| 124 | 125 | $(SRCDIR)/wysiwyg.c \ |
| 125 | 126 | $(SRCDIR)/xfer.c \ |
| 126 | 127 | $(SRCDIR)/xfersetup.c \ |
| 127 | 128 | $(SRCDIR)/zip.c |
| 128 | 129 | |
| 130 | +EXTRA_FILES = \ | |
| 131 | + $(SRCDIR)/diff.tcl | |
| 132 | + | |
| 129 | 133 | TRANS_SRC = \ |
| 130 | 134 | $(OBJDIR)/add_.c \ |
| 131 | 135 | $(OBJDIR)/allrepo_.c \ |
| 132 | 136 | $(OBJDIR)/attach_.c \ |
| 133 | 137 | $(OBJDIR)/bag_.c \ |
| 134 | 138 | $(OBJDIR)/bisect_.c \ |
| 135 | 139 | $(OBJDIR)/blob_.c \ |
| 136 | 140 | $(OBJDIR)/branch_.c \ |
| 137 | 141 | $(OBJDIR)/browse_.c \ |
| 142 | + $(OBJDIR)/builtin_.c \ | |
| 138 | 143 | $(OBJDIR)/cache_.c \ |
| 139 | 144 | $(OBJDIR)/captcha_.c \ |
| 140 | 145 | $(OBJDIR)/cgi_.c \ |
| 141 | 146 | $(OBJDIR)/checkin_.c \ |
| 142 | 147 | $(OBJDIR)/checkout_.c \ |
| @@ -246,10 +251,11 @@ | ||
| 246 | 251 | $(OBJDIR)/bag.o \ |
| 247 | 252 | $(OBJDIR)/bisect.o \ |
| 248 | 253 | $(OBJDIR)/blob.o \ |
| 249 | 254 | $(OBJDIR)/branch.o \ |
| 250 | 255 | $(OBJDIR)/browse.o \ |
| 256 | + $(OBJDIR)/builtin.o \ | |
| 251 | 257 | $(OBJDIR)/cache.o \ |
| 252 | 258 | $(OBJDIR)/captcha.o \ |
| 253 | 259 | $(OBJDIR)/cgi.o \ |
| 254 | 260 | $(OBJDIR)/checkin.o \ |
| 255 | 261 | $(OBJDIR)/checkout.o \ |
| @@ -360,10 +366,13 @@ | ||
| 360 | 366 | |
| 361 | 367 | install: $(APPNAME) |
| 362 | 368 | mkdir -p $(INSTALLDIR) |
| 363 | 369 | mv $(APPNAME) $(INSTALLDIR) |
| 364 | 370 | |
| 371 | +codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 | |
| 372 | + $(OBJDIR)/codecheck1 $(TRANS_SRC) | |
| 373 | + | |
| 365 | 374 | $(OBJDIR): |
| 366 | 375 | -mkdir $(OBJDIR) |
| 367 | 376 | |
| 368 | 377 | $(OBJDIR)/translate: $(SRCDIR)/translate.c |
| 369 | 378 | $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| @@ -372,13 +381,19 @@ | ||
| 372 | 381 | $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c |
| 373 | 382 | |
| 374 | 383 | $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c |
| 375 | 384 | $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c |
| 376 | 385 | |
| 386 | +$(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c | |
| 387 | + $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c | |
| 388 | + | |
| 377 | 389 | $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c |
| 378 | 390 | $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c |
| 379 | 391 | |
| 392 | +$(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c | |
| 393 | + $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c | |
| 394 | + | |
| 380 | 395 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 381 | 396 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 382 | 397 | # the repository after running the tests. |
| 383 | 398 | test: $(OBJDIR) $(APPNAME) |
| 384 | 399 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| @@ -430,11 +445,12 @@ | ||
| 430 | 445 | $(OBJDIR)/th_lang.o \ |
| 431 | 446 | $(OBJDIR)/th_tcl.o \ |
| 432 | 447 | $(OBJDIR)/cson_amalgamation.o |
| 433 | 448 | |
| 434 | 449 | |
| 435 | -$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) | |
| 450 | +$(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ) | |
| 451 | + $(OBJDIR)/codecheck1 $(TRANS_SRC) | |
| 436 | 452 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 437 | 453 | |
| 438 | 454 | # This rule prevents make from using its default rules to try build |
| 439 | 455 | # an executable named "manifest" out of the file named "manifest.c" |
| 440 | 456 | # |
| @@ -445,19 +461,24 @@ | ||
| 445 | 461 | rm -rf $(OBJDIR)/* $(APPNAME) |
| 446 | 462 | |
| 447 | 463 | |
| 448 | 464 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 449 | 465 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 450 | -$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h | |
| 466 | + | |
| 467 | +$(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) | |
| 468 | + $(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@ | |
| 469 | + | |
| 470 | +$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h | |
| 451 | 471 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 452 | 472 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 453 | 473 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 454 | 474 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 455 | 475 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 456 | 476 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 457 | 477 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 458 | 478 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 479 | + $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ | |
| 459 | 480 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 460 | 481 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 461 | 482 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 462 | 483 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 463 | 484 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -620,10 +641,17 @@ | ||
| 620 | 641 | |
| 621 | 642 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 622 | 643 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 623 | 644 | |
| 624 | 645 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 646 | +$(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(OBJDIR)/translate | |
| 647 | + $(OBJDIR)/translate $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c | |
| 648 | + | |
| 649 | +$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h | |
| 650 | + $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c | |
| 651 | + | |
| 652 | +$(OBJDIR)/builtin.h: $(OBJDIR)/headers | |
| 625 | 653 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate |
| 626 | 654 | $(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 627 | 655 | |
| 628 | 656 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 629 | 657 | $(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c |
| 630 | 658 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -20,10 +20,11 @@ | |
| 20 | $(SRCDIR)/bag.c \ |
| 21 | $(SRCDIR)/bisect.c \ |
| 22 | $(SRCDIR)/blob.c \ |
| 23 | $(SRCDIR)/branch.c \ |
| 24 | $(SRCDIR)/browse.c \ |
| 25 | $(SRCDIR)/cache.c \ |
| 26 | $(SRCDIR)/captcha.c \ |
| 27 | $(SRCDIR)/cgi.c \ |
| 28 | $(SRCDIR)/checkin.c \ |
| 29 | $(SRCDIR)/checkout.c \ |
| @@ -124,19 +125,23 @@ | |
| 124 | $(SRCDIR)/wysiwyg.c \ |
| 125 | $(SRCDIR)/xfer.c \ |
| 126 | $(SRCDIR)/xfersetup.c \ |
| 127 | $(SRCDIR)/zip.c |
| 128 | |
| 129 | TRANS_SRC = \ |
| 130 | $(OBJDIR)/add_.c \ |
| 131 | $(OBJDIR)/allrepo_.c \ |
| 132 | $(OBJDIR)/attach_.c \ |
| 133 | $(OBJDIR)/bag_.c \ |
| 134 | $(OBJDIR)/bisect_.c \ |
| 135 | $(OBJDIR)/blob_.c \ |
| 136 | $(OBJDIR)/branch_.c \ |
| 137 | $(OBJDIR)/browse_.c \ |
| 138 | $(OBJDIR)/cache_.c \ |
| 139 | $(OBJDIR)/captcha_.c \ |
| 140 | $(OBJDIR)/cgi_.c \ |
| 141 | $(OBJDIR)/checkin_.c \ |
| 142 | $(OBJDIR)/checkout_.c \ |
| @@ -246,10 +251,11 @@ | |
| 246 | $(OBJDIR)/bag.o \ |
| 247 | $(OBJDIR)/bisect.o \ |
| 248 | $(OBJDIR)/blob.o \ |
| 249 | $(OBJDIR)/branch.o \ |
| 250 | $(OBJDIR)/browse.o \ |
| 251 | $(OBJDIR)/cache.o \ |
| 252 | $(OBJDIR)/captcha.o \ |
| 253 | $(OBJDIR)/cgi.o \ |
| 254 | $(OBJDIR)/checkin.o \ |
| 255 | $(OBJDIR)/checkout.o \ |
| @@ -360,10 +366,13 @@ | |
| 360 | |
| 361 | install: $(APPNAME) |
| 362 | mkdir -p $(INSTALLDIR) |
| 363 | mv $(APPNAME) $(INSTALLDIR) |
| 364 | |
| 365 | $(OBJDIR): |
| 366 | -mkdir $(OBJDIR) |
| 367 | |
| 368 | $(OBJDIR)/translate: $(SRCDIR)/translate.c |
| 369 | $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| @@ -372,13 +381,19 @@ | |
| 372 | $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c |
| 373 | |
| 374 | $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c |
| 375 | $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c |
| 376 | |
| 377 | $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c |
| 378 | $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c |
| 379 | |
| 380 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 381 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 382 | # the repository after running the tests. |
| 383 | test: $(OBJDIR) $(APPNAME) |
| 384 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| @@ -430,11 +445,12 @@ | |
| 430 | $(OBJDIR)/th_lang.o \ |
| 431 | $(OBJDIR)/th_tcl.o \ |
| 432 | $(OBJDIR)/cson_amalgamation.o |
| 433 | |
| 434 | |
| 435 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 436 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 437 | |
| 438 | # This rule prevents make from using its default rules to try build |
| 439 | # an executable named "manifest" out of the file named "manifest.c" |
| 440 | # |
| @@ -445,19 +461,24 @@ | |
| 445 | rm -rf $(OBJDIR)/* $(APPNAME) |
| 446 | |
| 447 | |
| 448 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 449 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 450 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 451 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 452 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 453 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 454 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 455 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 456 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 457 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 458 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 459 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 460 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 461 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 462 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 463 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -620,10 +641,17 @@ | |
| 620 | |
| 621 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 622 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 623 | |
| 624 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 625 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate |
| 626 | $(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 627 | |
| 628 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 629 | $(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c |
| 630 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -20,10 +20,11 @@ | |
| 20 | $(SRCDIR)/bag.c \ |
| 21 | $(SRCDIR)/bisect.c \ |
| 22 | $(SRCDIR)/blob.c \ |
| 23 | $(SRCDIR)/branch.c \ |
| 24 | $(SRCDIR)/browse.c \ |
| 25 | $(SRCDIR)/builtin.c \ |
| 26 | $(SRCDIR)/cache.c \ |
| 27 | $(SRCDIR)/captcha.c \ |
| 28 | $(SRCDIR)/cgi.c \ |
| 29 | $(SRCDIR)/checkin.c \ |
| 30 | $(SRCDIR)/checkout.c \ |
| @@ -124,19 +125,23 @@ | |
| 125 | $(SRCDIR)/wysiwyg.c \ |
| 126 | $(SRCDIR)/xfer.c \ |
| 127 | $(SRCDIR)/xfersetup.c \ |
| 128 | $(SRCDIR)/zip.c |
| 129 | |
| 130 | EXTRA_FILES = \ |
| 131 | $(SRCDIR)/diff.tcl |
| 132 | |
| 133 | TRANS_SRC = \ |
| 134 | $(OBJDIR)/add_.c \ |
| 135 | $(OBJDIR)/allrepo_.c \ |
| 136 | $(OBJDIR)/attach_.c \ |
| 137 | $(OBJDIR)/bag_.c \ |
| 138 | $(OBJDIR)/bisect_.c \ |
| 139 | $(OBJDIR)/blob_.c \ |
| 140 | $(OBJDIR)/branch_.c \ |
| 141 | $(OBJDIR)/browse_.c \ |
| 142 | $(OBJDIR)/builtin_.c \ |
| 143 | $(OBJDIR)/cache_.c \ |
| 144 | $(OBJDIR)/captcha_.c \ |
| 145 | $(OBJDIR)/cgi_.c \ |
| 146 | $(OBJDIR)/checkin_.c \ |
| 147 | $(OBJDIR)/checkout_.c \ |
| @@ -246,10 +251,11 @@ | |
| 251 | $(OBJDIR)/bag.o \ |
| 252 | $(OBJDIR)/bisect.o \ |
| 253 | $(OBJDIR)/blob.o \ |
| 254 | $(OBJDIR)/branch.o \ |
| 255 | $(OBJDIR)/browse.o \ |
| 256 | $(OBJDIR)/builtin.o \ |
| 257 | $(OBJDIR)/cache.o \ |
| 258 | $(OBJDIR)/captcha.o \ |
| 259 | $(OBJDIR)/cgi.o \ |
| 260 | $(OBJDIR)/checkin.o \ |
| 261 | $(OBJDIR)/checkout.o \ |
| @@ -360,10 +366,13 @@ | |
| 366 | |
| 367 | install: $(APPNAME) |
| 368 | mkdir -p $(INSTALLDIR) |
| 369 | mv $(APPNAME) $(INSTALLDIR) |
| 370 | |
| 371 | codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 |
| 372 | $(OBJDIR)/codecheck1 $(TRANS_SRC) |
| 373 | |
| 374 | $(OBJDIR): |
| 375 | -mkdir $(OBJDIR) |
| 376 | |
| 377 | $(OBJDIR)/translate: $(SRCDIR)/translate.c |
| 378 | $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| @@ -372,13 +381,19 @@ | |
| 381 | $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c |
| 382 | |
| 383 | $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c |
| 384 | $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c |
| 385 | |
| 386 | $(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c |
| 387 | $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c |
| 388 | |
| 389 | $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c |
| 390 | $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c |
| 391 | |
| 392 | $(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c |
| 393 | $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c |
| 394 | |
| 395 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 396 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 397 | # the repository after running the tests. |
| 398 | test: $(OBJDIR) $(APPNAME) |
| 399 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| @@ -430,11 +445,12 @@ | |
| 445 | $(OBJDIR)/th_lang.o \ |
| 446 | $(OBJDIR)/th_tcl.o \ |
| 447 | $(OBJDIR)/cson_amalgamation.o |
| 448 | |
| 449 | |
| 450 | $(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ) |
| 451 | $(OBJDIR)/codecheck1 $(TRANS_SRC) |
| 452 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 453 | |
| 454 | # This rule prevents make from using its default rules to try build |
| 455 | # an executable named "manifest" out of the file named "manifest.c" |
| 456 | # |
| @@ -445,19 +461,24 @@ | |
| 461 | rm -rf $(OBJDIR)/* $(APPNAME) |
| 462 | |
| 463 | |
| 464 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 465 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 466 | |
| 467 | $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) |
| 468 | $(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@ |
| 469 | |
| 470 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 471 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 472 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 473 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 474 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 475 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 476 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 477 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 478 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 479 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 480 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 481 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 482 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 483 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 484 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -620,10 +641,17 @@ | |
| 641 | |
| 642 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 643 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 644 | |
| 645 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 646 | $(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(OBJDIR)/translate |
| 647 | $(OBJDIR)/translate $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c |
| 648 | |
| 649 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 650 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 651 | |
| 652 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 653 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate |
| 654 | $(OBJDIR)/translate $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 655 | |
| 656 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 657 | $(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c |
| 658 |
+140
-26
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -12,12 +12,15 @@ | ||
| 12 | 12 | # tclsh makemake.tcl |
| 13 | 13 | # |
| 14 | 14 | ############################################################################# |
| 15 | 15 | |
| 16 | 16 | # Basenames of all source files that get preprocessed using |
| 17 | -# "translate" and "makeheaders". To add new source files to the | |
| 17 | +# "translate" and "makeheaders". To add new C-language source files to the | |
| 18 | 18 | # project, simply add the basename to this list and rerun this script. |
| 19 | +# | |
| 20 | +# Set the separate extra_files variable further down for how to add non-C | |
| 21 | +# files, such as string and BLOB resources. | |
| 19 | 22 | # |
| 20 | 23 | set src { |
| 21 | 24 | add |
| 22 | 25 | allrepo |
| 23 | 26 | attach |
| @@ -24,10 +27,11 @@ | ||
| 24 | 27 | bag |
| 25 | 28 | bisect |
| 26 | 29 | blob |
| 27 | 30 | branch |
| 28 | 31 | browse |
| 32 | + builtin | |
| 29 | 33 | cache |
| 30 | 34 | captcha |
| 31 | 35 | cgi |
| 32 | 36 | checkin |
| 33 | 37 | checkout |
| @@ -128,10 +132,16 @@ | ||
| 128 | 132 | xfer |
| 129 | 133 | xfersetup |
| 130 | 134 | zip |
| 131 | 135 | http_ssl |
| 132 | 136 | } |
| 137 | + | |
| 138 | +# Additional resource files that get built into the executable. | |
| 139 | +# | |
| 140 | +set extra_files { | |
| 141 | + diff.tcl | |
| 142 | +} | |
| 133 | 143 | |
| 134 | 144 | # Options used to compile the included SQLite library. |
| 135 | 145 | # |
| 136 | 146 | set SQLITE_OPTIONS { |
| 137 | 147 | -DNDEBUG=1 |
| @@ -217,10 +227,15 @@ | ||
| 217 | 227 | } |
| 218 | 228 | writeln -nonewline "SRC =" |
| 219 | 229 | foreach s [lsort $src] { |
| 220 | 230 | writeln -nonewline " \\\n \$(SRCDIR)/$s.c" |
| 221 | 231 | } |
| 232 | +writeln "\n" | |
| 233 | +writeln -nonewline "EXTRA_FILES =" | |
| 234 | +foreach s [lsort $extra_files] { | |
| 235 | + writeln -nonewline " \\\n \$(SRCDIR)/$s" | |
| 236 | +} | |
| 222 | 237 | writeln "\n" |
| 223 | 238 | writeln -nonewline "TRANS_SRC =" |
| 224 | 239 | foreach s [lsort $src] { |
| 225 | 240 | writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c" |
| 226 | 241 | } |
| @@ -241,10 +256,13 @@ | ||
| 241 | 256 | |
| 242 | 257 | install: $(APPNAME) |
| 243 | 258 | mkdir -p $(INSTALLDIR) |
| 244 | 259 | mv $(APPNAME) $(INSTALLDIR) |
| 245 | 260 | |
| 261 | +codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 | |
| 262 | + $(OBJDIR)/codecheck1 $(TRANS_SRC) | |
| 263 | + | |
| 246 | 264 | $(OBJDIR): |
| 247 | 265 | -mkdir $(OBJDIR) |
| 248 | 266 | |
| 249 | 267 | $(OBJDIR)/translate: $(SRCDIR)/translate.c |
| 250 | 268 | $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| @@ -253,13 +271,19 @@ | ||
| 253 | 271 | $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c |
| 254 | 272 | |
| 255 | 273 | $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c |
| 256 | 274 | $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c |
| 257 | 275 | |
| 276 | +$(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c | |
| 277 | + $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c | |
| 278 | + | |
| 258 | 279 | $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c |
| 259 | 280 | $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c |
| 260 | 281 | |
| 282 | +$(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c | |
| 283 | + $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c | |
| 284 | + | |
| 261 | 285 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 262 | 286 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 263 | 287 | # the repository after running the tests. |
| 264 | 288 | test: $(OBJDIR) $(APPNAME) |
| 265 | 289 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| @@ -304,11 +328,12 @@ | ||
| 304 | 328 | $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>> |
| 305 | 329 | $(OBJDIR)/cson_amalgamation.o |
| 306 | 330 | }] |
| 307 | 331 | |
| 308 | 332 | writeln { |
| 309 | -$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) | |
| 333 | +$(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ) | |
| 334 | + $(OBJDIR)/codecheck1 $(TRANS_SRC) | |
| 310 | 335 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 311 | 336 | |
| 312 | 337 | # This rule prevents make from using its default rules to try build |
| 313 | 338 | # an executable named "manifest" out of the file named "manifest.c" |
| 314 | 339 | # |
| @@ -329,18 +354,23 @@ | ||
| 329 | 354 | append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>" |
| 330 | 355 | #append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>" |
| 331 | 356 | append mhargs "\$(OBJDIR)/VERSION.h" |
| 332 | 357 | set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs] |
| 333 | 358 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 334 | -writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" | |
| 335 | -writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" | |
| 359 | +writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@\n" | |
| 360 | + | |
| 361 | +writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)" | |
| 362 | +writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >$@\n" | |
| 363 | + | |
| 364 | +writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" | |
| 336 | 365 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 337 | 366 | writeln "\ttouch \$(OBJDIR)/headers" |
| 338 | 367 | writeln "\$(OBJDIR)/headers: Makefile" |
| 339 | 368 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 340 | 369 | writeln "Makefile:" |
| 341 | 370 | set extra_h(main) " \$(OBJDIR)/page_index.h " |
| 371 | +set extra_h(builtin) " \$(OBJDIR)/builtin_data.h " | |
| 342 | 372 | |
| 343 | 373 | foreach s [lsort $src] { |
| 344 | 374 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| 345 | 375 | writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n" |
| 346 | 376 | writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h" |
| @@ -505,12 +535,12 @@ | ||
| 505 | 535 | #### The directories where the OpenSSL include and library files are located. |
| 506 | 536 | # The recommended usage here is to use the Sysinternals junction tool |
| 507 | 537 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 508 | 538 | # Fossil source code directory and the target OpenSSL source directory. |
| 509 | 539 | # |
| 510 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include | |
| 511 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i | |
| 540 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include | |
| 541 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j | |
| 512 | 542 | |
| 513 | 543 | #### Either the directory where the Tcl library is installed or the Tcl |
| 514 | 544 | # source code directory resides (depending on the value of the macro |
| 515 | 545 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 516 | 546 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -726,10 +756,15 @@ | ||
| 726 | 756 | } |
| 727 | 757 | writeln -nonewline "SRC =" |
| 728 | 758 | foreach s [lsort $src] { |
| 729 | 759 | writeln -nonewline " \\\n \$(SRCDIR)/$s.c" |
| 730 | 760 | } |
| 761 | +writeln "\n" | |
| 762 | +writeln -nonewline "EXTRA_FILES =" | |
| 763 | +foreach s [lsort $extra_files] { | |
| 764 | + writeln -nonewline " \\\n \$(SRCDIR)/$s" | |
| 765 | +} | |
| 731 | 766 | writeln "\n" |
| 732 | 767 | writeln -nonewline "TRANS_SRC =" |
| 733 | 768 | foreach s [lsort $src] { |
| 734 | 769 | writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c" |
| 735 | 770 | } |
| @@ -752,11 +787,13 @@ | ||
| 752 | 787 | # |
| 753 | 788 | ifdef USE_WINDOWS |
| 754 | 789 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 755 | 790 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 756 | 791 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 757 | -VERSION = $(subst /,\,$(OBJDIR)/version.exe) | |
| 792 | +MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe) | |
| 793 | +MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe) | |
| 794 | +CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe) | |
| 758 | 795 | CAT = type |
| 759 | 796 | CP = copy |
| 760 | 797 | GREP = find |
| 761 | 798 | MV = copy |
| 762 | 799 | RM = del /Q |
| @@ -764,11 +801,13 @@ | ||
| 764 | 801 | RMDIR = rmdir /S /Q |
| 765 | 802 | else |
| 766 | 803 | TRANSLATE = $(OBJDIR)/translate.exe |
| 767 | 804 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 768 | 805 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 769 | -VERSION = $(OBJDIR)/version.exe | |
| 806 | +MKBUILTIN = $(OBJDIR)/mkbuiltin.exe | |
| 807 | +MKVERSION = $(OBJDIR)/mkversion.exe | |
| 808 | +CODECHECK1 = $(OBJDIR)/codecheck1.exe | |
| 770 | 809 | CAT = cat |
| 771 | 810 | CP = cp |
| 772 | 811 | GREP = grep |
| 773 | 812 | MV = mv |
| 774 | 813 | RM = rm -f |
| @@ -816,21 +855,27 @@ | ||
| 816 | 855 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 817 | 856 | |
| 818 | 857 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 819 | 858 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 820 | 859 | |
| 821 | -$(VERSION): $(SRCDIR)/mkversion.c | |
| 822 | - $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c | |
| 860 | +$(MKBUILTIN): $(SRCDIR)/mkbuiltin.c | |
| 861 | + $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c | |
| 862 | + | |
| 863 | +$(MKVERSION): $(SRCDIR)/mkversion.c | |
| 864 | + $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c | |
| 865 | + | |
| 866 | +$(CODECHECK1): $(SRCDIR)/codecheck1.c | |
| 867 | + $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c | |
| 823 | 868 | |
| 824 | 869 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 825 | 870 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 826 | 871 | # the repository after running the tests. |
| 827 | 872 | test: $(OBJDIR) $(APPNAME) |
| 828 | 873 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 829 | 874 | |
| 830 | -$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) | |
| 831 | - $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 875 | +$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION) | |
| 876 | + $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 832 | 877 | |
| 833 | 878 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 834 | 879 | # to 1. If it is set to 1, then there is no need to build or link |
| 835 | 880 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 836 | 881 | # using -lsqlite3. |
| @@ -886,11 +931,12 @@ | ||
| 886 | 931 | |
| 887 | 932 | ifdef FOSSIL_BUILD_SSL |
| 888 | 933 | APPTARGETS += openssl |
| 889 | 934 | endif |
| 890 | 935 | |
| 891 | -$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) | |
| 936 | +$(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) | |
| 937 | + $(CODECHECK1) $(TRANS_SRC) | |
| 892 | 938 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 893 | 939 | |
| 894 | 940 | # This rule prevents make from using its default rules to try build |
| 895 | 941 | # an executable named "manifest" out of the file named "manifest.c" |
| 896 | 942 | # |
| @@ -922,16 +968,24 @@ | ||
| 922 | 968 | append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h" |
| 923 | 969 | append mhargs " \\\n\t\t\$(SRCDIR)/th.h" |
| 924 | 970 | append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h" |
| 925 | 971 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)" |
| 926 | 972 | writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n" |
| 927 | -writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" | |
| 973 | + | |
| 974 | +writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" | |
| 975 | +writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >$@\n" | |
| 976 | + | |
| 977 | +writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" | |
| 928 | 978 | writeln "\t\$(MAKEHEADERS) $mhargs" |
| 929 | 979 | writeln "\techo Done >\$(OBJDIR)/headers\n" |
| 930 | 980 | writeln "\$(OBJDIR)/headers: Makefile\n" |
| 931 | 981 | writeln "Makefile:\n" |
| 932 | 982 | set extra_h(main) " \$(OBJDIR)/page_index.h " |
| 983 | +set extra_h(builtin) " \$(OBJDIR)/builtin_data.h " | |
| 984 | + | |
| 985 | +writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" | |
| 986 | +writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$(OBJDIR)/builtin_data.h\n" | |
| 933 | 987 | |
| 934 | 988 | foreach s [lsort $src] { |
| 935 | 989 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)" |
| 936 | 990 | writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n" |
| 937 | 991 | writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h" |
| @@ -1037,12 +1091,13 @@ | ||
| 1037 | 1091 | |
| 1038 | 1092 | APPNAME = $(OBJDIR)\fossil$(E) |
| 1039 | 1093 | |
| 1040 | 1094 | all: $(APPNAME) |
| 1041 | 1095 | |
| 1042 | -$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link | |
| 1096 | +$(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link | |
| 1043 | 1097 | cd $(OBJDIR) |
| 1098 | + codecheck1$E $(SRC) | |
| 1044 | 1099 | $(DMDIR)\bin\link @link |
| 1045 | 1100 | |
| 1046 | 1101 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 1047 | 1102 | $(RC) $(RCFLAGS) -o$@ $** |
| 1048 | 1103 | |
| @@ -1066,11 +1121,17 @@ | ||
| 1066 | 1121 | $(BCC) -o$@ $** |
| 1067 | 1122 | |
| 1068 | 1123 | mkindex$E: $(SRCDIR)\mkindex.c |
| 1069 | 1124 | $(BCC) -o$@ $** |
| 1070 | 1125 | |
| 1071 | -version$E: $B\src\mkversion.c | |
| 1126 | +mkbuiltin$E: $(SRCDIR)\mkbuiltin.c | |
| 1127 | + $(BCC) -o$@ $** | |
| 1128 | + | |
| 1129 | +mkversion$E: $(SRCDIR)\mkversion.c | |
| 1130 | + $(BCC) -o$@ $** | |
| 1131 | + | |
| 1132 | +codecheck1$E: $(SRCDIR)\codecheck1.c | |
| 1072 | 1133 | $(BCC) -o$@ $** |
| 1073 | 1134 | |
| 1074 | 1135 | $(OBJDIR)\shell$O : $(SRCDIR)\shell.c |
| 1075 | 1136 | $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $** |
| 1076 | 1137 | |
| @@ -1084,22 +1145,25 @@ | ||
| 1084 | 1145 | $(TCC) -o$@ -c $** |
| 1085 | 1146 | |
| 1086 | 1147 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 1087 | 1148 | cp $@ $@ |
| 1088 | 1149 | |
| 1089 | -VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 1150 | +VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 1090 | 1151 | +$** > $@ |
| 1091 | 1152 | |
| 1092 | 1153 | page_index.h: mkindex$E $(SRC) |
| 1093 | 1154 | +$** > $@ |
| 1155 | + | |
| 1156 | +builtin_data.h: mkbuiltin$E $(EXTRA_FILES) | |
| 1157 | + +$** > $@ | |
| 1094 | 1158 | |
| 1095 | 1159 | clean: |
| 1096 | 1160 | -del $(OBJDIR)\*.obj |
| 1097 | 1161 | -del *.obj *_.c *.h *.map |
| 1098 | 1162 | |
| 1099 | 1163 | realclean: |
| 1100 | - -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E | |
| 1164 | + -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E | |
| 1101 | 1165 | |
| 1102 | 1166 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 1103 | 1167 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 1104 | 1168 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 1105 | 1169 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -1122,11 +1186,11 @@ | ||
| 1122 | 1186 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| 1123 | 1187 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| 1124 | 1188 | writeln "\t+translate\$E \$** > \$@\n" |
| 1125 | 1189 | } |
| 1126 | 1190 | |
| 1127 | -writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " | |
| 1191 | +writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E " | |
| 1128 | 1192 | foreach s [lsort $src] { |
| 1129 | 1193 | writeln -nonewline "${s}_.c:$s.h " |
| 1130 | 1194 | } |
| 1131 | 1195 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 1132 | 1196 | writeln "\t@copy /Y nul: headers" |
| @@ -1174,10 +1238,13 @@ | ||
| 1174 | 1238 | PERLDIR = C:\Perl\bin |
| 1175 | 1239 | PERL = perl.exe |
| 1176 | 1240 | |
| 1177 | 1241 | # Uncomment to enable debug symbols |
| 1178 | 1242 | # DEBUG = 1 |
| 1243 | + | |
| 1244 | +# Uncomment to support Windows XP with Visual Studio 201x | |
| 1245 | +# FOSSIL_ENABLE_WINXP = 1 | |
| 1179 | 1246 | |
| 1180 | 1247 | # Uncomment to enable JSON API |
| 1181 | 1248 | # FOSSIL_ENABLE_JSON = 1 |
| 1182 | 1249 | |
| 1183 | 1250 | # Uncomment to enable miniz usage |
| @@ -1197,13 +1264,14 @@ | ||
| 1197 | 1264 | |
| 1198 | 1265 | # Uncomment to enable Tcl support |
| 1199 | 1266 | # FOSSIL_ENABLE_TCL = 1 |
| 1200 | 1267 | |
| 1201 | 1268 | !ifdef FOSSIL_ENABLE_SSL |
| 1202 | -SSLDIR = $(B)\compat\openssl-1.0.1i | |
| 1269 | +SSLDIR = $(B)\compat\openssl-1.0.1j | |
| 1203 | 1270 | SSLINCDIR = $(SSLDIR)\inc32 |
| 1204 | 1271 | SSLLIBDIR = $(SSLDIR)\out32 |
| 1272 | +SSLLFLAGS = /nologo /opt:ref /debug | |
| 1205 | 1273 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1206 | 1274 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1207 | 1275 | !message Using 'x64' platform for OpenSSL... |
| 1208 | 1276 | SSLCONFIG = VC-WIN64A no-asm |
| 1209 | 1277 | SSLSETUP = ms\do_win64a.bat |
| @@ -1246,10 +1314,21 @@ | ||
| 1246 | 1314 | INCL = $(INCL) /I$(TCLINCDIR) |
| 1247 | 1315 | !endif |
| 1248 | 1316 | |
| 1249 | 1317 | CFLAGS = /nologo |
| 1250 | 1318 | LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO |
| 1319 | + | |
| 1320 | +!ifdef FOSSIL_ENABLE_WINXP | |
| 1321 | +XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1 | |
| 1322 | +CFLAGS = $(CFLAGS) $(XPCFLAGS) | |
| 1323 | +!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" | |
| 1324 | +XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02 | |
| 1325 | +!else | |
| 1326 | +XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01 | |
| 1327 | +!endif | |
| 1328 | +LDFLAGS = $(LDFLAGS) $(XPLDFLAGS) | |
| 1329 | +!endif | |
| 1251 | 1330 | |
| 1252 | 1331 | !ifdef DEBUG |
| 1253 | 1332 | CFLAGS = $(CFLAGS) /Zi /MTd /Od |
| 1254 | 1333 | LDFLAGS = $(LDFLAGS) /DEBUG |
| 1255 | 1334 | !else |
| @@ -1324,10 +1403,20 @@ | ||
| 1324 | 1403 | writeln " \\" |
| 1325 | 1404 | writeln -nonewline " " |
| 1326 | 1405 | } |
| 1327 | 1406 | writeln -nonewline "${s}_.c"; incr i |
| 1328 | 1407 | } |
| 1408 | +writeln "\n" | |
| 1409 | +writeln -nonewline "EXTRA_FILES = " | |
| 1410 | +set i 0 | |
| 1411 | +foreach s [lsort $extra_files] { | |
| 1412 | + if {$i > 0} { | |
| 1413 | + writeln " \\" | |
| 1414 | + writeln -nonewline " " | |
| 1415 | + } | |
| 1416 | + writeln -nonewline "\$(SRCDIR)\\${s}"; incr i | |
| 1417 | +} | |
| 1329 | 1418 | writeln "\n" |
| 1330 | 1419 | set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation] |
| 1331 | 1420 | writeln -nonewline "OBJ = " |
| 1332 | 1421 | set i 0 |
| 1333 | 1422 | foreach s [lsort [concat $src $AdditionalObj]] { |
| @@ -1352,21 +1441,29 @@ | ||
| 1352 | 1441 | |
| 1353 | 1442 | all: $(OX) $(APPNAME) |
| 1354 | 1443 | |
| 1355 | 1444 | zlib: |
| 1356 | 1445 | @echo Building zlib from "$(ZLIBDIR)"... |
| 1446 | +!ifdef FOSSIL_ENABLE_WINXP | |
| 1447 | + @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd | |
| 1448 | +!else | |
| 1357 | 1449 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd |
| 1450 | +!endif | |
| 1358 | 1451 | |
| 1359 | 1452 | !ifdef FOSSIL_ENABLE_SSL |
| 1360 | 1453 | openssl: |
| 1361 | 1454 | @echo Building OpenSSL from "$(SSLDIR)"... |
| 1362 | 1455 | !if "$(PERLDIR)" != "" |
| 1363 | 1456 | @set PATH=$(PERLDIR);$(PATH) |
| 1364 | 1457 | !endif |
| 1365 | 1458 | @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd |
| 1366 | 1459 | @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd |
| 1460 | +!ifdef FOSSIL_ENABLE_WINXP | |
| 1461 | + @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd | |
| 1462 | +!else | |
| 1367 | 1463 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd |
| 1464 | +!endif | |
| 1368 | 1465 | !endif |
| 1369 | 1466 | |
| 1370 | 1467 | !ifndef FOSSIL_ENABLE_MINIZ |
| 1371 | 1468 | APPTARGETS = $(APPTARGETS) zlib |
| 1372 | 1469 | !endif |
| @@ -1375,12 +1472,13 @@ | ||
| 1375 | 1472 | !ifdef FOSSIL_BUILD_SSL |
| 1376 | 1473 | APPTARGETS = $(APPTARGETS) openssl |
| 1377 | 1474 | !endif |
| 1378 | 1475 | !endif |
| 1379 | 1476 | |
| 1380 | -$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts | |
| 1477 | +$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts | |
| 1381 | 1478 | cd $(OX) |
| 1479 | + codecheck1$E $(SRC) | |
| 1382 | 1480 | link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts |
| 1383 | 1481 | |
| 1384 | 1482 | $(OX)\linkopts: $B\win\Makefile.msc} |
| 1385 | 1483 | set redir {>} |
| 1386 | 1484 | foreach s [lsort [concat $src $AdditionalObj]] { |
| @@ -1403,11 +1501,17 @@ | ||
| 1403 | 1501 | $(BCC) $** |
| 1404 | 1502 | |
| 1405 | 1503 | mkindex$E: $(SRCDIR)\mkindex.c |
| 1406 | 1504 | $(BCC) $** |
| 1407 | 1505 | |
| 1408 | -mkversion$E: $B\src\mkversion.c | |
| 1506 | +mkbuiltin$E: $(SRCDIR)\mkbuiltin.c | |
| 1507 | + $(BCC) $** | |
| 1508 | + | |
| 1509 | +mkversion$E: $(SRCDIR)\mkversion.c | |
| 1510 | + $(BCC) $** | |
| 1511 | + | |
| 1512 | +codecheck1$E: $(SRCDIR)\codecheck1.c | |
| 1409 | 1513 | $(BCC) $** |
| 1410 | 1514 | |
| 1411 | 1515 | $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc |
| 1412 | 1516 | $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c |
| 1413 | 1517 | |
| @@ -1432,10 +1536,13 @@ | ||
| 1432 | 1536 | $(TCC) /Fo$@ /c $** |
| 1433 | 1537 | |
| 1434 | 1538 | page_index.h: mkindex$E $(SRC) |
| 1435 | 1539 | $** > $@ |
| 1436 | 1540 | |
| 1541 | +builtin_data.h: mkbuiltin$E $(EXTRA_FILES) | |
| 1542 | + $** > $@ | |
| 1543 | + | |
| 1437 | 1544 | clean: |
| 1438 | 1545 | -del $(OX)\*.obj |
| 1439 | 1546 | -del *.obj |
| 1440 | 1547 | -del *_.c |
| 1441 | 1548 | -del *.h |
| @@ -1455,10 +1562,14 @@ | ||
| 1455 | 1562 | -del mkindex$P |
| 1456 | 1563 | -del makeheaders$E |
| 1457 | 1564 | -del makeheaders$P |
| 1458 | 1565 | -del mkversion$E |
| 1459 | 1566 | -del mkversion$P |
| 1567 | + -del codecheck1$E | |
| 1568 | + -del codecheck1$P | |
| 1569 | + -del mkbuiltin$E | |
| 1570 | + -del mkbuiltin$P | |
| 1460 | 1571 | |
| 1461 | 1572 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 1462 | 1573 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 1463 | 1574 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 1464 | 1575 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -1482,11 +1593,11 @@ | ||
| 1482 | 1593 | } |
| 1483 | 1594 | |
| 1484 | 1595 | writeln "fossil.res : \$B\\win\\fossil.rc" |
| 1485 | 1596 | writeln "\t\$(RCC) /fo \$@ \$**\n" |
| 1486 | 1597 | |
| 1487 | -writeln "headers: makeheaders\$E page_index.h VERSION.h" | |
| 1598 | +writeln "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h" | |
| 1488 | 1599 | writeln -nonewline "\tmakeheaders\$E " |
| 1489 | 1600 | set i 0 |
| 1490 | 1601 | foreach s [lsort $src] { |
| 1491 | 1602 | if {$i > 0} { |
| 1492 | 1603 | writeln " \\" |
| @@ -1592,11 +1703,11 @@ | ||
| 1592 | 1703 | RC=$(PellesCDir)\bin\porc.exe |
| 1593 | 1704 | RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION) |
| 1594 | 1705 | |
| 1595 | 1706 | # define the special utilities files, needed to generate |
| 1596 | 1707 | # the automatically generated source files |
| 1597 | -UTILS=translate.exe mkindex.exe makeheaders.exe | |
| 1708 | +UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe | |
| 1598 | 1709 | UTILS_OBJ=$(UTILS:.exe=.obj) |
| 1599 | 1710 | UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) |
| 1600 | 1711 | |
| 1601 | 1712 | # define the SQLite files, which need special flags on compile |
| 1602 | 1713 | SQLITESRC=sqlite3.c |
| @@ -1631,11 +1742,11 @@ | ||
| 1631 | 1742 | # main target file is the application |
| 1632 | 1743 | APPLICATION=fossil.exe |
| 1633 | 1744 | |
| 1634 | 1745 | # define the standard make target |
| 1635 | 1746 | .PHONY: default |
| 1636 | -default: page_index.h headers $(APPLICATION) | |
| 1747 | +default: page_index.h builtin_data.h headers $(APPLICATION) | |
| 1637 | 1748 | |
| 1638 | 1749 | # symbolic target to generate the source generate utils |
| 1639 | 1750 | .PHONY: utils |
| 1640 | 1751 | utils: $(UTILS) |
| 1641 | 1752 | |
| @@ -1656,17 +1767,20 @@ | ||
| 1656 | 1767 | translate.exe $< >$@ |
| 1657 | 1768 | |
| 1658 | 1769 | # generate the index source, containing all web references,.. |
| 1659 | 1770 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 1660 | 1771 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 1772 | + | |
| 1773 | +builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe | |
| 1774 | + mkbuiltin.exe $(EXTRA_FILES) >$@ | |
| 1661 | 1775 | |
| 1662 | 1776 | # extracting version info from manifest |
| 1663 | 1777 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 1664 | 1778 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 1665 | 1779 | |
| 1666 | 1780 | # generate the simplified headers |
| 1667 | -headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h | |
| 1781 | +headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h | |
| 1668 | 1782 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 1669 | 1783 | echo Done >$@ |
| 1670 | 1784 | |
| 1671 | 1785 | # compile C sources with relevant options |
| 1672 | 1786 | |
| 1673 | 1787 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -12,12 +12,15 @@ | |
| 12 | # tclsh makemake.tcl |
| 13 | # |
| 14 | ############################################################################# |
| 15 | |
| 16 | # Basenames of all source files that get preprocessed using |
| 17 | # "translate" and "makeheaders". To add new source files to the |
| 18 | # project, simply add the basename to this list and rerun this script. |
| 19 | # |
| 20 | set src { |
| 21 | add |
| 22 | allrepo |
| 23 | attach |
| @@ -24,10 +27,11 @@ | |
| 24 | bag |
| 25 | bisect |
| 26 | blob |
| 27 | branch |
| 28 | browse |
| 29 | cache |
| 30 | captcha |
| 31 | cgi |
| 32 | checkin |
| 33 | checkout |
| @@ -128,10 +132,16 @@ | |
| 128 | xfer |
| 129 | xfersetup |
| 130 | zip |
| 131 | http_ssl |
| 132 | } |
| 133 | |
| 134 | # Options used to compile the included SQLite library. |
| 135 | # |
| 136 | set SQLITE_OPTIONS { |
| 137 | -DNDEBUG=1 |
| @@ -217,10 +227,15 @@ | |
| 217 | } |
| 218 | writeln -nonewline "SRC =" |
| 219 | foreach s [lsort $src] { |
| 220 | writeln -nonewline " \\\n \$(SRCDIR)/$s.c" |
| 221 | } |
| 222 | writeln "\n" |
| 223 | writeln -nonewline "TRANS_SRC =" |
| 224 | foreach s [lsort $src] { |
| 225 | writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c" |
| 226 | } |
| @@ -241,10 +256,13 @@ | |
| 241 | |
| 242 | install: $(APPNAME) |
| 243 | mkdir -p $(INSTALLDIR) |
| 244 | mv $(APPNAME) $(INSTALLDIR) |
| 245 | |
| 246 | $(OBJDIR): |
| 247 | -mkdir $(OBJDIR) |
| 248 | |
| 249 | $(OBJDIR)/translate: $(SRCDIR)/translate.c |
| 250 | $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| @@ -253,13 +271,19 @@ | |
| 253 | $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c |
| 254 | |
| 255 | $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c |
| 256 | $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c |
| 257 | |
| 258 | $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c |
| 259 | $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c |
| 260 | |
| 261 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 262 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 263 | # the repository after running the tests. |
| 264 | test: $(OBJDIR) $(APPNAME) |
| 265 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| @@ -304,11 +328,12 @@ | |
| 304 | $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>> |
| 305 | $(OBJDIR)/cson_amalgamation.o |
| 306 | }] |
| 307 | |
| 308 | writeln { |
| 309 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 310 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 311 | |
| 312 | # This rule prevents make from using its default rules to try build |
| 313 | # an executable named "manifest" out of the file named "manifest.c" |
| 314 | # |
| @@ -329,18 +354,23 @@ | |
| 329 | append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>" |
| 330 | #append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>" |
| 331 | append mhargs "\$(OBJDIR)/VERSION.h" |
| 332 | set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs] |
| 333 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 334 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 335 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 336 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 337 | writeln "\ttouch \$(OBJDIR)/headers" |
| 338 | writeln "\$(OBJDIR)/headers: Makefile" |
| 339 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 340 | writeln "Makefile:" |
| 341 | set extra_h(main) " \$(OBJDIR)/page_index.h " |
| 342 | |
| 343 | foreach s [lsort $src] { |
| 344 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| 345 | writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n" |
| 346 | writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h" |
| @@ -505,12 +535,12 @@ | |
| 505 | #### The directories where the OpenSSL include and library files are located. |
| 506 | # The recommended usage here is to use the Sysinternals junction tool |
| 507 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 508 | # Fossil source code directory and the target OpenSSL source directory. |
| 509 | # |
| 510 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include |
| 511 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i |
| 512 | |
| 513 | #### Either the directory where the Tcl library is installed or the Tcl |
| 514 | # source code directory resides (depending on the value of the macro |
| 515 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 516 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -726,10 +756,15 @@ | |
| 726 | } |
| 727 | writeln -nonewline "SRC =" |
| 728 | foreach s [lsort $src] { |
| 729 | writeln -nonewline " \\\n \$(SRCDIR)/$s.c" |
| 730 | } |
| 731 | writeln "\n" |
| 732 | writeln -nonewline "TRANS_SRC =" |
| 733 | foreach s [lsort $src] { |
| 734 | writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c" |
| 735 | } |
| @@ -752,11 +787,13 @@ | |
| 752 | # |
| 753 | ifdef USE_WINDOWS |
| 754 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 755 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 756 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 757 | VERSION = $(subst /,\,$(OBJDIR)/version.exe) |
| 758 | CAT = type |
| 759 | CP = copy |
| 760 | GREP = find |
| 761 | MV = copy |
| 762 | RM = del /Q |
| @@ -764,11 +801,13 @@ | |
| 764 | RMDIR = rmdir /S /Q |
| 765 | else |
| 766 | TRANSLATE = $(OBJDIR)/translate.exe |
| 767 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 768 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 769 | VERSION = $(OBJDIR)/version.exe |
| 770 | CAT = cat |
| 771 | CP = cp |
| 772 | GREP = grep |
| 773 | MV = mv |
| 774 | RM = rm -f |
| @@ -816,21 +855,27 @@ | |
| 816 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 817 | |
| 818 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 819 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 820 | |
| 821 | $(VERSION): $(SRCDIR)/mkversion.c |
| 822 | $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c |
| 823 | |
| 824 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 825 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 826 | # the repository after running the tests. |
| 827 | test: $(OBJDIR) $(APPNAME) |
| 828 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 829 | |
| 830 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 831 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 832 | |
| 833 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 834 | # to 1. If it is set to 1, then there is no need to build or link |
| 835 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 836 | # using -lsqlite3. |
| @@ -886,11 +931,12 @@ | |
| 886 | |
| 887 | ifdef FOSSIL_BUILD_SSL |
| 888 | APPTARGETS += openssl |
| 889 | endif |
| 890 | |
| 891 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) |
| 892 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 893 | |
| 894 | # This rule prevents make from using its default rules to try build |
| 895 | # an executable named "manifest" out of the file named "manifest.c" |
| 896 | # |
| @@ -922,16 +968,24 @@ | |
| 922 | append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h" |
| 923 | append mhargs " \\\n\t\t\$(SRCDIR)/th.h" |
| 924 | append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h" |
| 925 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)" |
| 926 | writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n" |
| 927 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" |
| 928 | writeln "\t\$(MAKEHEADERS) $mhargs" |
| 929 | writeln "\techo Done >\$(OBJDIR)/headers\n" |
| 930 | writeln "\$(OBJDIR)/headers: Makefile\n" |
| 931 | writeln "Makefile:\n" |
| 932 | set extra_h(main) " \$(OBJDIR)/page_index.h " |
| 933 | |
| 934 | foreach s [lsort $src] { |
| 935 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)" |
| 936 | writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n" |
| 937 | writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h" |
| @@ -1037,12 +1091,13 @@ | |
| 1037 | |
| 1038 | APPNAME = $(OBJDIR)\fossil$(E) |
| 1039 | |
| 1040 | all: $(APPNAME) |
| 1041 | |
| 1042 | $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link |
| 1043 | cd $(OBJDIR) |
| 1044 | $(DMDIR)\bin\link @link |
| 1045 | |
| 1046 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 1047 | $(RC) $(RCFLAGS) -o$@ $** |
| 1048 | |
| @@ -1066,11 +1121,17 @@ | |
| 1066 | $(BCC) -o$@ $** |
| 1067 | |
| 1068 | mkindex$E: $(SRCDIR)\mkindex.c |
| 1069 | $(BCC) -o$@ $** |
| 1070 | |
| 1071 | version$E: $B\src\mkversion.c |
| 1072 | $(BCC) -o$@ $** |
| 1073 | |
| 1074 | $(OBJDIR)\shell$O : $(SRCDIR)\shell.c |
| 1075 | $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $** |
| 1076 | |
| @@ -1084,22 +1145,25 @@ | |
| 1084 | $(TCC) -o$@ -c $** |
| 1085 | |
| 1086 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 1087 | cp $@ $@ |
| 1088 | |
| 1089 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 1090 | +$** > $@ |
| 1091 | |
| 1092 | page_index.h: mkindex$E $(SRC) |
| 1093 | +$** > $@ |
| 1094 | |
| 1095 | clean: |
| 1096 | -del $(OBJDIR)\*.obj |
| 1097 | -del *.obj *_.c *.h *.map |
| 1098 | |
| 1099 | realclean: |
| 1100 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 1101 | |
| 1102 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 1103 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 1104 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 1105 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -1122,11 +1186,11 @@ | |
| 1122 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| 1123 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| 1124 | writeln "\t+translate\$E \$** > \$@\n" |
| 1125 | } |
| 1126 | |
| 1127 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 1128 | foreach s [lsort $src] { |
| 1129 | writeln -nonewline "${s}_.c:$s.h " |
| 1130 | } |
| 1131 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 1132 | writeln "\t@copy /Y nul: headers" |
| @@ -1174,10 +1238,13 @@ | |
| 1174 | PERLDIR = C:\Perl\bin |
| 1175 | PERL = perl.exe |
| 1176 | |
| 1177 | # Uncomment to enable debug symbols |
| 1178 | # DEBUG = 1 |
| 1179 | |
| 1180 | # Uncomment to enable JSON API |
| 1181 | # FOSSIL_ENABLE_JSON = 1 |
| 1182 | |
| 1183 | # Uncomment to enable miniz usage |
| @@ -1197,13 +1264,14 @@ | |
| 1197 | |
| 1198 | # Uncomment to enable Tcl support |
| 1199 | # FOSSIL_ENABLE_TCL = 1 |
| 1200 | |
| 1201 | !ifdef FOSSIL_ENABLE_SSL |
| 1202 | SSLDIR = $(B)\compat\openssl-1.0.1i |
| 1203 | SSLINCDIR = $(SSLDIR)\inc32 |
| 1204 | SSLLIBDIR = $(SSLDIR)\out32 |
| 1205 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1206 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1207 | !message Using 'x64' platform for OpenSSL... |
| 1208 | SSLCONFIG = VC-WIN64A no-asm |
| 1209 | SSLSETUP = ms\do_win64a.bat |
| @@ -1246,10 +1314,21 @@ | |
| 1246 | INCL = $(INCL) /I$(TCLINCDIR) |
| 1247 | !endif |
| 1248 | |
| 1249 | CFLAGS = /nologo |
| 1250 | LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO |
| 1251 | |
| 1252 | !ifdef DEBUG |
| 1253 | CFLAGS = $(CFLAGS) /Zi /MTd /Od |
| 1254 | LDFLAGS = $(LDFLAGS) /DEBUG |
| 1255 | !else |
| @@ -1324,10 +1403,20 @@ | |
| 1324 | writeln " \\" |
| 1325 | writeln -nonewline " " |
| 1326 | } |
| 1327 | writeln -nonewline "${s}_.c"; incr i |
| 1328 | } |
| 1329 | writeln "\n" |
| 1330 | set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation] |
| 1331 | writeln -nonewline "OBJ = " |
| 1332 | set i 0 |
| 1333 | foreach s [lsort [concat $src $AdditionalObj]] { |
| @@ -1352,21 +1441,29 @@ | |
| 1352 | |
| 1353 | all: $(OX) $(APPNAME) |
| 1354 | |
| 1355 | zlib: |
| 1356 | @echo Building zlib from "$(ZLIBDIR)"... |
| 1357 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd |
| 1358 | |
| 1359 | !ifdef FOSSIL_ENABLE_SSL |
| 1360 | openssl: |
| 1361 | @echo Building OpenSSL from "$(SSLDIR)"... |
| 1362 | !if "$(PERLDIR)" != "" |
| 1363 | @set PATH=$(PERLDIR);$(PATH) |
| 1364 | !endif |
| 1365 | @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd |
| 1366 | @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd |
| 1367 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd |
| 1368 | !endif |
| 1369 | |
| 1370 | !ifndef FOSSIL_ENABLE_MINIZ |
| 1371 | APPTARGETS = $(APPTARGETS) zlib |
| 1372 | !endif |
| @@ -1375,12 +1472,13 @@ | |
| 1375 | !ifdef FOSSIL_BUILD_SSL |
| 1376 | APPTARGETS = $(APPTARGETS) openssl |
| 1377 | !endif |
| 1378 | !endif |
| 1379 | |
| 1380 | $(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts |
| 1381 | cd $(OX) |
| 1382 | link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts |
| 1383 | |
| 1384 | $(OX)\linkopts: $B\win\Makefile.msc} |
| 1385 | set redir {>} |
| 1386 | foreach s [lsort [concat $src $AdditionalObj]] { |
| @@ -1403,11 +1501,17 @@ | |
| 1403 | $(BCC) $** |
| 1404 | |
| 1405 | mkindex$E: $(SRCDIR)\mkindex.c |
| 1406 | $(BCC) $** |
| 1407 | |
| 1408 | mkversion$E: $B\src\mkversion.c |
| 1409 | $(BCC) $** |
| 1410 | |
| 1411 | $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc |
| 1412 | $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c |
| 1413 | |
| @@ -1432,10 +1536,13 @@ | |
| 1432 | $(TCC) /Fo$@ /c $** |
| 1433 | |
| 1434 | page_index.h: mkindex$E $(SRC) |
| 1435 | $** > $@ |
| 1436 | |
| 1437 | clean: |
| 1438 | -del $(OX)\*.obj |
| 1439 | -del *.obj |
| 1440 | -del *_.c |
| 1441 | -del *.h |
| @@ -1455,10 +1562,14 @@ | |
| 1455 | -del mkindex$P |
| 1456 | -del makeheaders$E |
| 1457 | -del makeheaders$P |
| 1458 | -del mkversion$E |
| 1459 | -del mkversion$P |
| 1460 | |
| 1461 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 1462 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 1463 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 1464 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -1482,11 +1593,11 @@ | |
| 1482 | } |
| 1483 | |
| 1484 | writeln "fossil.res : \$B\\win\\fossil.rc" |
| 1485 | writeln "\t\$(RCC) /fo \$@ \$**\n" |
| 1486 | |
| 1487 | writeln "headers: makeheaders\$E page_index.h VERSION.h" |
| 1488 | writeln -nonewline "\tmakeheaders\$E " |
| 1489 | set i 0 |
| 1490 | foreach s [lsort $src] { |
| 1491 | if {$i > 0} { |
| 1492 | writeln " \\" |
| @@ -1592,11 +1703,11 @@ | |
| 1592 | RC=$(PellesCDir)\bin\porc.exe |
| 1593 | RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION) |
| 1594 | |
| 1595 | # define the special utilities files, needed to generate |
| 1596 | # the automatically generated source files |
| 1597 | UTILS=translate.exe mkindex.exe makeheaders.exe |
| 1598 | UTILS_OBJ=$(UTILS:.exe=.obj) |
| 1599 | UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) |
| 1600 | |
| 1601 | # define the SQLite files, which need special flags on compile |
| 1602 | SQLITESRC=sqlite3.c |
| @@ -1631,11 +1742,11 @@ | |
| 1631 | # main target file is the application |
| 1632 | APPLICATION=fossil.exe |
| 1633 | |
| 1634 | # define the standard make target |
| 1635 | .PHONY: default |
| 1636 | default: page_index.h headers $(APPLICATION) |
| 1637 | |
| 1638 | # symbolic target to generate the source generate utils |
| 1639 | .PHONY: utils |
| 1640 | utils: $(UTILS) |
| 1641 | |
| @@ -1656,17 +1767,20 @@ | |
| 1656 | translate.exe $< >$@ |
| 1657 | |
| 1658 | # generate the index source, containing all web references,.. |
| 1659 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 1660 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 1661 | |
| 1662 | # extracting version info from manifest |
| 1663 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 1664 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 1665 | |
| 1666 | # generate the simplified headers |
| 1667 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 1668 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 1669 | echo Done >$@ |
| 1670 | |
| 1671 | # compile C sources with relevant options |
| 1672 | |
| 1673 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -12,12 +12,15 @@ | |
| 12 | # tclsh makemake.tcl |
| 13 | # |
| 14 | ############################################################################# |
| 15 | |
| 16 | # Basenames of all source files that get preprocessed using |
| 17 | # "translate" and "makeheaders". To add new C-language source files to the |
| 18 | # project, simply add the basename to this list and rerun this script. |
| 19 | # |
| 20 | # Set the separate extra_files variable further down for how to add non-C |
| 21 | # files, such as string and BLOB resources. |
| 22 | # |
| 23 | set src { |
| 24 | add |
| 25 | allrepo |
| 26 | attach |
| @@ -24,10 +27,11 @@ | |
| 27 | bag |
| 28 | bisect |
| 29 | blob |
| 30 | branch |
| 31 | browse |
| 32 | builtin |
| 33 | cache |
| 34 | captcha |
| 35 | cgi |
| 36 | checkin |
| 37 | checkout |
| @@ -128,10 +132,16 @@ | |
| 132 | xfer |
| 133 | xfersetup |
| 134 | zip |
| 135 | http_ssl |
| 136 | } |
| 137 | |
| 138 | # Additional resource files that get built into the executable. |
| 139 | # |
| 140 | set extra_files { |
| 141 | diff.tcl |
| 142 | } |
| 143 | |
| 144 | # Options used to compile the included SQLite library. |
| 145 | # |
| 146 | set SQLITE_OPTIONS { |
| 147 | -DNDEBUG=1 |
| @@ -217,10 +227,15 @@ | |
| 227 | } |
| 228 | writeln -nonewline "SRC =" |
| 229 | foreach s [lsort $src] { |
| 230 | writeln -nonewline " \\\n \$(SRCDIR)/$s.c" |
| 231 | } |
| 232 | writeln "\n" |
| 233 | writeln -nonewline "EXTRA_FILES =" |
| 234 | foreach s [lsort $extra_files] { |
| 235 | writeln -nonewline " \\\n \$(SRCDIR)/$s" |
| 236 | } |
| 237 | writeln "\n" |
| 238 | writeln -nonewline "TRANS_SRC =" |
| 239 | foreach s [lsort $src] { |
| 240 | writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c" |
| 241 | } |
| @@ -241,10 +256,13 @@ | |
| 256 | |
| 257 | install: $(APPNAME) |
| 258 | mkdir -p $(INSTALLDIR) |
| 259 | mv $(APPNAME) $(INSTALLDIR) |
| 260 | |
| 261 | codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 |
| 262 | $(OBJDIR)/codecheck1 $(TRANS_SRC) |
| 263 | |
| 264 | $(OBJDIR): |
| 265 | -mkdir $(OBJDIR) |
| 266 | |
| 267 | $(OBJDIR)/translate: $(SRCDIR)/translate.c |
| 268 | $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c |
| @@ -253,13 +271,19 @@ | |
| 271 | $(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c |
| 272 | |
| 273 | $(OBJDIR)/mkindex: $(SRCDIR)/mkindex.c |
| 274 | $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c |
| 275 | |
| 276 | $(OBJDIR)/mkbuiltin: $(SRCDIR)/mkbuiltin.c |
| 277 | $(BCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR)/mkbuiltin.c |
| 278 | |
| 279 | $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c |
| 280 | $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c |
| 281 | |
| 282 | $(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c |
| 283 | $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c |
| 284 | |
| 285 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 286 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 287 | # the repository after running the tests. |
| 288 | test: $(OBJDIR) $(APPNAME) |
| 289 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| @@ -304,11 +328,12 @@ | |
| 328 | $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>> |
| 329 | $(OBJDIR)/cson_amalgamation.o |
| 330 | }] |
| 331 | |
| 332 | writeln { |
| 333 | $(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ) |
| 334 | $(OBJDIR)/codecheck1 $(TRANS_SRC) |
| 335 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 336 | |
| 337 | # This rule prevents make from using its default rules to try build |
| 338 | # an executable named "manifest" out of the file named "manifest.c" |
| 339 | # |
| @@ -329,18 +354,23 @@ | |
| 354 | append mhargs "\$(SRCDIR)/th.h <<<NEXT_LINE>>>" |
| 355 | #append mhargs "\$(SRCDIR)/cson_amalgamation.h <<<NEXT_LINE>>>" |
| 356 | append mhargs "\$(OBJDIR)/VERSION.h" |
| 357 | set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs] |
| 358 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 359 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@\n" |
| 360 | |
| 361 | writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)" |
| 362 | writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >$@\n" |
| 363 | |
| 364 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 365 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 366 | writeln "\ttouch \$(OBJDIR)/headers" |
| 367 | writeln "\$(OBJDIR)/headers: Makefile" |
| 368 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_config.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_dir.o \$(OBJDIR)/json_finfo.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_status.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 369 | writeln "Makefile:" |
| 370 | set extra_h(main) " \$(OBJDIR)/page_index.h " |
| 371 | set extra_h(builtin) " \$(OBJDIR)/builtin_data.h " |
| 372 | |
| 373 | foreach s [lsort $src] { |
| 374 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| 375 | writeln "\t\$(OBJDIR)/translate \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n" |
| 376 | writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h" |
| @@ -505,12 +535,12 @@ | |
| 535 | #### The directories where the OpenSSL include and library files are located. |
| 536 | # The recommended usage here is to use the Sysinternals junction tool |
| 537 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 538 | # Fossil source code directory and the target OpenSSL source directory. |
| 539 | # |
| 540 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include |
| 541 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j |
| 542 | |
| 543 | #### Either the directory where the Tcl library is installed or the Tcl |
| 544 | # source code directory resides (depending on the value of the macro |
| 545 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 546 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -726,10 +756,15 @@ | |
| 756 | } |
| 757 | writeln -nonewline "SRC =" |
| 758 | foreach s [lsort $src] { |
| 759 | writeln -nonewline " \\\n \$(SRCDIR)/$s.c" |
| 760 | } |
| 761 | writeln "\n" |
| 762 | writeln -nonewline "EXTRA_FILES =" |
| 763 | foreach s [lsort $extra_files] { |
| 764 | writeln -nonewline " \\\n \$(SRCDIR)/$s" |
| 765 | } |
| 766 | writeln "\n" |
| 767 | writeln -nonewline "TRANS_SRC =" |
| 768 | foreach s [lsort $src] { |
| 769 | writeln -nonewline " \\\n \$(OBJDIR)/${s}_.c" |
| 770 | } |
| @@ -752,11 +787,13 @@ | |
| 787 | # |
| 788 | ifdef USE_WINDOWS |
| 789 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 790 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 791 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 792 | MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe) |
| 793 | MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe) |
| 794 | CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe) |
| 795 | CAT = type |
| 796 | CP = copy |
| 797 | GREP = find |
| 798 | MV = copy |
| 799 | RM = del /Q |
| @@ -764,11 +801,13 @@ | |
| 801 | RMDIR = rmdir /S /Q |
| 802 | else |
| 803 | TRANSLATE = $(OBJDIR)/translate.exe |
| 804 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 805 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 806 | MKBUILTIN = $(OBJDIR)/mkbuiltin.exe |
| 807 | MKVERSION = $(OBJDIR)/mkversion.exe |
| 808 | CODECHECK1 = $(OBJDIR)/codecheck1.exe |
| 809 | CAT = cat |
| 810 | CP = cp |
| 811 | GREP = grep |
| 812 | MV = mv |
| 813 | RM = rm -f |
| @@ -816,21 +855,27 @@ | |
| 855 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 856 | |
| 857 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 858 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 859 | |
| 860 | $(MKBUILTIN): $(SRCDIR)/mkbuiltin.c |
| 861 | $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c |
| 862 | |
| 863 | $(MKVERSION): $(SRCDIR)/mkversion.c |
| 864 | $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c |
| 865 | |
| 866 | $(CODECHECK1): $(SRCDIR)/codecheck1.c |
| 867 | $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c |
| 868 | |
| 869 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 870 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 871 | # the repository after running the tests. |
| 872 | test: $(OBJDIR) $(APPNAME) |
| 873 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 874 | |
| 875 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION) |
| 876 | $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 877 | |
| 878 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 879 | # to 1. If it is set to 1, then there is no need to build or link |
| 880 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 881 | # using -lsqlite3. |
| @@ -886,11 +931,12 @@ | |
| 931 | |
| 932 | ifdef FOSSIL_BUILD_SSL |
| 933 | APPTARGETS += openssl |
| 934 | endif |
| 935 | |
| 936 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) |
| 937 | $(CODECHECK1) $(TRANS_SRC) |
| 938 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 939 | |
| 940 | # This rule prevents make from using its default rules to try build |
| 941 | # an executable named "manifest" out of the file named "manifest.c" |
| 942 | # |
| @@ -922,16 +968,24 @@ | |
| 968 | append mhargs " \\\n\t\t\$(SRCDIR)/sqlite3.h" |
| 969 | append mhargs " \\\n\t\t\$(SRCDIR)/th.h" |
| 970 | append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h" |
| 971 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)" |
| 972 | writeln "\t\$(MKINDEX) \$(TRANS_SRC) >$@\n" |
| 973 | |
| 974 | writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" |
| 975 | writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >$@\n" |
| 976 | |
| 977 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" |
| 978 | writeln "\t\$(MAKEHEADERS) $mhargs" |
| 979 | writeln "\techo Done >\$(OBJDIR)/headers\n" |
| 980 | writeln "\$(OBJDIR)/headers: Makefile\n" |
| 981 | writeln "Makefile:\n" |
| 982 | set extra_h(main) " \$(OBJDIR)/page_index.h " |
| 983 | set extra_h(builtin) " \$(OBJDIR)/builtin_data.h " |
| 984 | |
| 985 | writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" |
| 986 | writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$(OBJDIR)/builtin_data.h\n" |
| 987 | |
| 988 | foreach s [lsort $src] { |
| 989 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(TRANSLATE)" |
| 990 | writeln "\t\$(TRANSLATE) \$(SRCDIR)/$s.c >\$(OBJDIR)/${s}_.c\n" |
| 991 | writeln "\$(OBJDIR)/$s.o:\t\$(OBJDIR)/${s}_.c \$(OBJDIR)/$s.h$extra_h($s)\$(SRCDIR)/config.h" |
| @@ -1037,12 +1091,13 @@ | |
| 1091 | |
| 1092 | APPNAME = $(OBJDIR)\fossil$(E) |
| 1093 | |
| 1094 | all: $(APPNAME) |
| 1095 | |
| 1096 | $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link |
| 1097 | cd $(OBJDIR) |
| 1098 | codecheck1$E $(SRC) |
| 1099 | $(DMDIR)\bin\link @link |
| 1100 | |
| 1101 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 1102 | $(RC) $(RCFLAGS) -o$@ $** |
| 1103 | |
| @@ -1066,11 +1121,17 @@ | |
| 1121 | $(BCC) -o$@ $** |
| 1122 | |
| 1123 | mkindex$E: $(SRCDIR)\mkindex.c |
| 1124 | $(BCC) -o$@ $** |
| 1125 | |
| 1126 | mkbuiltin$E: $(SRCDIR)\mkbuiltin.c |
| 1127 | $(BCC) -o$@ $** |
| 1128 | |
| 1129 | mkversion$E: $(SRCDIR)\mkversion.c |
| 1130 | $(BCC) -o$@ $** |
| 1131 | |
| 1132 | codecheck1$E: $(SRCDIR)\codecheck1.c |
| 1133 | $(BCC) -o$@ $** |
| 1134 | |
| 1135 | $(OBJDIR)\shell$O : $(SRCDIR)\shell.c |
| 1136 | $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $** |
| 1137 | |
| @@ -1084,22 +1145,25 @@ | |
| 1145 | $(TCC) -o$@ -c $** |
| 1146 | |
| 1147 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 1148 | cp $@ $@ |
| 1149 | |
| 1150 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 1151 | +$** > $@ |
| 1152 | |
| 1153 | page_index.h: mkindex$E $(SRC) |
| 1154 | +$** > $@ |
| 1155 | |
| 1156 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1157 | +$** > $@ |
| 1158 | |
| 1159 | clean: |
| 1160 | -del $(OBJDIR)\*.obj |
| 1161 | -del *.obj *_.c *.h *.map |
| 1162 | |
| 1163 | realclean: |
| 1164 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E |
| 1165 | |
| 1166 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 1167 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 1168 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 1169 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -1122,11 +1186,11 @@ | |
| 1186 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| 1187 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| 1188 | writeln "\t+translate\$E \$** > \$@\n" |
| 1189 | } |
| 1190 | |
| 1191 | writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E " |
| 1192 | foreach s [lsort $src] { |
| 1193 | writeln -nonewline "${s}_.c:$s.h " |
| 1194 | } |
| 1195 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 1196 | writeln "\t@copy /Y nul: headers" |
| @@ -1174,10 +1238,13 @@ | |
| 1238 | PERLDIR = C:\Perl\bin |
| 1239 | PERL = perl.exe |
| 1240 | |
| 1241 | # Uncomment to enable debug symbols |
| 1242 | # DEBUG = 1 |
| 1243 | |
| 1244 | # Uncomment to support Windows XP with Visual Studio 201x |
| 1245 | # FOSSIL_ENABLE_WINXP = 1 |
| 1246 | |
| 1247 | # Uncomment to enable JSON API |
| 1248 | # FOSSIL_ENABLE_JSON = 1 |
| 1249 | |
| 1250 | # Uncomment to enable miniz usage |
| @@ -1197,13 +1264,14 @@ | |
| 1264 | |
| 1265 | # Uncomment to enable Tcl support |
| 1266 | # FOSSIL_ENABLE_TCL = 1 |
| 1267 | |
| 1268 | !ifdef FOSSIL_ENABLE_SSL |
| 1269 | SSLDIR = $(B)\compat\openssl-1.0.1j |
| 1270 | SSLINCDIR = $(SSLDIR)\inc32 |
| 1271 | SSLLIBDIR = $(SSLDIR)\out32 |
| 1272 | SSLLFLAGS = /nologo /opt:ref /debug |
| 1273 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1274 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1275 | !message Using 'x64' platform for OpenSSL... |
| 1276 | SSLCONFIG = VC-WIN64A no-asm |
| 1277 | SSLSETUP = ms\do_win64a.bat |
| @@ -1246,10 +1314,21 @@ | |
| 1314 | INCL = $(INCL) /I$(TCLINCDIR) |
| 1315 | !endif |
| 1316 | |
| 1317 | CFLAGS = /nologo |
| 1318 | LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO |
| 1319 | |
| 1320 | !ifdef FOSSIL_ENABLE_WINXP |
| 1321 | XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1 |
| 1322 | CFLAGS = $(CFLAGS) $(XPCFLAGS) |
| 1323 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1324 | XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02 |
| 1325 | !else |
| 1326 | XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01 |
| 1327 | !endif |
| 1328 | LDFLAGS = $(LDFLAGS) $(XPLDFLAGS) |
| 1329 | !endif |
| 1330 | |
| 1331 | !ifdef DEBUG |
| 1332 | CFLAGS = $(CFLAGS) /Zi /MTd /Od |
| 1333 | LDFLAGS = $(LDFLAGS) /DEBUG |
| 1334 | !else |
| @@ -1324,10 +1403,20 @@ | |
| 1403 | writeln " \\" |
| 1404 | writeln -nonewline " " |
| 1405 | } |
| 1406 | writeln -nonewline "${s}_.c"; incr i |
| 1407 | } |
| 1408 | writeln "\n" |
| 1409 | writeln -nonewline "EXTRA_FILES = " |
| 1410 | set i 0 |
| 1411 | foreach s [lsort $extra_files] { |
| 1412 | if {$i > 0} { |
| 1413 | writeln " \\" |
| 1414 | writeln -nonewline " " |
| 1415 | } |
| 1416 | writeln -nonewline "\$(SRCDIR)\\${s}"; incr i |
| 1417 | } |
| 1418 | writeln "\n" |
| 1419 | set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation] |
| 1420 | writeln -nonewline "OBJ = " |
| 1421 | set i 0 |
| 1422 | foreach s [lsort [concat $src $AdditionalObj]] { |
| @@ -1352,21 +1441,29 @@ | |
| 1441 | |
| 1442 | all: $(OX) $(APPNAME) |
| 1443 | |
| 1444 | zlib: |
| 1445 | @echo Building zlib from "$(ZLIBDIR)"... |
| 1446 | !ifdef FOSSIL_ENABLE_WINXP |
| 1447 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd |
| 1448 | !else |
| 1449 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd |
| 1450 | !endif |
| 1451 | |
| 1452 | !ifdef FOSSIL_ENABLE_SSL |
| 1453 | openssl: |
| 1454 | @echo Building OpenSSL from "$(SSLDIR)"... |
| 1455 | !if "$(PERLDIR)" != "" |
| 1456 | @set PATH=$(PERLDIR);$(PATH) |
| 1457 | !endif |
| 1458 | @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd |
| 1459 | @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd |
| 1460 | !ifdef FOSSIL_ENABLE_WINXP |
| 1461 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd |
| 1462 | !else |
| 1463 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd |
| 1464 | !endif |
| 1465 | !endif |
| 1466 | |
| 1467 | !ifndef FOSSIL_ENABLE_MINIZ |
| 1468 | APPTARGETS = $(APPTARGETS) zlib |
| 1469 | !endif |
| @@ -1375,12 +1472,13 @@ | |
| 1472 | !ifdef FOSSIL_BUILD_SSL |
| 1473 | APPTARGETS = $(APPTARGETS) openssl |
| 1474 | !endif |
| 1475 | !endif |
| 1476 | |
| 1477 | $(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts |
| 1478 | cd $(OX) |
| 1479 | codecheck1$E $(SRC) |
| 1480 | link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts |
| 1481 | |
| 1482 | $(OX)\linkopts: $B\win\Makefile.msc} |
| 1483 | set redir {>} |
| 1484 | foreach s [lsort [concat $src $AdditionalObj]] { |
| @@ -1403,11 +1501,17 @@ | |
| 1501 | $(BCC) $** |
| 1502 | |
| 1503 | mkindex$E: $(SRCDIR)\mkindex.c |
| 1504 | $(BCC) $** |
| 1505 | |
| 1506 | mkbuiltin$E: $(SRCDIR)\mkbuiltin.c |
| 1507 | $(BCC) $** |
| 1508 | |
| 1509 | mkversion$E: $(SRCDIR)\mkversion.c |
| 1510 | $(BCC) $** |
| 1511 | |
| 1512 | codecheck1$E: $(SRCDIR)\codecheck1.c |
| 1513 | $(BCC) $** |
| 1514 | |
| 1515 | $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc |
| 1516 | $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c |
| 1517 | |
| @@ -1432,10 +1536,13 @@ | |
| 1536 | $(TCC) /Fo$@ /c $** |
| 1537 | |
| 1538 | page_index.h: mkindex$E $(SRC) |
| 1539 | $** > $@ |
| 1540 | |
| 1541 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1542 | $** > $@ |
| 1543 | |
| 1544 | clean: |
| 1545 | -del $(OX)\*.obj |
| 1546 | -del *.obj |
| 1547 | -del *_.c |
| 1548 | -del *.h |
| @@ -1455,10 +1562,14 @@ | |
| 1562 | -del mkindex$P |
| 1563 | -del makeheaders$E |
| 1564 | -del makeheaders$P |
| 1565 | -del mkversion$E |
| 1566 | -del mkversion$P |
| 1567 | -del codecheck1$E |
| 1568 | -del codecheck1$P |
| 1569 | -del mkbuiltin$E |
| 1570 | -del mkbuiltin$P |
| 1571 | |
| 1572 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 1573 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 1574 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 1575 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -1482,11 +1593,11 @@ | |
| 1593 | } |
| 1594 | |
| 1595 | writeln "fossil.res : \$B\\win\\fossil.rc" |
| 1596 | writeln "\t\$(RCC) /fo \$@ \$**\n" |
| 1597 | |
| 1598 | writeln "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h" |
| 1599 | writeln -nonewline "\tmakeheaders\$E " |
| 1600 | set i 0 |
| 1601 | foreach s [lsort $src] { |
| 1602 | if {$i > 0} { |
| 1603 | writeln " \\" |
| @@ -1592,11 +1703,11 @@ | |
| 1703 | RC=$(PellesCDir)\bin\porc.exe |
| 1704 | RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION) |
| 1705 | |
| 1706 | # define the special utilities files, needed to generate |
| 1707 | # the automatically generated source files |
| 1708 | UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe |
| 1709 | UTILS_OBJ=$(UTILS:.exe=.obj) |
| 1710 | UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) |
| 1711 | |
| 1712 | # define the SQLite files, which need special flags on compile |
| 1713 | SQLITESRC=sqlite3.c |
| @@ -1631,11 +1742,11 @@ | |
| 1742 | # main target file is the application |
| 1743 | APPLICATION=fossil.exe |
| 1744 | |
| 1745 | # define the standard make target |
| 1746 | .PHONY: default |
| 1747 | default: page_index.h builtin_data.h headers $(APPLICATION) |
| 1748 | |
| 1749 | # symbolic target to generate the source generate utils |
| 1750 | .PHONY: utils |
| 1751 | utils: $(UTILS) |
| 1752 | |
| @@ -1656,17 +1767,20 @@ | |
| 1767 | translate.exe $< >$@ |
| 1768 | |
| 1769 | # generate the index source, containing all web references,.. |
| 1770 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 1771 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 1772 | |
| 1773 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 1774 | mkbuiltin.exe $(EXTRA_FILES) >$@ |
| 1775 | |
| 1776 | # extracting version info from manifest |
| 1777 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 1778 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 1779 | |
| 1780 | # generate the simplified headers |
| 1781 | headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 1782 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 1783 | echo Done >$@ |
| 1784 | |
| 1785 | # compile C sources with relevant options |
| 1786 | |
| 1787 |
+26
-9
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -47,10 +47,11 @@ | ||
| 47 | 47 | /* |
| 48 | 48 | ** Flags for use with manifest_crosslink(). |
| 49 | 49 | */ |
| 50 | 50 | #define MC_NONE 0 /* default handling */ |
| 51 | 51 | #define MC_PERMIT_HOOKS 1 /* permit hooks to execute */ |
| 52 | +#define MC_NO_ERRORS 2 /* do not issue errors for a bad parse */ | |
| 52 | 53 | |
| 53 | 54 | /* |
| 54 | 55 | ** A single F-card within a manifest |
| 55 | 56 | */ |
| 56 | 57 | struct ManifestFile { |
| @@ -360,10 +361,11 @@ | ||
| 360 | 361 | char *z; |
| 361 | 362 | int n; |
| 362 | 363 | char *zUuid; |
| 363 | 364 | int sz = 0; |
| 364 | 365 | int isRepeat, hasSelfRefTag = 0; |
| 366 | + Blob bUuid = BLOB_INITIALIZER; | |
| 365 | 367 | static Bag seen; |
| 366 | 368 | const char *zErr = 0; |
| 367 | 369 | |
| 368 | 370 | if( rid==0 ){ |
| 369 | 371 | isRepeat = 1; |
| @@ -378,13 +380,13 @@ | ||
| 378 | 380 | ** if that is not the case for this artifact. |
| 379 | 381 | */ |
| 380 | 382 | if( !isRepeat ) g.parseCnt[0]++; |
| 381 | 383 | z = blob_materialize(pContent); |
| 382 | 384 | n = blob_size(pContent); |
| 383 | - if( n<=0 || z[n-1]!='\n' ){ | |
| 385 | + if( pErr && (n<=0 || z[n-1]!='\n') ){ | |
| 384 | 386 | blob_reset(pContent); |
| 385 | - blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length"); | |
| 387 | + blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1); | |
| 386 | 388 | return 0; |
| 387 | 389 | } |
| 388 | 390 | |
| 389 | 391 | /* Strip off the PGP signature if there is one. |
| 390 | 392 | */ |
| @@ -403,10 +405,15 @@ | ||
| 403 | 405 | if( verify_z_card(z, n)==2 ){ |
| 404 | 406 | blob_reset(pContent); |
| 405 | 407 | blob_appendf(pErr, "incorrect Z-card cksum"); |
| 406 | 408 | return 0; |
| 407 | 409 | } |
| 410 | + | |
| 411 | + /* Store the UUID (before modifying the blob) only for error | |
| 412 | + ** reporting purposes. | |
| 413 | + */ | |
| 414 | + sha1sum_blob(pContent, &bUuid); | |
| 408 | 415 | |
| 409 | 416 | /* Allocate a Manifest object to hold the parsed control artifact. |
| 410 | 417 | */ |
| 411 | 418 | p = fossil_malloc( sizeof(*p) ); |
| 412 | 419 | memset(p, 0, sizeof(*p)); |
| @@ -944,13 +951,18 @@ | ||
| 944 | 951 | if( !seenZ ) SYNTAX("missing Z-card on control"); |
| 945 | 952 | p->type = CFTYPE_CONTROL; |
| 946 | 953 | } |
| 947 | 954 | md5sum_init(); |
| 948 | 955 | if( !isRepeat ) g.parseCnt[p->type]++; |
| 956 | + blob_reset(&bUuid); | |
| 949 | 957 | return p; |
| 950 | 958 | |
| 951 | 959 | manifest_syntax_error: |
| 960 | + if(bUuid.nUsed){ | |
| 961 | + blob_appendf(pErr, "manifest [%.40s] ", blob_str(&bUuid)); | |
| 962 | + blob_reset(&bUuid); | |
| 963 | + } | |
| 952 | 964 | if( zErr ){ |
| 953 | 965 | blob_appendf(pErr, "line %d: %s", lineNo, zErr); |
| 954 | 966 | }else{ |
| 955 | 967 | blob_appendf(pErr, "unknown error on line %d", lineNo); |
| 956 | 968 | } |
| @@ -1589,11 +1601,11 @@ | ||
| 1589 | 1601 | once = 0; |
| 1590 | 1602 | zTitleExpr = db_get("ticket-title-expr", "title"); |
| 1591 | 1603 | zStatusColumn = db_get("ticket-status-column", "status"); |
| 1592 | 1604 | } |
| 1593 | 1605 | zTitle = db_text("unknown", |
| 1594 | - "SELECT %s FROM ticket WHERE tkt_uuid='%s'", | |
| 1606 | + "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q", | |
| 1595 | 1607 | zTitleExpr, pManifest->zTicketUuid |
| 1596 | 1608 | ); |
| 1597 | 1609 | if( !isNew ){ |
| 1598 | 1610 | for(i=0; i<pManifest->nField; i++){ |
| 1599 | 1611 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| @@ -1610,11 +1622,11 @@ | ||
| 1610 | 1622 | } |
| 1611 | 1623 | blob_appendf(&brief, "%h ticket [%s|%S].", |
| 1612 | 1624 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1613 | 1625 | }else{ |
| 1614 | 1626 | zNewStatus = db_text("unknown", |
| 1615 | - "SELECT %s FROM ticket WHERE tkt_uuid='%s'", | |
| 1627 | + "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q", | |
| 1616 | 1628 | zStatusColumn, pManifest->zTicketUuid |
| 1617 | 1629 | ); |
| 1618 | 1630 | blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with " |
| 1619 | 1631 | "%d other change%s", |
| 1620 | 1632 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| @@ -1733,23 +1745,29 @@ | ||
| 1733 | 1745 | |
| 1734 | 1746 | if( (p = manifest_cache_find(rid))!=0 ){ |
| 1735 | 1747 | blob_reset(pContent); |
| 1736 | 1748 | }else if( (p = manifest_parse(pContent, rid, 0))==0 ){ |
| 1737 | 1749 | assert( blob_is_reset(pContent) || pContent==0 ); |
| 1738 | - fossil_error(1, "syntax error in manifest"); | |
| 1750 | + if( (flags & MC_NO_ERRORS)==0 ){ | |
| 1751 | + fossil_error(1, "syntax error in manifest [%s]", | |
| 1752 | + db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid)); | |
| 1753 | + } | |
| 1739 | 1754 | return 0; |
| 1740 | 1755 | } |
| 1741 | 1756 | if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){ |
| 1742 | 1757 | manifest_destroy(p); |
| 1743 | 1758 | assert( blob_is_reset(pContent) ); |
| 1744 | - fossil_error(1, "no manifest"); | |
| 1759 | + if( (flags & MC_NO_ERRORS)==0 ) fossil_error(1, "no manifest"); | |
| 1745 | 1760 | return 0; |
| 1746 | 1761 | } |
| 1747 | 1762 | if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){ |
| 1748 | 1763 | manifest_destroy(p); |
| 1749 | 1764 | assert( blob_is_reset(pContent) ); |
| 1750 | - fossil_error(1, "cannot fetch baseline manifest"); | |
| 1765 | + if( (flags & MC_NO_ERRORS)==0 ){ | |
| 1766 | + fossil_error(1, "cannot fetch baseline for manifest [%s]", | |
| 1767 | + db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid)); | |
| 1768 | + } | |
| 1751 | 1769 | return 0; |
| 1752 | 1770 | } |
| 1753 | 1771 | db_begin_transaction(); |
| 1754 | 1772 | if( p->type==CFTYPE_MANIFEST ){ |
| 1755 | 1773 | if( permitHooks ){ |
| @@ -1894,11 +1912,10 @@ | ||
| 1894 | 1912 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1)," |
| 1895 | 1913 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)," |
| 1896 | 1914 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", |
| 1897 | 1915 | p->rDate, rid, p->zUser, zComment, |
| 1898 | 1916 | TAG_BGCOLOR, rid, |
| 1899 | - TAG_BGCOLOR, rid, | |
| 1900 | 1917 | TAG_USER, rid, |
| 1901 | 1918 | TAG_COMMENT, rid |
| 1902 | 1919 | ); |
| 1903 | 1920 | fossil_free(zComment); |
| 1904 | 1921 | } |
| @@ -2026,11 +2043,11 @@ | ||
| 2026 | 2043 | " Edit [%s|%S]:", |
| 2027 | 2044 | zTagUuid, zTagUuid); |
| 2028 | 2045 | branchMove = 0; |
| 2029 | 2046 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 2030 | 2047 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 2031 | - " AND blob.uuid='%s'", zTagUuid) ){ | |
| 2048 | + " AND blob.uuid=%Q", zTagUuid) ){ | |
| 2032 | 2049 | zScript = xfer_commit_code(); |
| 2033 | 2050 | zUuid = zTagUuid; |
| 2034 | 2051 | } |
| 2035 | 2052 | } |
| 2036 | 2053 | zName = p->aTag[i].zName; |
| 2037 | 2054 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -47,10 +47,11 @@ | |
| 47 | /* |
| 48 | ** Flags for use with manifest_crosslink(). |
| 49 | */ |
| 50 | #define MC_NONE 0 /* default handling */ |
| 51 | #define MC_PERMIT_HOOKS 1 /* permit hooks to execute */ |
| 52 | |
| 53 | /* |
| 54 | ** A single F-card within a manifest |
| 55 | */ |
| 56 | struct ManifestFile { |
| @@ -360,10 +361,11 @@ | |
| 360 | char *z; |
| 361 | int n; |
| 362 | char *zUuid; |
| 363 | int sz = 0; |
| 364 | int isRepeat, hasSelfRefTag = 0; |
| 365 | static Bag seen; |
| 366 | const char *zErr = 0; |
| 367 | |
| 368 | if( rid==0 ){ |
| 369 | isRepeat = 1; |
| @@ -378,13 +380,13 @@ | |
| 378 | ** if that is not the case for this artifact. |
| 379 | */ |
| 380 | if( !isRepeat ) g.parseCnt[0]++; |
| 381 | z = blob_materialize(pContent); |
| 382 | n = blob_size(pContent); |
| 383 | if( n<=0 || z[n-1]!='\n' ){ |
| 384 | blob_reset(pContent); |
| 385 | blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length"); |
| 386 | return 0; |
| 387 | } |
| 388 | |
| 389 | /* Strip off the PGP signature if there is one. |
| 390 | */ |
| @@ -403,10 +405,15 @@ | |
| 403 | if( verify_z_card(z, n)==2 ){ |
| 404 | blob_reset(pContent); |
| 405 | blob_appendf(pErr, "incorrect Z-card cksum"); |
| 406 | return 0; |
| 407 | } |
| 408 | |
| 409 | /* Allocate a Manifest object to hold the parsed control artifact. |
| 410 | */ |
| 411 | p = fossil_malloc( sizeof(*p) ); |
| 412 | memset(p, 0, sizeof(*p)); |
| @@ -944,13 +951,18 @@ | |
| 944 | if( !seenZ ) SYNTAX("missing Z-card on control"); |
| 945 | p->type = CFTYPE_CONTROL; |
| 946 | } |
| 947 | md5sum_init(); |
| 948 | if( !isRepeat ) g.parseCnt[p->type]++; |
| 949 | return p; |
| 950 | |
| 951 | manifest_syntax_error: |
| 952 | if( zErr ){ |
| 953 | blob_appendf(pErr, "line %d: %s", lineNo, zErr); |
| 954 | }else{ |
| 955 | blob_appendf(pErr, "unknown error on line %d", lineNo); |
| 956 | } |
| @@ -1589,11 +1601,11 @@ | |
| 1589 | once = 0; |
| 1590 | zTitleExpr = db_get("ticket-title-expr", "title"); |
| 1591 | zStatusColumn = db_get("ticket-status-column", "status"); |
| 1592 | } |
| 1593 | zTitle = db_text("unknown", |
| 1594 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1595 | zTitleExpr, pManifest->zTicketUuid |
| 1596 | ); |
| 1597 | if( !isNew ){ |
| 1598 | for(i=0; i<pManifest->nField; i++){ |
| 1599 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| @@ -1610,11 +1622,11 @@ | |
| 1610 | } |
| 1611 | blob_appendf(&brief, "%h ticket [%s|%S].", |
| 1612 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1613 | }else{ |
| 1614 | zNewStatus = db_text("unknown", |
| 1615 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1616 | zStatusColumn, pManifest->zTicketUuid |
| 1617 | ); |
| 1618 | blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with " |
| 1619 | "%d other change%s", |
| 1620 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| @@ -1733,23 +1745,29 @@ | |
| 1733 | |
| 1734 | if( (p = manifest_cache_find(rid))!=0 ){ |
| 1735 | blob_reset(pContent); |
| 1736 | }else if( (p = manifest_parse(pContent, rid, 0))==0 ){ |
| 1737 | assert( blob_is_reset(pContent) || pContent==0 ); |
| 1738 | fossil_error(1, "syntax error in manifest"); |
| 1739 | return 0; |
| 1740 | } |
| 1741 | if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){ |
| 1742 | manifest_destroy(p); |
| 1743 | assert( blob_is_reset(pContent) ); |
| 1744 | fossil_error(1, "no manifest"); |
| 1745 | return 0; |
| 1746 | } |
| 1747 | if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){ |
| 1748 | manifest_destroy(p); |
| 1749 | assert( blob_is_reset(pContent) ); |
| 1750 | fossil_error(1, "cannot fetch baseline manifest"); |
| 1751 | return 0; |
| 1752 | } |
| 1753 | db_begin_transaction(); |
| 1754 | if( p->type==CFTYPE_MANIFEST ){ |
| 1755 | if( permitHooks ){ |
| @@ -1894,11 +1912,10 @@ | |
| 1894 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1)," |
| 1895 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)," |
| 1896 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", |
| 1897 | p->rDate, rid, p->zUser, zComment, |
| 1898 | TAG_BGCOLOR, rid, |
| 1899 | TAG_BGCOLOR, rid, |
| 1900 | TAG_USER, rid, |
| 1901 | TAG_COMMENT, rid |
| 1902 | ); |
| 1903 | fossil_free(zComment); |
| 1904 | } |
| @@ -2026,11 +2043,11 @@ | |
| 2026 | " Edit [%s|%S]:", |
| 2027 | zTagUuid, zTagUuid); |
| 2028 | branchMove = 0; |
| 2029 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 2030 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 2031 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 2032 | zScript = xfer_commit_code(); |
| 2033 | zUuid = zTagUuid; |
| 2034 | } |
| 2035 | } |
| 2036 | zName = p->aTag[i].zName; |
| 2037 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -47,10 +47,11 @@ | |
| 47 | /* |
| 48 | ** Flags for use with manifest_crosslink(). |
| 49 | */ |
| 50 | #define MC_NONE 0 /* default handling */ |
| 51 | #define MC_PERMIT_HOOKS 1 /* permit hooks to execute */ |
| 52 | #define MC_NO_ERRORS 2 /* do not issue errors for a bad parse */ |
| 53 | |
| 54 | /* |
| 55 | ** A single F-card within a manifest |
| 56 | */ |
| 57 | struct ManifestFile { |
| @@ -360,10 +361,11 @@ | |
| 361 | char *z; |
| 362 | int n; |
| 363 | char *zUuid; |
| 364 | int sz = 0; |
| 365 | int isRepeat, hasSelfRefTag = 0; |
| 366 | Blob bUuid = BLOB_INITIALIZER; |
| 367 | static Bag seen; |
| 368 | const char *zErr = 0; |
| 369 | |
| 370 | if( rid==0 ){ |
| 371 | isRepeat = 1; |
| @@ -378,13 +380,13 @@ | |
| 380 | ** if that is not the case for this artifact. |
| 381 | */ |
| 382 | if( !isRepeat ) g.parseCnt[0]++; |
| 383 | z = blob_materialize(pContent); |
| 384 | n = blob_size(pContent); |
| 385 | if( pErr && (n<=0 || z[n-1]!='\n') ){ |
| 386 | blob_reset(pContent); |
| 387 | blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1); |
| 388 | return 0; |
| 389 | } |
| 390 | |
| 391 | /* Strip off the PGP signature if there is one. |
| 392 | */ |
| @@ -403,10 +405,15 @@ | |
| 405 | if( verify_z_card(z, n)==2 ){ |
| 406 | blob_reset(pContent); |
| 407 | blob_appendf(pErr, "incorrect Z-card cksum"); |
| 408 | return 0; |
| 409 | } |
| 410 | |
| 411 | /* Store the UUID (before modifying the blob) only for error |
| 412 | ** reporting purposes. |
| 413 | */ |
| 414 | sha1sum_blob(pContent, &bUuid); |
| 415 | |
| 416 | /* Allocate a Manifest object to hold the parsed control artifact. |
| 417 | */ |
| 418 | p = fossil_malloc( sizeof(*p) ); |
| 419 | memset(p, 0, sizeof(*p)); |
| @@ -944,13 +951,18 @@ | |
| 951 | if( !seenZ ) SYNTAX("missing Z-card on control"); |
| 952 | p->type = CFTYPE_CONTROL; |
| 953 | } |
| 954 | md5sum_init(); |
| 955 | if( !isRepeat ) g.parseCnt[p->type]++; |
| 956 | blob_reset(&bUuid); |
| 957 | return p; |
| 958 | |
| 959 | manifest_syntax_error: |
| 960 | if(bUuid.nUsed){ |
| 961 | blob_appendf(pErr, "manifest [%.40s] ", blob_str(&bUuid)); |
| 962 | blob_reset(&bUuid); |
| 963 | } |
| 964 | if( zErr ){ |
| 965 | blob_appendf(pErr, "line %d: %s", lineNo, zErr); |
| 966 | }else{ |
| 967 | blob_appendf(pErr, "unknown error on line %d", lineNo); |
| 968 | } |
| @@ -1589,11 +1601,11 @@ | |
| 1601 | once = 0; |
| 1602 | zTitleExpr = db_get("ticket-title-expr", "title"); |
| 1603 | zStatusColumn = db_get("ticket-status-column", "status"); |
| 1604 | } |
| 1605 | zTitle = db_text("unknown", |
| 1606 | "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q", |
| 1607 | zTitleExpr, pManifest->zTicketUuid |
| 1608 | ); |
| 1609 | if( !isNew ){ |
| 1610 | for(i=0; i<pManifest->nField; i++){ |
| 1611 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| @@ -1610,11 +1622,11 @@ | |
| 1622 | } |
| 1623 | blob_appendf(&brief, "%h ticket [%s|%S].", |
| 1624 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1625 | }else{ |
| 1626 | zNewStatus = db_text("unknown", |
| 1627 | "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q", |
| 1628 | zStatusColumn, pManifest->zTicketUuid |
| 1629 | ); |
| 1630 | blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with " |
| 1631 | "%d other change%s", |
| 1632 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| @@ -1733,23 +1745,29 @@ | |
| 1745 | |
| 1746 | if( (p = manifest_cache_find(rid))!=0 ){ |
| 1747 | blob_reset(pContent); |
| 1748 | }else if( (p = manifest_parse(pContent, rid, 0))==0 ){ |
| 1749 | assert( blob_is_reset(pContent) || pContent==0 ); |
| 1750 | if( (flags & MC_NO_ERRORS)==0 ){ |
| 1751 | fossil_error(1, "syntax error in manifest [%s]", |
| 1752 | db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid)); |
| 1753 | } |
| 1754 | return 0; |
| 1755 | } |
| 1756 | if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){ |
| 1757 | manifest_destroy(p); |
| 1758 | assert( blob_is_reset(pContent) ); |
| 1759 | if( (flags & MC_NO_ERRORS)==0 ) fossil_error(1, "no manifest"); |
| 1760 | return 0; |
| 1761 | } |
| 1762 | if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){ |
| 1763 | manifest_destroy(p); |
| 1764 | assert( blob_is_reset(pContent) ); |
| 1765 | if( (flags & MC_NO_ERRORS)==0 ){ |
| 1766 | fossil_error(1, "cannot fetch baseline for manifest [%s]", |
| 1767 | db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid)); |
| 1768 | } |
| 1769 | return 0; |
| 1770 | } |
| 1771 | db_begin_transaction(); |
| 1772 | if( p->type==CFTYPE_MANIFEST ){ |
| 1773 | if( permitHooks ){ |
| @@ -1894,11 +1912,10 @@ | |
| 1912 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1)," |
| 1913 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)," |
| 1914 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", |
| 1915 | p->rDate, rid, p->zUser, zComment, |
| 1916 | TAG_BGCOLOR, rid, |
| 1917 | TAG_USER, rid, |
| 1918 | TAG_COMMENT, rid |
| 1919 | ); |
| 1920 | fossil_free(zComment); |
| 1921 | } |
| @@ -2026,11 +2043,11 @@ | |
| 2043 | " Edit [%s|%S]:", |
| 2044 | zTagUuid, zTagUuid); |
| 2045 | branchMove = 0; |
| 2046 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 2047 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 2048 | " AND blob.uuid=%Q", zTagUuid) ){ |
| 2049 | zScript = xfer_commit_code(); |
| 2050 | zUuid = zTagUuid; |
| 2051 | } |
| 2052 | } |
| 2053 | zName = p->aTag[i].zName; |
| 2054 |
+4
-4
| --- src/merge3.c | ||
| +++ src/merge3.c | ||
| @@ -268,17 +268,17 @@ | ||
| 268 | 268 | nConflict++; |
| 269 | 269 | while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){ |
| 270 | 270 | sz++; |
| 271 | 271 | } |
| 272 | 272 | DEBUG( printf("CONFLICT %d\n", sz); ) |
| 273 | - blob_appendf(pOut, mergeMarker[0]); | |
| 273 | + blob_append(pOut, mergeMarker[0], -1); | |
| 274 | 274 | i1 = output_one_side(pOut, pV1, aC1, i1, sz); |
| 275 | - blob_appendf(pOut, mergeMarker[1]); | |
| 275 | + blob_append(pOut, mergeMarker[1], -1); | |
| 276 | 276 | blob_copy_lines(pOut, pPivot, sz); |
| 277 | - blob_appendf(pOut, mergeMarker[2]); | |
| 277 | + blob_append(pOut, mergeMarker[2], -1); | |
| 278 | 278 | i2 = output_one_side(pOut, pV2, aC2, i2, sz); |
| 279 | - blob_appendf(pOut, mergeMarker[3]); | |
| 279 | + blob_append(pOut, mergeMarker[3], -1); | |
| 280 | 280 | } |
| 281 | 281 | |
| 282 | 282 | /* If we are finished with an edit triple, advance to the next |
| 283 | 283 | ** triple. |
| 284 | 284 | */ |
| 285 | 285 | |
| 286 | 286 | ADDED src/mkbuiltin.c |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -268,17 +268,17 @@ | |
| 268 | nConflict++; |
| 269 | while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){ |
| 270 | sz++; |
| 271 | } |
| 272 | DEBUG( printf("CONFLICT %d\n", sz); ) |
| 273 | blob_appendf(pOut, mergeMarker[0]); |
| 274 | i1 = output_one_side(pOut, pV1, aC1, i1, sz); |
| 275 | blob_appendf(pOut, mergeMarker[1]); |
| 276 | blob_copy_lines(pOut, pPivot, sz); |
| 277 | blob_appendf(pOut, mergeMarker[2]); |
| 278 | i2 = output_one_side(pOut, pV2, aC2, i2, sz); |
| 279 | blob_appendf(pOut, mergeMarker[3]); |
| 280 | } |
| 281 | |
| 282 | /* If we are finished with an edit triple, advance to the next |
| 283 | ** triple. |
| 284 | */ |
| 285 | |
| 286 | DDED src/mkbuiltin.c |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -268,17 +268,17 @@ | |
| 268 | nConflict++; |
| 269 | while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){ |
| 270 | sz++; |
| 271 | } |
| 272 | DEBUG( printf("CONFLICT %d\n", sz); ) |
| 273 | blob_append(pOut, mergeMarker[0], -1); |
| 274 | i1 = output_one_side(pOut, pV1, aC1, i1, sz); |
| 275 | blob_append(pOut, mergeMarker[1], -1); |
| 276 | blob_copy_lines(pOut, pPivot, sz); |
| 277 | blob_append(pOut, mergeMarker[2], -1); |
| 278 | i2 = output_one_side(pOut, pV2, aC2, i2, sz); |
| 279 | blob_append(pOut, mergeMarker[3], -1); |
| 280 | } |
| 281 | |
| 282 | /* If we are finished with an edit triple, advance to the next |
| 283 | ** triple. |
| 284 | */ |
| 285 | |
| 286 | DDED src/mkbuiltin.c |
+61
| --- a/src/mkbuiltin.c | ||
| +++ b/src/mkbuiltin.c | ||
| @@ -0,0 +1,61 @@ | ||
| 1 | +/* | |
| 2 | +** Con = argc-1/* | |
| 3 | + /* | |
| 4 | +** Con = argc-1/* | |
| 5 | +** Const/* | |
| 6 | +** Copyright (st/* | |
| 7 | +** Copyright (c) 2014 D. Richard Hipp | |
| 8 | +** | |
| 9 | +** This program is free software; you can redistribute it and/or | |
| 10 | +** modify it under the terms of the Simplif Copvoid *a, const v*)a; | |
| 11 | + Resource *pB = esource*)b; | |
| 12 | + return strcmp(pA->zName, pB->zName) nRes = argc - 1; | |
| 13 | + aRes = malloc( nRes*sizeof(aRes[0]) ); | |
| 14 | + if( aRes==0t (c) 2014 D. Richard Hip/return 1; | |
| 15 | + } | |
| 16 | +aRes[ireturn nErr; | |
| 17 | +} | |
| 18 | +const char *zTail; | |
| 19 | + int nSlash = 0; | |
| 20 | + zTail = z; | |
| 21 | + while( z && z[0] ){ | |
| 22 | + if( z[0]=='/' || z[0]=='\\' ){ | |
| 23 | + nSlash++; | |
| 24 | + if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1]; | |
| 25 | + } | |
| 26 | + z++; | |
| 27 | + }zTail); | |
| 28 | + for(j=Tail;/* | |
| 29 | +** Con = argc-1/* | |
| 30 | +** Const/* | |
| 31 | +** Copyright (st/* | |
| 32 | +** Copyright (c) 20gc-1/* | |
| 33 | +** Const** Const/* | |
| 34 | +** Copyright (st/* | |
| 35 | +** Copyright (c) 2014 D. Richard Hipp | |
| 36 | +** | |
| 37 | +** This program is free software; you can redistribute it and/or | |
| 38 | +** modify it under the terms of the Simplif Copvoid *a, const v*)a; | |
| 39 | + Resource *pB = esource*)b; | |
| 40 | + return strcmp(pA->zName, pB->zName) nRes = argc - 1; | |
| 41 | + aRes = malloc( nRes*sizeof(aRes[0]) ); | |
| 42 | + if( aRes==0t (c) 2014 D. Richard Hip/return 1; | |
| 43 | + } | |
| 44 | +aRes[ireturn nErr; | |
| 45 | +} | |
| 46 | +const char *zTail; | |
| 47 | + int nSlash = 0; | |
| 48 | + zTail = z; | |
| 49 | + while( z && z[0] ){ | |
| 50 | + if( z[0]=='/' || z[0]=='\\' ){ | |
| 51 | + nSlash++; | |
| 52 | + if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1]; | |
| 53 | + } | |
| 54 | + z++; | |
| 55 | + }zTail); | |
| 56 | + for(j=Tail;/* | |
| 57 | +** Con = argc-1/* | |
| 58 | +** Const/* | |
| 59 | +** Copyright (st/* | |
| 60 | +** Copyright (c) 20gc-1/* | |
| 61 | +** Const |
| --- a/src/mkbuiltin.c | |
| +++ b/src/mkbuiltin.c | |
| @@ -0,0 +1,61 @@ | |
| --- a/src/mkbuiltin.c | |
| +++ b/src/mkbuiltin.c | |
| @@ -0,0 +1,61 @@ | |
| 1 | /* |
| 2 | ** Con = argc-1/* |
| 3 | /* |
| 4 | ** Con = argc-1/* |
| 5 | ** Const/* |
| 6 | ** Copyright (st/* |
| 7 | ** Copyright (c) 2014 D. Richard Hipp |
| 8 | ** |
| 9 | ** This program is free software; you can redistribute it and/or |
| 10 | ** modify it under the terms of the Simplif Copvoid *a, const v*)a; |
| 11 | Resource *pB = esource*)b; |
| 12 | return strcmp(pA->zName, pB->zName) nRes = argc - 1; |
| 13 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 14 | if( aRes==0t (c) 2014 D. Richard Hip/return 1; |
| 15 | } |
| 16 | aRes[ireturn nErr; |
| 17 | } |
| 18 | const char *zTail; |
| 19 | int nSlash = 0; |
| 20 | zTail = z; |
| 21 | while( z && z[0] ){ |
| 22 | if( z[0]=='/' || z[0]=='\\' ){ |
| 23 | nSlash++; |
| 24 | if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1]; |
| 25 | } |
| 26 | z++; |
| 27 | }zTail); |
| 28 | for(j=Tail;/* |
| 29 | ** Con = argc-1/* |
| 30 | ** Const/* |
| 31 | ** Copyright (st/* |
| 32 | ** Copyright (c) 20gc-1/* |
| 33 | ** Const** Const/* |
| 34 | ** Copyright (st/* |
| 35 | ** Copyright (c) 2014 D. Richard Hipp |
| 36 | ** |
| 37 | ** This program is free software; you can redistribute it and/or |
| 38 | ** modify it under the terms of the Simplif Copvoid *a, const v*)a; |
| 39 | Resource *pB = esource*)b; |
| 40 | return strcmp(pA->zName, pB->zName) nRes = argc - 1; |
| 41 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 42 | if( aRes==0t (c) 2014 D. Richard Hip/return 1; |
| 43 | } |
| 44 | aRes[ireturn nErr; |
| 45 | } |
| 46 | const char *zTail; |
| 47 | int nSlash = 0; |
| 48 | zTail = z; |
| 49 | while( z && z[0] ){ |
| 50 | if( z[0]=='/' || z[0]=='\\' ){ |
| 51 | nSlash++; |
| 52 | if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1]; |
| 53 | } |
| 54 | z++; |
| 55 | }zTail); |
| 56 | for(j=Tail;/* |
| 57 | ** Con = argc-1/* |
| 58 | ** Const/* |
| 59 | ** Copyright (st/* |
| 60 | ** Copyright (c) 20gc-1/* |
| 61 | ** Const |
+3
-3
| --- src/moderate.c | ||
| +++ src/moderate.c | ||
| @@ -73,11 +73,11 @@ | ||
| 73 | 73 | "tagxref", "srcid", |
| 74 | 74 | "tagxref", "rid", |
| 75 | 75 | }; |
| 76 | 76 | int i; |
| 77 | 77 | for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){ |
| 78 | - if( db_exists("SELECT 1 FROM %s WHERE %s=%d", | |
| 78 | + if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d", | |
| 79 | 79 | aTabField[i], aTabField[i+1], rid) ) return 1; |
| 80 | 80 | } |
| 81 | 81 | return 0; |
| 82 | 82 | } |
| 83 | 83 | |
| @@ -152,15 +152,15 @@ | ||
| 152 | 152 | if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; } |
| 153 | 153 | style_header("Pending Moderation Requests"); |
| 154 | 154 | @ <h2>All Pending Moderation Requests</h2> |
| 155 | 155 | if( moderation_table_exists() ){ |
| 156 | 156 | blob_init(&sql, timeline_query_for_www(), -1); |
| 157 | - blob_appendf(&sql, | |
| 157 | + blob_append_sql(&sql, | |
| 158 | 158 | " AND event.objid IN (SELECT objid FROM modreq)" |
| 159 | 159 | " ORDER BY event.mtime DESC" |
| 160 | 160 | ); |
| 161 | - db_prepare(&q, blob_str(&sql)); | |
| 161 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 162 | 162 | www_print_timeline(&q, 0, 0, 0, 0); |
| 163 | 163 | db_finalize(&q); |
| 164 | 164 | } |
| 165 | 165 | style_footer(); |
| 166 | 166 | } |
| 167 | 167 |
| --- src/moderate.c | |
| +++ src/moderate.c | |
| @@ -73,11 +73,11 @@ | |
| 73 | "tagxref", "srcid", |
| 74 | "tagxref", "rid", |
| 75 | }; |
| 76 | int i; |
| 77 | for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){ |
| 78 | if( db_exists("SELECT 1 FROM %s WHERE %s=%d", |
| 79 | aTabField[i], aTabField[i+1], rid) ) return 1; |
| 80 | } |
| 81 | return 0; |
| 82 | } |
| 83 | |
| @@ -152,15 +152,15 @@ | |
| 152 | if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; } |
| 153 | style_header("Pending Moderation Requests"); |
| 154 | @ <h2>All Pending Moderation Requests</h2> |
| 155 | if( moderation_table_exists() ){ |
| 156 | blob_init(&sql, timeline_query_for_www(), -1); |
| 157 | blob_appendf(&sql, |
| 158 | " AND event.objid IN (SELECT objid FROM modreq)" |
| 159 | " ORDER BY event.mtime DESC" |
| 160 | ); |
| 161 | db_prepare(&q, blob_str(&sql)); |
| 162 | www_print_timeline(&q, 0, 0, 0, 0); |
| 163 | db_finalize(&q); |
| 164 | } |
| 165 | style_footer(); |
| 166 | } |
| 167 |
| --- src/moderate.c | |
| +++ src/moderate.c | |
| @@ -73,11 +73,11 @@ | |
| 73 | "tagxref", "srcid", |
| 74 | "tagxref", "rid", |
| 75 | }; |
| 76 | int i; |
| 77 | for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){ |
| 78 | if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d", |
| 79 | aTabField[i], aTabField[i+1], rid) ) return 1; |
| 80 | } |
| 81 | return 0; |
| 82 | } |
| 83 | |
| @@ -152,15 +152,15 @@ | |
| 152 | if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; } |
| 153 | style_header("Pending Moderation Requests"); |
| 154 | @ <h2>All Pending Moderation Requests</h2> |
| 155 | if( moderation_table_exists() ){ |
| 156 | blob_init(&sql, timeline_query_for_www(), -1); |
| 157 | blob_append_sql(&sql, |
| 158 | " AND event.objid IN (SELECT objid FROM modreq)" |
| 159 | " ORDER BY event.mtime DESC" |
| 160 | ); |
| 161 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 162 | www_print_timeline(&q, 0, 0, 0, 0); |
| 163 | db_finalize(&q); |
| 164 | } |
| 165 | style_footer(); |
| 166 | } |
| 167 |
+4
-4
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -216,16 +216,16 @@ | ||
| 216 | 216 | char zUuid[UUID_SIZE+1]; |
| 217 | 217 | memcpy(zUuid, zTag, nTag+1); |
| 218 | 218 | canonical16(zUuid, nTag); |
| 219 | 219 | rid = 0; |
| 220 | 220 | if( zType[0]=='*' ){ |
| 221 | - db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid); | |
| 221 | + db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid); | |
| 222 | 222 | }else{ |
| 223 | 223 | db_prepare(&q, |
| 224 | 224 | "SELECT blob.rid" |
| 225 | 225 | " FROM blob, event" |
| 226 | - " WHERE blob.uuid GLOB '%s*'" | |
| 226 | + " WHERE blob.uuid GLOB '%q*'" | |
| 227 | 227 | " AND event.objid=blob.rid" |
| 228 | 228 | " AND event.type GLOB '%q'", |
| 229 | 229 | zUuid, zType |
| 230 | 230 | ); |
| 231 | 231 | } |
| @@ -259,11 +259,11 @@ | ||
| 259 | 259 | }else{ |
| 260 | 260 | rid = db_int(0, |
| 261 | 261 | "SELECT event.objid" |
| 262 | 262 | " FROM event" |
| 263 | 263 | " WHERE event.objid=%s" |
| 264 | - " AND event.type GLOB '%q'", zTag, zType); | |
| 264 | + " AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType); | |
| 265 | 265 | } |
| 266 | 266 | } |
| 267 | 267 | } |
| 268 | 268 | return rid; |
| 269 | 269 | } |
| @@ -554,11 +554,11 @@ | ||
| 554 | 554 | "SELECT tagname" |
| 555 | 555 | " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" |
| 556 | 556 | " WHERE tagxref.rid=%d" |
| 557 | 557 | " AND tag.tagid IN (5,6,7,9)" |
| 558 | 558 | " ORDER BY 1", |
| 559 | - rid, rid | |
| 559 | + rid | |
| 560 | 560 | ); |
| 561 | 561 | cnt = 0; |
| 562 | 562 | while( db_step(&q)==SQLITE_ROW ){ |
| 563 | 563 | const char *zPrefix = cnt++ ? ", " : "raw-tags: "; |
| 564 | 564 | fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 565 | 565 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -216,16 +216,16 @@ | |
| 216 | char zUuid[UUID_SIZE+1]; |
| 217 | memcpy(zUuid, zTag, nTag+1); |
| 218 | canonical16(zUuid, nTag); |
| 219 | rid = 0; |
| 220 | if( zType[0]=='*' ){ |
| 221 | db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid); |
| 222 | }else{ |
| 223 | db_prepare(&q, |
| 224 | "SELECT blob.rid" |
| 225 | " FROM blob, event" |
| 226 | " WHERE blob.uuid GLOB '%s*'" |
| 227 | " AND event.objid=blob.rid" |
| 228 | " AND event.type GLOB '%q'", |
| 229 | zUuid, zType |
| 230 | ); |
| 231 | } |
| @@ -259,11 +259,11 @@ | |
| 259 | }else{ |
| 260 | rid = db_int(0, |
| 261 | "SELECT event.objid" |
| 262 | " FROM event" |
| 263 | " WHERE event.objid=%s" |
| 264 | " AND event.type GLOB '%q'", zTag, zType); |
| 265 | } |
| 266 | } |
| 267 | } |
| 268 | return rid; |
| 269 | } |
| @@ -554,11 +554,11 @@ | |
| 554 | "SELECT tagname" |
| 555 | " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" |
| 556 | " WHERE tagxref.rid=%d" |
| 557 | " AND tag.tagid IN (5,6,7,9)" |
| 558 | " ORDER BY 1", |
| 559 | rid, rid |
| 560 | ); |
| 561 | cnt = 0; |
| 562 | while( db_step(&q)==SQLITE_ROW ){ |
| 563 | const char *zPrefix = cnt++ ? ", " : "raw-tags: "; |
| 564 | fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 565 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -216,16 +216,16 @@ | |
| 216 | char zUuid[UUID_SIZE+1]; |
| 217 | memcpy(zUuid, zTag, nTag+1); |
| 218 | canonical16(zUuid, nTag); |
| 219 | rid = 0; |
| 220 | if( zType[0]=='*' ){ |
| 221 | db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid); |
| 222 | }else{ |
| 223 | db_prepare(&q, |
| 224 | "SELECT blob.rid" |
| 225 | " FROM blob, event" |
| 226 | " WHERE blob.uuid GLOB '%q*'" |
| 227 | " AND event.objid=blob.rid" |
| 228 | " AND event.type GLOB '%q'", |
| 229 | zUuid, zType |
| 230 | ); |
| 231 | } |
| @@ -259,11 +259,11 @@ | |
| 259 | }else{ |
| 260 | rid = db_int(0, |
| 261 | "SELECT event.objid" |
| 262 | " FROM event" |
| 263 | " WHERE event.objid=%s" |
| 264 | " AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType); |
| 265 | } |
| 266 | } |
| 267 | } |
| 268 | return rid; |
| 269 | } |
| @@ -554,11 +554,11 @@ | |
| 554 | "SELECT tagname" |
| 555 | " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" |
| 556 | " WHERE tagxref.rid=%d" |
| 557 | " AND tag.tagid IN (5,6,7,9)" |
| 558 | " ORDER BY 1", |
| 559 | rid |
| 560 | ); |
| 561 | cnt = 0; |
| 562 | while( db_step(&q)==SQLITE_ROW ){ |
| 563 | const char *zPrefix = cnt++ ? ", " : "raw-tags: "; |
| 564 | fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 565 |
+10
-10
| --- src/path.c | ||
| +++ src/path.c | ||
| @@ -112,11 +112,11 @@ | ||
| 112 | 112 | ** Compute the shortest path from iFrom to iTo |
| 113 | 113 | ** |
| 114 | 114 | ** If directOnly is true, then use only the "primary" links from parent to |
| 115 | 115 | ** child. In other words, ignore merges. |
| 116 | 116 | ** |
| 117 | -** Return a pointer to the beginning of the path (the iFrom node). | |
| 117 | +** Return a pointer to the beginning of the path (the iFrom node). | |
| 118 | 118 | ** Elements of the path can be traversed by following the PathNode.u.pTo |
| 119 | 119 | ** pointer chain. |
| 120 | 120 | ** |
| 121 | 121 | ** Return NULL if no path is found. |
| 122 | 122 | */ |
| @@ -135,25 +135,25 @@ | ||
| 135 | 135 | if( iTo==iFrom ){ |
| 136 | 136 | path.pEnd = path.pStart; |
| 137 | 137 | return path.pStart; |
| 138 | 138 | } |
| 139 | 139 | if( oneWayOnly && directOnly ){ |
| 140 | - db_prepare(&s, | |
| 140 | + db_prepare(&s, | |
| 141 | 141 | "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim" |
| 142 | 142 | ); |
| 143 | 143 | }else if( oneWayOnly ){ |
| 144 | - db_prepare(&s, | |
| 144 | + db_prepare(&s, | |
| 145 | 145 | "SELECT cid, 1 FROM plink WHERE pid=:pid " |
| 146 | 146 | ); |
| 147 | 147 | }else if( directOnly ){ |
| 148 | - db_prepare(&s, | |
| 148 | + db_prepare(&s, | |
| 149 | 149 | "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim " |
| 150 | 150 | "UNION ALL " |
| 151 | 151 | "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim" |
| 152 | 152 | ); |
| 153 | 153 | }else{ |
| 154 | - db_prepare(&s, | |
| 154 | + db_prepare(&s, | |
| 155 | 155 | "SELECT cid, 1 FROM plink WHERE pid=:pid " |
| 156 | 156 | "UNION ALL " |
| 157 | 157 | "SELECT pid, 0 FROM plink WHERE cid=:pid" |
| 158 | 158 | ); |
| 159 | 159 | } |
| @@ -230,11 +230,11 @@ | ||
| 230 | 230 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 231 | 231 | p->rid, p->rid); |
| 232 | 232 | fossil_print("%4d: %5d %s", n, p->rid, z); |
| 233 | 233 | fossil_free(z); |
| 234 | 234 | if( p->u.pTo ){ |
| 235 | - fossil_print(" is a %s of\n", | |
| 235 | + fossil_print(" is a %s of\n", | |
| 236 | 236 | p->u.pTo->fromIsParent ? "parent" : "child"); |
| 237 | 237 | }else{ |
| 238 | 238 | fossil_print("\n"); |
| 239 | 239 | } |
| 240 | 240 | } |
| @@ -353,11 +353,11 @@ | ||
| 353 | 353 | /* |
| 354 | 354 | ** Compute all file name changes that occur going from checkin iFrom |
| 355 | 355 | ** to checkin iTo. |
| 356 | 356 | ** |
| 357 | 357 | ** The number of name changes is written into *pnChng. For each name |
| 358 | -** change, two integers are allocated for *piChng. The first is the | |
| 358 | +** change, two integers are allocated for *piChng. The first is the | |
| 359 | 359 | ** filename.fnid for the original name as seen in check-in iFrom and |
| 360 | 360 | ** the second is for new name as it is used in check-in iTo. |
| 361 | 361 | ** |
| 362 | 362 | ** Space to hold *piChng is obtained from fossil_malloc() and should |
| 363 | 363 | ** be released by the caller. |
| @@ -516,11 +516,11 @@ | ||
| 516 | 516 | g.argc -= 2; |
| 517 | 517 | } |
| 518 | 518 | } |
| 519 | 519 | |
| 520 | 520 | /* Query to extract all rename operations */ |
| 521 | -static const char zRenameQuery[] = | |
| 521 | +static const char zRenameQuery[] = | |
| 522 | 522 | @ SELECT |
| 523 | 523 | @ datetime(event.mtime), |
| 524 | 524 | @ F.name AS old_name, |
| 525 | 525 | @ T.name AS new_name, |
| 526 | 526 | @ blob.uuid |
| @@ -531,11 +531,11 @@ | ||
| 531 | 531 | @ AND event.objid=mlink.mid |
| 532 | 532 | @ AND event.type='ci' |
| 533 | 533 | @ AND blob.rid=mlink.mid |
| 534 | 534 | @ ORDER BY 1 DESC, 2; |
| 535 | 535 | ; |
| 536 | - | |
| 536 | + | |
| 537 | 537 | /* |
| 538 | 538 | ** WEBPAGE: test-rename-list |
| 539 | 539 | ** |
| 540 | 540 | ** Print a list of all file rename operations throughout history. |
| 541 | 541 | ** This page is intended for for testing purposes only and may change |
| @@ -551,11 +551,11 @@ | ||
| 551 | 551 | @ <table border="1" width="100%%"> |
| 552 | 552 | @ <tr><th>Date & Time</th> |
| 553 | 553 | @ <th>Old Name</th> |
| 554 | 554 | @ <th>New Name</th> |
| 555 | 555 | @ <th>Check-in</th></tr> |
| 556 | - db_prepare(&q, zRenameQuery); | |
| 556 | + db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/); | |
| 557 | 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | 558 | const char *zDate = db_column_text(&q, 0); |
| 559 | 559 | const char *zOld = db_column_text(&q, 1); |
| 560 | 560 | const char *zNew = db_column_text(&q, 2); |
| 561 | 561 | const char *zUuid = db_column_text(&q, 3); |
| 562 | 562 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -112,11 +112,11 @@ | |
| 112 | ** Compute the shortest path from iFrom to iTo |
| 113 | ** |
| 114 | ** If directOnly is true, then use only the "primary" links from parent to |
| 115 | ** child. In other words, ignore merges. |
| 116 | ** |
| 117 | ** Return a pointer to the beginning of the path (the iFrom node). |
| 118 | ** Elements of the path can be traversed by following the PathNode.u.pTo |
| 119 | ** pointer chain. |
| 120 | ** |
| 121 | ** Return NULL if no path is found. |
| 122 | */ |
| @@ -135,25 +135,25 @@ | |
| 135 | if( iTo==iFrom ){ |
| 136 | path.pEnd = path.pStart; |
| 137 | return path.pStart; |
| 138 | } |
| 139 | if( oneWayOnly && directOnly ){ |
| 140 | db_prepare(&s, |
| 141 | "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim" |
| 142 | ); |
| 143 | }else if( oneWayOnly ){ |
| 144 | db_prepare(&s, |
| 145 | "SELECT cid, 1 FROM plink WHERE pid=:pid " |
| 146 | ); |
| 147 | }else if( directOnly ){ |
| 148 | db_prepare(&s, |
| 149 | "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim " |
| 150 | "UNION ALL " |
| 151 | "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim" |
| 152 | ); |
| 153 | }else{ |
| 154 | db_prepare(&s, |
| 155 | "SELECT cid, 1 FROM plink WHERE pid=:pid " |
| 156 | "UNION ALL " |
| 157 | "SELECT pid, 0 FROM plink WHERE cid=:pid" |
| 158 | ); |
| 159 | } |
| @@ -230,11 +230,11 @@ | |
| 230 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 231 | p->rid, p->rid); |
| 232 | fossil_print("%4d: %5d %s", n, p->rid, z); |
| 233 | fossil_free(z); |
| 234 | if( p->u.pTo ){ |
| 235 | fossil_print(" is a %s of\n", |
| 236 | p->u.pTo->fromIsParent ? "parent" : "child"); |
| 237 | }else{ |
| 238 | fossil_print("\n"); |
| 239 | } |
| 240 | } |
| @@ -353,11 +353,11 @@ | |
| 353 | /* |
| 354 | ** Compute all file name changes that occur going from checkin iFrom |
| 355 | ** to checkin iTo. |
| 356 | ** |
| 357 | ** The number of name changes is written into *pnChng. For each name |
| 358 | ** change, two integers are allocated for *piChng. The first is the |
| 359 | ** filename.fnid for the original name as seen in check-in iFrom and |
| 360 | ** the second is for new name as it is used in check-in iTo. |
| 361 | ** |
| 362 | ** Space to hold *piChng is obtained from fossil_malloc() and should |
| 363 | ** be released by the caller. |
| @@ -516,11 +516,11 @@ | |
| 516 | g.argc -= 2; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | /* Query to extract all rename operations */ |
| 521 | static const char zRenameQuery[] = |
| 522 | @ SELECT |
| 523 | @ datetime(event.mtime), |
| 524 | @ F.name AS old_name, |
| 525 | @ T.name AS new_name, |
| 526 | @ blob.uuid |
| @@ -531,11 +531,11 @@ | |
| 531 | @ AND event.objid=mlink.mid |
| 532 | @ AND event.type='ci' |
| 533 | @ AND blob.rid=mlink.mid |
| 534 | @ ORDER BY 1 DESC, 2; |
| 535 | ; |
| 536 | |
| 537 | /* |
| 538 | ** WEBPAGE: test-rename-list |
| 539 | ** |
| 540 | ** Print a list of all file rename operations throughout history. |
| 541 | ** This page is intended for for testing purposes only and may change |
| @@ -551,11 +551,11 @@ | |
| 551 | @ <table border="1" width="100%%"> |
| 552 | @ <tr><th>Date & Time</th> |
| 553 | @ <th>Old Name</th> |
| 554 | @ <th>New Name</th> |
| 555 | @ <th>Check-in</th></tr> |
| 556 | db_prepare(&q, zRenameQuery); |
| 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | const char *zDate = db_column_text(&q, 0); |
| 559 | const char *zOld = db_column_text(&q, 1); |
| 560 | const char *zNew = db_column_text(&q, 2); |
| 561 | const char *zUuid = db_column_text(&q, 3); |
| 562 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -112,11 +112,11 @@ | |
| 112 | ** Compute the shortest path from iFrom to iTo |
| 113 | ** |
| 114 | ** If directOnly is true, then use only the "primary" links from parent to |
| 115 | ** child. In other words, ignore merges. |
| 116 | ** |
| 117 | ** Return a pointer to the beginning of the path (the iFrom node). |
| 118 | ** Elements of the path can be traversed by following the PathNode.u.pTo |
| 119 | ** pointer chain. |
| 120 | ** |
| 121 | ** Return NULL if no path is found. |
| 122 | */ |
| @@ -135,25 +135,25 @@ | |
| 135 | if( iTo==iFrom ){ |
| 136 | path.pEnd = path.pStart; |
| 137 | return path.pStart; |
| 138 | } |
| 139 | if( oneWayOnly && directOnly ){ |
| 140 | db_prepare(&s, |
| 141 | "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim" |
| 142 | ); |
| 143 | }else if( oneWayOnly ){ |
| 144 | db_prepare(&s, |
| 145 | "SELECT cid, 1 FROM plink WHERE pid=:pid " |
| 146 | ); |
| 147 | }else if( directOnly ){ |
| 148 | db_prepare(&s, |
| 149 | "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim " |
| 150 | "UNION ALL " |
| 151 | "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim" |
| 152 | ); |
| 153 | }else{ |
| 154 | db_prepare(&s, |
| 155 | "SELECT cid, 1 FROM plink WHERE pid=:pid " |
| 156 | "UNION ALL " |
| 157 | "SELECT pid, 0 FROM plink WHERE cid=:pid" |
| 158 | ); |
| 159 | } |
| @@ -230,11 +230,11 @@ | |
| 230 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 231 | p->rid, p->rid); |
| 232 | fossil_print("%4d: %5d %s", n, p->rid, z); |
| 233 | fossil_free(z); |
| 234 | if( p->u.pTo ){ |
| 235 | fossil_print(" is a %s of\n", |
| 236 | p->u.pTo->fromIsParent ? "parent" : "child"); |
| 237 | }else{ |
| 238 | fossil_print("\n"); |
| 239 | } |
| 240 | } |
| @@ -353,11 +353,11 @@ | |
| 353 | /* |
| 354 | ** Compute all file name changes that occur going from checkin iFrom |
| 355 | ** to checkin iTo. |
| 356 | ** |
| 357 | ** The number of name changes is written into *pnChng. For each name |
| 358 | ** change, two integers are allocated for *piChng. The first is the |
| 359 | ** filename.fnid for the original name as seen in check-in iFrom and |
| 360 | ** the second is for new name as it is used in check-in iTo. |
| 361 | ** |
| 362 | ** Space to hold *piChng is obtained from fossil_malloc() and should |
| 363 | ** be released by the caller. |
| @@ -516,11 +516,11 @@ | |
| 516 | g.argc -= 2; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | /* Query to extract all rename operations */ |
| 521 | static const char zRenameQuery[] = |
| 522 | @ SELECT |
| 523 | @ datetime(event.mtime), |
| 524 | @ F.name AS old_name, |
| 525 | @ T.name AS new_name, |
| 526 | @ blob.uuid |
| @@ -531,11 +531,11 @@ | |
| 531 | @ AND event.objid=mlink.mid |
| 532 | @ AND event.type='ci' |
| 533 | @ AND blob.rid=mlink.mid |
| 534 | @ ORDER BY 1 DESC, 2; |
| 535 | ; |
| 536 | |
| 537 | /* |
| 538 | ** WEBPAGE: test-rename-list |
| 539 | ** |
| 540 | ** Print a list of all file rename operations throughout history. |
| 541 | ** This page is intended for for testing purposes only and may change |
| @@ -551,11 +551,11 @@ | |
| 551 | @ <table border="1" width="100%%"> |
| 552 | @ <tr><th>Date & Time</th> |
| 553 | @ <th>Old Name</th> |
| 554 | @ <th>New Name</th> |
| 555 | @ <th>Check-in</th></tr> |
| 556 | db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/); |
| 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | const char *zDate = db_column_text(&q, 0); |
| 559 | const char *zOld = db_column_text(&q, 1); |
| 560 | const char *zNew = db_column_text(&q, 2); |
| 561 | const char *zUuid = db_column_text(&q, 3); |
| 562 |
+18
-14
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -44,19 +44,20 @@ | ||
| 44 | 44 | #define etBLOB 11 /* Blob objects. %b */ |
| 45 | 45 | #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */ |
| 46 | 46 | #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */ |
| 47 | 47 | #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '', |
| 48 | 48 | NULL pointers replaced by SQL NULL. %Q */ |
| 49 | -#define etPOINTER 15 /* The %p conversion */ | |
| 50 | -#define etHTMLIZE 16 /* Make text safe for HTML */ | |
| 51 | -#define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ | |
| 52 | -#define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ | |
| 53 | -#define etFOSSILIZE 19 /* The fossil header encoding format. */ | |
| 54 | -#define etPATH 20 /* Path type */ | |
| 55 | -#define etWIKISTR 21 /* Timeline comment text rendered from a char*: %w */ | |
| 49 | +#define etSQLESCAPE3 15 /* Double '"' characters within an indentifier. %w */ | |
| 50 | +#define etPOINTER 16 /* The %p conversion */ | |
| 51 | +#define etHTMLIZE 17 /* Make text safe for HTML */ | |
| 52 | +#define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */ | |
| 53 | +#define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */ | |
| 54 | +#define etFOSSILIZE 20 /* The fossil header encoding format. */ | |
| 55 | +#define etPATH 21 /* Path type */ | |
| 56 | +#define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */ | |
| 56 | 57 | #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ |
| 57 | -#define etROOT 24 /* String value of g.zTop: % */ | |
| 58 | +#define etROOT 24 /* String value of g.zTop: %R */ | |
| 58 | 59 | |
| 59 | 60 | |
| 60 | 61 | /* |
| 61 | 62 | ** An "etByte" is an 8-bit unsigned value. |
| 62 | 63 | */ |
| @@ -96,15 +97,16 @@ | ||
| 96 | 97 | { 'z', 0, 6, etDYNSTRING, 0, 0 }, |
| 97 | 98 | { 'q', 0, 4, etSQLESCAPE, 0, 0 }, |
| 98 | 99 | { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, |
| 99 | 100 | { 'b', 0, 2, etBLOB, 0, 0 }, |
| 100 | 101 | { 'B', 0, 2, etBLOBSQL, 0, 0 }, |
| 101 | - { 'w', 0, 2, etWIKISTR, 0, 0 }, | |
| 102 | + { 'W', 0, 2, etWIKISTR, 0, 0 }, | |
| 102 | 103 | { 'h', 0, 4, etHTMLIZE, 0, 0 }, |
| 103 | 104 | { 'R', 0, 0, etROOT, 0, 0 }, |
| 104 | 105 | { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ |
| 105 | 106 | { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ |
| 107 | + { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, | |
| 106 | 108 | { 'F', 0, 4, etFOSSILIZE, 0, 0 }, |
| 107 | 109 | { 'S', 0, 4, etSTRINGID, 0, 0 }, |
| 108 | 110 | { 'c', 0, 0, etCHARX, 0, 0 }, |
| 109 | 111 | { 'o', 8, 0, etRADIX, 0, 2 }, |
| 110 | 112 | { 'u', 10, 0, etRADIX, 0, 0 }, |
| @@ -661,35 +663,37 @@ | ||
| 661 | 663 | length = j; |
| 662 | 664 | assert( length==n+cnt+2 ); |
| 663 | 665 | break; |
| 664 | 666 | } |
| 665 | 667 | case etSQLESCAPE: |
| 666 | - case etSQLESCAPE2: { | |
| 668 | + case etSQLESCAPE2: | |
| 669 | + case etSQLESCAPE3: { | |
| 667 | 670 | int i, j, n, ch, isnull; |
| 668 | 671 | int needQuote; |
| 669 | 672 | int limit = flag_alternateform ? va_arg(ap,int) : -1; |
| 673 | + char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */ | |
| 670 | 674 | char *escarg = va_arg(ap,char*); |
| 671 | 675 | isnull = escarg==0; |
| 672 | 676 | if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); |
| 673 | 677 | if( limit<0 ) limit = strlen(escarg); |
| 674 | 678 | for(i=n=0; i<limit; i++){ |
| 675 | - if( escarg[i]=='\'' ) n++; | |
| 679 | + if( escarg[i]==q ) n++; | |
| 676 | 680 | } |
| 677 | 681 | needQuote = !isnull && xtype==etSQLESCAPE2; |
| 678 | 682 | n += i + 1 + needQuote*2; |
| 679 | 683 | if( n>etBUFSIZE ){ |
| 680 | 684 | bufpt = zExtra = fossil_malloc( n ); |
| 681 | 685 | }else{ |
| 682 | 686 | bufpt = buf; |
| 683 | 687 | } |
| 684 | 688 | j = 0; |
| 685 | - if( needQuote ) bufpt[j++] = '\''; | |
| 689 | + if( needQuote ) bufpt[j++] = q; | |
| 686 | 690 | for(i=0; i<limit; i++){ |
| 687 | 691 | bufpt[j++] = ch = escarg[i]; |
| 688 | - if( ch=='\'' ) bufpt[j++] = ch; | |
| 692 | + if( ch==q ) bufpt[j++] = ch; | |
| 689 | 693 | } |
| 690 | - if( needQuote ) bufpt[j++] = '\''; | |
| 694 | + if( needQuote ) bufpt[j++] = q; | |
| 691 | 695 | bufpt[j] = 0; |
| 692 | 696 | length = j; |
| 693 | 697 | if( precision>=0 && precision<length ) length = precision; |
| 694 | 698 | break; |
| 695 | 699 | } |
| 696 | 700 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -44,19 +44,20 @@ | |
| 44 | #define etBLOB 11 /* Blob objects. %b */ |
| 45 | #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */ |
| 46 | #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */ |
| 47 | #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '', |
| 48 | NULL pointers replaced by SQL NULL. %Q */ |
| 49 | #define etPOINTER 15 /* The %p conversion */ |
| 50 | #define etHTMLIZE 16 /* Make text safe for HTML */ |
| 51 | #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ |
| 52 | #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ |
| 53 | #define etFOSSILIZE 19 /* The fossil header encoding format. */ |
| 54 | #define etPATH 20 /* Path type */ |
| 55 | #define etWIKISTR 21 /* Timeline comment text rendered from a char*: %w */ |
| 56 | #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ |
| 57 | #define etROOT 24 /* String value of g.zTop: % */ |
| 58 | |
| 59 | |
| 60 | /* |
| 61 | ** An "etByte" is an 8-bit unsigned value. |
| 62 | */ |
| @@ -96,15 +97,16 @@ | |
| 96 | { 'z', 0, 6, etDYNSTRING, 0, 0 }, |
| 97 | { 'q', 0, 4, etSQLESCAPE, 0, 0 }, |
| 98 | { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, |
| 99 | { 'b', 0, 2, etBLOB, 0, 0 }, |
| 100 | { 'B', 0, 2, etBLOBSQL, 0, 0 }, |
| 101 | { 'w', 0, 2, etWIKISTR, 0, 0 }, |
| 102 | { 'h', 0, 4, etHTMLIZE, 0, 0 }, |
| 103 | { 'R', 0, 0, etROOT, 0, 0 }, |
| 104 | { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ |
| 105 | { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ |
| 106 | { 'F', 0, 4, etFOSSILIZE, 0, 0 }, |
| 107 | { 'S', 0, 4, etSTRINGID, 0, 0 }, |
| 108 | { 'c', 0, 0, etCHARX, 0, 0 }, |
| 109 | { 'o', 8, 0, etRADIX, 0, 2 }, |
| 110 | { 'u', 10, 0, etRADIX, 0, 0 }, |
| @@ -661,35 +663,37 @@ | |
| 661 | length = j; |
| 662 | assert( length==n+cnt+2 ); |
| 663 | break; |
| 664 | } |
| 665 | case etSQLESCAPE: |
| 666 | case etSQLESCAPE2: { |
| 667 | int i, j, n, ch, isnull; |
| 668 | int needQuote; |
| 669 | int limit = flag_alternateform ? va_arg(ap,int) : -1; |
| 670 | char *escarg = va_arg(ap,char*); |
| 671 | isnull = escarg==0; |
| 672 | if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); |
| 673 | if( limit<0 ) limit = strlen(escarg); |
| 674 | for(i=n=0; i<limit; i++){ |
| 675 | if( escarg[i]=='\'' ) n++; |
| 676 | } |
| 677 | needQuote = !isnull && xtype==etSQLESCAPE2; |
| 678 | n += i + 1 + needQuote*2; |
| 679 | if( n>etBUFSIZE ){ |
| 680 | bufpt = zExtra = fossil_malloc( n ); |
| 681 | }else{ |
| 682 | bufpt = buf; |
| 683 | } |
| 684 | j = 0; |
| 685 | if( needQuote ) bufpt[j++] = '\''; |
| 686 | for(i=0; i<limit; i++){ |
| 687 | bufpt[j++] = ch = escarg[i]; |
| 688 | if( ch=='\'' ) bufpt[j++] = ch; |
| 689 | } |
| 690 | if( needQuote ) bufpt[j++] = '\''; |
| 691 | bufpt[j] = 0; |
| 692 | length = j; |
| 693 | if( precision>=0 && precision<length ) length = precision; |
| 694 | break; |
| 695 | } |
| 696 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -44,19 +44,20 @@ | |
| 44 | #define etBLOB 11 /* Blob objects. %b */ |
| 45 | #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */ |
| 46 | #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */ |
| 47 | #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '', |
| 48 | NULL pointers replaced by SQL NULL. %Q */ |
| 49 | #define etSQLESCAPE3 15 /* Double '"' characters within an indentifier. %w */ |
| 50 | #define etPOINTER 16 /* The %p conversion */ |
| 51 | #define etHTMLIZE 17 /* Make text safe for HTML */ |
| 52 | #define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */ |
| 53 | #define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */ |
| 54 | #define etFOSSILIZE 20 /* The fossil header encoding format. */ |
| 55 | #define etPATH 21 /* Path type */ |
| 56 | #define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */ |
| 57 | #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ |
| 58 | #define etROOT 24 /* String value of g.zTop: %R */ |
| 59 | |
| 60 | |
| 61 | /* |
| 62 | ** An "etByte" is an 8-bit unsigned value. |
| 63 | */ |
| @@ -96,15 +97,16 @@ | |
| 97 | { 'z', 0, 6, etDYNSTRING, 0, 0 }, |
| 98 | { 'q', 0, 4, etSQLESCAPE, 0, 0 }, |
| 99 | { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, |
| 100 | { 'b', 0, 2, etBLOB, 0, 0 }, |
| 101 | { 'B', 0, 2, etBLOBSQL, 0, 0 }, |
| 102 | { 'W', 0, 2, etWIKISTR, 0, 0 }, |
| 103 | { 'h', 0, 4, etHTMLIZE, 0, 0 }, |
| 104 | { 'R', 0, 0, etROOT, 0, 0 }, |
| 105 | { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ |
| 106 | { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ |
| 107 | { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, |
| 108 | { 'F', 0, 4, etFOSSILIZE, 0, 0 }, |
| 109 | { 'S', 0, 4, etSTRINGID, 0, 0 }, |
| 110 | { 'c', 0, 0, etCHARX, 0, 0 }, |
| 111 | { 'o', 8, 0, etRADIX, 0, 2 }, |
| 112 | { 'u', 10, 0, etRADIX, 0, 0 }, |
| @@ -661,35 +663,37 @@ | |
| 663 | length = j; |
| 664 | assert( length==n+cnt+2 ); |
| 665 | break; |
| 666 | } |
| 667 | case etSQLESCAPE: |
| 668 | case etSQLESCAPE2: |
| 669 | case etSQLESCAPE3: { |
| 670 | int i, j, n, ch, isnull; |
| 671 | int needQuote; |
| 672 | int limit = flag_alternateform ? va_arg(ap,int) : -1; |
| 673 | char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */ |
| 674 | char *escarg = va_arg(ap,char*); |
| 675 | isnull = escarg==0; |
| 676 | if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); |
| 677 | if( limit<0 ) limit = strlen(escarg); |
| 678 | for(i=n=0; i<limit; i++){ |
| 679 | if( escarg[i]==q ) n++; |
| 680 | } |
| 681 | needQuote = !isnull && xtype==etSQLESCAPE2; |
| 682 | n += i + 1 + needQuote*2; |
| 683 | if( n>etBUFSIZE ){ |
| 684 | bufpt = zExtra = fossil_malloc( n ); |
| 685 | }else{ |
| 686 | bufpt = buf; |
| 687 | } |
| 688 | j = 0; |
| 689 | if( needQuote ) bufpt[j++] = q; |
| 690 | for(i=0; i<limit; i++){ |
| 691 | bufpt[j++] = ch = escarg[i]; |
| 692 | if( ch==q ) bufpt[j++] = ch; |
| 693 | } |
| 694 | if( needQuote ) bufpt[j++] = q; |
| 695 | bufpt[j] = 0; |
| 696 | length = j; |
| 697 | if( precision>=0 && precision<length ) length = precision; |
| 698 | break; |
| 699 | } |
| 700 |
+9
-8
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -81,12 +81,12 @@ | ||
| 81 | 81 | @ ); |
| 82 | 82 | ; |
| 83 | 83 | |
| 84 | 84 | static void rebuild_update_schema(void){ |
| 85 | 85 | int rc; |
| 86 | - db_multi_exec(zSchemaUpdates1); | |
| 87 | - db_multi_exec(zSchemaUpdates2); | |
| 86 | + db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/); | |
| 87 | + db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/); | |
| 88 | 88 | |
| 89 | 89 | rc = db_exists("SELECT 1 FROM sqlite_master" |
| 90 | 90 | " WHERE name='user' AND sql GLOB '* mtime *'"); |
| 91 | 91 | if( rc==0 ){ |
| 92 | 92 | db_multi_exec( |
| @@ -135,11 +135,11 @@ | ||
| 135 | 135 | if( rc==0 ){ |
| 136 | 136 | db_multi_exec( |
| 137 | 137 | "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;" |
| 138 | 138 | "DROP TABLE reportfmt;" |
| 139 | 139 | ); |
| 140 | - db_multi_exec(zSchemaUpdates2); | |
| 140 | + db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/); | |
| 141 | 141 | db_multi_exec( |
| 142 | 142 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 143 | 143 | " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;" |
| 144 | 144 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 145 | 145 | " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()" |
| @@ -254,11 +254,12 @@ | ||
| 254 | 254 | /* We are doing "fossil rebuild" */ |
| 255 | 255 | manifest_crosslink(rid, pUse, MC_NONE); |
| 256 | 256 | }else{ |
| 257 | 257 | /* We are doing "fossil deconstruct" */ |
| 258 | 258 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 259 | - char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength); | |
| 259 | + char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/, | |
| 260 | + zUuid, zUuid+prefixLength); | |
| 260 | 261 | blob_write_to_file(pUse,zFile); |
| 261 | 262 | free(zFile); |
| 262 | 263 | free(zUuid); |
| 263 | 264 | blob_reset(pUse); |
| 264 | 265 | } |
| @@ -355,11 +356,11 @@ | ||
| 355 | 356 | ); |
| 356 | 357 | if( zTable==0 ) break; |
| 357 | 358 | db_multi_exec("DROP TABLE %Q", zTable); |
| 358 | 359 | free(zTable); |
| 359 | 360 | } |
| 360 | - db_multi_exec(zRepositorySchema2); | |
| 361 | + db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/); | |
| 361 | 362 | ticket_create_table(0); |
| 362 | 363 | shun_artifacts(); |
| 363 | 364 | |
| 364 | 365 | db_multi_exec( |
| 365 | 366 | "INSERT INTO unclustered" |
| @@ -587,13 +588,13 @@ | ||
| 587 | 588 | db_begin_transaction(); |
| 588 | 589 | ttyOutput = 1; |
| 589 | 590 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); |
| 590 | 591 | reconstruct_private_table(); |
| 591 | 592 | db_multi_exec( |
| 592 | - "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" | |
| 593 | - "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());" | |
| 594 | - "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());", | |
| 593 | + "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());" | |
| 594 | + "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());" | |
| 595 | + "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());", | |
| 595 | 596 | CONTENT_SCHEMA, AUX_SCHEMA, get_version() |
| 596 | 597 | ); |
| 597 | 598 | if( errCnt && !forceFlag ){ |
| 598 | 599 | fossil_print( |
| 599 | 600 | "%d errors. Rolling back changes. Use --force to force a commit.\n", |
| 600 | 601 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -81,12 +81,12 @@ | |
| 81 | @ ); |
| 82 | ; |
| 83 | |
| 84 | static void rebuild_update_schema(void){ |
| 85 | int rc; |
| 86 | db_multi_exec(zSchemaUpdates1); |
| 87 | db_multi_exec(zSchemaUpdates2); |
| 88 | |
| 89 | rc = db_exists("SELECT 1 FROM sqlite_master" |
| 90 | " WHERE name='user' AND sql GLOB '* mtime *'"); |
| 91 | if( rc==0 ){ |
| 92 | db_multi_exec( |
| @@ -135,11 +135,11 @@ | |
| 135 | if( rc==0 ){ |
| 136 | db_multi_exec( |
| 137 | "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;" |
| 138 | "DROP TABLE reportfmt;" |
| 139 | ); |
| 140 | db_multi_exec(zSchemaUpdates2); |
| 141 | db_multi_exec( |
| 142 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 143 | " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;" |
| 144 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 145 | " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()" |
| @@ -254,11 +254,12 @@ | |
| 254 | /* We are doing "fossil rebuild" */ |
| 255 | manifest_crosslink(rid, pUse, MC_NONE); |
| 256 | }else{ |
| 257 | /* We are doing "fossil deconstruct" */ |
| 258 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 259 | char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength); |
| 260 | blob_write_to_file(pUse,zFile); |
| 261 | free(zFile); |
| 262 | free(zUuid); |
| 263 | blob_reset(pUse); |
| 264 | } |
| @@ -355,11 +356,11 @@ | |
| 355 | ); |
| 356 | if( zTable==0 ) break; |
| 357 | db_multi_exec("DROP TABLE %Q", zTable); |
| 358 | free(zTable); |
| 359 | } |
| 360 | db_multi_exec(zRepositorySchema2); |
| 361 | ticket_create_table(0); |
| 362 | shun_artifacts(); |
| 363 | |
| 364 | db_multi_exec( |
| 365 | "INSERT INTO unclustered" |
| @@ -587,13 +588,13 @@ | |
| 587 | db_begin_transaction(); |
| 588 | ttyOutput = 1; |
| 589 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); |
| 590 | reconstruct_private_table(); |
| 591 | db_multi_exec( |
| 592 | "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" |
| 593 | "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());" |
| 594 | "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());", |
| 595 | CONTENT_SCHEMA, AUX_SCHEMA, get_version() |
| 596 | ); |
| 597 | if( errCnt && !forceFlag ){ |
| 598 | fossil_print( |
| 599 | "%d errors. Rolling back changes. Use --force to force a commit.\n", |
| 600 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -81,12 +81,12 @@ | |
| 81 | @ ); |
| 82 | ; |
| 83 | |
| 84 | static void rebuild_update_schema(void){ |
| 85 | int rc; |
| 86 | db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/); |
| 87 | db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/); |
| 88 | |
| 89 | rc = db_exists("SELECT 1 FROM sqlite_master" |
| 90 | " WHERE name='user' AND sql GLOB '* mtime *'"); |
| 91 | if( rc==0 ){ |
| 92 | db_multi_exec( |
| @@ -135,11 +135,11 @@ | |
| 135 | if( rc==0 ){ |
| 136 | db_multi_exec( |
| 137 | "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;" |
| 138 | "DROP TABLE reportfmt;" |
| 139 | ); |
| 140 | db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/); |
| 141 | db_multi_exec( |
| 142 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 143 | " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;" |
| 144 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 145 | " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()" |
| @@ -254,11 +254,12 @@ | |
| 254 | /* We are doing "fossil rebuild" */ |
| 255 | manifest_crosslink(rid, pUse, MC_NONE); |
| 256 | }else{ |
| 257 | /* We are doing "fossil deconstruct" */ |
| 258 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 259 | char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/, |
| 260 | zUuid, zUuid+prefixLength); |
| 261 | blob_write_to_file(pUse,zFile); |
| 262 | free(zFile); |
| 263 | free(zUuid); |
| 264 | blob_reset(pUse); |
| 265 | } |
| @@ -355,11 +356,11 @@ | |
| 356 | ); |
| 357 | if( zTable==0 ) break; |
| 358 | db_multi_exec("DROP TABLE %Q", zTable); |
| 359 | free(zTable); |
| 360 | } |
| 361 | db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/); |
| 362 | ticket_create_table(0); |
| 363 | shun_artifacts(); |
| 364 | |
| 365 | db_multi_exec( |
| 366 | "INSERT INTO unclustered" |
| @@ -587,13 +588,13 @@ | |
| 588 | db_begin_transaction(); |
| 589 | ttyOutput = 1; |
| 590 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); |
| 591 | reconstruct_private_table(); |
| 592 | db_multi_exec( |
| 593 | "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());" |
| 594 | "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());" |
| 595 | "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());", |
| 596 | CONTENT_SCHEMA, AUX_SCHEMA, get_version() |
| 597 | ); |
| 598 | if( errCnt && !forceFlag ){ |
| 599 | fossil_print( |
| 600 | "%d errors. Rolling back changes. Use --force to force a commit.\n", |
| 601 |
+5
-7
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -436,11 +436,11 @@ | ||
| 436 | 436 | if( zOwner==0 ) zOwner = g.zLogin; |
| 437 | 437 | style_submenu_element("Cancel", "Cancel", "reportlist"); |
| 438 | 438 | if( rn>0 ){ |
| 439 | 439 | style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); |
| 440 | 440 | } |
| 441 | - style_header(rn>0 ? "Edit Report Format":"Create New Report Format"); | |
| 441 | + style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format"); | |
| 442 | 442 | if( zErr ){ |
| 443 | 443 | @ <blockquote class="reportError">%h(zErr)</blockquote> |
| 444 | 444 | } |
| 445 | 445 | @ <form action="rptedit" method="post"><div> |
| 446 | 446 | @ <input type="hidden" name="rn" value="%d(rn)" /> |
| @@ -1070,11 +1070,11 @@ | ||
| 1070 | 1070 | } |
| 1071 | 1071 | if( g.perm.NewTkt ){ |
| 1072 | 1072 | style_submenu_element("New Ticket", "Create a new ticket", |
| 1073 | 1073 | "%s/tktnew", g.zTop); |
| 1074 | 1074 | } |
| 1075 | - style_header(zTitle); | |
| 1075 | + style_header("%s", zTitle); | |
| 1076 | 1076 | output_color_key(zClrKey, 1, |
| 1077 | 1077 | "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\""); |
| 1078 | 1078 | @ <table border="1" cellpadding="2" cellspacing="0" class="report" |
| 1079 | 1079 | @ id="reportTable"> |
| 1080 | 1080 | sState.rn = rn; |
| @@ -1112,21 +1112,19 @@ | ||
| 1112 | 1112 | ** show all reports, which can be used for ticket show. |
| 1113 | 1113 | ** Output is written to stdout as tab delimited table |
| 1114 | 1114 | */ |
| 1115 | 1115 | void rpt_list_reports(void){ |
| 1116 | 1116 | Stmt q; |
| 1117 | - const char aRptOutFrmt[] = "%s\t%s\n"; | |
| 1118 | - | |
| 1119 | 1117 | fossil_print("Available reports:\n"); |
| 1120 | - fossil_print(aRptOutFrmt,"report number","report title"); | |
| 1121 | - fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle); | |
| 1118 | + fossil_print("%s\t%s\n","report number","report title"); | |
| 1119 | + fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle); | |
| 1122 | 1120 | db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn"); |
| 1123 | 1121 | while( db_step(&q)==SQLITE_ROW ){ |
| 1124 | 1122 | const char *zRn = db_column_text(&q, 0); |
| 1125 | 1123 | const char *zTitle = db_column_text(&q, 1); |
| 1126 | 1124 | |
| 1127 | - fossil_print(aRptOutFrmt,zRn,zTitle); | |
| 1125 | + fossil_print("%s\t%s\n",zRn,zTitle); | |
| 1128 | 1126 | } |
| 1129 | 1127 | db_finalize(&q); |
| 1130 | 1128 | } |
| 1131 | 1129 | |
| 1132 | 1130 | /* |
| 1133 | 1131 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -436,11 +436,11 @@ | |
| 436 | if( zOwner==0 ) zOwner = g.zLogin; |
| 437 | style_submenu_element("Cancel", "Cancel", "reportlist"); |
| 438 | if( rn>0 ){ |
| 439 | style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); |
| 440 | } |
| 441 | style_header(rn>0 ? "Edit Report Format":"Create New Report Format"); |
| 442 | if( zErr ){ |
| 443 | @ <blockquote class="reportError">%h(zErr)</blockquote> |
| 444 | } |
| 445 | @ <form action="rptedit" method="post"><div> |
| 446 | @ <input type="hidden" name="rn" value="%d(rn)" /> |
| @@ -1070,11 +1070,11 @@ | |
| 1070 | } |
| 1071 | if( g.perm.NewTkt ){ |
| 1072 | style_submenu_element("New Ticket", "Create a new ticket", |
| 1073 | "%s/tktnew", g.zTop); |
| 1074 | } |
| 1075 | style_header(zTitle); |
| 1076 | output_color_key(zClrKey, 1, |
| 1077 | "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\""); |
| 1078 | @ <table border="1" cellpadding="2" cellspacing="0" class="report" |
| 1079 | @ id="reportTable"> |
| 1080 | sState.rn = rn; |
| @@ -1112,21 +1112,19 @@ | |
| 1112 | ** show all reports, which can be used for ticket show. |
| 1113 | ** Output is written to stdout as tab delimited table |
| 1114 | */ |
| 1115 | void rpt_list_reports(void){ |
| 1116 | Stmt q; |
| 1117 | const char aRptOutFrmt[] = "%s\t%s\n"; |
| 1118 | |
| 1119 | fossil_print("Available reports:\n"); |
| 1120 | fossil_print(aRptOutFrmt,"report number","report title"); |
| 1121 | fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle); |
| 1122 | db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn"); |
| 1123 | while( db_step(&q)==SQLITE_ROW ){ |
| 1124 | const char *zRn = db_column_text(&q, 0); |
| 1125 | const char *zTitle = db_column_text(&q, 1); |
| 1126 | |
| 1127 | fossil_print(aRptOutFrmt,zRn,zTitle); |
| 1128 | } |
| 1129 | db_finalize(&q); |
| 1130 | } |
| 1131 | |
| 1132 | /* |
| 1133 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -436,11 +436,11 @@ | |
| 436 | if( zOwner==0 ) zOwner = g.zLogin; |
| 437 | style_submenu_element("Cancel", "Cancel", "reportlist"); |
| 438 | if( rn>0 ){ |
| 439 | style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); |
| 440 | } |
| 441 | style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format"); |
| 442 | if( zErr ){ |
| 443 | @ <blockquote class="reportError">%h(zErr)</blockquote> |
| 444 | } |
| 445 | @ <form action="rptedit" method="post"><div> |
| 446 | @ <input type="hidden" name="rn" value="%d(rn)" /> |
| @@ -1070,11 +1070,11 @@ | |
| 1070 | } |
| 1071 | if( g.perm.NewTkt ){ |
| 1072 | style_submenu_element("New Ticket", "Create a new ticket", |
| 1073 | "%s/tktnew", g.zTop); |
| 1074 | } |
| 1075 | style_header("%s", zTitle); |
| 1076 | output_color_key(zClrKey, 1, |
| 1077 | "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\""); |
| 1078 | @ <table border="1" cellpadding="2" cellspacing="0" class="report" |
| 1079 | @ id="reportTable"> |
| 1080 | sState.rn = rn; |
| @@ -1112,21 +1112,19 @@ | |
| 1112 | ** show all reports, which can be used for ticket show. |
| 1113 | ** Output is written to stdout as tab delimited table |
| 1114 | */ |
| 1115 | void rpt_list_reports(void){ |
| 1116 | Stmt q; |
| 1117 | fossil_print("Available reports:\n"); |
| 1118 | fossil_print("%s\t%s\n","report number","report title"); |
| 1119 | fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle); |
| 1120 | db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn"); |
| 1121 | while( db_step(&q)==SQLITE_ROW ){ |
| 1122 | const char *zRn = db_column_text(&q, 0); |
| 1123 | const char *zTitle = db_column_text(&q, 1); |
| 1124 | |
| 1125 | fossil_print("%s\t%s\n",zRn,zTitle); |
| 1126 | } |
| 1127 | db_finalize(&q); |
| 1128 | } |
| 1129 | |
| 1130 | /* |
| 1131 |
+10
-10
| --- src/rss.c | ||
| +++ src/rss.c | ||
| @@ -76,11 +76,11 @@ | ||
| 76 | 76 | |
| 77 | 77 | if( zType[0]!='a' ){ |
| 78 | 78 | if( zType[0]=='c' && !g.perm.Read ) zType = "x"; |
| 79 | 79 | if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x"; |
| 80 | 80 | if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x"; |
| 81 | - blob_appendf(&bSQL, " AND event.type=%Q", zType); | |
| 81 | + blob_append_sql(&bSQL, " AND event.type=%Q", zType); | |
| 82 | 82 | }else{ |
| 83 | 83 | if( !g.perm.Read ){ |
| 84 | 84 | if( g.perm.RdTkt && g.perm.RdWiki ){ |
| 85 | 85 | blob_append(&bSQL, " AND event.type!='ci'", -1); |
| 86 | 86 | }else if( g.perm.RdTkt ){ |
| @@ -122,18 +122,18 @@ | ||
| 122 | 122 | }else{ |
| 123 | 123 | nTagId = 0; |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | if( nTagId==-1 ){ |
| 127 | - blob_appendf(&bSQL, " AND 0"); | |
| 127 | + blob_append_sql(&bSQL, " AND 0"); | |
| 128 | 128 | }else if( nTagId!=0 ){ |
| 129 | - blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" | |
| 129 | + blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" | |
| 130 | 130 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | 133 | if( zFilename ){ |
| 134 | - blob_appendf(&bSQL, | |
| 134 | + blob_append_sql(&bSQL, | |
| 135 | 135 | " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)", |
| 136 | 136 | zFilename, filename_collation() |
| 137 | 137 | ); |
| 138 | 138 | } |
| 139 | 139 | |
| @@ -160,11 +160,11 @@ | ||
| 160 | 160 | @ <link>%s(g.zBaseURL)</link> |
| 161 | 161 | @ <description>%h(zProjectDescr)</description> |
| 162 | 162 | @ <pubDate>%s(zPubDate)</pubDate> |
| 163 | 163 | @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator> |
| 164 | 164 | free(zPubDate); |
| 165 | - db_prepare(&q, blob_str(&bSQL)); | |
| 165 | + db_prepare(&q, "%s", blob_sql_text(&bSQL)); | |
| 166 | 166 | blob_reset( &bSQL ); |
| 167 | 167 | while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){ |
| 168 | 168 | const char *zId = db_column_text(&q, 1); |
| 169 | 169 | const char *zCom = db_column_text(&q, 3); |
| 170 | 170 | const char *zAuthor = db_column_text(&q, 4); |
| @@ -280,11 +280,11 @@ | ||
| 280 | 280 | |
| 281 | 281 | blob_zero(&bSQL); |
| 282 | 282 | blob_append( &bSQL, zSQL1, -1 ); |
| 283 | 283 | |
| 284 | 284 | if( zType[0]!='a' ){ |
| 285 | - blob_appendf(&bSQL, " AND event.type=%Q", zType); | |
| 285 | + blob_append_sql(&bSQL, " AND event.type=%Q", zType); | |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | 288 | if( zTicketUuid ){ |
| 289 | 289 | nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'", |
| 290 | 290 | zTicketUuid); |
| @@ -306,18 +306,18 @@ | ||
| 306 | 306 | }else{ |
| 307 | 307 | nTagId = 0; |
| 308 | 308 | } |
| 309 | 309 | |
| 310 | 310 | if( nTagId==-1 ){ |
| 311 | - blob_appendf(&bSQL, " AND 0"); | |
| 311 | + blob_append_sql(&bSQL, " AND 0"); | |
| 312 | 312 | }else if( nTagId!=0 ){ |
| 313 | - blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" | |
| 313 | + blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" | |
| 314 | 314 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | 317 | if( zFilename ){ |
| 318 | - blob_appendf(&bSQL, | |
| 318 | + blob_append_sql(&bSQL, | |
| 319 | 319 | " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)", |
| 320 | 320 | zFilename, filename_collation() |
| 321 | 321 | ); |
| 322 | 322 | } |
| 323 | 323 | |
| @@ -343,11 +343,11 @@ | ||
| 343 | 343 | fossil_print("<description>%h</description>\n", zProjectDescr); |
| 344 | 344 | fossil_print("<pubDate>%s</pubDate>\n", zPubDate); |
| 345 | 345 | fossil_print("<generator>Fossil version %s %s</generator>\n", |
| 346 | 346 | MANIFEST_VERSION, MANIFEST_DATE); |
| 347 | 347 | free(zPubDate); |
| 348 | - db_prepare(&q, blob_str(&bSQL)); | |
| 348 | + db_prepare(&q, "%s", blob_sql_text(&bSQL)); | |
| 349 | 349 | blob_reset( &bSQL ); |
| 350 | 350 | while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){ |
| 351 | 351 | const char *zId = db_column_text(&q, 1); |
| 352 | 352 | const char *zCom = db_column_text(&q, 3); |
| 353 | 353 | const char *zAuthor = db_column_text(&q, 4); |
| 354 | 354 |
| --- src/rss.c | |
| +++ src/rss.c | |
| @@ -76,11 +76,11 @@ | |
| 76 | |
| 77 | if( zType[0]!='a' ){ |
| 78 | if( zType[0]=='c' && !g.perm.Read ) zType = "x"; |
| 79 | if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x"; |
| 80 | if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x"; |
| 81 | blob_appendf(&bSQL, " AND event.type=%Q", zType); |
| 82 | }else{ |
| 83 | if( !g.perm.Read ){ |
| 84 | if( g.perm.RdTkt && g.perm.RdWiki ){ |
| 85 | blob_append(&bSQL, " AND event.type!='ci'", -1); |
| 86 | }else if( g.perm.RdTkt ){ |
| @@ -122,18 +122,18 @@ | |
| 122 | }else{ |
| 123 | nTagId = 0; |
| 124 | } |
| 125 | |
| 126 | if( nTagId==-1 ){ |
| 127 | blob_appendf(&bSQL, " AND 0"); |
| 128 | }else if( nTagId!=0 ){ |
| 129 | blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" |
| 130 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); |
| 131 | } |
| 132 | |
| 133 | if( zFilename ){ |
| 134 | blob_appendf(&bSQL, |
| 135 | " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)", |
| 136 | zFilename, filename_collation() |
| 137 | ); |
| 138 | } |
| 139 | |
| @@ -160,11 +160,11 @@ | |
| 160 | @ <link>%s(g.zBaseURL)</link> |
| 161 | @ <description>%h(zProjectDescr)</description> |
| 162 | @ <pubDate>%s(zPubDate)</pubDate> |
| 163 | @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator> |
| 164 | free(zPubDate); |
| 165 | db_prepare(&q, blob_str(&bSQL)); |
| 166 | blob_reset( &bSQL ); |
| 167 | while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){ |
| 168 | const char *zId = db_column_text(&q, 1); |
| 169 | const char *zCom = db_column_text(&q, 3); |
| 170 | const char *zAuthor = db_column_text(&q, 4); |
| @@ -280,11 +280,11 @@ | |
| 280 | |
| 281 | blob_zero(&bSQL); |
| 282 | blob_append( &bSQL, zSQL1, -1 ); |
| 283 | |
| 284 | if( zType[0]!='a' ){ |
| 285 | blob_appendf(&bSQL, " AND event.type=%Q", zType); |
| 286 | } |
| 287 | |
| 288 | if( zTicketUuid ){ |
| 289 | nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'", |
| 290 | zTicketUuid); |
| @@ -306,18 +306,18 @@ | |
| 306 | }else{ |
| 307 | nTagId = 0; |
| 308 | } |
| 309 | |
| 310 | if( nTagId==-1 ){ |
| 311 | blob_appendf(&bSQL, " AND 0"); |
| 312 | }else if( nTagId!=0 ){ |
| 313 | blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" |
| 314 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); |
| 315 | } |
| 316 | |
| 317 | if( zFilename ){ |
| 318 | blob_appendf(&bSQL, |
| 319 | " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)", |
| 320 | zFilename, filename_collation() |
| 321 | ); |
| 322 | } |
| 323 | |
| @@ -343,11 +343,11 @@ | |
| 343 | fossil_print("<description>%h</description>\n", zProjectDescr); |
| 344 | fossil_print("<pubDate>%s</pubDate>\n", zPubDate); |
| 345 | fossil_print("<generator>Fossil version %s %s</generator>\n", |
| 346 | MANIFEST_VERSION, MANIFEST_DATE); |
| 347 | free(zPubDate); |
| 348 | db_prepare(&q, blob_str(&bSQL)); |
| 349 | blob_reset( &bSQL ); |
| 350 | while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){ |
| 351 | const char *zId = db_column_text(&q, 1); |
| 352 | const char *zCom = db_column_text(&q, 3); |
| 353 | const char *zAuthor = db_column_text(&q, 4); |
| 354 |
| --- src/rss.c | |
| +++ src/rss.c | |
| @@ -76,11 +76,11 @@ | |
| 76 | |
| 77 | if( zType[0]!='a' ){ |
| 78 | if( zType[0]=='c' && !g.perm.Read ) zType = "x"; |
| 79 | if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x"; |
| 80 | if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x"; |
| 81 | blob_append_sql(&bSQL, " AND event.type=%Q", zType); |
| 82 | }else{ |
| 83 | if( !g.perm.Read ){ |
| 84 | if( g.perm.RdTkt && g.perm.RdWiki ){ |
| 85 | blob_append(&bSQL, " AND event.type!='ci'", -1); |
| 86 | }else if( g.perm.RdTkt ){ |
| @@ -122,18 +122,18 @@ | |
| 122 | }else{ |
| 123 | nTagId = 0; |
| 124 | } |
| 125 | |
| 126 | if( nTagId==-1 ){ |
| 127 | blob_append_sql(&bSQL, " AND 0"); |
| 128 | }else if( nTagId!=0 ){ |
| 129 | blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" |
| 130 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); |
| 131 | } |
| 132 | |
| 133 | if( zFilename ){ |
| 134 | blob_append_sql(&bSQL, |
| 135 | " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)", |
| 136 | zFilename, filename_collation() |
| 137 | ); |
| 138 | } |
| 139 | |
| @@ -160,11 +160,11 @@ | |
| 160 | @ <link>%s(g.zBaseURL)</link> |
| 161 | @ <description>%h(zProjectDescr)</description> |
| 162 | @ <pubDate>%s(zPubDate)</pubDate> |
| 163 | @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator> |
| 164 | free(zPubDate); |
| 165 | db_prepare(&q, "%s", blob_sql_text(&bSQL)); |
| 166 | blob_reset( &bSQL ); |
| 167 | while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){ |
| 168 | const char *zId = db_column_text(&q, 1); |
| 169 | const char *zCom = db_column_text(&q, 3); |
| 170 | const char *zAuthor = db_column_text(&q, 4); |
| @@ -280,11 +280,11 @@ | |
| 280 | |
| 281 | blob_zero(&bSQL); |
| 282 | blob_append( &bSQL, zSQL1, -1 ); |
| 283 | |
| 284 | if( zType[0]!='a' ){ |
| 285 | blob_append_sql(&bSQL, " AND event.type=%Q", zType); |
| 286 | } |
| 287 | |
| 288 | if( zTicketUuid ){ |
| 289 | nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'", |
| 290 | zTicketUuid); |
| @@ -306,18 +306,18 @@ | |
| 306 | }else{ |
| 307 | nTagId = 0; |
| 308 | } |
| 309 | |
| 310 | if( nTagId==-1 ){ |
| 311 | blob_append_sql(&bSQL, " AND 0"); |
| 312 | }else if( nTagId!=0 ){ |
| 313 | blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" |
| 314 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); |
| 315 | } |
| 316 | |
| 317 | if( zFilename ){ |
| 318 | blob_append_sql(&bSQL, |
| 319 | " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)", |
| 320 | zFilename, filename_collation() |
| 321 | ); |
| 322 | } |
| 323 | |
| @@ -343,11 +343,11 @@ | |
| 343 | fossil_print("<description>%h</description>\n", zProjectDescr); |
| 344 | fossil_print("<pubDate>%s</pubDate>\n", zPubDate); |
| 345 | fossil_print("<generator>Fossil version %s %s</generator>\n", |
| 346 | MANIFEST_VERSION, MANIFEST_DATE); |
| 347 | free(zPubDate); |
| 348 | db_prepare(&q, "%s", blob_sql_text(&bSQL)); |
| 349 | blob_reset( &bSQL ); |
| 350 | while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){ |
| 351 | const char *zId = db_column_text(&q, 1); |
| 352 | const char *zCom = db_column_text(&q, 3); |
| 353 | const char *zAuthor = db_column_text(&q, 4); |
| 354 |
+2
-2
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -231,13 +231,13 @@ | ||
| 231 | 231 | iBest = db_int(0, "SELECT max(x) FROM srch"); |
| 232 | 232 | blob_append(&sql, |
| 233 | 233 | "SELECT rid, uuid, date, comment, 0, 0 FROM srch " |
| 234 | 234 | "WHERE 1 ", -1); |
| 235 | 235 | if(!fAll){ |
| 236 | - blob_appendf(&sql,"AND x>%d ", iBest/3); | |
| 236 | + blob_append_sql(&sql,"AND x>%d ", iBest/3); | |
| 237 | 237 | } |
| 238 | 238 | blob_append(&sql, "ORDER BY x DESC, date DESC ", -1); |
| 239 | - db_prepare(&q, blob_str(&sql)); | |
| 239 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 240 | 240 | blob_reset(&sql); |
| 241 | 241 | print_timeline(&q, nLimit, width, 0); |
| 242 | 242 | db_finalize(&q); |
| 243 | 243 | } |
| 244 | 244 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -231,13 +231,13 @@ | |
| 231 | iBest = db_int(0, "SELECT max(x) FROM srch"); |
| 232 | blob_append(&sql, |
| 233 | "SELECT rid, uuid, date, comment, 0, 0 FROM srch " |
| 234 | "WHERE 1 ", -1); |
| 235 | if(!fAll){ |
| 236 | blob_appendf(&sql,"AND x>%d ", iBest/3); |
| 237 | } |
| 238 | blob_append(&sql, "ORDER BY x DESC, date DESC ", -1); |
| 239 | db_prepare(&q, blob_str(&sql)); |
| 240 | blob_reset(&sql); |
| 241 | print_timeline(&q, nLimit, width, 0); |
| 242 | db_finalize(&q); |
| 243 | } |
| 244 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -231,13 +231,13 @@ | |
| 231 | iBest = db_int(0, "SELECT max(x) FROM srch"); |
| 232 | blob_append(&sql, |
| 233 | "SELECT rid, uuid, date, comment, 0, 0 FROM srch " |
| 234 | "WHERE 1 ", -1); |
| 235 | if(!fAll){ |
| 236 | blob_append_sql(&sql,"AND x>%d ", iBest/3); |
| 237 | } |
| 238 | blob_append(&sql, "ORDER BY x DESC, date DESC ", -1); |
| 239 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 240 | blob_reset(&sql); |
| 241 | print_timeline(&q, nLimit, width, 0); |
| 242 | db_finalize(&q); |
| 243 | } |
| 244 |
+12
-4
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -375,11 +375,11 @@ | ||
| 375 | 375 | return; |
| 376 | 376 | } |
| 377 | 377 | login_verify_csrf_secret(); |
| 378 | 378 | db_multi_exec( |
| 379 | 379 | "REPLACE INTO user(uid,login,info,pw,cap,mtime) " |
| 380 | - "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())", | |
| 380 | + "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())", | |
| 381 | 381 | uid, P("login"), P("info"), zPw, zCap |
| 382 | 382 | ); |
| 383 | 383 | if( atoi(PD("all","0"))>0 ){ |
| 384 | 384 | Blob sql; |
| 385 | 385 | char *zErr = 0; |
| @@ -477,11 +477,11 @@ | ||
| 477 | 477 | |
| 478 | 478 | /* Begin generating the page |
| 479 | 479 | */ |
| 480 | 480 | style_submenu_element("Cancel", "Cancel", "setup_ulist"); |
| 481 | 481 | if( uid ){ |
| 482 | - style_header(mprintf("Edit User %h", zLogin)); | |
| 482 | + style_header("Edit User %h", zLogin); | |
| 483 | 483 | }else{ |
| 484 | 484 | style_header("Add A New User"); |
| 485 | 485 | } |
| 486 | 486 | @ <div class="ueditCapBox"> |
| 487 | 487 | @ <form action="%s(g.zPath)" method="post"><div> |
| @@ -1075,10 +1075,14 @@ | ||
| 1075 | 1075 | @ every historical check-in, which can use a lot of CPU and bandwidth |
| 1076 | 1076 | @ even for relatively small projects.</p> |
| 1077 | 1077 | @ |
| 1078 | 1078 | @ <p>Additional parameters that control this behavior:</p> |
| 1079 | 1079 | @ <blockquote> |
| 1080 | + onoff_attribute("Enable hyperlinks for humans (as deduced from the UserAgent " | |
| 1081 | + " HTTP header string)", | |
| 1082 | + "auto-hyperlink-ishuman", "ahis", 0, 0); | |
| 1083 | + @ <br> | |
| 1080 | 1084 | onoff_attribute("Require mouse movement before enabling hyperlinks", |
| 1081 | 1085 | "auto-hyperlink-mouseover", "ahmo", 0, 0); |
| 1082 | 1086 | @ <br> |
| 1083 | 1087 | entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5, |
| 1084 | 1088 | "auto-hyperlink-delay", "ah-delay", "10", 0); |
| @@ -1157,11 +1161,11 @@ | ||
| 1157 | 1161 | login_check_credentials(); |
| 1158 | 1162 | if( !g.perm.Setup ){ |
| 1159 | 1163 | login_needed(); |
| 1160 | 1164 | } |
| 1161 | 1165 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1162 | - zSelfRepo = mprintf(blob_str(&fullName)); | |
| 1166 | + zSelfRepo = fossil_strdup(blob_str(&fullName)); | |
| 1163 | 1167 | blob_reset(&fullName); |
| 1164 | 1168 | if( P("join")!=0 ){ |
| 1165 | 1169 | login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg); |
| 1166 | 1170 | }else if( P("leave") ){ |
| 1167 | 1171 | login_group_leave(&zErrMsg); |
| @@ -1331,11 +1335,15 @@ | ||
| 1331 | 1335 | login_needed(); |
| 1332 | 1336 | } |
| 1333 | 1337 | |
| 1334 | 1338 | (void) aCmdHelp; /* NOTE: Silence compiler warning. */ |
| 1335 | 1339 | style_header("Settings"); |
| 1336 | - db_open_local(0); | |
| 1340 | + if(!g.repositoryOpen){ | |
| 1341 | + /* Provide read-only access to versioned settings, | |
| 1342 | + but only if no repo file was explicitly provided. */ | |
| 1343 | + db_open_local(0); | |
| 1344 | + } | |
| 1337 | 1345 | db_begin_transaction(); |
| 1338 | 1346 | @ <p>This page provides a simple interface to the "fossil setting" command. |
| 1339 | 1347 | @ See the "fossil help setting" output below for further information on |
| 1340 | 1348 | @ the meaning of each setting.</p><hr /> |
| 1341 | 1349 | @ <form action="%s(g.zTop)/setup_settings" method="post"><div> |
| 1342 | 1350 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -375,11 +375,11 @@ | |
| 375 | return; |
| 376 | } |
| 377 | login_verify_csrf_secret(); |
| 378 | db_multi_exec( |
| 379 | "REPLACE INTO user(uid,login,info,pw,cap,mtime) " |
| 380 | "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())", |
| 381 | uid, P("login"), P("info"), zPw, zCap |
| 382 | ); |
| 383 | if( atoi(PD("all","0"))>0 ){ |
| 384 | Blob sql; |
| 385 | char *zErr = 0; |
| @@ -477,11 +477,11 @@ | |
| 477 | |
| 478 | /* Begin generating the page |
| 479 | */ |
| 480 | style_submenu_element("Cancel", "Cancel", "setup_ulist"); |
| 481 | if( uid ){ |
| 482 | style_header(mprintf("Edit User %h", zLogin)); |
| 483 | }else{ |
| 484 | style_header("Add A New User"); |
| 485 | } |
| 486 | @ <div class="ueditCapBox"> |
| 487 | @ <form action="%s(g.zPath)" method="post"><div> |
| @@ -1075,10 +1075,14 @@ | |
| 1075 | @ every historical check-in, which can use a lot of CPU and bandwidth |
| 1076 | @ even for relatively small projects.</p> |
| 1077 | @ |
| 1078 | @ <p>Additional parameters that control this behavior:</p> |
| 1079 | @ <blockquote> |
| 1080 | onoff_attribute("Require mouse movement before enabling hyperlinks", |
| 1081 | "auto-hyperlink-mouseover", "ahmo", 0, 0); |
| 1082 | @ <br> |
| 1083 | entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5, |
| 1084 | "auto-hyperlink-delay", "ah-delay", "10", 0); |
| @@ -1157,11 +1161,11 @@ | |
| 1157 | login_check_credentials(); |
| 1158 | if( !g.perm.Setup ){ |
| 1159 | login_needed(); |
| 1160 | } |
| 1161 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1162 | zSelfRepo = mprintf(blob_str(&fullName)); |
| 1163 | blob_reset(&fullName); |
| 1164 | if( P("join")!=0 ){ |
| 1165 | login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg); |
| 1166 | }else if( P("leave") ){ |
| 1167 | login_group_leave(&zErrMsg); |
| @@ -1331,11 +1335,15 @@ | |
| 1331 | login_needed(); |
| 1332 | } |
| 1333 | |
| 1334 | (void) aCmdHelp; /* NOTE: Silence compiler warning. */ |
| 1335 | style_header("Settings"); |
| 1336 | db_open_local(0); |
| 1337 | db_begin_transaction(); |
| 1338 | @ <p>This page provides a simple interface to the "fossil setting" command. |
| 1339 | @ See the "fossil help setting" output below for further information on |
| 1340 | @ the meaning of each setting.</p><hr /> |
| 1341 | @ <form action="%s(g.zTop)/setup_settings" method="post"><div> |
| 1342 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -375,11 +375,11 @@ | |
| 375 | return; |
| 376 | } |
| 377 | login_verify_csrf_secret(); |
| 378 | db_multi_exec( |
| 379 | "REPLACE INTO user(uid,login,info,pw,cap,mtime) " |
| 380 | "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())", |
| 381 | uid, P("login"), P("info"), zPw, zCap |
| 382 | ); |
| 383 | if( atoi(PD("all","0"))>0 ){ |
| 384 | Blob sql; |
| 385 | char *zErr = 0; |
| @@ -477,11 +477,11 @@ | |
| 477 | |
| 478 | /* Begin generating the page |
| 479 | */ |
| 480 | style_submenu_element("Cancel", "Cancel", "setup_ulist"); |
| 481 | if( uid ){ |
| 482 | style_header("Edit User %h", zLogin); |
| 483 | }else{ |
| 484 | style_header("Add A New User"); |
| 485 | } |
| 486 | @ <div class="ueditCapBox"> |
| 487 | @ <form action="%s(g.zPath)" method="post"><div> |
| @@ -1075,10 +1075,14 @@ | |
| 1075 | @ every historical check-in, which can use a lot of CPU and bandwidth |
| 1076 | @ even for relatively small projects.</p> |
| 1077 | @ |
| 1078 | @ <p>Additional parameters that control this behavior:</p> |
| 1079 | @ <blockquote> |
| 1080 | onoff_attribute("Enable hyperlinks for humans (as deduced from the UserAgent " |
| 1081 | " HTTP header string)", |
| 1082 | "auto-hyperlink-ishuman", "ahis", 0, 0); |
| 1083 | @ <br> |
| 1084 | onoff_attribute("Require mouse movement before enabling hyperlinks", |
| 1085 | "auto-hyperlink-mouseover", "ahmo", 0, 0); |
| 1086 | @ <br> |
| 1087 | entry_attribute("Delay before enabling hyperlinks (milliseconds)", 5, |
| 1088 | "auto-hyperlink-delay", "ah-delay", "10", 0); |
| @@ -1157,11 +1161,11 @@ | |
| 1161 | login_check_credentials(); |
| 1162 | if( !g.perm.Setup ){ |
| 1163 | login_needed(); |
| 1164 | } |
| 1165 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1166 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 1167 | blob_reset(&fullName); |
| 1168 | if( P("join")!=0 ){ |
| 1169 | login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg); |
| 1170 | }else if( P("leave") ){ |
| 1171 | login_group_leave(&zErrMsg); |
| @@ -1331,11 +1335,15 @@ | |
| 1335 | login_needed(); |
| 1336 | } |
| 1337 | |
| 1338 | (void) aCmdHelp; /* NOTE: Silence compiler warning. */ |
| 1339 | style_header("Settings"); |
| 1340 | if(!g.repositoryOpen){ |
| 1341 | /* Provide read-only access to versioned settings, |
| 1342 | but only if no repo file was explicitly provided. */ |
| 1343 | db_open_local(0); |
| 1344 | } |
| 1345 | db_begin_transaction(); |
| 1346 | @ <p>This page provides a simple interface to the "fossil setting" command. |
| 1347 | @ See the "fossil help setting" output below for further information on |
| 1348 | @ the meaning of each setting.</p><hr /> |
| 1349 | @ <form action="%s(g.zTop)/setup_settings" method="post"><div> |
| 1350 |
+13
-1
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -880,11 +880,11 @@ | ||
| 880 | 880 | for(i=0; i<nArg; i++){ |
| 881 | 881 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 882 | 882 | } |
| 883 | 883 | fprintf(p->out,"%s",p->newline); |
| 884 | 884 | } |
| 885 | - if( azArg>0 ){ | |
| 885 | + if( nArg>0 ){ | |
| 886 | 886 | for(i=0; i<nArg; i++){ |
| 887 | 887 | output_csv(p, azArg[i], i<nArg-1); |
| 888 | 888 | } |
| 889 | 889 | fprintf(p->out,"%s",p->newline); |
| 890 | 890 | } |
| @@ -1350,10 +1350,21 @@ | ||
| 1350 | 1350 | } |
| 1351 | 1351 | } |
| 1352 | 1352 | sqlite3_finalize(pExplain); |
| 1353 | 1353 | sqlite3_free(zEQP); |
| 1354 | 1354 | } |
| 1355 | + | |
| 1356 | +#if USE_SYSTEM_SQLITE+0==1 | |
| 1357 | + /* Output TESTCTRL_EXPLAIN text of requested */ | |
| 1358 | + if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){ | |
| 1359 | + const char *zExplain = 0; | |
| 1360 | + sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); | |
| 1361 | + if( zExplain && zExplain[0] ){ | |
| 1362 | + fprintf(pArg->out, "%s", zExplain); | |
| 1363 | + } | |
| 1364 | + } | |
| 1365 | +#endif | |
| 1355 | 1366 | |
| 1356 | 1367 | /* If the shell is currently in ".explain" mode, gather the extra |
| 1357 | 1368 | ** data required to add indents to the output.*/ |
| 1358 | 1369 | if( pArg && pArg->mode==MODE_Explain ){ |
| 1359 | 1370 | explain_data_prepare(pArg, pStmt); |
| @@ -3723,10 +3734,11 @@ | ||
| 3723 | 3734 | } |
| 3724 | 3735 | } |
| 3725 | 3736 | if( nSql ){ |
| 3726 | 3737 | if( !_all_whitespace(zSql) ){ |
| 3727 | 3738 | fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); |
| 3739 | + errCnt++; | |
| 3728 | 3740 | } |
| 3729 | 3741 | free(zSql); |
| 3730 | 3742 | } |
| 3731 | 3743 | free(zLine); |
| 3732 | 3744 | return errCnt>0; |
| 3733 | 3745 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -880,11 +880,11 @@ | |
| 880 | for(i=0; i<nArg; i++){ |
| 881 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 882 | } |
| 883 | fprintf(p->out,"%s",p->newline); |
| 884 | } |
| 885 | if( azArg>0 ){ |
| 886 | for(i=0; i<nArg; i++){ |
| 887 | output_csv(p, azArg[i], i<nArg-1); |
| 888 | } |
| 889 | fprintf(p->out,"%s",p->newline); |
| 890 | } |
| @@ -1350,10 +1350,21 @@ | |
| 1350 | } |
| 1351 | } |
| 1352 | sqlite3_finalize(pExplain); |
| 1353 | sqlite3_free(zEQP); |
| 1354 | } |
| 1355 | |
| 1356 | /* If the shell is currently in ".explain" mode, gather the extra |
| 1357 | ** data required to add indents to the output.*/ |
| 1358 | if( pArg && pArg->mode==MODE_Explain ){ |
| 1359 | explain_data_prepare(pArg, pStmt); |
| @@ -3723,10 +3734,11 @@ | |
| 3723 | } |
| 3724 | } |
| 3725 | if( nSql ){ |
| 3726 | if( !_all_whitespace(zSql) ){ |
| 3727 | fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); |
| 3728 | } |
| 3729 | free(zSql); |
| 3730 | } |
| 3731 | free(zLine); |
| 3732 | return errCnt>0; |
| 3733 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -880,11 +880,11 @@ | |
| 880 | for(i=0; i<nArg; i++){ |
| 881 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 882 | } |
| 883 | fprintf(p->out,"%s",p->newline); |
| 884 | } |
| 885 | if( nArg>0 ){ |
| 886 | for(i=0; i<nArg; i++){ |
| 887 | output_csv(p, azArg[i], i<nArg-1); |
| 888 | } |
| 889 | fprintf(p->out,"%s",p->newline); |
| 890 | } |
| @@ -1350,10 +1350,21 @@ | |
| 1350 | } |
| 1351 | } |
| 1352 | sqlite3_finalize(pExplain); |
| 1353 | sqlite3_free(zEQP); |
| 1354 | } |
| 1355 | |
| 1356 | #if USE_SYSTEM_SQLITE+0==1 |
| 1357 | /* Output TESTCTRL_EXPLAIN text of requested */ |
| 1358 | if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){ |
| 1359 | const char *zExplain = 0; |
| 1360 | sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); |
| 1361 | if( zExplain && zExplain[0] ){ |
| 1362 | fprintf(pArg->out, "%s", zExplain); |
| 1363 | } |
| 1364 | } |
| 1365 | #endif |
| 1366 | |
| 1367 | /* If the shell is currently in ".explain" mode, gather the extra |
| 1368 | ** data required to add indents to the output.*/ |
| 1369 | if( pArg && pArg->mode==MODE_Explain ){ |
| 1370 | explain_data_prepare(pArg, pStmt); |
| @@ -3723,10 +3734,11 @@ | |
| 3734 | } |
| 3735 | } |
| 3736 | if( nSql ){ |
| 3737 | if( !_all_whitespace(zSql) ){ |
| 3738 | fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); |
| 3739 | errCnt++; |
| 3740 | } |
| 3741 | free(zSql); |
| 3742 | } |
| 3743 | free(zLine); |
| 3744 | return errCnt>0; |
| 3745 |
+9
-9
| --- src/shun.c | ||
| +++ src/shun.c | ||
| @@ -43,12 +43,11 @@ | ||
| 43 | 43 | int cnt = 0; |
| 44 | 44 | const char *zUuid = P("uuid"); |
| 45 | 45 | const char *zShun = P("shun"); |
| 46 | 46 | const char *zAccept = P("accept"); |
| 47 | 47 | const char *zRcvid = P("rcvid"); |
| 48 | - int nRcvid; | |
| 49 | - int nUuid; | |
| 48 | + int nRcvid = 0; | |
| 50 | 49 | int numRows = 3; |
| 51 | 50 | char *zCanonical = 0; |
| 52 | 51 | |
| 53 | 52 | login_check_credentials(); |
| 54 | 53 | if( !g.perm.Admin ){ |
| @@ -79,11 +78,11 @@ | ||
| 79 | 78 | i++; |
| 80 | 79 | } |
| 81 | 80 | zCanonical[j+1] = zCanonical[j] = 0; |
| 82 | 81 | p = zCanonical; |
| 83 | 82 | while( *p ){ |
| 84 | - nUuid = strlen(p); | |
| 83 | + int nUuid = strlen(p); | |
| 85 | 84 | if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){ |
| 86 | 85 | @ <p class="generalError">Error: Bad artifact IDs.</p> |
| 87 | 86 | fossil_free(zCanonical); |
| 88 | 87 | zCanonical = 0; |
| 89 | 88 | break; |
| @@ -98,12 +97,12 @@ | ||
| 98 | 97 | if( zUuid && P("sub") ){ |
| 99 | 98 | const char *p = zUuid; |
| 100 | 99 | int allExist = 1; |
| 101 | 100 | login_verify_csrf_secret(); |
| 102 | 101 | while( *p ){ |
| 103 | - db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p); | |
| 104 | - if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){ | |
| 102 | + db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p); | |
| 103 | + if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){ | |
| 105 | 104 | allExist = 0; |
| 106 | 105 | } |
| 107 | 106 | p += UUID_SIZE+1; |
| 108 | 107 | } |
| 109 | 108 | if( allExist ){ |
| @@ -128,11 +127,11 @@ | ||
| 128 | 127 | int rid, tagid; |
| 129 | 128 | login_verify_csrf_secret(); |
| 130 | 129 | while( *p ){ |
| 131 | 130 | db_multi_exec( |
| 132 | 131 | "INSERT OR IGNORE INTO shun(uuid,mtime)" |
| 133 | - " VALUES('%s', now())", p); | |
| 132 | + " VALUES(%Q, now())", p); | |
| 134 | 133 | db_multi_exec("DELETE FROM attachment WHERE src=%Q", p); |
| 135 | 134 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p); |
| 136 | 135 | if( rid ){ |
| 137 | 136 | db_multi_exec("DELETE FROM event WHERE objid=%d", rid); |
| 138 | 137 | } |
| @@ -152,11 +151,12 @@ | ||
| 152 | 151 | @ They will be removed from the repository the next time the repository |
| 153 | 152 | @ is rebuilt using the <b>fossil rebuild</b> command-line</p> |
| 154 | 153 | } |
| 155 | 154 | if( zRcvid ){ |
| 156 | 155 | nRcvid = atoi(zRcvid); |
| 157 | - numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid); | |
| 156 | + numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", | |
| 157 | + nRcvid); | |
| 158 | 158 | } |
| 159 | 159 | @ <p>A shunned artifact will not be pushed nor accepted in a pull and the |
| 160 | 160 | @ artifact content will be purged from the repository the next time the |
| 161 | 161 | @ repository is rebuilt. A list of shunned artifacts can be seen at the |
| 162 | 162 | @ bottom of this page.</p> |
| @@ -183,11 +183,11 @@ | ||
| 183 | 183 | login_insert_csrf_secret(); |
| 184 | 184 | @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid"> |
| 185 | 185 | if( zShun ){ |
| 186 | 186 | if( strlen(zShun) ){ |
| 187 | 187 | @ %h(zShun) |
| 188 | - }else if( zRcvid ){ | |
| 188 | + }else if( nRcvid ){ | |
| 189 | 189 | db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid); |
| 190 | 190 | while( db_step(&q)==SQLITE_ROW ){ |
| 191 | 191 | @ %s(db_column_text(&q, 0)) |
| 192 | 192 | } |
| 193 | 193 | db_finalize(&q); |
| @@ -210,11 +210,11 @@ | ||
| 210 | 210 | login_insert_csrf_secret(); |
| 211 | 211 | @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid"> |
| 212 | 212 | if( zAccept ){ |
| 213 | 213 | if( strlen(zAccept) ){ |
| 214 | 214 | @ %h(zAccept) |
| 215 | - }else if( zRcvid ){ | |
| 215 | + }else if( nRcvid ){ | |
| 216 | 216 | db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid); |
| 217 | 217 | while( db_step(&q)==SQLITE_ROW ){ |
| 218 | 218 | @ %s(db_column_text(&q, 0)) |
| 219 | 219 | } |
| 220 | 220 | db_finalize(&q); |
| 221 | 221 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -43,12 +43,11 @@ | |
| 43 | int cnt = 0; |
| 44 | const char *zUuid = P("uuid"); |
| 45 | const char *zShun = P("shun"); |
| 46 | const char *zAccept = P("accept"); |
| 47 | const char *zRcvid = P("rcvid"); |
| 48 | int nRcvid; |
| 49 | int nUuid; |
| 50 | int numRows = 3; |
| 51 | char *zCanonical = 0; |
| 52 | |
| 53 | login_check_credentials(); |
| 54 | if( !g.perm.Admin ){ |
| @@ -79,11 +78,11 @@ | |
| 79 | i++; |
| 80 | } |
| 81 | zCanonical[j+1] = zCanonical[j] = 0; |
| 82 | p = zCanonical; |
| 83 | while( *p ){ |
| 84 | nUuid = strlen(p); |
| 85 | if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){ |
| 86 | @ <p class="generalError">Error: Bad artifact IDs.</p> |
| 87 | fossil_free(zCanonical); |
| 88 | zCanonical = 0; |
| 89 | break; |
| @@ -98,12 +97,12 @@ | |
| 98 | if( zUuid && P("sub") ){ |
| 99 | const char *p = zUuid; |
| 100 | int allExist = 1; |
| 101 | login_verify_csrf_secret(); |
| 102 | while( *p ){ |
| 103 | db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p); |
| 104 | if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){ |
| 105 | allExist = 0; |
| 106 | } |
| 107 | p += UUID_SIZE+1; |
| 108 | } |
| 109 | if( allExist ){ |
| @@ -128,11 +127,11 @@ | |
| 128 | int rid, tagid; |
| 129 | login_verify_csrf_secret(); |
| 130 | while( *p ){ |
| 131 | db_multi_exec( |
| 132 | "INSERT OR IGNORE INTO shun(uuid,mtime)" |
| 133 | " VALUES('%s', now())", p); |
| 134 | db_multi_exec("DELETE FROM attachment WHERE src=%Q", p); |
| 135 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p); |
| 136 | if( rid ){ |
| 137 | db_multi_exec("DELETE FROM event WHERE objid=%d", rid); |
| 138 | } |
| @@ -152,11 +151,12 @@ | |
| 152 | @ They will be removed from the repository the next time the repository |
| 153 | @ is rebuilt using the <b>fossil rebuild</b> command-line</p> |
| 154 | } |
| 155 | if( zRcvid ){ |
| 156 | nRcvid = atoi(zRcvid); |
| 157 | numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid); |
| 158 | } |
| 159 | @ <p>A shunned artifact will not be pushed nor accepted in a pull and the |
| 160 | @ artifact content will be purged from the repository the next time the |
| 161 | @ repository is rebuilt. A list of shunned artifacts can be seen at the |
| 162 | @ bottom of this page.</p> |
| @@ -183,11 +183,11 @@ | |
| 183 | login_insert_csrf_secret(); |
| 184 | @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid"> |
| 185 | if( zShun ){ |
| 186 | if( strlen(zShun) ){ |
| 187 | @ %h(zShun) |
| 188 | }else if( zRcvid ){ |
| 189 | db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid); |
| 190 | while( db_step(&q)==SQLITE_ROW ){ |
| 191 | @ %s(db_column_text(&q, 0)) |
| 192 | } |
| 193 | db_finalize(&q); |
| @@ -210,11 +210,11 @@ | |
| 210 | login_insert_csrf_secret(); |
| 211 | @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid"> |
| 212 | if( zAccept ){ |
| 213 | if( strlen(zAccept) ){ |
| 214 | @ %h(zAccept) |
| 215 | }else if( zRcvid ){ |
| 216 | db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid); |
| 217 | while( db_step(&q)==SQLITE_ROW ){ |
| 218 | @ %s(db_column_text(&q, 0)) |
| 219 | } |
| 220 | db_finalize(&q); |
| 221 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -43,12 +43,11 @@ | |
| 43 | int cnt = 0; |
| 44 | const char *zUuid = P("uuid"); |
| 45 | const char *zShun = P("shun"); |
| 46 | const char *zAccept = P("accept"); |
| 47 | const char *zRcvid = P("rcvid"); |
| 48 | int nRcvid = 0; |
| 49 | int numRows = 3; |
| 50 | char *zCanonical = 0; |
| 51 | |
| 52 | login_check_credentials(); |
| 53 | if( !g.perm.Admin ){ |
| @@ -79,11 +78,11 @@ | |
| 78 | i++; |
| 79 | } |
| 80 | zCanonical[j+1] = zCanonical[j] = 0; |
| 81 | p = zCanonical; |
| 82 | while( *p ){ |
| 83 | int nUuid = strlen(p); |
| 84 | if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){ |
| 85 | @ <p class="generalError">Error: Bad artifact IDs.</p> |
| 86 | fossil_free(zCanonical); |
| 87 | zCanonical = 0; |
| 88 | break; |
| @@ -98,12 +97,12 @@ | |
| 97 | if( zUuid && P("sub") ){ |
| 98 | const char *p = zUuid; |
| 99 | int allExist = 1; |
| 100 | login_verify_csrf_secret(); |
| 101 | while( *p ){ |
| 102 | db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p); |
| 103 | if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){ |
| 104 | allExist = 0; |
| 105 | } |
| 106 | p += UUID_SIZE+1; |
| 107 | } |
| 108 | if( allExist ){ |
| @@ -128,11 +127,11 @@ | |
| 127 | int rid, tagid; |
| 128 | login_verify_csrf_secret(); |
| 129 | while( *p ){ |
| 130 | db_multi_exec( |
| 131 | "INSERT OR IGNORE INTO shun(uuid,mtime)" |
| 132 | " VALUES(%Q, now())", p); |
| 133 | db_multi_exec("DELETE FROM attachment WHERE src=%Q", p); |
| 134 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p); |
| 135 | if( rid ){ |
| 136 | db_multi_exec("DELETE FROM event WHERE objid=%d", rid); |
| 137 | } |
| @@ -152,11 +151,12 @@ | |
| 151 | @ They will be removed from the repository the next time the repository |
| 152 | @ is rebuilt using the <b>fossil rebuild</b> command-line</p> |
| 153 | } |
| 154 | if( zRcvid ){ |
| 155 | nRcvid = atoi(zRcvid); |
| 156 | numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", |
| 157 | nRcvid); |
| 158 | } |
| 159 | @ <p>A shunned artifact will not be pushed nor accepted in a pull and the |
| 160 | @ artifact content will be purged from the repository the next time the |
| 161 | @ repository is rebuilt. A list of shunned artifacts can be seen at the |
| 162 | @ bottom of this page.</p> |
| @@ -183,11 +183,11 @@ | |
| 183 | login_insert_csrf_secret(); |
| 184 | @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid"> |
| 185 | if( zShun ){ |
| 186 | if( strlen(zShun) ){ |
| 187 | @ %h(zShun) |
| 188 | }else if( nRcvid ){ |
| 189 | db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid); |
| 190 | while( db_step(&q)==SQLITE_ROW ){ |
| 191 | @ %s(db_column_text(&q, 0)) |
| 192 | } |
| 193 | db_finalize(&q); |
| @@ -210,11 +210,11 @@ | |
| 210 | login_insert_csrf_secret(); |
| 211 | @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid"> |
| 212 | if( zAccept ){ |
| 213 | if( strlen(zAccept) ){ |
| 214 | @ %h(zAccept) |
| 215 | }else if( nRcvid ){ |
| 216 | db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid); |
| 217 | while( db_step(&q)==SQLITE_ROW ){ |
| 218 | @ %s(db_column_text(&q, 0)) |
| 219 | } |
| 220 | db_finalize(&q); |
| 221 |
+2
-2
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -1392,18 +1392,18 @@ | ||
| 1392 | 1392 | seen = 0; |
| 1393 | 1393 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1394 | 1394 | if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){ |
| 1395 | 1395 | seen = 1; |
| 1396 | 1396 | zCurrent = aBuiltinSkin[i].zValue; |
| 1397 | - db_multi_exec("%s", zCurrent); | |
| 1397 | + db_multi_exec("%s", zCurrent/*safe-for-%s*/); | |
| 1398 | 1398 | break; |
| 1399 | 1399 | } |
| 1400 | 1400 | } |
| 1401 | 1401 | if( !seen ){ |
| 1402 | 1402 | zName = skinVarName(z,0); |
| 1403 | 1403 | zCurrent = db_get(zName, 0); |
| 1404 | - db_multi_exec("%s", zCurrent); | |
| 1404 | + db_multi_exec("%s", zCurrent/*safe-for-%s*/); | |
| 1405 | 1405 | } |
| 1406 | 1406 | } |
| 1407 | 1407 | |
| 1408 | 1408 | style_header("Skins"); |
| 1409 | 1409 | if( zErr ){ |
| 1410 | 1410 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -1392,18 +1392,18 @@ | |
| 1392 | seen = 0; |
| 1393 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1394 | if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){ |
| 1395 | seen = 1; |
| 1396 | zCurrent = aBuiltinSkin[i].zValue; |
| 1397 | db_multi_exec("%s", zCurrent); |
| 1398 | break; |
| 1399 | } |
| 1400 | } |
| 1401 | if( !seen ){ |
| 1402 | zName = skinVarName(z,0); |
| 1403 | zCurrent = db_get(zName, 0); |
| 1404 | db_multi_exec("%s", zCurrent); |
| 1405 | } |
| 1406 | } |
| 1407 | |
| 1408 | style_header("Skins"); |
| 1409 | if( zErr ){ |
| 1410 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -1392,18 +1392,18 @@ | |
| 1392 | seen = 0; |
| 1393 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1394 | if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){ |
| 1395 | seen = 1; |
| 1396 | zCurrent = aBuiltinSkin[i].zValue; |
| 1397 | db_multi_exec("%s", zCurrent/*safe-for-%s*/); |
| 1398 | break; |
| 1399 | } |
| 1400 | } |
| 1401 | if( !seen ){ |
| 1402 | zName = skinVarName(z,0); |
| 1403 | zCurrent = db_get(zName, 0); |
| 1404 | db_multi_exec("%s", zCurrent/*safe-for-%s*/); |
| 1405 | } |
| 1406 | } |
| 1407 | |
| 1408 | style_header("Skins"); |
| 1409 | if( zErr ){ |
| 1410 |
+4
| --- src/sqlcmd.c | ||
| +++ src/sqlcmd.c | ||
| @@ -148,11 +148,15 @@ | ||
| 148 | 148 | extern int sqlite3_shell(int, char**); |
| 149 | 149 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 150 | 150 | db_close(1); |
| 151 | 151 | sqlite3_shutdown(); |
| 152 | 152 | sqlite3_shell(g.argc-1, g.argv+1); |
| 153 | + sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit); | |
| 153 | 154 | g.db = 0; |
| 155 | + g.zMainDbType = 0; | |
| 156 | + g.repositoryOpen = 0; | |
| 157 | + g.localOpen = 0; | |
| 154 | 158 | } |
| 155 | 159 | |
| 156 | 160 | /* |
| 157 | 161 | ** This routine is called by the patched sqlite3 command-line shell in order |
| 158 | 162 | ** to load the name and database connection for the open Fossil database. |
| 159 | 163 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -148,11 +148,15 @@ | |
| 148 | extern int sqlite3_shell(int, char**); |
| 149 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 150 | db_close(1); |
| 151 | sqlite3_shutdown(); |
| 152 | sqlite3_shell(g.argc-1, g.argv+1); |
| 153 | g.db = 0; |
| 154 | } |
| 155 | |
| 156 | /* |
| 157 | ** This routine is called by the patched sqlite3 command-line shell in order |
| 158 | ** to load the name and database connection for the open Fossil database. |
| 159 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -148,11 +148,15 @@ | |
| 148 | extern int sqlite3_shell(int, char**); |
| 149 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 150 | db_close(1); |
| 151 | sqlite3_shutdown(); |
| 152 | sqlite3_shell(g.argc-1, g.argv+1); |
| 153 | sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit); |
| 154 | g.db = 0; |
| 155 | g.zMainDbType = 0; |
| 156 | g.repositoryOpen = 0; |
| 157 | g.localOpen = 0; |
| 158 | } |
| 159 | |
| 160 | /* |
| 161 | ** This routine is called by the patched sqlite3 command-line shell in order |
| 162 | ** to load the name and database connection for the open Fossil database. |
| 163 |
+315
-232
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | -** version 3.8.7. By combining all the individual C code files into this | |
| 3 | +** version 3.8.7.1. By combining all the individual C code files into this | |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| @@ -229,13 +229,13 @@ | ||
| 229 | 229 | ** |
| 230 | 230 | ** See also: [sqlite3_libversion()], |
| 231 | 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | 233 | */ |
| 234 | -#define SQLITE_VERSION "3.8.7" | |
| 234 | +#define SQLITE_VERSION "3.8.7.1" | |
| 235 | 235 | #define SQLITE_VERSION_NUMBER 3008007 |
| 236 | -#define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d" | |
| 236 | +#define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52" | |
| 237 | 237 | |
| 238 | 238 | /* |
| 239 | 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | 241 | ** |
| @@ -7944,11 +7944,11 @@ | ||
| 7944 | 7944 | ** A macro to hint to the compiler that a function should not be |
| 7945 | 7945 | ** inlined. |
| 7946 | 7946 | */ |
| 7947 | 7947 | #if defined(__GNUC__) |
| 7948 | 7948 | # define SQLITE_NOINLINE __attribute__((noinline)) |
| 7949 | -#elif defined(_MSC_VER) | |
| 7949 | +#elif defined(_MSC_VER) && _MSC_VER>=1310 | |
| 7950 | 7950 | # define SQLITE_NOINLINE __declspec(noinline) |
| 7951 | 7951 | #else |
| 7952 | 7952 | # define SQLITE_NOINLINE |
| 7953 | 7953 | #endif |
| 7954 | 7954 | |
| @@ -11322,10 +11322,11 @@ | ||
| 11322 | 11322 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 11323 | 11323 | int nSample; /* Number of elements in aSample[] */ |
| 11324 | 11324 | int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 11325 | 11325 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 11326 | 11326 | IndexSample *aSample; /* Samples of the left-most key */ |
| 11327 | + tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this table */ | |
| 11327 | 11328 | #endif |
| 11328 | 11329 | }; |
| 11329 | 11330 | |
| 11330 | 11331 | /* |
| 11331 | 11332 | ** Allowed values for Index.idxType |
| @@ -12186,11 +12187,10 @@ | ||
| 12186 | 12187 | #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ |
| 12187 | 12188 | #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ |
| 12188 | 12189 | #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ |
| 12189 | 12190 | #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ |
| 12190 | 12191 | #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ |
| 12191 | -#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ | |
| 12192 | 12192 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 12193 | 12193 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 12194 | 12194 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ |
| 12195 | 12195 | #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ |
| 12196 | 12196 | #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ |
| @@ -13320,14 +13320,13 @@ | ||
| 13320 | 13320 | # define sqlite3MemdebugSetType(X,Y) /* no-op */ |
| 13321 | 13321 | # define sqlite3MemdebugHasType(X,Y) 1 |
| 13322 | 13322 | # define sqlite3MemdebugNoType(X,Y) 1 |
| 13323 | 13323 | #endif |
| 13324 | 13324 | #define MEMTYPE_HEAP 0x01 /* General heap allocations */ |
| 13325 | -#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ | |
| 13325 | +#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ | |
| 13326 | 13326 | #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ |
| 13327 | 13327 | #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ |
| 13328 | -#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */ | |
| 13329 | 13328 | |
| 13330 | 13329 | /* |
| 13331 | 13330 | ** Threading interface |
| 13332 | 13331 | */ |
| 13333 | 13332 | #if SQLITE_MAX_WORKER_THREADS>0 |
| @@ -14095,21 +14094,19 @@ | ||
| 14095 | 14094 | #ifdef SQLITE_DEBUG |
| 14096 | 14095 | u8 seekOp; /* Most recent seek operation on this cursor */ |
| 14097 | 14096 | #endif |
| 14098 | 14097 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 14099 | 14098 | u8 nullRow; /* True if pointing to a row with no data */ |
| 14100 | - u8 rowidIsValid; /* True if lastRowid is valid */ | |
| 14101 | 14099 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 14102 | 14100 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 14103 | 14101 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 14104 | 14102 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 14105 | 14103 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 14106 | 14104 | Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 14107 | 14105 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 14108 | 14106 | i64 seqCount; /* Sequence counter */ |
| 14109 | 14107 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 14110 | - i64 lastRowid; /* Rowid being deleted by OP_Delete */ | |
| 14111 | 14108 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| 14112 | 14109 | |
| 14113 | 14110 | /* Cached information about the header for the data record that the |
| 14114 | 14111 | ** cursor is currently pointing to. Only valid if cacheStatus matches |
| 14115 | 14112 | ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| @@ -14122,10 +14119,11 @@ | ||
| 14122 | 14119 | u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
| 14123 | 14120 | u32 payloadSize; /* Total number of bytes in the record */ |
| 14124 | 14121 | u32 szRow; /* Byte available in aRow */ |
| 14125 | 14122 | u32 iHdrOffset; /* Offset to next unparsed byte of the header */ |
| 14126 | 14123 | const u8 *aRow; /* Data for the current row, if all on one page */ |
| 14124 | + u32 *aOffset; /* Pointer to aType[nField] */ | |
| 14127 | 14125 | u32 aType[1]; /* Type values for all entries in the record */ |
| 14128 | 14126 | /* 2*nField extra array elements allocated for aType[], beyond the one |
| 14129 | 14127 | ** static element declared in the structure. nField total array slots for |
| 14130 | 14128 | ** aType[] and nField+1 array slots for aOffset[] */ |
| 14131 | 14129 | }; |
| @@ -14198,11 +14196,11 @@ | ||
| 14198 | 14196 | int n; /* Number of characters in string value, excluding '\0' */ |
| 14199 | 14197 | char *z; /* String or BLOB value */ |
| 14200 | 14198 | /* ShallowCopy only needs to copy the information above */ |
| 14201 | 14199 | char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ |
| 14202 | 14200 | int szMalloc; /* Size of the zMalloc allocation */ |
| 14203 | - int iPadding1; /* Padding for 8-byte alignment */ | |
| 14201 | + u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ | |
| 14204 | 14202 | sqlite3 *db; /* The associated database connection */ |
| 14205 | 14203 | void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ |
| 14206 | 14204 | #ifdef SQLITE_DEBUG |
| 14207 | 14205 | Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ |
| 14208 | 14206 | void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ |
| @@ -14406,10 +14404,11 @@ | ||
| 14406 | 14404 | ** Function prototypes |
| 14407 | 14405 | */ |
| 14408 | 14406 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); |
| 14409 | 14407 | void sqliteVdbePopStack(Vdbe*,int); |
| 14410 | 14408 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*); |
| 14409 | +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); | |
| 14411 | 14410 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 14412 | 14411 | SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); |
| 14413 | 14412 | #endif |
| 14414 | 14413 | SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); |
| 14415 | 14414 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); |
| @@ -17130,11 +17129,11 @@ | ||
| 17130 | 17129 | ** allocation p. Also return true if p==NULL. |
| 17131 | 17130 | ** |
| 17132 | 17131 | ** This routine is designed for use within an assert() statement, to |
| 17133 | 17132 | ** verify the type of an allocation. For example: |
| 17134 | 17133 | ** |
| 17135 | -** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); | |
| 17134 | +** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); | |
| 17136 | 17135 | */ |
| 17137 | 17136 | SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ |
| 17138 | 17137 | int rc = 1; |
| 17139 | 17138 | if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ |
| 17140 | 17139 | struct MemBlockHdr *pHdr; |
| @@ -17152,11 +17151,11 @@ | ||
| 17152 | 17151 | ** allocation p. Also return true if p==NULL. |
| 17153 | 17152 | ** |
| 17154 | 17153 | ** This routine is designed for use within an assert() statement, to |
| 17155 | 17154 | ** verify the type of an allocation. For example: |
| 17156 | 17155 | ** |
| 17157 | -** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); | |
| 17156 | +** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); | |
| 17158 | 17157 | */ |
| 17159 | 17158 | SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ |
| 17160 | 17159 | int rc = 1; |
| 17161 | 17160 | if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ |
| 17162 | 17161 | struct MemBlockHdr *pHdr; |
| @@ -20364,39 +20363,41 @@ | ||
| 20364 | 20363 | ** Return the size of a memory allocation previously obtained from |
| 20365 | 20364 | ** sqlite3Malloc() or sqlite3_malloc(). |
| 20366 | 20365 | */ |
| 20367 | 20366 | SQLITE_PRIVATE int sqlite3MallocSize(void *p){ |
| 20368 | 20367 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20369 | - assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); | |
| 20370 | 20368 | return sqlite3GlobalConfig.m.xSize(p); |
| 20371 | 20369 | } |
| 20372 | 20370 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ |
| 20373 | 20371 | if( db==0 ){ |
| 20372 | + assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); | |
| 20373 | + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); | |
| 20374 | 20374 | return sqlite3MallocSize(p); |
| 20375 | 20375 | }else{ |
| 20376 | 20376 | assert( sqlite3_mutex_held(db->mutex) ); |
| 20377 | 20377 | if( isLookaside(db, p) ){ |
| 20378 | 20378 | return db->lookaside.sz; |
| 20379 | 20379 | }else{ |
| 20380 | - assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); | |
| 20381 | - assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); | |
| 20382 | - assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); | |
| 20380 | + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | |
| 20381 | + assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | |
| 20383 | 20382 | return sqlite3GlobalConfig.m.xSize(p); |
| 20384 | 20383 | } |
| 20385 | 20384 | } |
| 20386 | 20385 | } |
| 20387 | 20386 | SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ |
| 20387 | + assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); | |
| 20388 | + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); | |
| 20388 | 20389 | return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p); |
| 20389 | 20390 | } |
| 20390 | 20391 | |
| 20391 | 20392 | /* |
| 20392 | 20393 | ** Free memory previously obtained from sqlite3Malloc(). |
| 20393 | 20394 | */ |
| 20394 | 20395 | SQLITE_API void sqlite3_free(void *p){ |
| 20395 | 20396 | if( p==0 ) return; /* IMP: R-49053-54554 */ |
| 20396 | - assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); | |
| 20397 | 20397 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20398 | + assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); | |
| 20398 | 20399 | if( sqlite3GlobalConfig.bMemstat ){ |
| 20399 | 20400 | sqlite3_mutex_enter(mem0.mutex); |
| 20400 | 20401 | sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); |
| 20401 | 20402 | sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); |
| 20402 | 20403 | sqlite3GlobalConfig.m.xFree(p); |
| @@ -20436,12 +20437,12 @@ | ||
| 20436 | 20437 | db->lookaside.pFree = pBuf; |
| 20437 | 20438 | db->lookaside.nOut--; |
| 20438 | 20439 | return; |
| 20439 | 20440 | } |
| 20440 | 20441 | } |
| 20441 | - assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); | |
| 20442 | - assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); | |
| 20442 | + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | |
| 20443 | + assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | |
| 20443 | 20444 | assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); |
| 20444 | 20445 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 20445 | 20446 | sqlite3_free(p); |
| 20446 | 20447 | } |
| 20447 | 20448 | |
| @@ -20449,10 +20450,12 @@ | ||
| 20449 | 20450 | ** Change the size of an existing memory allocation |
| 20450 | 20451 | */ |
| 20451 | 20452 | SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ |
| 20452 | 20453 | int nOld, nNew, nDiff; |
| 20453 | 20454 | void *pNew; |
| 20455 | + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); | |
| 20456 | + assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); | |
| 20454 | 20457 | if( pOld==0 ){ |
| 20455 | 20458 | return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ |
| 20456 | 20459 | } |
| 20457 | 20460 | if( nBytes==0 ){ |
| 20458 | 20461 | sqlite3_free(pOld); /* IMP: R-26507-47431 */ |
| @@ -20475,12 +20478,10 @@ | ||
| 20475 | 20478 | nDiff = nNew - nOld; |
| 20476 | 20479 | if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= |
| 20477 | 20480 | mem0.alarmThreshold-nDiff ){ |
| 20478 | 20481 | sqlite3MallocAlarm(nDiff); |
| 20479 | 20482 | } |
| 20480 | - assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); | |
| 20481 | - assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); | |
| 20482 | 20483 | pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); |
| 20483 | 20484 | if( pNew==0 && mem0.alarmCallback ){ |
| 20484 | 20485 | sqlite3MallocAlarm((int)nBytes); |
| 20485 | 20486 | pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); |
| 20486 | 20487 | } |
| @@ -20589,12 +20590,12 @@ | ||
| 20589 | 20590 | #endif |
| 20590 | 20591 | p = sqlite3Malloc(n); |
| 20591 | 20592 | if( !p && db ){ |
| 20592 | 20593 | db->mallocFailed = 1; |
| 20593 | 20594 | } |
| 20594 | - sqlite3MemdebugSetType(p, MEMTYPE_DB | | |
| 20595 | - ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); | |
| 20595 | + sqlite3MemdebugSetType(p, | |
| 20596 | + (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); | |
| 20596 | 20597 | return p; |
| 20597 | 20598 | } |
| 20598 | 20599 | |
| 20599 | 20600 | /* |
| 20600 | 20601 | ** Resize the block of memory pointed to by p to n bytes. If the |
| @@ -20616,19 +20617,18 @@ | ||
| 20616 | 20617 | if( pNew ){ |
| 20617 | 20618 | memcpy(pNew, p, db->lookaside.sz); |
| 20618 | 20619 | sqlite3DbFree(db, p); |
| 20619 | 20620 | } |
| 20620 | 20621 | }else{ |
| 20621 | - assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); | |
| 20622 | - assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); | |
| 20622 | + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | |
| 20623 | + assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | |
| 20623 | 20624 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 20624 | 20625 | pNew = sqlite3_realloc64(p, n); |
| 20625 | 20626 | if( !pNew ){ |
| 20626 | - sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP); | |
| 20627 | 20627 | db->mallocFailed = 1; |
| 20628 | 20628 | } |
| 20629 | - sqlite3MemdebugSetType(pNew, MEMTYPE_DB | | |
| 20629 | + sqlite3MemdebugSetType(pNew, | |
| 20630 | 20630 | (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); |
| 20631 | 20631 | } |
| 20632 | 20632 | } |
| 20633 | 20633 | return pNew; |
| 20634 | 20634 | } |
| @@ -20754,15 +20754,11 @@ | ||
| 20754 | 20754 | ** HAVE_STRCHRNUL. If that routine is not available, this module |
| 20755 | 20755 | ** will supply its own. The built-in version is slower than |
| 20756 | 20756 | ** the glibc version so the glibc version is definitely preferred. |
| 20757 | 20757 | */ |
| 20758 | 20758 | #if !defined(HAVE_STRCHRNUL) |
| 20759 | -# if defined(linux) | |
| 20760 | -# define HAVE_STRCHRNUL 1 | |
| 20761 | -# else | |
| 20762 | -# define HAVE_STRCHRNUL 0 | |
| 20763 | -# endif | |
| 20759 | +# define HAVE_STRCHRNUL 0 | |
| 20764 | 20760 | #endif |
| 20765 | 20761 | |
| 20766 | 20762 | |
| 20767 | 20763 | /* |
| 20768 | 20764 | ** Conversion types fall into various categories as defined by the |
| @@ -22091,18 +22087,18 @@ | ||
| 22091 | 22087 | #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ |
| 22092 | 22088 | /******************************** End Unix Pthreads *************************/ |
| 22093 | 22089 | |
| 22094 | 22090 | |
| 22095 | 22091 | /********************************* Win32 Threads ****************************/ |
| 22096 | -#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 | |
| 22092 | +#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 | |
| 22097 | 22093 | |
| 22098 | 22094 | #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ |
| 22099 | 22095 | #include <process.h> |
| 22100 | 22096 | |
| 22101 | 22097 | /* A running thread */ |
| 22102 | 22098 | struct SQLiteThread { |
| 22103 | - uintptr_t tid; /* The thread handle */ | |
| 22099 | + void *tid; /* The thread handle */ | |
| 22104 | 22100 | unsigned id; /* The thread identifier */ |
| 22105 | 22101 | void *(*xTask)(void*); /* The routine to run as a thread */ |
| 22106 | 22102 | void *pIn; /* Argument to xTask */ |
| 22107 | 22103 | void *pResult; /* Result of xTask */ |
| 22108 | 22104 | }; |
| @@ -22146,11 +22142,11 @@ | ||
| 22146 | 22142 | if( sqlite3GlobalConfig.bCoreMutex==0 ){ |
| 22147 | 22143 | memset(p, 0, sizeof(*p)); |
| 22148 | 22144 | }else{ |
| 22149 | 22145 | p->xTask = xTask; |
| 22150 | 22146 | p->pIn = pIn; |
| 22151 | - p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); | |
| 22147 | + p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); | |
| 22152 | 22148 | if( p->tid==0 ){ |
| 22153 | 22149 | memset(p, 0, sizeof(*p)); |
| 22154 | 22150 | } |
| 22155 | 22151 | } |
| 22156 | 22152 | if( p->xTask==0 ){ |
| @@ -22184,11 +22180,11 @@ | ||
| 22184 | 22180 | if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; |
| 22185 | 22181 | sqlite3_free(p); |
| 22186 | 22182 | return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; |
| 22187 | 22183 | } |
| 22188 | 22184 | |
| 22189 | -#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */ | |
| 22185 | +#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */ | |
| 22190 | 22186 | /******************************** End Win32 Threads *************************/ |
| 22191 | 22187 | |
| 22192 | 22188 | |
| 22193 | 22189 | /********************************* Single-Threaded **************************/ |
| 22194 | 22190 | #ifndef SQLITE_THREADS_IMPLEMENTED |
| @@ -33487,11 +33483,15 @@ | ||
| 33487 | 33483 | #endif |
| 33488 | 33484 | |
| 33489 | 33485 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 33490 | 33486 | DWORD))aSyscall[63].pCurrent) |
| 33491 | 33487 | |
| 33488 | +#if !SQLITE_OS_WINCE | |
| 33492 | 33489 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 33490 | +#else | |
| 33491 | + { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, | |
| 33492 | +#endif | |
| 33493 | 33493 | |
| 33494 | 33494 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 33495 | 33495 | BOOL))aSyscall[64].pCurrent) |
| 33496 | 33496 | |
| 33497 | 33497 | #if SQLITE_OS_WINRT |
| @@ -33830,11 +33830,12 @@ | ||
| 33830 | 33830 | #else |
| 33831 | 33831 | osSleep(milliseconds); |
| 33832 | 33832 | #endif |
| 33833 | 33833 | } |
| 33834 | 33834 | |
| 33835 | -#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 | |
| 33835 | +#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ | |
| 33836 | + SQLITE_THREADSAFE>0 | |
| 33836 | 33837 | SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ |
| 33837 | 33838 | DWORD rc; |
| 33838 | 33839 | while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, |
| 33839 | 33840 | TRUE))==WAIT_IO_COMPLETION ){} |
| 33840 | 33841 | return rc; |
| @@ -39855,11 +39856,11 @@ | ||
| 39855 | 39856 | assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); |
| 39856 | 39857 | assert( pCache->n90pct == pCache->nMax*9/10 ); |
| 39857 | 39858 | if( createFlag==1 && ( |
| 39858 | 39859 | nPinned>=pGroup->mxPinned |
| 39859 | 39860 | || nPinned>=pCache->n90pct |
| 39860 | - || pcache1UnderMemoryPressure(pCache) | |
| 39861 | + || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned) | |
| 39861 | 39862 | )){ |
| 39862 | 39863 | return 0; |
| 39863 | 39864 | } |
| 39864 | 39865 | |
| 39865 | 39866 | if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache); |
| @@ -42799,10 +42800,18 @@ | ||
| 42799 | 42800 | }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ |
| 42800 | 42801 | if( pPager->journalOff==0 ){ |
| 42801 | 42802 | rc = SQLITE_OK; |
| 42802 | 42803 | }else{ |
| 42803 | 42804 | rc = sqlite3OsTruncate(pPager->jfd, 0); |
| 42805 | + if( rc==SQLITE_OK && pPager->fullSync ){ | |
| 42806 | + /* Make sure the new file size is written into the inode right away. | |
| 42807 | + ** Otherwise the journal might resurrect following a power loss and | |
| 42808 | + ** cause the last transaction to roll back. See | |
| 42809 | + ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 | |
| 42810 | + */ | |
| 42811 | + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); | |
| 42812 | + } | |
| 42804 | 42813 | } |
| 42805 | 42814 | pPager->journalOff = 0; |
| 42806 | 42815 | }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
| 42807 | 42816 | || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) |
| 42808 | 42817 | ){ |
| @@ -44476,17 +44485,19 @@ | ||
| 44476 | 44485 | if( !pNew ) rc = SQLITE_NOMEM; |
| 44477 | 44486 | } |
| 44478 | 44487 | |
| 44479 | 44488 | if( rc==SQLITE_OK ){ |
| 44480 | 44489 | pager_reset(pPager); |
| 44481 | - sqlite3PageFree(pPager->pTmpSpace); | |
| 44482 | - pPager->pTmpSpace = pNew; | |
| 44483 | 44490 | rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); |
| 44484 | 44491 | } |
| 44485 | 44492 | if( rc==SQLITE_OK ){ |
| 44493 | + sqlite3PageFree(pPager->pTmpSpace); | |
| 44494 | + pPager->pTmpSpace = pNew; | |
| 44486 | 44495 | pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); |
| 44487 | 44496 | pPager->pageSize = pageSize; |
| 44497 | + }else{ | |
| 44498 | + sqlite3PageFree(pNew); | |
| 44488 | 44499 | } |
| 44489 | 44500 | } |
| 44490 | 44501 | |
| 44491 | 44502 | *pPageSize = pPager->pageSize; |
| 44492 | 44503 | if( rc==SQLITE_OK ){ |
| @@ -51649,11 +51660,11 @@ | ||
| 51649 | 51660 | int nRef; /* Number of references to this structure */ |
| 51650 | 51661 | BtShared *pNext; /* Next on a list of sharable BtShared structs */ |
| 51651 | 51662 | BtLock *pLock; /* List of locks held on this shared-btree struct */ |
| 51652 | 51663 | Btree *pWriter; /* Btree with currently open write transaction */ |
| 51653 | 51664 | #endif |
| 51654 | - u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ | |
| 51665 | + u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ | |
| 51655 | 51666 | }; |
| 51656 | 51667 | |
| 51657 | 51668 | /* |
| 51658 | 51669 | ** Allowed values for BtShared.btsFlags |
| 51659 | 51670 | */ |
| @@ -52947,11 +52958,11 @@ | ||
| 52947 | 52958 | ** |
| 52948 | 52959 | ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor |
| 52949 | 52960 | ** back to where it ought to be if this routine returns true. |
| 52950 | 52961 | */ |
| 52951 | 52962 | SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ |
| 52952 | - return pCur && pCur->eState!=CURSOR_VALID; | |
| 52963 | + return pCur->eState!=CURSOR_VALID; | |
| 52953 | 52964 | } |
| 52954 | 52965 | |
| 52955 | 52966 | /* |
| 52956 | 52967 | ** This routine restores a cursor back to its original position after it |
| 52957 | 52968 | ** has been moved by some outside activity (such as a btree rebalance or |
| @@ -54279,11 +54290,12 @@ | ||
| 54279 | 54290 | #endif |
| 54280 | 54291 | } |
| 54281 | 54292 | |
| 54282 | 54293 | /* |
| 54283 | 54294 | ** Make sure pBt->pTmpSpace points to an allocation of |
| 54284 | -** MX_CELL_SIZE(pBt) bytes. | |
| 54295 | +** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child | |
| 54296 | +** pointer. | |
| 54285 | 54297 | */ |
| 54286 | 54298 | static void allocateTempSpace(BtShared *pBt){ |
| 54287 | 54299 | if( !pBt->pTmpSpace ){ |
| 54288 | 54300 | pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); |
| 54289 | 54301 | |
| @@ -54294,21 +54306,32 @@ | ||
| 54294 | 54306 | ** can mean that fillInCell() only initializes the first 2 or 3 |
| 54295 | 54307 | ** bytes of pTmpSpace, but that the first 4 bytes are copied from |
| 54296 | 54308 | ** it into a database page. This is not actually a problem, but it |
| 54297 | 54309 | ** does cause a valgrind error when the 1 or 2 bytes of unitialized |
| 54298 | 54310 | ** data is passed to system call write(). So to avoid this error, |
| 54299 | - ** zero the first 4 bytes of temp space here. */ | |
| 54300 | - if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4); | |
| 54311 | + ** zero the first 4 bytes of temp space here. | |
| 54312 | + ** | |
| 54313 | + ** Also: Provide four bytes of initialized space before the | |
| 54314 | + ** beginning of pTmpSpace as an area available to prepend the | |
| 54315 | + ** left-child pointer to the beginning of a cell. | |
| 54316 | + */ | |
| 54317 | + if( pBt->pTmpSpace ){ | |
| 54318 | + memset(pBt->pTmpSpace, 0, 8); | |
| 54319 | + pBt->pTmpSpace += 4; | |
| 54320 | + } | |
| 54301 | 54321 | } |
| 54302 | 54322 | } |
| 54303 | 54323 | |
| 54304 | 54324 | /* |
| 54305 | 54325 | ** Free the pBt->pTmpSpace allocation |
| 54306 | 54326 | */ |
| 54307 | 54327 | static void freeTempSpace(BtShared *pBt){ |
| 54308 | - sqlite3PageFree( pBt->pTmpSpace); | |
| 54309 | - pBt->pTmpSpace = 0; | |
| 54328 | + if( pBt->pTmpSpace ){ | |
| 54329 | + pBt->pTmpSpace -= 4; | |
| 54330 | + sqlite3PageFree(pBt->pTmpSpace); | |
| 54331 | + pBt->pTmpSpace = 0; | |
| 54332 | + } | |
| 54310 | 54333 | } |
| 54311 | 54334 | |
| 54312 | 54335 | /* |
| 54313 | 54336 | ** Close an open database and invalidate all cursors. |
| 54314 | 54337 | */ |
| @@ -58016,15 +58039,10 @@ | ||
| 58016 | 58039 | ** pTemp is not null. Regardless of pTemp, allocate a new entry |
| 58017 | 58040 | ** in pPage->apOvfl[] and make it point to the cell content (either |
| 58018 | 58041 | ** in pTemp or the original pCell) and also record its index. |
| 58019 | 58042 | ** Allocating a new entry in pPage->aCell[] implies that |
| 58020 | 58043 | ** pPage->nOverflow is incremented. |
| 58021 | -** | |
| 58022 | -** If nSkip is non-zero, then do not copy the first nSkip bytes of the | |
| 58023 | -** cell. The caller will overwrite them after this function returns. If | |
| 58024 | -** nSkip is non-zero, then pCell may not point to an invalid memory location | |
| 58025 | -** (but pCell+nSkip is always valid). | |
| 58026 | 58044 | */ |
| 58027 | 58045 | static void insertCell( |
| 58028 | 58046 | MemPage *pPage, /* Page into which we are copying */ |
| 58029 | 58047 | int i, /* New cell becomes the i-th cell of the page */ |
| 58030 | 58048 | u8 *pCell, /* Content of the new cell */ |
| @@ -58037,11 +58055,10 @@ | ||
| 58037 | 58055 | int j; /* Loop counter */ |
| 58038 | 58056 | int end; /* First byte past the last cell pointer in data[] */ |
| 58039 | 58057 | int ins; /* Index in data[] where new cell pointer is inserted */ |
| 58040 | 58058 | int cellOffset; /* Address of first cell pointer in data[] */ |
| 58041 | 58059 | u8 *data; /* The content of the whole page */ |
| 58042 | - int nSkip = (iChild ? 4 : 0); | |
| 58043 | 58060 | |
| 58044 | 58061 | if( *pRC ) return; |
| 58045 | 58062 | |
| 58046 | 58063 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); |
| 58047 | 58064 | assert( MX_CELL(pPage->pBt)<=10921 ); |
| @@ -58055,11 +58072,11 @@ | ||
| 58055 | 58072 | ** might be less than 8 (leaf-size + pointer) on the interior node. Hence |
| 58056 | 58073 | ** the term after the || in the following assert(). */ |
| 58057 | 58074 | assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) ); |
| 58058 | 58075 | if( pPage->nOverflow || sz+2>pPage->nFree ){ |
| 58059 | 58076 | if( pTemp ){ |
| 58060 | - memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); | |
| 58077 | + memcpy(pTemp, pCell, sz); | |
| 58061 | 58078 | pCell = pTemp; |
| 58062 | 58079 | } |
| 58063 | 58080 | if( iChild ){ |
| 58064 | 58081 | put4byte(pCell, iChild); |
| 58065 | 58082 | } |
| @@ -58084,11 +58101,11 @@ | ||
| 58084 | 58101 | ** if it returns success */ |
| 58085 | 58102 | assert( idx >= end+2 ); |
| 58086 | 58103 | assert( idx+sz <= (int)pPage->pBt->usableSize ); |
| 58087 | 58104 | pPage->nCell++; |
| 58088 | 58105 | pPage->nFree -= (u16)(2 + sz); |
| 58089 | - memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); | |
| 58106 | + memcpy(&data[idx], pCell, sz); | |
| 58090 | 58107 | if( iChild ){ |
| 58091 | 58108 | put4byte(&data[idx], iChild); |
| 58092 | 58109 | } |
| 58093 | 58110 | memmove(&data[ins+2], &data[ins], end-ins); |
| 58094 | 58111 | put2byte(&data[ins], idx); |
| @@ -61630,11 +61647,14 @@ | ||
| 61630 | 61647 | /* If MEM_Dyn is set then Mem.xDel!=0. |
| 61631 | 61648 | ** Mem.xDel is might not be initialized if MEM_Dyn is clear. |
| 61632 | 61649 | */ |
| 61633 | 61650 | assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); |
| 61634 | 61651 | |
| 61635 | - /* MEM_Dyn may only be set if Mem.szMalloc==0 */ | |
| 61652 | + /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we | |
| 61653 | + ** ensure that if Mem.szMalloc>0 then it is safe to do | |
| 61654 | + ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. | |
| 61655 | + ** That saves a few cycles in inner loops. */ | |
| 61636 | 61656 | assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); |
| 61637 | 61657 | |
| 61638 | 61658 | /* Cannot be both MEM_Int and MEM_Real at the same time */ |
| 61639 | 61659 | assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); |
| 61640 | 61660 | |
| @@ -61739,11 +61759,11 @@ | ||
| 61739 | 61759 | }else{ |
| 61740 | 61760 | pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); |
| 61741 | 61761 | } |
| 61742 | 61762 | } |
| 61743 | 61763 | |
| 61744 | - if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){ | |
| 61764 | + if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ | |
| 61745 | 61765 | memcpy(pMem->zMalloc, pMem->z, pMem->n); |
| 61746 | 61766 | } |
| 61747 | 61767 | if( (pMem->flags&MEM_Dyn)!=0 ){ |
| 61748 | 61768 | assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); |
| 61749 | 61769 | pMem->xDel((void *)(pMem->z)); |
| @@ -61766,11 +61786,12 @@ | ||
| 61766 | 61786 | ** |
| 61767 | 61787 | ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) |
| 61768 | 61788 | ** if unable to complete the resizing. |
| 61769 | 61789 | */ |
| 61770 | 61790 | SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ |
| 61771 | - assert( szNew>=0 ); | |
| 61791 | + assert( szNew>0 ); | |
| 61792 | + assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); | |
| 61772 | 61793 | if( pMem->szMalloc<szNew ){ |
| 61773 | 61794 | return sqlite3VdbeMemGrow(pMem, szNew, 0); |
| 61774 | 61795 | } |
| 61775 | 61796 | assert( (pMem->flags & MEM_Dyn)==0 ); |
| 61776 | 61797 | pMem->z = pMem->zMalloc; |
| @@ -62490,11 +62511,14 @@ | ||
| 62490 | 62511 | nAlloc += (enc==SQLITE_UTF8?1:2); |
| 62491 | 62512 | } |
| 62492 | 62513 | if( nByte>iLimit ){ |
| 62493 | 62514 | return SQLITE_TOOBIG; |
| 62494 | 62515 | } |
| 62495 | - if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){ | |
| 62516 | + testcase( nAlloc==0 ); | |
| 62517 | + testcase( nAlloc==31 ); | |
| 62518 | + testcase( nAlloc==32 ); | |
| 62519 | + if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){ | |
| 62496 | 62520 | return SQLITE_NOMEM; |
| 62497 | 62521 | } |
| 62498 | 62522 | memcpy(pMem->z, z, nAlloc); |
| 62499 | 62523 | }else if( xDel==SQLITE_DYNAMIC ){ |
| 62500 | 62524 | sqlite3VdbeMemRelease(pMem); |
| @@ -62593,11 +62617,11 @@ | ||
| 62593 | 62617 | /* |
| 62594 | 62618 | ** The pVal argument is known to be a value other than NULL. |
| 62595 | 62619 | ** Convert it into a string with encoding enc and return a pointer |
| 62596 | 62620 | ** to a zero-terminated version of that string. |
| 62597 | 62621 | */ |
| 62598 | -SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ | |
| 62622 | +static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ | |
| 62599 | 62623 | assert( pVal!=0 ); |
| 62600 | 62624 | assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 62601 | 62625 | assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 62602 | 62626 | assert( (pVal->flags & MEM_RowSet)==0 ); |
| 62603 | 62627 | assert( (pVal->flags & (MEM_Null))==0 ); |
| @@ -64913,11 +64937,11 @@ | ||
| 64913 | 64937 | ** the call above. */ |
| 64914 | 64938 | }else if( pCx->pCursor ){ |
| 64915 | 64939 | sqlite3BtreeCloseCursor(pCx->pCursor); |
| 64916 | 64940 | } |
| 64917 | 64941 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 64918 | - if( pCx->pVtabCursor ){ | |
| 64942 | + else if( pCx->pVtabCursor ){ | |
| 64919 | 64943 | sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; |
| 64920 | 64944 | const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; |
| 64921 | 64945 | p->inVtabMethod = 1; |
| 64922 | 64946 | pModule->xClose(pVtabCursor); |
| 64923 | 64947 | p->inVtabMethod = 0; |
| @@ -64956,13 +64980,14 @@ | ||
| 64956 | 64980 | static void closeAllCursors(Vdbe *p){ |
| 64957 | 64981 | if( p->pFrame ){ |
| 64958 | 64982 | VdbeFrame *pFrame; |
| 64959 | 64983 | for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); |
| 64960 | 64984 | sqlite3VdbeFrameRestore(pFrame); |
| 64985 | + p->pFrame = 0; | |
| 64986 | + p->nFrame = 0; | |
| 64961 | 64987 | } |
| 64962 | - p->pFrame = 0; | |
| 64963 | - p->nFrame = 0; | |
| 64988 | + assert( p->nFrame==0 ); | |
| 64964 | 64989 | |
| 64965 | 64990 | if( p->apCsr ){ |
| 64966 | 64991 | int i; |
| 64967 | 64992 | for(i=0; i<p->nCursor; i++){ |
| 64968 | 64993 | VdbeCursor *pC = p->apCsr[i]; |
| @@ -64980,11 +65005,11 @@ | ||
| 64980 | 65005 | p->pDelFrame = pDel->pParent; |
| 64981 | 65006 | sqlite3VdbeFrameDelete(pDel); |
| 64982 | 65007 | } |
| 64983 | 65008 | |
| 64984 | 65009 | /* Delete any auxdata allocations made by the VM */ |
| 64985 | - sqlite3VdbeDeleteAuxData(p, -1, 0); | |
| 65010 | + if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0); | |
| 64986 | 65011 | assert( p->pAuxData==0 ); |
| 64987 | 65012 | } |
| 64988 | 65013 | |
| 64989 | 65014 | /* |
| 64990 | 65015 | ** Clean up the VM after a single run. |
| @@ -65886,13 +65911,11 @@ | ||
| 65886 | 65911 | #endif |
| 65887 | 65912 | assert( p->deferredMoveto ); |
| 65888 | 65913 | assert( p->isTable ); |
| 65889 | 65914 | rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); |
| 65890 | 65915 | if( rc ) return rc; |
| 65891 | - p->lastRowid = p->movetoTarget; | |
| 65892 | 65916 | if( res!=0 ) return SQLITE_CORRUPT_BKPT; |
| 65893 | - p->rowidIsValid = 1; | |
| 65894 | 65917 | #ifdef SQLITE_TEST |
| 65895 | 65918 | sqlite3_search_count++; |
| 65896 | 65919 | #endif |
| 65897 | 65920 | p->deferredMoveto = 0; |
| 65898 | 65921 | p->cacheStatus = CACHE_STALE; |
| @@ -65913,10 +65936,21 @@ | ||
| 65913 | 65936 | rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow); |
| 65914 | 65937 | p->cacheStatus = CACHE_STALE; |
| 65915 | 65938 | if( isDifferentRow ) p->nullRow = 1; |
| 65916 | 65939 | return rc; |
| 65917 | 65940 | } |
| 65941 | + | |
| 65942 | +/* | |
| 65943 | +** Check to ensure that the cursor is valid. Restore the cursor | |
| 65944 | +** if need be. Return any I/O error from the restore operation. | |
| 65945 | +*/ | |
| 65946 | +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ | |
| 65947 | + if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ | |
| 65948 | + return handleMovedCursor(p); | |
| 65949 | + } | |
| 65950 | + return SQLITE_OK; | |
| 65951 | +} | |
| 65918 | 65952 | |
| 65919 | 65953 | /* |
| 65920 | 65954 | ** Make sure the cursor p is ready to read or write the row to which it |
| 65921 | 65955 | ** was last positioned. Return an error code if an OOM fault or I/O error |
| 65922 | 65956 | ** prevents us from positioning the cursor to its correct position. |
| @@ -65931,11 +65965,11 @@ | ||
| 65931 | 65965 | */ |
| 65932 | 65966 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ |
| 65933 | 65967 | if( p->deferredMoveto ){ |
| 65934 | 65968 | return handleDeferredMoveto(p); |
| 65935 | 65969 | } |
| 65936 | - if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ | |
| 65970 | + if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){ | |
| 65937 | 65971 | return handleMovedCursor(p); |
| 65938 | 65972 | } |
| 65939 | 65973 | return SQLITE_OK; |
| 65940 | 65974 | } |
| 65941 | 65975 | |
| @@ -69095,10 +69129,11 @@ | ||
| 69095 | 69129 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| 69096 | 69130 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; |
| 69097 | 69131 | memset(pCx, 0, sizeof(VdbeCursor)); |
| 69098 | 69132 | pCx->iDb = iDb; |
| 69099 | 69133 | pCx->nField = nField; |
| 69134 | + pCx->aOffset = &pCx->aType[nField]; | |
| 69100 | 69135 | if( isBtreeCursor ){ |
| 69101 | 69136 | pCx->pCursor = (BtCursor*) |
| 69102 | 69137 | &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; |
| 69103 | 69138 | sqlite3BtreeCursorZero(pCx->pCursor); |
| 69104 | 69139 | } |
| @@ -70528,11 +70563,11 @@ | ||
| 70528 | 70563 | ctx.pFunc = pOp->p4.pFunc; |
| 70529 | 70564 | ctx.iOp = pc; |
| 70530 | 70565 | ctx.pVdbe = p; |
| 70531 | 70566 | MemSetTypeFlag(ctx.pOut, MEM_Null); |
| 70532 | 70567 | ctx.fErrorOrAux = 0; |
| 70533 | - assert( db->lastRowid==lastRowid ); | |
| 70568 | + db->lastRowid = lastRowid; | |
| 70534 | 70569 | (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 70535 | 70570 | lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */ |
| 70536 | 70571 | |
| 70537 | 70572 | /* If the function returned an error, throw an exception */ |
| 70538 | 70573 | if( ctx.fErrorOrAux ){ |
| @@ -71246,11 +71281,11 @@ | ||
| 71246 | 71281 | memAboutToChange(p, pDest); |
| 71247 | 71282 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71248 | 71283 | pC = p->apCsr[pOp->p1]; |
| 71249 | 71284 | assert( pC!=0 ); |
| 71250 | 71285 | assert( p2<pC->nField ); |
| 71251 | - aOffset = pC->aType + pC->nField; | |
| 71286 | + aOffset = pC->aOffset; | |
| 71252 | 71287 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 71253 | 71288 | assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ |
| 71254 | 71289 | #endif |
| 71255 | 71290 | pCrsr = pC->pCursor; |
| 71256 | 71291 | assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ |
| @@ -71257,11 +71292,11 @@ | ||
| 71257 | 71292 | assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ |
| 71258 | 71293 | |
| 71259 | 71294 | /* If the cursor cache is stale, bring it up-to-date */ |
| 71260 | 71295 | rc = sqlite3VdbeCursorMoveto(pC); |
| 71261 | 71296 | if( rc ) goto abort_due_to_error; |
| 71262 | - if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){ | |
| 71297 | + if( pC->cacheStatus!=p->cacheCtr ){ | |
| 71263 | 71298 | if( pC->nullRow ){ |
| 71264 | 71299 | if( pCrsr==0 ){ |
| 71265 | 71300 | assert( pC->pseudoTableReg>0 ); |
| 71266 | 71301 | pReg = &aMem[pC->pseudoTableReg]; |
| 71267 | 71302 | assert( pReg->flags & MEM_Blob ); |
| @@ -71302,18 +71337,10 @@ | ||
| 71302 | 71337 | } |
| 71303 | 71338 | pC->cacheStatus = p->cacheCtr; |
| 71304 | 71339 | pC->iHdrOffset = getVarint32(pC->aRow, offset); |
| 71305 | 71340 | pC->nHdrParsed = 0; |
| 71306 | 71341 | aOffset[0] = offset; |
| 71307 | - if( avail<offset ){ | |
| 71308 | - /* pC->aRow does not have to hold the entire row, but it does at least | |
| 71309 | - ** need to cover the header of the record. If pC->aRow does not contain | |
| 71310 | - ** the complete header, then set it to zero, forcing the header to be | |
| 71311 | - ** dynamically allocated. */ | |
| 71312 | - pC->aRow = 0; | |
| 71313 | - pC->szRow = 0; | |
| 71314 | - } | |
| 71315 | 71342 | |
| 71316 | 71343 | /* Make sure a corrupt database has not given us an oversize header. |
| 71317 | 71344 | ** Do this now to avoid an oversize memory allocation. |
| 71318 | 71345 | ** |
| 71319 | 71346 | ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte |
| @@ -71324,19 +71351,36 @@ | ||
| 71324 | 71351 | */ |
| 71325 | 71352 | if( offset > 98307 || offset > pC->payloadSize ){ |
| 71326 | 71353 | rc = SQLITE_CORRUPT_BKPT; |
| 71327 | 71354 | goto op_column_error; |
| 71328 | 71355 | } |
| 71356 | + | |
| 71357 | + if( avail<offset ){ | |
| 71358 | + /* pC->aRow does not have to hold the entire row, but it does at least | |
| 71359 | + ** need to cover the header of the record. If pC->aRow does not contain | |
| 71360 | + ** the complete header, then set it to zero, forcing the header to be | |
| 71361 | + ** dynamically allocated. */ | |
| 71362 | + pC->aRow = 0; | |
| 71363 | + pC->szRow = 0; | |
| 71364 | + } | |
| 71365 | + | |
| 71366 | + /* The following goto is an optimization. It can be omitted and | |
| 71367 | + ** everything will still work. But OP_Column is measurably faster | |
| 71368 | + ** by skipping the subsequent conditional, which is always true. | |
| 71369 | + */ | |
| 71370 | + assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ | |
| 71371 | + goto op_column_read_header; | |
| 71329 | 71372 | } |
| 71330 | 71373 | |
| 71331 | 71374 | /* Make sure at least the first p2+1 entries of the header have been |
| 71332 | 71375 | ** parsed and valid information is in aOffset[] and pC->aType[]. |
| 71333 | 71376 | */ |
| 71334 | 71377 | if( pC->nHdrParsed<=p2 ){ |
| 71335 | 71378 | /* If there is more header available for parsing in the record, try |
| 71336 | 71379 | ** to extract additional fields up through the p2+1-th field |
| 71337 | 71380 | */ |
| 71381 | + op_column_read_header: | |
| 71338 | 71382 | if( pC->iHdrOffset<aOffset[0] ){ |
| 71339 | 71383 | /* Make sure zData points to enough of the record to cover the header. */ |
| 71340 | 71384 | if( pC->aRow==0 ){ |
| 71341 | 71385 | memset(&sMem, 0, sizeof(sMem)); |
| 71342 | 71386 | rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], |
| @@ -71377,19 +71421,20 @@ | ||
| 71377 | 71421 | if( pC->aRow==0 ){ |
| 71378 | 71422 | sqlite3VdbeMemRelease(&sMem); |
| 71379 | 71423 | sMem.flags = MEM_Null; |
| 71380 | 71424 | } |
| 71381 | 71425 | |
| 71382 | - /* If we have read more header data than was contained in the header, | |
| 71383 | - ** or if the end of the last field appears to be past the end of the | |
| 71384 | - ** record, or if the end of the last field appears to be before the end | |
| 71385 | - ** of the record (when all fields present), then we must be dealing | |
| 71386 | - ** with a corrupt database. | |
| 71426 | + /* The record is corrupt if any of the following are true: | |
| 71427 | + ** (1) the bytes of the header extend past the declared header size | |
| 71428 | + ** (zHdr>zEndHdr) | |
| 71429 | + ** (2) the entire header was used but not all data was used | |
| 71430 | + ** (zHdr==zEndHdr && offset!=pC->payloadSize) | |
| 71431 | + ** (3) the end of the data extends beyond the end of the record. | |
| 71432 | + ** (offset > pC->payloadSize) | |
| 71387 | 71433 | */ |
| 71388 | - if( (zHdr > zEndHdr) | |
| 71434 | + if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize)) | |
| 71389 | 71435 | || (offset > pC->payloadSize) |
| 71390 | - || (zHdr==zEndHdr && offset!=pC->payloadSize) | |
| 71391 | 71436 | ){ |
| 71392 | 71437 | rc = SQLITE_CORRUPT_BKPT; |
| 71393 | 71438 | goto op_column_error; |
| 71394 | 71439 | } |
| 71395 | 71440 | } |
| @@ -71400,11 +71445,11 @@ | ||
| 71400 | 71445 | */ |
| 71401 | 71446 | if( pC->nHdrParsed<=p2 ){ |
| 71402 | 71447 | if( pOp->p4type==P4_MEM ){ |
| 71403 | 71448 | sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); |
| 71404 | 71449 | }else{ |
| 71405 | - MemSetTypeFlag(pDest, MEM_Null); | |
| 71450 | + sqlite3VdbeMemSetNull(pDest); | |
| 71406 | 71451 | } |
| 71407 | 71452 | goto op_column_out; |
| 71408 | 71453 | } |
| 71409 | 71454 | } |
| 71410 | 71455 | |
| @@ -71576,11 +71621,11 @@ | ||
| 71576 | 71621 | ** out how much space is required for the new record. |
| 71577 | 71622 | */ |
| 71578 | 71623 | pRec = pLast; |
| 71579 | 71624 | do{ |
| 71580 | 71625 | assert( memIsValid(pRec) ); |
| 71581 | - serial_type = sqlite3VdbeSerialType(pRec, file_format); | |
| 71626 | + pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format); | |
| 71582 | 71627 | len = sqlite3VdbeSerialTypeLen(serial_type); |
| 71583 | 71628 | if( pRec->flags & MEM_Zero ){ |
| 71584 | 71629 | if( nData ){ |
| 71585 | 71630 | sqlite3VdbeMemExpandBlob(pRec); |
| 71586 | 71631 | }else{ |
| @@ -71625,11 +71670,11 @@ | ||
| 71625 | 71670 | i = putVarint32(zNewRecord, nHdr); |
| 71626 | 71671 | j = nHdr; |
| 71627 | 71672 | assert( pData0<=pLast ); |
| 71628 | 71673 | pRec = pData0; |
| 71629 | 71674 | do{ |
| 71630 | - serial_type = sqlite3VdbeSerialType(pRec, file_format); | |
| 71675 | + serial_type = pRec->uTemp; | |
| 71631 | 71676 | i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ |
| 71632 | 71677 | j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 71633 | 71678 | }while( (++pRec)<=pLast ); |
| 71634 | 71679 | assert( i==nHdr ); |
| 71635 | 71680 | assert( j==nByte ); |
| @@ -72524,11 +72569,10 @@ | ||
| 72524 | 72569 | pIn3 = &aMem[pOp->p3]; |
| 72525 | 72570 | if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ |
| 72526 | 72571 | applyNumericAffinity(pIn3, 0); |
| 72527 | 72572 | } |
| 72528 | 72573 | iKey = sqlite3VdbeIntValue(pIn3); |
| 72529 | - pC->rowidIsValid = 0; | |
| 72530 | 72574 | |
| 72531 | 72575 | /* If the P3 value could not be converted into an integer without |
| 72532 | 72576 | ** loss of information, then special processing is required... */ |
| 72533 | 72577 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 72534 | 72578 | if( (pIn3->flags & MEM_Real)==0 ){ |
| @@ -72560,17 +72604,14 @@ | ||
| 72560 | 72604 | assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); |
| 72561 | 72605 | if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; |
| 72562 | 72606 | } |
| 72563 | 72607 | } |
| 72564 | 72608 | rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); |
| 72609 | + pC->movetoTarget = iKey; /* Used by OP_Delete */ | |
| 72565 | 72610 | if( rc!=SQLITE_OK ){ |
| 72566 | 72611 | goto abort_due_to_error; |
| 72567 | 72612 | } |
| 72568 | - if( res==0 ){ | |
| 72569 | - pC->rowidIsValid = 1; | |
| 72570 | - pC->lastRowid = iKey; | |
| 72571 | - } | |
| 72572 | 72613 | }else{ |
| 72573 | 72614 | nField = pOp->p4.i; |
| 72574 | 72615 | assert( pOp->p4type==P4_INT32 ); |
| 72575 | 72616 | assert( nField>0 ); |
| 72576 | 72617 | r.pKeyInfo = pC->pKeyInfo; |
| @@ -72596,11 +72637,10 @@ | ||
| 72596 | 72637 | ExpandBlob(r.aMem); |
| 72597 | 72638 | rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); |
| 72598 | 72639 | if( rc!=SQLITE_OK ){ |
| 72599 | 72640 | goto abort_due_to_error; |
| 72600 | 72641 | } |
| 72601 | - pC->rowidIsValid = 0; | |
| 72602 | 72642 | } |
| 72603 | 72643 | pC->deferredMoveto = 0; |
| 72604 | 72644 | pC->cacheStatus = CACHE_STALE; |
| 72605 | 72645 | #ifdef SQLITE_TEST |
| 72606 | 72646 | sqlite3_search_count++; |
| @@ -72608,21 +72648,19 @@ | ||
| 72608 | 72648 | if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); |
| 72609 | 72649 | if( res<0 || (res==0 && oc==OP_SeekGT) ){ |
| 72610 | 72650 | res = 0; |
| 72611 | 72651 | rc = sqlite3BtreeNext(pC->pCursor, &res); |
| 72612 | 72652 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 72613 | - pC->rowidIsValid = 0; | |
| 72614 | 72653 | }else{ |
| 72615 | 72654 | res = 0; |
| 72616 | 72655 | } |
| 72617 | 72656 | }else{ |
| 72618 | 72657 | assert( oc==OP_SeekLT || oc==OP_SeekLE ); |
| 72619 | 72658 | if( res>0 || (res==0 && oc==OP_SeekLT) ){ |
| 72620 | 72659 | res = 0; |
| 72621 | 72660 | rc = sqlite3BtreePrevious(pC->pCursor, &res); |
| 72622 | 72661 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 72623 | - pC->rowidIsValid = 0; | |
| 72624 | 72662 | }else{ |
| 72625 | 72663 | /* res might be negative because the table is empty. Check to |
| 72626 | 72664 | ** see if this is the case. |
| 72627 | 72665 | */ |
| 72628 | 72666 | res = sqlite3BtreeEof(pC->pCursor); |
| @@ -72655,11 +72693,10 @@ | ||
| 72655 | 72693 | assert( pC->pCursor!=0 ); |
| 72656 | 72694 | assert( pC->isTable ); |
| 72657 | 72695 | pC->nullRow = 0; |
| 72658 | 72696 | pIn2 = &aMem[pOp->p2]; |
| 72659 | 72697 | pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 72660 | - pC->rowidIsValid = 0; | |
| 72661 | 72698 | pC->deferredMoveto = 1; |
| 72662 | 72699 | break; |
| 72663 | 72700 | } |
| 72664 | 72701 | |
| 72665 | 72702 | |
| @@ -72841,19 +72878,17 @@ | ||
| 72841 | 72878 | pCrsr = pC->pCursor; |
| 72842 | 72879 | assert( pCrsr!=0 ); |
| 72843 | 72880 | res = 0; |
| 72844 | 72881 | iKey = pIn3->u.i; |
| 72845 | 72882 | rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); |
| 72846 | - pC->lastRowid = pIn3->u.i; | |
| 72847 | - pC->rowidIsValid = res==0 ?1:0; | |
| 72883 | + pC->movetoTarget = iKey; /* Used by OP_Delete */ | |
| 72848 | 72884 | pC->nullRow = 0; |
| 72849 | 72885 | pC->cacheStatus = CACHE_STALE; |
| 72850 | 72886 | pC->deferredMoveto = 0; |
| 72851 | 72887 | VdbeBranchTaken(res!=0,2); |
| 72852 | 72888 | if( res!=0 ){ |
| 72853 | 72889 | pc = pOp->p2 - 1; |
| 72854 | - assert( pC->rowidIsValid==0 ); | |
| 72855 | 72890 | } |
| 72856 | 72891 | pC->seekResult = res; |
| 72857 | 72892 | break; |
| 72858 | 72893 | } |
| 72859 | 72894 | |
| @@ -72997,11 +73032,10 @@ | ||
| 72997 | 73032 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 72998 | 73033 | goto abort_due_to_error; |
| 72999 | 73034 | } |
| 73000 | 73035 | assert( v>0 ); /* EV: R-40812-03570 */ |
| 73001 | 73036 | } |
| 73002 | - pC->rowidIsValid = 0; | |
| 73003 | 73037 | pC->deferredMoveto = 0; |
| 73004 | 73038 | pC->cacheStatus = CACHE_STALE; |
| 73005 | 73039 | } |
| 73006 | 73040 | pOut->u.i = v; |
| 73007 | 73041 | break; |
| @@ -73102,11 +73136,10 @@ | ||
| 73102 | 73136 | } |
| 73103 | 73137 | rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, |
| 73104 | 73138 | pData->z, pData->n, nZero, |
| 73105 | 73139 | (pOp->p5 & OPFLAG_APPEND)!=0, seekResult |
| 73106 | 73140 | ); |
| 73107 | - pC->rowidIsValid = 0; | |
| 73108 | 73141 | pC->deferredMoveto = 0; |
| 73109 | 73142 | pC->cacheStatus = CACHE_STALE; |
| 73110 | 73143 | |
| 73111 | 73144 | /* Invoke the update-hook if required. */ |
| 73112 | 73145 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| @@ -73139,37 +73172,36 @@ | ||
| 73139 | 73172 | ** pointing to. The update hook will be invoked, if it exists. |
| 73140 | 73173 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 73141 | 73174 | ** using OP_NotFound prior to invoking this opcode. |
| 73142 | 73175 | */ |
| 73143 | 73176 | case OP_Delete: { |
| 73144 | - i64 iKey; | |
| 73145 | 73177 | VdbeCursor *pC; |
| 73146 | 73178 | |
| 73147 | 73179 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73148 | 73180 | pC = p->apCsr[pOp->p1]; |
| 73149 | 73181 | assert( pC!=0 ); |
| 73150 | 73182 | assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 73151 | - iKey = pC->lastRowid; /* Only used for the update hook */ | |
| 73152 | - | |
| 73153 | - /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or | |
| 73154 | - ** OP_Column on the same table without any intervening operations that | |
| 73155 | - ** might move or invalidate the cursor. Hence cursor pC is always pointing | |
| 73156 | - ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation | |
| 73157 | - ** below is always a no-op and cannot fail. We will run it anyhow, though, | |
| 73158 | - ** to guard against future changes to the code generator. | |
| 73159 | - **/ | |
| 73160 | 73183 | assert( pC->deferredMoveto==0 ); |
| 73161 | - rc = sqlite3VdbeCursorMoveto(pC); | |
| 73162 | - if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | |
| 73163 | 73184 | |
| 73185 | +#ifdef SQLITE_DEBUG | |
| 73186 | + /* The seek operation that positioned the cursor prior to OP_Delete will | |
| 73187 | + ** have also set the pC->movetoTarget field to the rowid of the row that | |
| 73188 | + ** is being deleted */ | |
| 73189 | + if( pOp->p4.z && pC->isTable ){ | |
| 73190 | + i64 iKey = 0; | |
| 73191 | + sqlite3BtreeKeySize(pC->pCursor, &iKey); | |
| 73192 | + assert( pC->movetoTarget==iKey ); | |
| 73193 | + } | |
| 73194 | +#endif | |
| 73195 | + | |
| 73164 | 73196 | rc = sqlite3BtreeDelete(pC->pCursor); |
| 73165 | 73197 | pC->cacheStatus = CACHE_STALE; |
| 73166 | 73198 | |
| 73167 | 73199 | /* Invoke the update-hook if required. */ |
| 73168 | 73200 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ |
| 73169 | 73201 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, |
| 73170 | - db->aDb[pC->iDb].zName, pOp->p4.z, iKey); | |
| 73202 | + db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget); | |
| 73171 | 73203 | assert( pC->iDb>=0 ); |
| 73172 | 73204 | } |
| 73173 | 73205 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 73174 | 73206 | break; |
| 73175 | 73207 | } |
| @@ -73218,23 +73250,32 @@ | ||
| 73218 | 73250 | pc = pOp->p2-1; |
| 73219 | 73251 | } |
| 73220 | 73252 | break; |
| 73221 | 73253 | }; |
| 73222 | 73254 | |
| 73223 | -/* Opcode: SorterData P1 P2 * * * | |
| 73255 | +/* Opcode: SorterData P1 P2 P3 * * | |
| 73224 | 73256 | ** Synopsis: r[P2]=data |
| 73225 | 73257 | ** |
| 73226 | 73258 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 73259 | +** Then clear the column header cache on cursor P3. | |
| 73260 | +** | |
| 73261 | +** This opcode is normally use to move a record out of the sorter and into | |
| 73262 | +** a register that is the source for a pseudo-table cursor created using | |
| 73263 | +** OpenPseudo. That pseudo-table cursor is the one that is identified by | |
| 73264 | +** parameter P3. Clearing the P3 column cache as part of this opcode saves | |
| 73265 | +** us from having to issue a separate NullRow instruction to clear that cache. | |
| 73227 | 73266 | */ |
| 73228 | 73267 | case OP_SorterData: { |
| 73229 | 73268 | VdbeCursor *pC; |
| 73230 | 73269 | |
| 73231 | 73270 | pOut = &aMem[pOp->p2]; |
| 73232 | 73271 | pC = p->apCsr[pOp->p1]; |
| 73233 | 73272 | assert( isSorter(pC) ); |
| 73234 | 73273 | rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 73235 | 73274 | assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); |
| 73275 | + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | |
| 73276 | + p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; | |
| 73236 | 73277 | break; |
| 73237 | 73278 | } |
| 73238 | 73279 | |
| 73239 | 73280 | /* Opcode: RowData P1 P2 * * * |
| 73240 | 73281 | ** Synopsis: r[P2]=data |
| @@ -73277,20 +73318,24 @@ | ||
| 73277 | 73318 | assert( pC!=0 ); |
| 73278 | 73319 | assert( pC->nullRow==0 ); |
| 73279 | 73320 | assert( pC->pseudoTableReg==0 ); |
| 73280 | 73321 | assert( pC->pCursor!=0 ); |
| 73281 | 73322 | pCrsr = pC->pCursor; |
| 73282 | - assert( sqlite3BtreeCursorIsValid(pCrsr) ); | |
| 73283 | 73323 | |
| 73284 | 73324 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 73285 | 73325 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 73286 | - ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always | |
| 73287 | - ** a no-op and can never fail. But we leave it in place as a safety. | |
| 73326 | + ** the cursor. If this where not the case, on of the following assert()s | |
| 73327 | + ** would fail. Should this ever change (because of changes in the code | |
| 73328 | + ** generator) then the fix would be to insert a call to | |
| 73329 | + ** sqlite3VdbeCursorMoveto(). | |
| 73288 | 73330 | */ |
| 73289 | 73331 | assert( pC->deferredMoveto==0 ); |
| 73332 | + assert( sqlite3BtreeCursorIsValid(pCrsr) ); | |
| 73333 | +#if 0 /* Not required due to the previous to assert() statements */ | |
| 73290 | 73334 | rc = sqlite3VdbeCursorMoveto(pC); |
| 73291 | - if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | |
| 73335 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 73336 | +#endif | |
| 73292 | 73337 | |
| 73293 | 73338 | if( pC->isTable==0 ){ |
| 73294 | 73339 | assert( !pC->isTable ); |
| 73295 | 73340 | VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); |
| 73296 | 73341 | assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| @@ -73303,11 +73348,12 @@ | ||
| 73303 | 73348 | assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 73304 | 73349 | if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 73305 | 73350 | goto too_big; |
| 73306 | 73351 | } |
| 73307 | 73352 | } |
| 73308 | - if( sqlite3VdbeMemClearAndResize(pOut, n) ){ | |
| 73353 | + testcase( n==0 ); | |
| 73354 | + if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ | |
| 73309 | 73355 | goto no_mem; |
| 73310 | 73356 | } |
| 73311 | 73357 | pOut->n = n; |
| 73312 | 73358 | MemSetTypeFlag(pOut, MEM_Blob); |
| 73313 | 73359 | if( pC->isTable==0 ){ |
| @@ -73354,18 +73400,14 @@ | ||
| 73354 | 73400 | rc = pModule->xRowid(pC->pVtabCursor, &v); |
| 73355 | 73401 | sqlite3VtabImportErrmsg(p, pVtab); |
| 73356 | 73402 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 73357 | 73403 | }else{ |
| 73358 | 73404 | assert( pC->pCursor!=0 ); |
| 73359 | - rc = sqlite3VdbeCursorMoveto(pC); | |
| 73405 | + rc = sqlite3VdbeCursorRestore(pC); | |
| 73360 | 73406 | if( rc ) goto abort_due_to_error; |
| 73361 | - if( pC->rowidIsValid ){ | |
| 73362 | - v = pC->lastRowid; | |
| 73363 | - }else{ | |
| 73364 | - rc = sqlite3BtreeKeySize(pC->pCursor, &v); | |
| 73365 | - assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ | |
| 73366 | - } | |
| 73407 | + rc = sqlite3BtreeKeySize(pC->pCursor, &v); | |
| 73408 | + assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */ | |
| 73367 | 73409 | } |
| 73368 | 73410 | pOut->u.i = v; |
| 73369 | 73411 | break; |
| 73370 | 73412 | } |
| 73371 | 73413 | |
| @@ -73380,11 +73422,10 @@ | ||
| 73380 | 73422 | |
| 73381 | 73423 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73382 | 73424 | pC = p->apCsr[pOp->p1]; |
| 73383 | 73425 | assert( pC!=0 ); |
| 73384 | 73426 | pC->nullRow = 1; |
| 73385 | - pC->rowidIsValid = 0; | |
| 73386 | 73427 | pC->cacheStatus = CACHE_STALE; |
| 73387 | 73428 | if( pC->pCursor ){ |
| 73388 | 73429 | sqlite3BtreeClearCursor(pC->pCursor); |
| 73389 | 73430 | } |
| 73390 | 73431 | break; |
| @@ -73414,11 +73455,10 @@ | ||
| 73414 | 73455 | res = 0; |
| 73415 | 73456 | assert( pCrsr!=0 ); |
| 73416 | 73457 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 73417 | 73458 | pC->nullRow = (u8)res; |
| 73418 | 73459 | pC->deferredMoveto = 0; |
| 73419 | - pC->rowidIsValid = 0; | |
| 73420 | 73460 | pC->cacheStatus = CACHE_STALE; |
| 73421 | 73461 | #ifdef SQLITE_DEBUG |
| 73422 | 73462 | pC->seekOp = OP_Last; |
| 73423 | 73463 | #endif |
| 73424 | 73464 | if( pOp->p2>0 ){ |
| @@ -73481,11 +73521,10 @@ | ||
| 73481 | 73521 | pCrsr = pC->pCursor; |
| 73482 | 73522 | assert( pCrsr ); |
| 73483 | 73523 | rc = sqlite3BtreeFirst(pCrsr, &res); |
| 73484 | 73524 | pC->deferredMoveto = 0; |
| 73485 | 73525 | pC->cacheStatus = CACHE_STALE; |
| 73486 | - pC->rowidIsValid = 0; | |
| 73487 | 73526 | } |
| 73488 | 73527 | pC->nullRow = (u8)res; |
| 73489 | 73528 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 73490 | 73529 | VdbeBranchTaken(res!=0,2); |
| 73491 | 73530 | if( res ){ |
| @@ -73607,11 +73646,10 @@ | ||
| 73607 | 73646 | sqlite3_search_count++; |
| 73608 | 73647 | #endif |
| 73609 | 73648 | }else{ |
| 73610 | 73649 | pC->nullRow = 1; |
| 73611 | 73650 | } |
| 73612 | - pC->rowidIsValid = 0; | |
| 73613 | 73651 | goto check_for_interrupt; |
| 73614 | 73652 | } |
| 73615 | 73653 | |
| 73616 | 73654 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 73617 | 73655 | ** Synopsis: key=r[P2] |
| @@ -73723,14 +73761,20 @@ | ||
| 73723 | 73761 | pC = p->apCsr[pOp->p1]; |
| 73724 | 73762 | assert( pC!=0 ); |
| 73725 | 73763 | pCrsr = pC->pCursor; |
| 73726 | 73764 | assert( pCrsr!=0 ); |
| 73727 | 73765 | pOut->flags = MEM_Null; |
| 73728 | - rc = sqlite3VdbeCursorMoveto(pC); | |
| 73729 | - if( NEVER(rc) ) goto abort_due_to_error; | |
| 73766 | + assert( pC->isTable==0 ); | |
| 73730 | 73767 | assert( pC->deferredMoveto==0 ); |
| 73731 | - assert( pC->isTable==0 ); | |
| 73768 | + | |
| 73769 | + /* sqlite3VbeCursorRestore() can only fail if the record has been deleted | |
| 73770 | + ** out from under the cursor. That will never happend for an IdxRowid | |
| 73771 | + ** opcode, hence the NEVER() arround the check of the return value. | |
| 73772 | + */ | |
| 73773 | + rc = sqlite3VdbeCursorRestore(pC); | |
| 73774 | + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | |
| 73775 | + | |
| 73732 | 73776 | if( !pC->nullRow ){ |
| 73733 | 73777 | rowid = 0; /* Not needed. Only used to silence a warning. */ |
| 73734 | 73778 | rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); |
| 73735 | 73779 | if( rc!=SQLITE_OK ){ |
| 73736 | 73780 | goto abort_due_to_error; |
| @@ -78187,11 +78231,11 @@ | ||
| 78187 | 78231 | if( rc==SQLITE_OK ){ |
| 78188 | 78232 | #if SQLITE_MAX_WORKER_THREADS |
| 78189 | 78233 | assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); |
| 78190 | 78234 | if( pSorter->bUseThreads ){ |
| 78191 | 78235 | int iTask; |
| 78192 | - PmaReader *pReadr; | |
| 78236 | + PmaReader *pReadr = 0; | |
| 78193 | 78237 | SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; |
| 78194 | 78238 | rc = vdbeSortAllocUnpacked(pLast); |
| 78195 | 78239 | if( rc==SQLITE_OK ){ |
| 78196 | 78240 | pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); |
| 78197 | 78241 | pSorter->pReader = pReadr; |
| @@ -87168,29 +87212,27 @@ | ||
| 87168 | 87212 | tRowcnt v; |
| 87169 | 87213 | |
| 87170 | 87214 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87171 | 87215 | if( z==0 ) z = ""; |
| 87172 | 87216 | #else |
| 87173 | - if( NEVER(z==0) ) z = ""; | |
| 87217 | + assert( z!=0 ); | |
| 87174 | 87218 | #endif |
| 87175 | 87219 | for(i=0; *z && i<nOut; i++){ |
| 87176 | 87220 | v = 0; |
| 87177 | 87221 | while( (c=z[0])>='0' && c<='9' ){ |
| 87178 | 87222 | v = v*10 + c - '0'; |
| 87179 | 87223 | z++; |
| 87180 | 87224 | } |
| 87181 | 87225 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87182 | - if( aOut ){ | |
| 87183 | - aOut[i] = v; | |
| 87184 | - }else | |
| 87226 | + if( aOut ) aOut[i] = v; | |
| 87227 | + if( aLog ) aLog[i] = sqlite3LogEst(v); | |
| 87185 | 87228 | #else |
| 87186 | 87229 | assert( aOut==0 ); |
| 87187 | 87230 | UNUSED_PARAMETER(aOut); |
| 87231 | + assert( aLog!=0 ); | |
| 87232 | + aLog[i] = sqlite3LogEst(v); | |
| 87188 | 87233 | #endif |
| 87189 | - { | |
| 87190 | - aLog[i] = sqlite3LogEst(v); | |
| 87191 | - } | |
| 87192 | 87234 | if( *z==' ' ) z++; |
| 87193 | 87235 | } |
| 87194 | 87236 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87195 | 87237 | assert( pIndex!=0 ); |
| 87196 | 87238 | #else |
| @@ -87247,12 +87289,21 @@ | ||
| 87247 | 87289 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 87248 | 87290 | } |
| 87249 | 87291 | z = argv[2]; |
| 87250 | 87292 | |
| 87251 | 87293 | if( pIndex ){ |
| 87294 | + int nCol = pIndex->nKeyCol+1; | |
| 87295 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 87296 | + tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero( | |
| 87297 | + sizeof(tRowcnt) * nCol | |
| 87298 | + ); | |
| 87299 | + if( aiRowEst==0 ) pInfo->db->mallocFailed = 1; | |
| 87300 | +#else | |
| 87301 | + tRowcnt * const aiRowEst = 0; | |
| 87302 | +#endif | |
| 87252 | 87303 | pIndex->bUnordered = 0; |
| 87253 | - decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); | |
| 87304 | + decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); | |
| 87254 | 87305 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 87255 | 87306 | }else{ |
| 87256 | 87307 | Index fakeIdx; |
| 87257 | 87308 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 87258 | 87309 | #ifdef SQLITE_ENABLE_COSTMULT |
| @@ -87307,29 +87358,42 @@ | ||
| 87307 | 87358 | ** unique. */ |
| 87308 | 87359 | nCol = pIdx->nSampleCol-1; |
| 87309 | 87360 | pIdx->aAvgEq[nCol] = 1; |
| 87310 | 87361 | } |
| 87311 | 87362 | for(iCol=0; iCol<nCol; iCol++){ |
| 87363 | + int nSample = pIdx->nSample; | |
| 87312 | 87364 | int i; /* Used to iterate through samples */ |
| 87313 | 87365 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 87314 | - tRowcnt nSum = 0; /* Number of terms contributing to sumEq */ | |
| 87315 | 87366 | tRowcnt avgEq = 0; |
| 87316 | - tRowcnt nDLt = pFinal->anDLt[iCol]; | |
| 87367 | + tRowcnt nRow; /* Number of rows in index */ | |
| 87368 | + i64 nSum100 = 0; /* Number of terms contributing to sumEq */ | |
| 87369 | + i64 nDist100; /* Number of distinct values in index */ | |
| 87370 | + | |
| 87371 | + if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){ | |
| 87372 | + nRow = pFinal->anLt[iCol]; | |
| 87373 | + nDist100 = (i64)100 * pFinal->anDLt[iCol]; | |
| 87374 | + nSample--; | |
| 87375 | + }else{ | |
| 87376 | + nRow = pIdx->aiRowEst[0]; | |
| 87377 | + nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; | |
| 87378 | + } | |
| 87317 | 87379 | |
| 87318 | 87380 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 87319 | - ** occur in the stat4 table for this index before pFinal. Set | |
| 87320 | - ** sumEq to the sum of the nEq values for column iCol for the same | |
| 87321 | - ** set (adding the value only once where there exist duplicate | |
| 87322 | - ** prefixes). */ | |
| 87323 | - for(i=0; i<(pIdx->nSample-1); i++){ | |
| 87324 | - if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ | |
| 87381 | + ** occur in the stat4 table for this index. Set sumEq to the sum of | |
| 87382 | + ** the nEq values for column iCol for the same set (adding the value | |
| 87383 | + ** only once where there exist duplicate prefixes). */ | |
| 87384 | + for(i=0; i<nSample; i++){ | |
| 87385 | + if( i==(pIdx->nSample-1) | |
| 87386 | + || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] | |
| 87387 | + ){ | |
| 87325 | 87388 | sumEq += aSample[i].anEq[iCol]; |
| 87326 | - nSum++; | |
| 87389 | + nSum100 += 100; | |
| 87327 | 87390 | } |
| 87328 | 87391 | } |
| 87329 | - if( nDLt>nSum ){ | |
| 87330 | - avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum); | |
| 87392 | + | |
| 87393 | + if( nDist100>nSum100 ){ | |
| 87394 | + avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); | |
| 87331 | 87395 | } |
| 87332 | 87396 | if( avgEq==0 ) avgEq = 1; |
| 87333 | 87397 | pIdx->aAvgEq[iCol] = avgEq; |
| 87334 | 87398 | } |
| 87335 | 87399 | } |
| @@ -87576,10 +87640,15 @@ | ||
| 87576 | 87640 | if( rc==SQLITE_OK ){ |
| 87577 | 87641 | int lookasideEnabled = db->lookaside.bEnabled; |
| 87578 | 87642 | db->lookaside.bEnabled = 0; |
| 87579 | 87643 | rc = loadStat4(db, sInfo.zDatabase); |
| 87580 | 87644 | db->lookaside.bEnabled = lookasideEnabled; |
| 87645 | + } | |
| 87646 | + for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ | |
| 87647 | + Index *pIdx = sqliteHashData(i); | |
| 87648 | + sqlite3_free(pIdx->aiRowEst); | |
| 87649 | + pIdx->aiRowEst = 0; | |
| 87581 | 87650 | } |
| 87582 | 87651 | #endif |
| 87583 | 87652 | |
| 87584 | 87653 | if( rc==SQLITE_NOMEM ){ |
| 87585 | 87654 | db->mallocFailed = 1; |
| @@ -88870,10 +88939,13 @@ | ||
| 88870 | 88939 | #endif |
| 88871 | 88940 | if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo); |
| 88872 | 88941 | sqlite3ExprDelete(db, p->pPartIdxWhere); |
| 88873 | 88942 | sqlite3DbFree(db, p->zColAff); |
| 88874 | 88943 | if( p->isResized ) sqlite3DbFree(db, p->azColl); |
| 88944 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 88945 | + sqlite3_free(p->aiRowEst); | |
| 88946 | +#endif | |
| 88875 | 88947 | sqlite3DbFree(db, p); |
| 88876 | 88948 | } |
| 88877 | 88949 | |
| 88878 | 88950 | /* |
| 88879 | 88951 | ** For the index called zIdxName which is found in the database iDb, |
| @@ -91179,11 +91251,11 @@ | ||
| 91179 | 91251 | pIndex->nKeyCol); VdbeCoverage(v); |
| 91180 | 91252 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 91181 | 91253 | }else{ |
| 91182 | 91254 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 91183 | 91255 | } |
| 91184 | - sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); | |
| 91256 | + sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); | |
| 91185 | 91257 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); |
| 91186 | 91258 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 91187 | 91259 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 91188 | 91260 | sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); |
| 91189 | 91261 | sqlite3VdbeJumpHere(v, addr1); |
| @@ -93687,11 +93759,11 @@ | ||
| 93687 | 93759 | if( okOnePass ){ |
| 93688 | 93760 | /* Just one row. Hence the top-of-loop is a no-op */ |
| 93689 | 93761 | assert( nKey==nPk ); /* OP_Found will use an unpacked key */ |
| 93690 | 93762 | assert( !IsVirtual(pTab) ); |
| 93691 | 93763 | if( aToOpen[iDataCur-iTabCur] ){ |
| 93692 | - assert( pPk!=0 ); | |
| 93764 | + assert( pPk!=0 || pTab->pSelect!=0 ); | |
| 93693 | 93765 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); |
| 93694 | 93766 | VdbeCoverage(v); |
| 93695 | 93767 | } |
| 93696 | 93768 | }else if( pPk ){ |
| 93697 | 93769 | addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); |
| @@ -105122,11 +105194,10 @@ | ||
| 105122 | 105194 | int regRow; |
| 105123 | 105195 | int regRowid; |
| 105124 | 105196 | int nKey; |
| 105125 | 105197 | int iSortTab; /* Sorter cursor to read from */ |
| 105126 | 105198 | int nSortData; /* Trailing values to read from sorter */ |
| 105127 | - u8 p5; /* p5 parameter for 1st OP_Column */ | |
| 105128 | 105199 | int i; |
| 105129 | 105200 | int bSeq; /* True if sorter record includes seq. no. */ |
| 105130 | 105201 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
| 105131 | 105202 | struct ExprList_item *aOutEx = p->pEList->a; |
| 105132 | 105203 | #endif |
| @@ -105156,23 +105227,20 @@ | ||
| 105156 | 105227 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); |
| 105157 | 105228 | if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 105158 | 105229 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 105159 | 105230 | VdbeCoverage(v); |
| 105160 | 105231 | codeOffset(v, p->iOffset, addrContinue); |
| 105161 | - sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); | |
| 105162 | - p5 = OPFLAG_CLEARCACHE; | |
| 105232 | + sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); | |
| 105163 | 105233 | bSeq = 0; |
| 105164 | 105234 | }else{ |
| 105165 | 105235 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); |
| 105166 | 105236 | codeOffset(v, p->iOffset, addrContinue); |
| 105167 | 105237 | iSortTab = iTab; |
| 105168 | - p5 = 0; | |
| 105169 | 105238 | bSeq = 1; |
| 105170 | 105239 | } |
| 105171 | 105240 | for(i=0; i<nSortData; i++){ |
| 105172 | 105241 | sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i); |
| 105173 | - if( i==0 ) sqlite3VdbeChangeP5(v, p5); | |
| 105174 | 105242 | VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); |
| 105175 | 105243 | } |
| 105176 | 105244 | switch( eDest ){ |
| 105177 | 105245 | case SRT_Table: |
| 105178 | 105246 | case SRT_EphemTab: { |
| @@ -109097,16 +109165,15 @@ | ||
| 109097 | 109165 | ** from the previous row currently stored in a0, a1, a2... |
| 109098 | 109166 | */ |
| 109099 | 109167 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 109100 | 109168 | sqlite3ExprCacheClear(pParse); |
| 109101 | 109169 | if( groupBySort ){ |
| 109102 | - sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); | |
| 109170 | + sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab); | |
| 109103 | 109171 | } |
| 109104 | 109172 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 109105 | 109173 | if( groupBySort ){ |
| 109106 | 109174 | sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); |
| 109107 | - if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); | |
| 109108 | 109175 | }else{ |
| 109109 | 109176 | sAggInfo.directMode = 1; |
| 109110 | 109177 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 109111 | 109178 | } |
| 109112 | 109179 | } |
| @@ -111216,12 +111283,12 @@ | ||
| 111216 | 111283 | 0, 0); |
| 111217 | 111284 | } |
| 111218 | 111285 | |
| 111219 | 111286 | /* Top of the update loop */ |
| 111220 | 111287 | if( okOnePass ){ |
| 111221 | - if( aToOpen[iDataCur-iBaseCur] ){ | |
| 111222 | - assert( pPk!=0 ); | |
| 111288 | + if( aToOpen[iDataCur-iBaseCur] && !isView ){ | |
| 111289 | + assert( pPk ); | |
| 111223 | 111290 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 111224 | 111291 | VdbeCoverageNeverTaken(v); |
| 111225 | 111292 | } |
| 111226 | 111293 | labelContinue = labelBreak; |
| 111227 | 111294 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| @@ -112450,10 +112517,11 @@ | ||
| 112450 | 112517 | } |
| 112451 | 112518 | sqlite3DbFree(db, pVTable); |
| 112452 | 112519 | }else if( ALWAYS(pVTable->pVtab) ){ |
| 112453 | 112520 | /* Justification of ALWAYS(): A correct vtab constructor must allocate |
| 112454 | 112521 | ** the sqlite3_vtab object if successful. */ |
| 112522 | + memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); | |
| 112455 | 112523 | pVTable->pVtab->pModule = pMod->pModule; |
| 112456 | 112524 | pVTable->nRef = 1; |
| 112457 | 112525 | if( sCtx.pTab ){ |
| 112458 | 112526 | const char *zFormat = "vtable constructor did not declare schema: %s"; |
| 112459 | 112527 | *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); |
| @@ -115700,21 +115768,28 @@ | ||
| 115700 | 115768 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 115701 | 115769 | whereKeyStats(pParse, p, pRec, 0, a); |
| 115702 | 115770 | iLower = a[0]; |
| 115703 | 115771 | iUpper = a[0] + a[1]; |
| 115704 | 115772 | } |
| 115773 | + | |
| 115774 | + assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 ); | |
| 115775 | + assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); | |
| 115776 | + assert( p->aSortOrder!=0 ); | |
| 115777 | + if( p->aSortOrder[nEq] ){ | |
| 115778 | + /* The roles of pLower and pUpper are swapped for a DESC index */ | |
| 115779 | + SWAP(WhereTerm*, pLower, pUpper); | |
| 115780 | + } | |
| 115705 | 115781 | |
| 115706 | 115782 | /* If possible, improve on the iLower estimate using ($P:$L). */ |
| 115707 | 115783 | if( pLower ){ |
| 115708 | 115784 | int bOk; /* True if value is extracted from pExpr */ |
| 115709 | 115785 | Expr *pExpr = pLower->pExpr->pRight; |
| 115710 | - assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 ); | |
| 115711 | 115786 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 115712 | 115787 | if( rc==SQLITE_OK && bOk ){ |
| 115713 | 115788 | tRowcnt iNew; |
| 115714 | 115789 | whereKeyStats(pParse, p, pRec, 0, a); |
| 115715 | - iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); | |
| 115790 | + iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); | |
| 115716 | 115791 | if( iNew>iLower ) iLower = iNew; |
| 115717 | 115792 | nOut--; |
| 115718 | 115793 | pLower = 0; |
| 115719 | 115794 | } |
| 115720 | 115795 | } |
| @@ -115721,16 +115796,15 @@ | ||
| 115721 | 115796 | |
| 115722 | 115797 | /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 115723 | 115798 | if( pUpper ){ |
| 115724 | 115799 | int bOk; /* True if value is extracted from pExpr */ |
| 115725 | 115800 | Expr *pExpr = pUpper->pExpr->pRight; |
| 115726 | - assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); | |
| 115727 | 115801 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 115728 | 115802 | if( rc==SQLITE_OK && bOk ){ |
| 115729 | 115803 | tRowcnt iNew; |
| 115730 | 115804 | whereKeyStats(pParse, p, pRec, 1, a); |
| 115731 | - iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); | |
| 115805 | + iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); | |
| 115732 | 115806 | if( iNew<iUpper ) iUpper = iNew; |
| 115733 | 115807 | nOut--; |
| 115734 | 115808 | pUpper = 0; |
| 115735 | 115809 | } |
| 115736 | 115810 | } |
| @@ -116225,65 +116299,52 @@ | ||
| 116225 | 116299 | sqlite3StrAccumAppend(pStr, "?", 1); |
| 116226 | 116300 | } |
| 116227 | 116301 | |
| 116228 | 116302 | /* |
| 116229 | 116303 | ** Argument pLevel describes a strategy for scanning table pTab. This |
| 116230 | -** function returns a pointer to a string buffer containing a description | |
| 116231 | -** of the subset of table rows scanned by the strategy in the form of an | |
| 116232 | -** SQL expression. Or, if all rows are scanned, NULL is returned. | |
| 116304 | +** function appends text to pStr that describes the subset of table | |
| 116305 | +** rows scanned by the strategy in the form of an SQL expression. | |
| 116233 | 116306 | ** |
| 116234 | 116307 | ** For example, if the query: |
| 116235 | 116308 | ** |
| 116236 | 116309 | ** SELECT * FROM t1 WHERE a=1 AND b>2; |
| 116237 | 116310 | ** |
| 116238 | 116311 | ** is run and there is an index on (a, b), then this function returns a |
| 116239 | 116312 | ** string similar to: |
| 116240 | 116313 | ** |
| 116241 | 116314 | ** "a=? AND b>?" |
| 116242 | -** | |
| 116243 | -** The returned pointer points to memory obtained from sqlite3DbMalloc(). | |
| 116244 | -** It is the responsibility of the caller to free the buffer when it is | |
| 116245 | -** no longer required. | |
| 116246 | 116315 | */ |
| 116247 | -static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){ | |
| 116316 | +static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){ | |
| 116248 | 116317 | Index *pIndex = pLoop->u.btree.pIndex; |
| 116249 | 116318 | u16 nEq = pLoop->u.btree.nEq; |
| 116250 | 116319 | u16 nSkip = pLoop->u.btree.nSkip; |
| 116251 | 116320 | int i, j; |
| 116252 | 116321 | Column *aCol = pTab->aCol; |
| 116253 | 116322 | i16 *aiColumn = pIndex->aiColumn; |
| 116254 | - StrAccum txt; | |
| 116255 | - | |
| 116256 | - if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){ | |
| 116257 | - return 0; | |
| 116258 | - } | |
| 116259 | - sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); | |
| 116260 | - txt.db = db; | |
| 116261 | - sqlite3StrAccumAppend(&txt, " (", 2); | |
| 116323 | + | |
| 116324 | + if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; | |
| 116325 | + sqlite3StrAccumAppend(pStr, " (", 2); | |
| 116262 | 116326 | for(i=0; i<nEq; i++){ |
| 116263 | 116327 | char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName; |
| 116264 | 116328 | if( i>=nSkip ){ |
| 116265 | - explainAppendTerm(&txt, i, z, "="); | |
| 116329 | + explainAppendTerm(pStr, i, z, "="); | |
| 116266 | 116330 | }else{ |
| 116267 | - if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5); | |
| 116268 | - sqlite3StrAccumAppend(&txt, "ANY(", 4); | |
| 116269 | - sqlite3StrAccumAppendAll(&txt, z); | |
| 116270 | - sqlite3StrAccumAppend(&txt, ")", 1); | |
| 116331 | + if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); | |
| 116332 | + sqlite3XPrintf(pStr, 0, "ANY(%s)", z); | |
| 116271 | 116333 | } |
| 116272 | 116334 | } |
| 116273 | 116335 | |
| 116274 | 116336 | j = i; |
| 116275 | 116337 | if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ |
| 116276 | 116338 | char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; |
| 116277 | - explainAppendTerm(&txt, i++, z, ">"); | |
| 116339 | + explainAppendTerm(pStr, i++, z, ">"); | |
| 116278 | 116340 | } |
| 116279 | 116341 | if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ |
| 116280 | 116342 | char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; |
| 116281 | - explainAppendTerm(&txt, i, z, "<"); | |
| 116343 | + explainAppendTerm(pStr, i, z, "<"); | |
| 116282 | 116344 | } |
| 116283 | - sqlite3StrAccumAppend(&txt, ")", 1); | |
| 116284 | - return sqlite3StrAccumFinish(&txt); | |
| 116345 | + sqlite3StrAccumAppend(pStr, ")", 1); | |
| 116285 | 116346 | } |
| 116286 | 116347 | |
| 116287 | 116348 | /* |
| 116288 | 116349 | ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN |
| 116289 | 116350 | ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single |
| @@ -116303,72 +116364,90 @@ | ||
| 116303 | 116364 | #endif |
| 116304 | 116365 | { |
| 116305 | 116366 | struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; |
| 116306 | 116367 | Vdbe *v = pParse->pVdbe; /* VM being constructed */ |
| 116307 | 116368 | sqlite3 *db = pParse->db; /* Database handle */ |
| 116308 | - char *zMsg; /* Text to add to EQP output */ | |
| 116309 | 116369 | int iId = pParse->iSelectId; /* Select id (left-most output column) */ |
| 116310 | 116370 | int isSearch; /* True for a SEARCH. False for SCAN. */ |
| 116311 | 116371 | WhereLoop *pLoop; /* The controlling WhereLoop object */ |
| 116312 | 116372 | u32 flags; /* Flags that describe this loop */ |
| 116373 | + char *zMsg; /* Text to add to EQP output */ | |
| 116374 | + StrAccum str; /* EQP output string */ | |
| 116375 | + char zBuf[100]; /* Initial space for EQP output string */ | |
| 116313 | 116376 | |
| 116314 | 116377 | pLoop = pLevel->pWLoop; |
| 116315 | 116378 | flags = pLoop->wsFlags; |
| 116316 | 116379 | if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return; |
| 116317 | 116380 | |
| 116318 | 116381 | isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 |
| 116319 | 116382 | || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) |
| 116320 | 116383 | || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); |
| 116321 | 116384 | |
| 116322 | - zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN"); | |
| 116385 | + sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); | |
| 116386 | + str.db = db; | |
| 116387 | + sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); | |
| 116323 | 116388 | if( pItem->pSelect ){ |
| 116324 | - zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId); | |
| 116389 | + sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId); | |
| 116325 | 116390 | }else{ |
| 116326 | - zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName); | |
| 116391 | + sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName); | |
| 116327 | 116392 | } |
| 116328 | 116393 | |
| 116329 | 116394 | if( pItem->zAlias ){ |
| 116330 | - zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); | |
| 116331 | - } | |
| 116332 | - if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 | |
| 116333 | - && ALWAYS(pLoop->u.btree.pIndex!=0) | |
| 116334 | - ){ | |
| 116335 | - const char *zFmt; | |
| 116336 | - Index *pIdx = pLoop->u.btree.pIndex; | |
| 116337 | - char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); | |
| 116395 | + sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias); | |
| 116396 | + } | |
| 116397 | + if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ | |
| 116398 | + const char *zFmt = 0; | |
| 116399 | + Index *pIdx; | |
| 116400 | + | |
| 116401 | + assert( pLoop->u.btree.pIndex!=0 ); | |
| 116402 | + pIdx = pLoop->u.btree.pIndex; | |
| 116338 | 116403 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); |
| 116339 | 116404 | if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 116340 | - zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s"; | |
| 116405 | + if( isSearch ){ | |
| 116406 | + zFmt = "PRIMARY KEY"; | |
| 116407 | + } | |
| 116341 | 116408 | }else if( flags & WHERE_AUTO_INDEX ){ |
| 116342 | - zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s"; | |
| 116409 | + zFmt = "AUTOMATIC COVERING INDEX"; | |
| 116343 | 116410 | }else if( flags & WHERE_IDX_ONLY ){ |
| 116344 | - zFmt = "%s USING COVERING INDEX %s%s"; | |
| 116411 | + zFmt = "COVERING INDEX %s"; | |
| 116345 | 116412 | }else{ |
| 116346 | - zFmt = "%s USING INDEX %s%s"; | |
| 116413 | + zFmt = "INDEX %s"; | |
| 116347 | 116414 | } |
| 116348 | - zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere); | |
| 116349 | - sqlite3DbFree(db, zWhere); | |
| 116415 | + if( zFmt ){ | |
| 116416 | + sqlite3StrAccumAppend(&str, " USING ", 7); | |
| 116417 | + sqlite3XPrintf(&str, 0, zFmt, pIdx->zName); | |
| 116418 | + explainIndexRange(&str, pLoop, pItem->pTab); | |
| 116419 | + } | |
| 116350 | 116420 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 116351 | - zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); | |
| 116352 | - | |
| 116421 | + const char *zRange; | |
| 116353 | 116422 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| 116354 | - zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg); | |
| 116423 | + zRange = "(rowid=?)"; | |
| 116355 | 116424 | }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ |
| 116356 | - zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg); | |
| 116425 | + zRange = "(rowid>? AND rowid<?)"; | |
| 116357 | 116426 | }else if( flags&WHERE_BTM_LIMIT ){ |
| 116358 | - zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg); | |
| 116359 | - }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){ | |
| 116360 | - zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg); | |
| 116427 | + zRange = "(rowid>?)"; | |
| 116428 | + }else{ | |
| 116429 | + assert( flags&WHERE_TOP_LIMIT); | |
| 116430 | + zRange = "(rowid<?)"; | |
| 116361 | 116431 | } |
| 116432 | + sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY "); | |
| 116433 | + sqlite3StrAccumAppendAll(&str, zRange); | |
| 116362 | 116434 | } |
| 116363 | 116435 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 116364 | 116436 | else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ |
| 116365 | - zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, | |
| 116437 | + sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s", | |
| 116366 | 116438 | pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); |
| 116367 | 116439 | } |
| 116368 | 116440 | #endif |
| 116369 | - zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg); | |
| 116441 | +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS | |
| 116442 | + if( pLoop->nOut>=10 ){ | |
| 116443 | + sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); | |
| 116444 | + }else{ | |
| 116445 | + sqlite3StrAccumAppend(&str, " (~1 row)", 9); | |
| 116446 | + } | |
| 116447 | +#endif | |
| 116448 | + zMsg = sqlite3StrAccumFinish(&str); | |
| 116370 | 116449 | sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC); |
| 116371 | 116450 | } |
| 116372 | 116451 | } |
| 116373 | 116452 | #else |
| 116374 | 116453 | # define explainOneScan(u,v,w,x,y,z) |
| @@ -117633,11 +117712,11 @@ | ||
| 117633 | 117712 | if( ppPrev==0 ){ |
| 117634 | 117713 | /* There already exists a WhereLoop on the list that is better |
| 117635 | 117714 | ** than pTemplate, so just ignore pTemplate */ |
| 117636 | 117715 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117637 | 117716 | if( sqlite3WhereTrace & 0x8 ){ |
| 117638 | - sqlite3DebugPrintf("ins-noop: "); | |
| 117717 | + sqlite3DebugPrintf(" skip: "); | |
| 117639 | 117718 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 117640 | 117719 | } |
| 117641 | 117720 | #endif |
| 117642 | 117721 | return SQLITE_OK; |
| 117643 | 117722 | }else{ |
| @@ -117649,14 +117728,14 @@ | ||
| 117649 | 117728 | ** WhereLoop and insert it. |
| 117650 | 117729 | */ |
| 117651 | 117730 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117652 | 117731 | if( sqlite3WhereTrace & 0x8 ){ |
| 117653 | 117732 | if( p!=0 ){ |
| 117654 | - sqlite3DebugPrintf("ins-del: "); | |
| 117733 | + sqlite3DebugPrintf("replace: "); | |
| 117655 | 117734 | whereLoopPrint(p, pBuilder->pWC); |
| 117656 | 117735 | } |
| 117657 | - sqlite3DebugPrintf("ins-new: "); | |
| 117736 | + sqlite3DebugPrintf(" add: "); | |
| 117658 | 117737 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 117659 | 117738 | } |
| 117660 | 117739 | #endif |
| 117661 | 117740 | if( p==0 ){ |
| 117662 | 117741 | /* Allocate a new WhereLoop to add to the end of the list */ |
| @@ -117676,11 +117755,11 @@ | ||
| 117676 | 117755 | pToDel = *ppTail; |
| 117677 | 117756 | if( pToDel==0 ) break; |
| 117678 | 117757 | *ppTail = pToDel->pNextLoop; |
| 117679 | 117758 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117680 | 117759 | if( sqlite3WhereTrace & 0x8 ){ |
| 117681 | - sqlite3DebugPrintf("ins-del: "); | |
| 117760 | + sqlite3DebugPrintf(" delete: "); | |
| 117682 | 117761 | whereLoopPrint(pToDel, pBuilder->pWC); |
| 117683 | 117762 | } |
| 117684 | 117763 | #endif |
| 117685 | 117764 | whereLoopDelete(db, pToDel); |
| 117686 | 117765 | } |
| @@ -118843,11 +118922,11 @@ | ||
| 118843 | 118922 | if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; |
| 118844 | 118923 | } |
| 118845 | 118924 | isMatch = 1; |
| 118846 | 118925 | break; |
| 118847 | 118926 | } |
| 118848 | - if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ | |
| 118927 | + if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ | |
| 118849 | 118928 | /* Make sure the sort order is compatible in an ORDER BY clause. |
| 118850 | 118929 | ** Sort order is irrelevant for a GROUP BY clause. */ |
| 118851 | 118930 | if( revSet ){ |
| 118852 | 118931 | if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; |
| 118853 | 118932 | }else{ |
| @@ -119308,16 +119387,19 @@ | ||
| 119308 | 119387 | pWInfo->revMask = pFrom->revLoop; |
| 119309 | 119388 | } |
| 119310 | 119389 | if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) |
| 119311 | 119390 | && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr |
| 119312 | 119391 | ){ |
| 119313 | - Bitmask notUsed = 0; | |
| 119392 | + Bitmask revMask = 0; | |
| 119314 | 119393 | int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, |
| 119315 | - pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used | |
| 119394 | + pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask | |
| 119316 | 119395 | ); |
| 119317 | 119396 | assert( pWInfo->sorted==0 ); |
| 119318 | - pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr); | |
| 119397 | + if( nOrder==pWInfo->pOrderBy->nExpr ){ | |
| 119398 | + pWInfo->sorted = 1; | |
| 119399 | + pWInfo->revMask = revMask; | |
| 119400 | + } | |
| 119319 | 119401 | } |
| 119320 | 119402 | } |
| 119321 | 119403 | |
| 119322 | 119404 | |
| 119323 | 119405 | pWInfo->nRowOut = pFrom->nRow; |
| @@ -132620,10 +132702,11 @@ | ||
| 132620 | 132702 | assert( iIdx==nVal ); |
| 132621 | 132703 | |
| 132622 | 132704 | /* In case the cursor has been used before, clear it now. */ |
| 132623 | 132705 | sqlite3_finalize(pCsr->pStmt); |
| 132624 | 132706 | sqlite3_free(pCsr->aDoclist); |
| 132707 | + sqlite3_free(pCsr->aMatchinfo); | |
| 132625 | 132708 | sqlite3Fts3ExprFree(pCsr->pExpr); |
| 132626 | 132709 | memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); |
| 132627 | 132710 | |
| 132628 | 132711 | /* Set the lower and upper bounds on docids to return */ |
| 132629 | 132712 | pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); |
| @@ -133930,11 +134013,11 @@ | ||
| 133930 | 134013 | if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ |
| 133931 | 134014 | iMax = a[i].iDocid; |
| 133932 | 134015 | bMaxSet = 1; |
| 133933 | 134016 | } |
| 133934 | 134017 | } |
| 133935 | - assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 ); | |
| 134018 | + assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) ); | |
| 133936 | 134019 | assert( rc!=SQLITE_OK || bMaxSet ); |
| 133937 | 134020 | |
| 133938 | 134021 | /* Keep advancing iterators until they all point to the same document */ |
| 133939 | 134022 | for(i=0; i<p->nToken; i++){ |
| 133940 | 134023 | while( rc==SQLITE_OK && bEof==0 |
| @@ -136047,11 +136130,11 @@ | ||
| 136047 | 136130 | int i = 0; |
| 136048 | 136131 | |
| 136049 | 136132 | /* Set variable i to the maximum number of bytes of input to tokenize. */ |
| 136050 | 136133 | for(i=0; i<n; i++){ |
| 136051 | 136134 | if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break; |
| 136052 | - if( z[i]=='*' || z[i]=='"' ) break; | |
| 136135 | + if( z[i]=='"' ) break; | |
| 136053 | 136136 | } |
| 136054 | 136137 | |
| 136055 | 136138 | *pnConsumed = i; |
| 136056 | 136139 | rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); |
| 136057 | 136140 | if( rc==SQLITE_OK ){ |
| 136058 | 136141 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.7. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -229,13 +229,13 @@ | |
| 229 | ** |
| 230 | ** See also: [sqlite3_libversion()], |
| 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | */ |
| 234 | #define SQLITE_VERSION "3.8.7" |
| 235 | #define SQLITE_VERSION_NUMBER 3008007 |
| 236 | #define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d" |
| 237 | |
| 238 | /* |
| 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | ** |
| @@ -7944,11 +7944,11 @@ | |
| 7944 | ** A macro to hint to the compiler that a function should not be |
| 7945 | ** inlined. |
| 7946 | */ |
| 7947 | #if defined(__GNUC__) |
| 7948 | # define SQLITE_NOINLINE __attribute__((noinline)) |
| 7949 | #elif defined(_MSC_VER) |
| 7950 | # define SQLITE_NOINLINE __declspec(noinline) |
| 7951 | #else |
| 7952 | # define SQLITE_NOINLINE |
| 7953 | #endif |
| 7954 | |
| @@ -11322,10 +11322,11 @@ | |
| 11322 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 11323 | int nSample; /* Number of elements in aSample[] */ |
| 11324 | int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 11325 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 11326 | IndexSample *aSample; /* Samples of the left-most key */ |
| 11327 | #endif |
| 11328 | }; |
| 11329 | |
| 11330 | /* |
| 11331 | ** Allowed values for Index.idxType |
| @@ -12186,11 +12187,10 @@ | |
| 12186 | #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ |
| 12187 | #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ |
| 12188 | #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ |
| 12189 | #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ |
| 12190 | #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ |
| 12191 | #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ |
| 12192 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 12193 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 12194 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ |
| 12195 | #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ |
| 12196 | #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ |
| @@ -13320,14 +13320,13 @@ | |
| 13320 | # define sqlite3MemdebugSetType(X,Y) /* no-op */ |
| 13321 | # define sqlite3MemdebugHasType(X,Y) 1 |
| 13322 | # define sqlite3MemdebugNoType(X,Y) 1 |
| 13323 | #endif |
| 13324 | #define MEMTYPE_HEAP 0x01 /* General heap allocations */ |
| 13325 | #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ |
| 13326 | #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ |
| 13327 | #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ |
| 13328 | #define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */ |
| 13329 | |
| 13330 | /* |
| 13331 | ** Threading interface |
| 13332 | */ |
| 13333 | #if SQLITE_MAX_WORKER_THREADS>0 |
| @@ -14095,21 +14094,19 @@ | |
| 14095 | #ifdef SQLITE_DEBUG |
| 14096 | u8 seekOp; /* Most recent seek operation on this cursor */ |
| 14097 | #endif |
| 14098 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 14099 | u8 nullRow; /* True if pointing to a row with no data */ |
| 14100 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 14101 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 14102 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 14103 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 14104 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 14105 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 14106 | Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 14107 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 14108 | i64 seqCount; /* Sequence counter */ |
| 14109 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 14110 | i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 14111 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| 14112 | |
| 14113 | /* Cached information about the header for the data record that the |
| 14114 | ** cursor is currently pointing to. Only valid if cacheStatus matches |
| 14115 | ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| @@ -14122,10 +14119,11 @@ | |
| 14122 | u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
| 14123 | u32 payloadSize; /* Total number of bytes in the record */ |
| 14124 | u32 szRow; /* Byte available in aRow */ |
| 14125 | u32 iHdrOffset; /* Offset to next unparsed byte of the header */ |
| 14126 | const u8 *aRow; /* Data for the current row, if all on one page */ |
| 14127 | u32 aType[1]; /* Type values for all entries in the record */ |
| 14128 | /* 2*nField extra array elements allocated for aType[], beyond the one |
| 14129 | ** static element declared in the structure. nField total array slots for |
| 14130 | ** aType[] and nField+1 array slots for aOffset[] */ |
| 14131 | }; |
| @@ -14198,11 +14196,11 @@ | |
| 14198 | int n; /* Number of characters in string value, excluding '\0' */ |
| 14199 | char *z; /* String or BLOB value */ |
| 14200 | /* ShallowCopy only needs to copy the information above */ |
| 14201 | char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ |
| 14202 | int szMalloc; /* Size of the zMalloc allocation */ |
| 14203 | int iPadding1; /* Padding for 8-byte alignment */ |
| 14204 | sqlite3 *db; /* The associated database connection */ |
| 14205 | void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ |
| 14206 | #ifdef SQLITE_DEBUG |
| 14207 | Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ |
| 14208 | void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ |
| @@ -14406,10 +14404,11 @@ | |
| 14406 | ** Function prototypes |
| 14407 | */ |
| 14408 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); |
| 14409 | void sqliteVdbePopStack(Vdbe*,int); |
| 14410 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*); |
| 14411 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 14412 | SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); |
| 14413 | #endif |
| 14414 | SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); |
| 14415 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); |
| @@ -17130,11 +17129,11 @@ | |
| 17130 | ** allocation p. Also return true if p==NULL. |
| 17131 | ** |
| 17132 | ** This routine is designed for use within an assert() statement, to |
| 17133 | ** verify the type of an allocation. For example: |
| 17134 | ** |
| 17135 | ** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); |
| 17136 | */ |
| 17137 | SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ |
| 17138 | int rc = 1; |
| 17139 | if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ |
| 17140 | struct MemBlockHdr *pHdr; |
| @@ -17152,11 +17151,11 @@ | |
| 17152 | ** allocation p. Also return true if p==NULL. |
| 17153 | ** |
| 17154 | ** This routine is designed for use within an assert() statement, to |
| 17155 | ** verify the type of an allocation. For example: |
| 17156 | ** |
| 17157 | ** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); |
| 17158 | */ |
| 17159 | SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ |
| 17160 | int rc = 1; |
| 17161 | if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ |
| 17162 | struct MemBlockHdr *pHdr; |
| @@ -20364,39 +20363,41 @@ | |
| 20364 | ** Return the size of a memory allocation previously obtained from |
| 20365 | ** sqlite3Malloc() or sqlite3_malloc(). |
| 20366 | */ |
| 20367 | SQLITE_PRIVATE int sqlite3MallocSize(void *p){ |
| 20368 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20369 | assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); |
| 20370 | return sqlite3GlobalConfig.m.xSize(p); |
| 20371 | } |
| 20372 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ |
| 20373 | if( db==0 ){ |
| 20374 | return sqlite3MallocSize(p); |
| 20375 | }else{ |
| 20376 | assert( sqlite3_mutex_held(db->mutex) ); |
| 20377 | if( isLookaside(db, p) ){ |
| 20378 | return db->lookaside.sz; |
| 20379 | }else{ |
| 20380 | assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); |
| 20381 | assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); |
| 20382 | assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); |
| 20383 | return sqlite3GlobalConfig.m.xSize(p); |
| 20384 | } |
| 20385 | } |
| 20386 | } |
| 20387 | SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ |
| 20388 | return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p); |
| 20389 | } |
| 20390 | |
| 20391 | /* |
| 20392 | ** Free memory previously obtained from sqlite3Malloc(). |
| 20393 | */ |
| 20394 | SQLITE_API void sqlite3_free(void *p){ |
| 20395 | if( p==0 ) return; /* IMP: R-49053-54554 */ |
| 20396 | assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); |
| 20397 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20398 | if( sqlite3GlobalConfig.bMemstat ){ |
| 20399 | sqlite3_mutex_enter(mem0.mutex); |
| 20400 | sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); |
| 20401 | sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); |
| 20402 | sqlite3GlobalConfig.m.xFree(p); |
| @@ -20436,12 +20437,12 @@ | |
| 20436 | db->lookaside.pFree = pBuf; |
| 20437 | db->lookaside.nOut--; |
| 20438 | return; |
| 20439 | } |
| 20440 | } |
| 20441 | assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); |
| 20442 | assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); |
| 20443 | assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); |
| 20444 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 20445 | sqlite3_free(p); |
| 20446 | } |
| 20447 | |
| @@ -20449,10 +20450,12 @@ | |
| 20449 | ** Change the size of an existing memory allocation |
| 20450 | */ |
| 20451 | SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ |
| 20452 | int nOld, nNew, nDiff; |
| 20453 | void *pNew; |
| 20454 | if( pOld==0 ){ |
| 20455 | return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ |
| 20456 | } |
| 20457 | if( nBytes==0 ){ |
| 20458 | sqlite3_free(pOld); /* IMP: R-26507-47431 */ |
| @@ -20475,12 +20478,10 @@ | |
| 20475 | nDiff = nNew - nOld; |
| 20476 | if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= |
| 20477 | mem0.alarmThreshold-nDiff ){ |
| 20478 | sqlite3MallocAlarm(nDiff); |
| 20479 | } |
| 20480 | assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); |
| 20481 | assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); |
| 20482 | pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); |
| 20483 | if( pNew==0 && mem0.alarmCallback ){ |
| 20484 | sqlite3MallocAlarm((int)nBytes); |
| 20485 | pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); |
| 20486 | } |
| @@ -20589,12 +20590,12 @@ | |
| 20589 | #endif |
| 20590 | p = sqlite3Malloc(n); |
| 20591 | if( !p && db ){ |
| 20592 | db->mallocFailed = 1; |
| 20593 | } |
| 20594 | sqlite3MemdebugSetType(p, MEMTYPE_DB | |
| 20595 | ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); |
| 20596 | return p; |
| 20597 | } |
| 20598 | |
| 20599 | /* |
| 20600 | ** Resize the block of memory pointed to by p to n bytes. If the |
| @@ -20616,19 +20617,18 @@ | |
| 20616 | if( pNew ){ |
| 20617 | memcpy(pNew, p, db->lookaside.sz); |
| 20618 | sqlite3DbFree(db, p); |
| 20619 | } |
| 20620 | }else{ |
| 20621 | assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); |
| 20622 | assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); |
| 20623 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 20624 | pNew = sqlite3_realloc64(p, n); |
| 20625 | if( !pNew ){ |
| 20626 | sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP); |
| 20627 | db->mallocFailed = 1; |
| 20628 | } |
| 20629 | sqlite3MemdebugSetType(pNew, MEMTYPE_DB | |
| 20630 | (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); |
| 20631 | } |
| 20632 | } |
| 20633 | return pNew; |
| 20634 | } |
| @@ -20754,15 +20754,11 @@ | |
| 20754 | ** HAVE_STRCHRNUL. If that routine is not available, this module |
| 20755 | ** will supply its own. The built-in version is slower than |
| 20756 | ** the glibc version so the glibc version is definitely preferred. |
| 20757 | */ |
| 20758 | #if !defined(HAVE_STRCHRNUL) |
| 20759 | # if defined(linux) |
| 20760 | # define HAVE_STRCHRNUL 1 |
| 20761 | # else |
| 20762 | # define HAVE_STRCHRNUL 0 |
| 20763 | # endif |
| 20764 | #endif |
| 20765 | |
| 20766 | |
| 20767 | /* |
| 20768 | ** Conversion types fall into various categories as defined by the |
| @@ -22091,18 +22087,18 @@ | |
| 22091 | #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ |
| 22092 | /******************************** End Unix Pthreads *************************/ |
| 22093 | |
| 22094 | |
| 22095 | /********************************* Win32 Threads ****************************/ |
| 22096 | #if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 |
| 22097 | |
| 22098 | #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ |
| 22099 | #include <process.h> |
| 22100 | |
| 22101 | /* A running thread */ |
| 22102 | struct SQLiteThread { |
| 22103 | uintptr_t tid; /* The thread handle */ |
| 22104 | unsigned id; /* The thread identifier */ |
| 22105 | void *(*xTask)(void*); /* The routine to run as a thread */ |
| 22106 | void *pIn; /* Argument to xTask */ |
| 22107 | void *pResult; /* Result of xTask */ |
| 22108 | }; |
| @@ -22146,11 +22142,11 @@ | |
| 22146 | if( sqlite3GlobalConfig.bCoreMutex==0 ){ |
| 22147 | memset(p, 0, sizeof(*p)); |
| 22148 | }else{ |
| 22149 | p->xTask = xTask; |
| 22150 | p->pIn = pIn; |
| 22151 | p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); |
| 22152 | if( p->tid==0 ){ |
| 22153 | memset(p, 0, sizeof(*p)); |
| 22154 | } |
| 22155 | } |
| 22156 | if( p->xTask==0 ){ |
| @@ -22184,11 +22180,11 @@ | |
| 22184 | if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; |
| 22185 | sqlite3_free(p); |
| 22186 | return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; |
| 22187 | } |
| 22188 | |
| 22189 | #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */ |
| 22190 | /******************************** End Win32 Threads *************************/ |
| 22191 | |
| 22192 | |
| 22193 | /********************************* Single-Threaded **************************/ |
| 22194 | #ifndef SQLITE_THREADS_IMPLEMENTED |
| @@ -33487,11 +33483,15 @@ | |
| 33487 | #endif |
| 33488 | |
| 33489 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 33490 | DWORD))aSyscall[63].pCurrent) |
| 33491 | |
| 33492 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 33493 | |
| 33494 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 33495 | BOOL))aSyscall[64].pCurrent) |
| 33496 | |
| 33497 | #if SQLITE_OS_WINRT |
| @@ -33830,11 +33830,12 @@ | |
| 33830 | #else |
| 33831 | osSleep(milliseconds); |
| 33832 | #endif |
| 33833 | } |
| 33834 | |
| 33835 | #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 |
| 33836 | SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ |
| 33837 | DWORD rc; |
| 33838 | while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, |
| 33839 | TRUE))==WAIT_IO_COMPLETION ){} |
| 33840 | return rc; |
| @@ -39855,11 +39856,11 @@ | |
| 39855 | assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); |
| 39856 | assert( pCache->n90pct == pCache->nMax*9/10 ); |
| 39857 | if( createFlag==1 && ( |
| 39858 | nPinned>=pGroup->mxPinned |
| 39859 | || nPinned>=pCache->n90pct |
| 39860 | || pcache1UnderMemoryPressure(pCache) |
| 39861 | )){ |
| 39862 | return 0; |
| 39863 | } |
| 39864 | |
| 39865 | if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache); |
| @@ -42799,10 +42800,18 @@ | |
| 42799 | }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ |
| 42800 | if( pPager->journalOff==0 ){ |
| 42801 | rc = SQLITE_OK; |
| 42802 | }else{ |
| 42803 | rc = sqlite3OsTruncate(pPager->jfd, 0); |
| 42804 | } |
| 42805 | pPager->journalOff = 0; |
| 42806 | }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
| 42807 | || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) |
| 42808 | ){ |
| @@ -44476,17 +44485,19 @@ | |
| 44476 | if( !pNew ) rc = SQLITE_NOMEM; |
| 44477 | } |
| 44478 | |
| 44479 | if( rc==SQLITE_OK ){ |
| 44480 | pager_reset(pPager); |
| 44481 | sqlite3PageFree(pPager->pTmpSpace); |
| 44482 | pPager->pTmpSpace = pNew; |
| 44483 | rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); |
| 44484 | } |
| 44485 | if( rc==SQLITE_OK ){ |
| 44486 | pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); |
| 44487 | pPager->pageSize = pageSize; |
| 44488 | } |
| 44489 | } |
| 44490 | |
| 44491 | *pPageSize = pPager->pageSize; |
| 44492 | if( rc==SQLITE_OK ){ |
| @@ -51649,11 +51660,11 @@ | |
| 51649 | int nRef; /* Number of references to this structure */ |
| 51650 | BtShared *pNext; /* Next on a list of sharable BtShared structs */ |
| 51651 | BtLock *pLock; /* List of locks held on this shared-btree struct */ |
| 51652 | Btree *pWriter; /* Btree with currently open write transaction */ |
| 51653 | #endif |
| 51654 | u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ |
| 51655 | }; |
| 51656 | |
| 51657 | /* |
| 51658 | ** Allowed values for BtShared.btsFlags |
| 51659 | */ |
| @@ -52947,11 +52958,11 @@ | |
| 52947 | ** |
| 52948 | ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor |
| 52949 | ** back to where it ought to be if this routine returns true. |
| 52950 | */ |
| 52951 | SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ |
| 52952 | return pCur && pCur->eState!=CURSOR_VALID; |
| 52953 | } |
| 52954 | |
| 52955 | /* |
| 52956 | ** This routine restores a cursor back to its original position after it |
| 52957 | ** has been moved by some outside activity (such as a btree rebalance or |
| @@ -54279,11 +54290,12 @@ | |
| 54279 | #endif |
| 54280 | } |
| 54281 | |
| 54282 | /* |
| 54283 | ** Make sure pBt->pTmpSpace points to an allocation of |
| 54284 | ** MX_CELL_SIZE(pBt) bytes. |
| 54285 | */ |
| 54286 | static void allocateTempSpace(BtShared *pBt){ |
| 54287 | if( !pBt->pTmpSpace ){ |
| 54288 | pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); |
| 54289 | |
| @@ -54294,21 +54306,32 @@ | |
| 54294 | ** can mean that fillInCell() only initializes the first 2 or 3 |
| 54295 | ** bytes of pTmpSpace, but that the first 4 bytes are copied from |
| 54296 | ** it into a database page. This is not actually a problem, but it |
| 54297 | ** does cause a valgrind error when the 1 or 2 bytes of unitialized |
| 54298 | ** data is passed to system call write(). So to avoid this error, |
| 54299 | ** zero the first 4 bytes of temp space here. */ |
| 54300 | if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4); |
| 54301 | } |
| 54302 | } |
| 54303 | |
| 54304 | /* |
| 54305 | ** Free the pBt->pTmpSpace allocation |
| 54306 | */ |
| 54307 | static void freeTempSpace(BtShared *pBt){ |
| 54308 | sqlite3PageFree( pBt->pTmpSpace); |
| 54309 | pBt->pTmpSpace = 0; |
| 54310 | } |
| 54311 | |
| 54312 | /* |
| 54313 | ** Close an open database and invalidate all cursors. |
| 54314 | */ |
| @@ -58016,15 +58039,10 @@ | |
| 58016 | ** pTemp is not null. Regardless of pTemp, allocate a new entry |
| 58017 | ** in pPage->apOvfl[] and make it point to the cell content (either |
| 58018 | ** in pTemp or the original pCell) and also record its index. |
| 58019 | ** Allocating a new entry in pPage->aCell[] implies that |
| 58020 | ** pPage->nOverflow is incremented. |
| 58021 | ** |
| 58022 | ** If nSkip is non-zero, then do not copy the first nSkip bytes of the |
| 58023 | ** cell. The caller will overwrite them after this function returns. If |
| 58024 | ** nSkip is non-zero, then pCell may not point to an invalid memory location |
| 58025 | ** (but pCell+nSkip is always valid). |
| 58026 | */ |
| 58027 | static void insertCell( |
| 58028 | MemPage *pPage, /* Page into which we are copying */ |
| 58029 | int i, /* New cell becomes the i-th cell of the page */ |
| 58030 | u8 *pCell, /* Content of the new cell */ |
| @@ -58037,11 +58055,10 @@ | |
| 58037 | int j; /* Loop counter */ |
| 58038 | int end; /* First byte past the last cell pointer in data[] */ |
| 58039 | int ins; /* Index in data[] where new cell pointer is inserted */ |
| 58040 | int cellOffset; /* Address of first cell pointer in data[] */ |
| 58041 | u8 *data; /* The content of the whole page */ |
| 58042 | int nSkip = (iChild ? 4 : 0); |
| 58043 | |
| 58044 | if( *pRC ) return; |
| 58045 | |
| 58046 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); |
| 58047 | assert( MX_CELL(pPage->pBt)<=10921 ); |
| @@ -58055,11 +58072,11 @@ | |
| 58055 | ** might be less than 8 (leaf-size + pointer) on the interior node. Hence |
| 58056 | ** the term after the || in the following assert(). */ |
| 58057 | assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) ); |
| 58058 | if( pPage->nOverflow || sz+2>pPage->nFree ){ |
| 58059 | if( pTemp ){ |
| 58060 | memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); |
| 58061 | pCell = pTemp; |
| 58062 | } |
| 58063 | if( iChild ){ |
| 58064 | put4byte(pCell, iChild); |
| 58065 | } |
| @@ -58084,11 +58101,11 @@ | |
| 58084 | ** if it returns success */ |
| 58085 | assert( idx >= end+2 ); |
| 58086 | assert( idx+sz <= (int)pPage->pBt->usableSize ); |
| 58087 | pPage->nCell++; |
| 58088 | pPage->nFree -= (u16)(2 + sz); |
| 58089 | memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); |
| 58090 | if( iChild ){ |
| 58091 | put4byte(&data[idx], iChild); |
| 58092 | } |
| 58093 | memmove(&data[ins+2], &data[ins], end-ins); |
| 58094 | put2byte(&data[ins], idx); |
| @@ -61630,11 +61647,14 @@ | |
| 61630 | /* If MEM_Dyn is set then Mem.xDel!=0. |
| 61631 | ** Mem.xDel is might not be initialized if MEM_Dyn is clear. |
| 61632 | */ |
| 61633 | assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); |
| 61634 | |
| 61635 | /* MEM_Dyn may only be set if Mem.szMalloc==0 */ |
| 61636 | assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); |
| 61637 | |
| 61638 | /* Cannot be both MEM_Int and MEM_Real at the same time */ |
| 61639 | assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); |
| 61640 | |
| @@ -61739,11 +61759,11 @@ | |
| 61739 | }else{ |
| 61740 | pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); |
| 61741 | } |
| 61742 | } |
| 61743 | |
| 61744 | if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){ |
| 61745 | memcpy(pMem->zMalloc, pMem->z, pMem->n); |
| 61746 | } |
| 61747 | if( (pMem->flags&MEM_Dyn)!=0 ){ |
| 61748 | assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); |
| 61749 | pMem->xDel((void *)(pMem->z)); |
| @@ -61766,11 +61786,12 @@ | |
| 61766 | ** |
| 61767 | ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) |
| 61768 | ** if unable to complete the resizing. |
| 61769 | */ |
| 61770 | SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ |
| 61771 | assert( szNew>=0 ); |
| 61772 | if( pMem->szMalloc<szNew ){ |
| 61773 | return sqlite3VdbeMemGrow(pMem, szNew, 0); |
| 61774 | } |
| 61775 | assert( (pMem->flags & MEM_Dyn)==0 ); |
| 61776 | pMem->z = pMem->zMalloc; |
| @@ -62490,11 +62511,14 @@ | |
| 62490 | nAlloc += (enc==SQLITE_UTF8?1:2); |
| 62491 | } |
| 62492 | if( nByte>iLimit ){ |
| 62493 | return SQLITE_TOOBIG; |
| 62494 | } |
| 62495 | if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){ |
| 62496 | return SQLITE_NOMEM; |
| 62497 | } |
| 62498 | memcpy(pMem->z, z, nAlloc); |
| 62499 | }else if( xDel==SQLITE_DYNAMIC ){ |
| 62500 | sqlite3VdbeMemRelease(pMem); |
| @@ -62593,11 +62617,11 @@ | |
| 62593 | /* |
| 62594 | ** The pVal argument is known to be a value other than NULL. |
| 62595 | ** Convert it into a string with encoding enc and return a pointer |
| 62596 | ** to a zero-terminated version of that string. |
| 62597 | */ |
| 62598 | SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ |
| 62599 | assert( pVal!=0 ); |
| 62600 | assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 62601 | assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 62602 | assert( (pVal->flags & MEM_RowSet)==0 ); |
| 62603 | assert( (pVal->flags & (MEM_Null))==0 ); |
| @@ -64913,11 +64937,11 @@ | |
| 64913 | ** the call above. */ |
| 64914 | }else if( pCx->pCursor ){ |
| 64915 | sqlite3BtreeCloseCursor(pCx->pCursor); |
| 64916 | } |
| 64917 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 64918 | if( pCx->pVtabCursor ){ |
| 64919 | sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; |
| 64920 | const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; |
| 64921 | p->inVtabMethod = 1; |
| 64922 | pModule->xClose(pVtabCursor); |
| 64923 | p->inVtabMethod = 0; |
| @@ -64956,13 +64980,14 @@ | |
| 64956 | static void closeAllCursors(Vdbe *p){ |
| 64957 | if( p->pFrame ){ |
| 64958 | VdbeFrame *pFrame; |
| 64959 | for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); |
| 64960 | sqlite3VdbeFrameRestore(pFrame); |
| 64961 | } |
| 64962 | p->pFrame = 0; |
| 64963 | p->nFrame = 0; |
| 64964 | |
| 64965 | if( p->apCsr ){ |
| 64966 | int i; |
| 64967 | for(i=0; i<p->nCursor; i++){ |
| 64968 | VdbeCursor *pC = p->apCsr[i]; |
| @@ -64980,11 +65005,11 @@ | |
| 64980 | p->pDelFrame = pDel->pParent; |
| 64981 | sqlite3VdbeFrameDelete(pDel); |
| 64982 | } |
| 64983 | |
| 64984 | /* Delete any auxdata allocations made by the VM */ |
| 64985 | sqlite3VdbeDeleteAuxData(p, -1, 0); |
| 64986 | assert( p->pAuxData==0 ); |
| 64987 | } |
| 64988 | |
| 64989 | /* |
| 64990 | ** Clean up the VM after a single run. |
| @@ -65886,13 +65911,11 @@ | |
| 65886 | #endif |
| 65887 | assert( p->deferredMoveto ); |
| 65888 | assert( p->isTable ); |
| 65889 | rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); |
| 65890 | if( rc ) return rc; |
| 65891 | p->lastRowid = p->movetoTarget; |
| 65892 | if( res!=0 ) return SQLITE_CORRUPT_BKPT; |
| 65893 | p->rowidIsValid = 1; |
| 65894 | #ifdef SQLITE_TEST |
| 65895 | sqlite3_search_count++; |
| 65896 | #endif |
| 65897 | p->deferredMoveto = 0; |
| 65898 | p->cacheStatus = CACHE_STALE; |
| @@ -65913,10 +65936,21 @@ | |
| 65913 | rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow); |
| 65914 | p->cacheStatus = CACHE_STALE; |
| 65915 | if( isDifferentRow ) p->nullRow = 1; |
| 65916 | return rc; |
| 65917 | } |
| 65918 | |
| 65919 | /* |
| 65920 | ** Make sure the cursor p is ready to read or write the row to which it |
| 65921 | ** was last positioned. Return an error code if an OOM fault or I/O error |
| 65922 | ** prevents us from positioning the cursor to its correct position. |
| @@ -65931,11 +65965,11 @@ | |
| 65931 | */ |
| 65932 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ |
| 65933 | if( p->deferredMoveto ){ |
| 65934 | return handleDeferredMoveto(p); |
| 65935 | } |
| 65936 | if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ |
| 65937 | return handleMovedCursor(p); |
| 65938 | } |
| 65939 | return SQLITE_OK; |
| 65940 | } |
| 65941 | |
| @@ -69095,10 +69129,11 @@ | |
| 69095 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| 69096 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; |
| 69097 | memset(pCx, 0, sizeof(VdbeCursor)); |
| 69098 | pCx->iDb = iDb; |
| 69099 | pCx->nField = nField; |
| 69100 | if( isBtreeCursor ){ |
| 69101 | pCx->pCursor = (BtCursor*) |
| 69102 | &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; |
| 69103 | sqlite3BtreeCursorZero(pCx->pCursor); |
| 69104 | } |
| @@ -70528,11 +70563,11 @@ | |
| 70528 | ctx.pFunc = pOp->p4.pFunc; |
| 70529 | ctx.iOp = pc; |
| 70530 | ctx.pVdbe = p; |
| 70531 | MemSetTypeFlag(ctx.pOut, MEM_Null); |
| 70532 | ctx.fErrorOrAux = 0; |
| 70533 | assert( db->lastRowid==lastRowid ); |
| 70534 | (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 70535 | lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */ |
| 70536 | |
| 70537 | /* If the function returned an error, throw an exception */ |
| 70538 | if( ctx.fErrorOrAux ){ |
| @@ -71246,11 +71281,11 @@ | |
| 71246 | memAboutToChange(p, pDest); |
| 71247 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71248 | pC = p->apCsr[pOp->p1]; |
| 71249 | assert( pC!=0 ); |
| 71250 | assert( p2<pC->nField ); |
| 71251 | aOffset = pC->aType + pC->nField; |
| 71252 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 71253 | assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ |
| 71254 | #endif |
| 71255 | pCrsr = pC->pCursor; |
| 71256 | assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ |
| @@ -71257,11 +71292,11 @@ | |
| 71257 | assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ |
| 71258 | |
| 71259 | /* If the cursor cache is stale, bring it up-to-date */ |
| 71260 | rc = sqlite3VdbeCursorMoveto(pC); |
| 71261 | if( rc ) goto abort_due_to_error; |
| 71262 | if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){ |
| 71263 | if( pC->nullRow ){ |
| 71264 | if( pCrsr==0 ){ |
| 71265 | assert( pC->pseudoTableReg>0 ); |
| 71266 | pReg = &aMem[pC->pseudoTableReg]; |
| 71267 | assert( pReg->flags & MEM_Blob ); |
| @@ -71302,18 +71337,10 @@ | |
| 71302 | } |
| 71303 | pC->cacheStatus = p->cacheCtr; |
| 71304 | pC->iHdrOffset = getVarint32(pC->aRow, offset); |
| 71305 | pC->nHdrParsed = 0; |
| 71306 | aOffset[0] = offset; |
| 71307 | if( avail<offset ){ |
| 71308 | /* pC->aRow does not have to hold the entire row, but it does at least |
| 71309 | ** need to cover the header of the record. If pC->aRow does not contain |
| 71310 | ** the complete header, then set it to zero, forcing the header to be |
| 71311 | ** dynamically allocated. */ |
| 71312 | pC->aRow = 0; |
| 71313 | pC->szRow = 0; |
| 71314 | } |
| 71315 | |
| 71316 | /* Make sure a corrupt database has not given us an oversize header. |
| 71317 | ** Do this now to avoid an oversize memory allocation. |
| 71318 | ** |
| 71319 | ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte |
| @@ -71324,19 +71351,36 @@ | |
| 71324 | */ |
| 71325 | if( offset > 98307 || offset > pC->payloadSize ){ |
| 71326 | rc = SQLITE_CORRUPT_BKPT; |
| 71327 | goto op_column_error; |
| 71328 | } |
| 71329 | } |
| 71330 | |
| 71331 | /* Make sure at least the first p2+1 entries of the header have been |
| 71332 | ** parsed and valid information is in aOffset[] and pC->aType[]. |
| 71333 | */ |
| 71334 | if( pC->nHdrParsed<=p2 ){ |
| 71335 | /* If there is more header available for parsing in the record, try |
| 71336 | ** to extract additional fields up through the p2+1-th field |
| 71337 | */ |
| 71338 | if( pC->iHdrOffset<aOffset[0] ){ |
| 71339 | /* Make sure zData points to enough of the record to cover the header. */ |
| 71340 | if( pC->aRow==0 ){ |
| 71341 | memset(&sMem, 0, sizeof(sMem)); |
| 71342 | rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], |
| @@ -71377,19 +71421,20 @@ | |
| 71377 | if( pC->aRow==0 ){ |
| 71378 | sqlite3VdbeMemRelease(&sMem); |
| 71379 | sMem.flags = MEM_Null; |
| 71380 | } |
| 71381 | |
| 71382 | /* If we have read more header data than was contained in the header, |
| 71383 | ** or if the end of the last field appears to be past the end of the |
| 71384 | ** record, or if the end of the last field appears to be before the end |
| 71385 | ** of the record (when all fields present), then we must be dealing |
| 71386 | ** with a corrupt database. |
| 71387 | */ |
| 71388 | if( (zHdr > zEndHdr) |
| 71389 | || (offset > pC->payloadSize) |
| 71390 | || (zHdr==zEndHdr && offset!=pC->payloadSize) |
| 71391 | ){ |
| 71392 | rc = SQLITE_CORRUPT_BKPT; |
| 71393 | goto op_column_error; |
| 71394 | } |
| 71395 | } |
| @@ -71400,11 +71445,11 @@ | |
| 71400 | */ |
| 71401 | if( pC->nHdrParsed<=p2 ){ |
| 71402 | if( pOp->p4type==P4_MEM ){ |
| 71403 | sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); |
| 71404 | }else{ |
| 71405 | MemSetTypeFlag(pDest, MEM_Null); |
| 71406 | } |
| 71407 | goto op_column_out; |
| 71408 | } |
| 71409 | } |
| 71410 | |
| @@ -71576,11 +71621,11 @@ | |
| 71576 | ** out how much space is required for the new record. |
| 71577 | */ |
| 71578 | pRec = pLast; |
| 71579 | do{ |
| 71580 | assert( memIsValid(pRec) ); |
| 71581 | serial_type = sqlite3VdbeSerialType(pRec, file_format); |
| 71582 | len = sqlite3VdbeSerialTypeLen(serial_type); |
| 71583 | if( pRec->flags & MEM_Zero ){ |
| 71584 | if( nData ){ |
| 71585 | sqlite3VdbeMemExpandBlob(pRec); |
| 71586 | }else{ |
| @@ -71625,11 +71670,11 @@ | |
| 71625 | i = putVarint32(zNewRecord, nHdr); |
| 71626 | j = nHdr; |
| 71627 | assert( pData0<=pLast ); |
| 71628 | pRec = pData0; |
| 71629 | do{ |
| 71630 | serial_type = sqlite3VdbeSerialType(pRec, file_format); |
| 71631 | i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ |
| 71632 | j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 71633 | }while( (++pRec)<=pLast ); |
| 71634 | assert( i==nHdr ); |
| 71635 | assert( j==nByte ); |
| @@ -72524,11 +72569,10 @@ | |
| 72524 | pIn3 = &aMem[pOp->p3]; |
| 72525 | if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ |
| 72526 | applyNumericAffinity(pIn3, 0); |
| 72527 | } |
| 72528 | iKey = sqlite3VdbeIntValue(pIn3); |
| 72529 | pC->rowidIsValid = 0; |
| 72530 | |
| 72531 | /* If the P3 value could not be converted into an integer without |
| 72532 | ** loss of information, then special processing is required... */ |
| 72533 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 72534 | if( (pIn3->flags & MEM_Real)==0 ){ |
| @@ -72560,17 +72604,14 @@ | |
| 72560 | assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); |
| 72561 | if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; |
| 72562 | } |
| 72563 | } |
| 72564 | rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); |
| 72565 | if( rc!=SQLITE_OK ){ |
| 72566 | goto abort_due_to_error; |
| 72567 | } |
| 72568 | if( res==0 ){ |
| 72569 | pC->rowidIsValid = 1; |
| 72570 | pC->lastRowid = iKey; |
| 72571 | } |
| 72572 | }else{ |
| 72573 | nField = pOp->p4.i; |
| 72574 | assert( pOp->p4type==P4_INT32 ); |
| 72575 | assert( nField>0 ); |
| 72576 | r.pKeyInfo = pC->pKeyInfo; |
| @@ -72596,11 +72637,10 @@ | |
| 72596 | ExpandBlob(r.aMem); |
| 72597 | rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); |
| 72598 | if( rc!=SQLITE_OK ){ |
| 72599 | goto abort_due_to_error; |
| 72600 | } |
| 72601 | pC->rowidIsValid = 0; |
| 72602 | } |
| 72603 | pC->deferredMoveto = 0; |
| 72604 | pC->cacheStatus = CACHE_STALE; |
| 72605 | #ifdef SQLITE_TEST |
| 72606 | sqlite3_search_count++; |
| @@ -72608,21 +72648,19 @@ | |
| 72608 | if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); |
| 72609 | if( res<0 || (res==0 && oc==OP_SeekGT) ){ |
| 72610 | res = 0; |
| 72611 | rc = sqlite3BtreeNext(pC->pCursor, &res); |
| 72612 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 72613 | pC->rowidIsValid = 0; |
| 72614 | }else{ |
| 72615 | res = 0; |
| 72616 | } |
| 72617 | }else{ |
| 72618 | assert( oc==OP_SeekLT || oc==OP_SeekLE ); |
| 72619 | if( res>0 || (res==0 && oc==OP_SeekLT) ){ |
| 72620 | res = 0; |
| 72621 | rc = sqlite3BtreePrevious(pC->pCursor, &res); |
| 72622 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 72623 | pC->rowidIsValid = 0; |
| 72624 | }else{ |
| 72625 | /* res might be negative because the table is empty. Check to |
| 72626 | ** see if this is the case. |
| 72627 | */ |
| 72628 | res = sqlite3BtreeEof(pC->pCursor); |
| @@ -72655,11 +72693,10 @@ | |
| 72655 | assert( pC->pCursor!=0 ); |
| 72656 | assert( pC->isTable ); |
| 72657 | pC->nullRow = 0; |
| 72658 | pIn2 = &aMem[pOp->p2]; |
| 72659 | pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 72660 | pC->rowidIsValid = 0; |
| 72661 | pC->deferredMoveto = 1; |
| 72662 | break; |
| 72663 | } |
| 72664 | |
| 72665 | |
| @@ -72841,19 +72878,17 @@ | |
| 72841 | pCrsr = pC->pCursor; |
| 72842 | assert( pCrsr!=0 ); |
| 72843 | res = 0; |
| 72844 | iKey = pIn3->u.i; |
| 72845 | rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); |
| 72846 | pC->lastRowid = pIn3->u.i; |
| 72847 | pC->rowidIsValid = res==0 ?1:0; |
| 72848 | pC->nullRow = 0; |
| 72849 | pC->cacheStatus = CACHE_STALE; |
| 72850 | pC->deferredMoveto = 0; |
| 72851 | VdbeBranchTaken(res!=0,2); |
| 72852 | if( res!=0 ){ |
| 72853 | pc = pOp->p2 - 1; |
| 72854 | assert( pC->rowidIsValid==0 ); |
| 72855 | } |
| 72856 | pC->seekResult = res; |
| 72857 | break; |
| 72858 | } |
| 72859 | |
| @@ -72997,11 +73032,10 @@ | |
| 72997 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 72998 | goto abort_due_to_error; |
| 72999 | } |
| 73000 | assert( v>0 ); /* EV: R-40812-03570 */ |
| 73001 | } |
| 73002 | pC->rowidIsValid = 0; |
| 73003 | pC->deferredMoveto = 0; |
| 73004 | pC->cacheStatus = CACHE_STALE; |
| 73005 | } |
| 73006 | pOut->u.i = v; |
| 73007 | break; |
| @@ -73102,11 +73136,10 @@ | |
| 73102 | } |
| 73103 | rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, |
| 73104 | pData->z, pData->n, nZero, |
| 73105 | (pOp->p5 & OPFLAG_APPEND)!=0, seekResult |
| 73106 | ); |
| 73107 | pC->rowidIsValid = 0; |
| 73108 | pC->deferredMoveto = 0; |
| 73109 | pC->cacheStatus = CACHE_STALE; |
| 73110 | |
| 73111 | /* Invoke the update-hook if required. */ |
| 73112 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| @@ -73139,37 +73172,36 @@ | |
| 73139 | ** pointing to. The update hook will be invoked, if it exists. |
| 73140 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 73141 | ** using OP_NotFound prior to invoking this opcode. |
| 73142 | */ |
| 73143 | case OP_Delete: { |
| 73144 | i64 iKey; |
| 73145 | VdbeCursor *pC; |
| 73146 | |
| 73147 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73148 | pC = p->apCsr[pOp->p1]; |
| 73149 | assert( pC!=0 ); |
| 73150 | assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 73151 | iKey = pC->lastRowid; /* Only used for the update hook */ |
| 73152 | |
| 73153 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 73154 | ** OP_Column on the same table without any intervening operations that |
| 73155 | ** might move or invalidate the cursor. Hence cursor pC is always pointing |
| 73156 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 73157 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 73158 | ** to guard against future changes to the code generator. |
| 73159 | **/ |
| 73160 | assert( pC->deferredMoveto==0 ); |
| 73161 | rc = sqlite3VdbeCursorMoveto(pC); |
| 73162 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 73163 | |
| 73164 | rc = sqlite3BtreeDelete(pC->pCursor); |
| 73165 | pC->cacheStatus = CACHE_STALE; |
| 73166 | |
| 73167 | /* Invoke the update-hook if required. */ |
| 73168 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ |
| 73169 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, |
| 73170 | db->aDb[pC->iDb].zName, pOp->p4.z, iKey); |
| 73171 | assert( pC->iDb>=0 ); |
| 73172 | } |
| 73173 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 73174 | break; |
| 73175 | } |
| @@ -73218,23 +73250,32 @@ | |
| 73218 | pc = pOp->p2-1; |
| 73219 | } |
| 73220 | break; |
| 73221 | }; |
| 73222 | |
| 73223 | /* Opcode: SorterData P1 P2 * * * |
| 73224 | ** Synopsis: r[P2]=data |
| 73225 | ** |
| 73226 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 73227 | */ |
| 73228 | case OP_SorterData: { |
| 73229 | VdbeCursor *pC; |
| 73230 | |
| 73231 | pOut = &aMem[pOp->p2]; |
| 73232 | pC = p->apCsr[pOp->p1]; |
| 73233 | assert( isSorter(pC) ); |
| 73234 | rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 73235 | assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); |
| 73236 | break; |
| 73237 | } |
| 73238 | |
| 73239 | /* Opcode: RowData P1 P2 * * * |
| 73240 | ** Synopsis: r[P2]=data |
| @@ -73277,20 +73318,24 @@ | |
| 73277 | assert( pC!=0 ); |
| 73278 | assert( pC->nullRow==0 ); |
| 73279 | assert( pC->pseudoTableReg==0 ); |
| 73280 | assert( pC->pCursor!=0 ); |
| 73281 | pCrsr = pC->pCursor; |
| 73282 | assert( sqlite3BtreeCursorIsValid(pCrsr) ); |
| 73283 | |
| 73284 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 73285 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 73286 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 73287 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 73288 | */ |
| 73289 | assert( pC->deferredMoveto==0 ); |
| 73290 | rc = sqlite3VdbeCursorMoveto(pC); |
| 73291 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 73292 | |
| 73293 | if( pC->isTable==0 ){ |
| 73294 | assert( !pC->isTable ); |
| 73295 | VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); |
| 73296 | assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| @@ -73303,11 +73348,12 @@ | |
| 73303 | assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 73304 | if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 73305 | goto too_big; |
| 73306 | } |
| 73307 | } |
| 73308 | if( sqlite3VdbeMemClearAndResize(pOut, n) ){ |
| 73309 | goto no_mem; |
| 73310 | } |
| 73311 | pOut->n = n; |
| 73312 | MemSetTypeFlag(pOut, MEM_Blob); |
| 73313 | if( pC->isTable==0 ){ |
| @@ -73354,18 +73400,14 @@ | |
| 73354 | rc = pModule->xRowid(pC->pVtabCursor, &v); |
| 73355 | sqlite3VtabImportErrmsg(p, pVtab); |
| 73356 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 73357 | }else{ |
| 73358 | assert( pC->pCursor!=0 ); |
| 73359 | rc = sqlite3VdbeCursorMoveto(pC); |
| 73360 | if( rc ) goto abort_due_to_error; |
| 73361 | if( pC->rowidIsValid ){ |
| 73362 | v = pC->lastRowid; |
| 73363 | }else{ |
| 73364 | rc = sqlite3BtreeKeySize(pC->pCursor, &v); |
| 73365 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 73366 | } |
| 73367 | } |
| 73368 | pOut->u.i = v; |
| 73369 | break; |
| 73370 | } |
| 73371 | |
| @@ -73380,11 +73422,10 @@ | |
| 73380 | |
| 73381 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73382 | pC = p->apCsr[pOp->p1]; |
| 73383 | assert( pC!=0 ); |
| 73384 | pC->nullRow = 1; |
| 73385 | pC->rowidIsValid = 0; |
| 73386 | pC->cacheStatus = CACHE_STALE; |
| 73387 | if( pC->pCursor ){ |
| 73388 | sqlite3BtreeClearCursor(pC->pCursor); |
| 73389 | } |
| 73390 | break; |
| @@ -73414,11 +73455,10 @@ | |
| 73414 | res = 0; |
| 73415 | assert( pCrsr!=0 ); |
| 73416 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 73417 | pC->nullRow = (u8)res; |
| 73418 | pC->deferredMoveto = 0; |
| 73419 | pC->rowidIsValid = 0; |
| 73420 | pC->cacheStatus = CACHE_STALE; |
| 73421 | #ifdef SQLITE_DEBUG |
| 73422 | pC->seekOp = OP_Last; |
| 73423 | #endif |
| 73424 | if( pOp->p2>0 ){ |
| @@ -73481,11 +73521,10 @@ | |
| 73481 | pCrsr = pC->pCursor; |
| 73482 | assert( pCrsr ); |
| 73483 | rc = sqlite3BtreeFirst(pCrsr, &res); |
| 73484 | pC->deferredMoveto = 0; |
| 73485 | pC->cacheStatus = CACHE_STALE; |
| 73486 | pC->rowidIsValid = 0; |
| 73487 | } |
| 73488 | pC->nullRow = (u8)res; |
| 73489 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 73490 | VdbeBranchTaken(res!=0,2); |
| 73491 | if( res ){ |
| @@ -73607,11 +73646,10 @@ | |
| 73607 | sqlite3_search_count++; |
| 73608 | #endif |
| 73609 | }else{ |
| 73610 | pC->nullRow = 1; |
| 73611 | } |
| 73612 | pC->rowidIsValid = 0; |
| 73613 | goto check_for_interrupt; |
| 73614 | } |
| 73615 | |
| 73616 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 73617 | ** Synopsis: key=r[P2] |
| @@ -73723,14 +73761,20 @@ | |
| 73723 | pC = p->apCsr[pOp->p1]; |
| 73724 | assert( pC!=0 ); |
| 73725 | pCrsr = pC->pCursor; |
| 73726 | assert( pCrsr!=0 ); |
| 73727 | pOut->flags = MEM_Null; |
| 73728 | rc = sqlite3VdbeCursorMoveto(pC); |
| 73729 | if( NEVER(rc) ) goto abort_due_to_error; |
| 73730 | assert( pC->deferredMoveto==0 ); |
| 73731 | assert( pC->isTable==0 ); |
| 73732 | if( !pC->nullRow ){ |
| 73733 | rowid = 0; /* Not needed. Only used to silence a warning. */ |
| 73734 | rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); |
| 73735 | if( rc!=SQLITE_OK ){ |
| 73736 | goto abort_due_to_error; |
| @@ -78187,11 +78231,11 @@ | |
| 78187 | if( rc==SQLITE_OK ){ |
| 78188 | #if SQLITE_MAX_WORKER_THREADS |
| 78189 | assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); |
| 78190 | if( pSorter->bUseThreads ){ |
| 78191 | int iTask; |
| 78192 | PmaReader *pReadr; |
| 78193 | SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; |
| 78194 | rc = vdbeSortAllocUnpacked(pLast); |
| 78195 | if( rc==SQLITE_OK ){ |
| 78196 | pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); |
| 78197 | pSorter->pReader = pReadr; |
| @@ -87168,29 +87212,27 @@ | |
| 87168 | tRowcnt v; |
| 87169 | |
| 87170 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87171 | if( z==0 ) z = ""; |
| 87172 | #else |
| 87173 | if( NEVER(z==0) ) z = ""; |
| 87174 | #endif |
| 87175 | for(i=0; *z && i<nOut; i++){ |
| 87176 | v = 0; |
| 87177 | while( (c=z[0])>='0' && c<='9' ){ |
| 87178 | v = v*10 + c - '0'; |
| 87179 | z++; |
| 87180 | } |
| 87181 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87182 | if( aOut ){ |
| 87183 | aOut[i] = v; |
| 87184 | }else |
| 87185 | #else |
| 87186 | assert( aOut==0 ); |
| 87187 | UNUSED_PARAMETER(aOut); |
| 87188 | #endif |
| 87189 | { |
| 87190 | aLog[i] = sqlite3LogEst(v); |
| 87191 | } |
| 87192 | if( *z==' ' ) z++; |
| 87193 | } |
| 87194 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87195 | assert( pIndex!=0 ); |
| 87196 | #else |
| @@ -87247,12 +87289,21 @@ | |
| 87247 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 87248 | } |
| 87249 | z = argv[2]; |
| 87250 | |
| 87251 | if( pIndex ){ |
| 87252 | pIndex->bUnordered = 0; |
| 87253 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 87254 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 87255 | }else{ |
| 87256 | Index fakeIdx; |
| 87257 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 87258 | #ifdef SQLITE_ENABLE_COSTMULT |
| @@ -87307,29 +87358,42 @@ | |
| 87307 | ** unique. */ |
| 87308 | nCol = pIdx->nSampleCol-1; |
| 87309 | pIdx->aAvgEq[nCol] = 1; |
| 87310 | } |
| 87311 | for(iCol=0; iCol<nCol; iCol++){ |
| 87312 | int i; /* Used to iterate through samples */ |
| 87313 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 87314 | tRowcnt nSum = 0; /* Number of terms contributing to sumEq */ |
| 87315 | tRowcnt avgEq = 0; |
| 87316 | tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 87317 | |
| 87318 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 87319 | ** occur in the stat4 table for this index before pFinal. Set |
| 87320 | ** sumEq to the sum of the nEq values for column iCol for the same |
| 87321 | ** set (adding the value only once where there exist duplicate |
| 87322 | ** prefixes). */ |
| 87323 | for(i=0; i<(pIdx->nSample-1); i++){ |
| 87324 | if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ |
| 87325 | sumEq += aSample[i].anEq[iCol]; |
| 87326 | nSum++; |
| 87327 | } |
| 87328 | } |
| 87329 | if( nDLt>nSum ){ |
| 87330 | avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum); |
| 87331 | } |
| 87332 | if( avgEq==0 ) avgEq = 1; |
| 87333 | pIdx->aAvgEq[iCol] = avgEq; |
| 87334 | } |
| 87335 | } |
| @@ -87576,10 +87640,15 @@ | |
| 87576 | if( rc==SQLITE_OK ){ |
| 87577 | int lookasideEnabled = db->lookaside.bEnabled; |
| 87578 | db->lookaside.bEnabled = 0; |
| 87579 | rc = loadStat4(db, sInfo.zDatabase); |
| 87580 | db->lookaside.bEnabled = lookasideEnabled; |
| 87581 | } |
| 87582 | #endif |
| 87583 | |
| 87584 | if( rc==SQLITE_NOMEM ){ |
| 87585 | db->mallocFailed = 1; |
| @@ -88870,10 +88939,13 @@ | |
| 88870 | #endif |
| 88871 | if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo); |
| 88872 | sqlite3ExprDelete(db, p->pPartIdxWhere); |
| 88873 | sqlite3DbFree(db, p->zColAff); |
| 88874 | if( p->isResized ) sqlite3DbFree(db, p->azColl); |
| 88875 | sqlite3DbFree(db, p); |
| 88876 | } |
| 88877 | |
| 88878 | /* |
| 88879 | ** For the index called zIdxName which is found in the database iDb, |
| @@ -91179,11 +91251,11 @@ | |
| 91179 | pIndex->nKeyCol); VdbeCoverage(v); |
| 91180 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 91181 | }else{ |
| 91182 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 91183 | } |
| 91184 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| 91185 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); |
| 91186 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 91187 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 91188 | sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); |
| 91189 | sqlite3VdbeJumpHere(v, addr1); |
| @@ -93687,11 +93759,11 @@ | |
| 93687 | if( okOnePass ){ |
| 93688 | /* Just one row. Hence the top-of-loop is a no-op */ |
| 93689 | assert( nKey==nPk ); /* OP_Found will use an unpacked key */ |
| 93690 | assert( !IsVirtual(pTab) ); |
| 93691 | if( aToOpen[iDataCur-iTabCur] ){ |
| 93692 | assert( pPk!=0 ); |
| 93693 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); |
| 93694 | VdbeCoverage(v); |
| 93695 | } |
| 93696 | }else if( pPk ){ |
| 93697 | addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); |
| @@ -105122,11 +105194,10 @@ | |
| 105122 | int regRow; |
| 105123 | int regRowid; |
| 105124 | int nKey; |
| 105125 | int iSortTab; /* Sorter cursor to read from */ |
| 105126 | int nSortData; /* Trailing values to read from sorter */ |
| 105127 | u8 p5; /* p5 parameter for 1st OP_Column */ |
| 105128 | int i; |
| 105129 | int bSeq; /* True if sorter record includes seq. no. */ |
| 105130 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
| 105131 | struct ExprList_item *aOutEx = p->pEList->a; |
| 105132 | #endif |
| @@ -105156,23 +105227,20 @@ | |
| 105156 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); |
| 105157 | if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 105158 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 105159 | VdbeCoverage(v); |
| 105160 | codeOffset(v, p->iOffset, addrContinue); |
| 105161 | sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); |
| 105162 | p5 = OPFLAG_CLEARCACHE; |
| 105163 | bSeq = 0; |
| 105164 | }else{ |
| 105165 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); |
| 105166 | codeOffset(v, p->iOffset, addrContinue); |
| 105167 | iSortTab = iTab; |
| 105168 | p5 = 0; |
| 105169 | bSeq = 1; |
| 105170 | } |
| 105171 | for(i=0; i<nSortData; i++){ |
| 105172 | sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i); |
| 105173 | if( i==0 ) sqlite3VdbeChangeP5(v, p5); |
| 105174 | VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); |
| 105175 | } |
| 105176 | switch( eDest ){ |
| 105177 | case SRT_Table: |
| 105178 | case SRT_EphemTab: { |
| @@ -109097,16 +109165,15 @@ | |
| 109097 | ** from the previous row currently stored in a0, a1, a2... |
| 109098 | */ |
| 109099 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 109100 | sqlite3ExprCacheClear(pParse); |
| 109101 | if( groupBySort ){ |
| 109102 | sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); |
| 109103 | } |
| 109104 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 109105 | if( groupBySort ){ |
| 109106 | sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); |
| 109107 | if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 109108 | }else{ |
| 109109 | sAggInfo.directMode = 1; |
| 109110 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 109111 | } |
| 109112 | } |
| @@ -111216,12 +111283,12 @@ | |
| 111216 | 0, 0); |
| 111217 | } |
| 111218 | |
| 111219 | /* Top of the update loop */ |
| 111220 | if( okOnePass ){ |
| 111221 | if( aToOpen[iDataCur-iBaseCur] ){ |
| 111222 | assert( pPk!=0 ); |
| 111223 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 111224 | VdbeCoverageNeverTaken(v); |
| 111225 | } |
| 111226 | labelContinue = labelBreak; |
| 111227 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| @@ -112450,10 +112517,11 @@ | |
| 112450 | } |
| 112451 | sqlite3DbFree(db, pVTable); |
| 112452 | }else if( ALWAYS(pVTable->pVtab) ){ |
| 112453 | /* Justification of ALWAYS(): A correct vtab constructor must allocate |
| 112454 | ** the sqlite3_vtab object if successful. */ |
| 112455 | pVTable->pVtab->pModule = pMod->pModule; |
| 112456 | pVTable->nRef = 1; |
| 112457 | if( sCtx.pTab ){ |
| 112458 | const char *zFormat = "vtable constructor did not declare schema: %s"; |
| 112459 | *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); |
| @@ -115700,21 +115768,28 @@ | |
| 115700 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 115701 | whereKeyStats(pParse, p, pRec, 0, a); |
| 115702 | iLower = a[0]; |
| 115703 | iUpper = a[0] + a[1]; |
| 115704 | } |
| 115705 | |
| 115706 | /* If possible, improve on the iLower estimate using ($P:$L). */ |
| 115707 | if( pLower ){ |
| 115708 | int bOk; /* True if value is extracted from pExpr */ |
| 115709 | Expr *pExpr = pLower->pExpr->pRight; |
| 115710 | assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 ); |
| 115711 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 115712 | if( rc==SQLITE_OK && bOk ){ |
| 115713 | tRowcnt iNew; |
| 115714 | whereKeyStats(pParse, p, pRec, 0, a); |
| 115715 | iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); |
| 115716 | if( iNew>iLower ) iLower = iNew; |
| 115717 | nOut--; |
| 115718 | pLower = 0; |
| 115719 | } |
| 115720 | } |
| @@ -115721,16 +115796,15 @@ | |
| 115721 | |
| 115722 | /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 115723 | if( pUpper ){ |
| 115724 | int bOk; /* True if value is extracted from pExpr */ |
| 115725 | Expr *pExpr = pUpper->pExpr->pRight; |
| 115726 | assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); |
| 115727 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 115728 | if( rc==SQLITE_OK && bOk ){ |
| 115729 | tRowcnt iNew; |
| 115730 | whereKeyStats(pParse, p, pRec, 1, a); |
| 115731 | iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); |
| 115732 | if( iNew<iUpper ) iUpper = iNew; |
| 115733 | nOut--; |
| 115734 | pUpper = 0; |
| 115735 | } |
| 115736 | } |
| @@ -116225,65 +116299,52 @@ | |
| 116225 | sqlite3StrAccumAppend(pStr, "?", 1); |
| 116226 | } |
| 116227 | |
| 116228 | /* |
| 116229 | ** Argument pLevel describes a strategy for scanning table pTab. This |
| 116230 | ** function returns a pointer to a string buffer containing a description |
| 116231 | ** of the subset of table rows scanned by the strategy in the form of an |
| 116232 | ** SQL expression. Or, if all rows are scanned, NULL is returned. |
| 116233 | ** |
| 116234 | ** For example, if the query: |
| 116235 | ** |
| 116236 | ** SELECT * FROM t1 WHERE a=1 AND b>2; |
| 116237 | ** |
| 116238 | ** is run and there is an index on (a, b), then this function returns a |
| 116239 | ** string similar to: |
| 116240 | ** |
| 116241 | ** "a=? AND b>?" |
| 116242 | ** |
| 116243 | ** The returned pointer points to memory obtained from sqlite3DbMalloc(). |
| 116244 | ** It is the responsibility of the caller to free the buffer when it is |
| 116245 | ** no longer required. |
| 116246 | */ |
| 116247 | static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){ |
| 116248 | Index *pIndex = pLoop->u.btree.pIndex; |
| 116249 | u16 nEq = pLoop->u.btree.nEq; |
| 116250 | u16 nSkip = pLoop->u.btree.nSkip; |
| 116251 | int i, j; |
| 116252 | Column *aCol = pTab->aCol; |
| 116253 | i16 *aiColumn = pIndex->aiColumn; |
| 116254 | StrAccum txt; |
| 116255 | |
| 116256 | if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){ |
| 116257 | return 0; |
| 116258 | } |
| 116259 | sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); |
| 116260 | txt.db = db; |
| 116261 | sqlite3StrAccumAppend(&txt, " (", 2); |
| 116262 | for(i=0; i<nEq; i++){ |
| 116263 | char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName; |
| 116264 | if( i>=nSkip ){ |
| 116265 | explainAppendTerm(&txt, i, z, "="); |
| 116266 | }else{ |
| 116267 | if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5); |
| 116268 | sqlite3StrAccumAppend(&txt, "ANY(", 4); |
| 116269 | sqlite3StrAccumAppendAll(&txt, z); |
| 116270 | sqlite3StrAccumAppend(&txt, ")", 1); |
| 116271 | } |
| 116272 | } |
| 116273 | |
| 116274 | j = i; |
| 116275 | if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ |
| 116276 | char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; |
| 116277 | explainAppendTerm(&txt, i++, z, ">"); |
| 116278 | } |
| 116279 | if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ |
| 116280 | char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; |
| 116281 | explainAppendTerm(&txt, i, z, "<"); |
| 116282 | } |
| 116283 | sqlite3StrAccumAppend(&txt, ")", 1); |
| 116284 | return sqlite3StrAccumFinish(&txt); |
| 116285 | } |
| 116286 | |
| 116287 | /* |
| 116288 | ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN |
| 116289 | ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single |
| @@ -116303,72 +116364,90 @@ | |
| 116303 | #endif |
| 116304 | { |
| 116305 | struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; |
| 116306 | Vdbe *v = pParse->pVdbe; /* VM being constructed */ |
| 116307 | sqlite3 *db = pParse->db; /* Database handle */ |
| 116308 | char *zMsg; /* Text to add to EQP output */ |
| 116309 | int iId = pParse->iSelectId; /* Select id (left-most output column) */ |
| 116310 | int isSearch; /* True for a SEARCH. False for SCAN. */ |
| 116311 | WhereLoop *pLoop; /* The controlling WhereLoop object */ |
| 116312 | u32 flags; /* Flags that describe this loop */ |
| 116313 | |
| 116314 | pLoop = pLevel->pWLoop; |
| 116315 | flags = pLoop->wsFlags; |
| 116316 | if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return; |
| 116317 | |
| 116318 | isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 |
| 116319 | || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) |
| 116320 | || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); |
| 116321 | |
| 116322 | zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN"); |
| 116323 | if( pItem->pSelect ){ |
| 116324 | zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId); |
| 116325 | }else{ |
| 116326 | zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName); |
| 116327 | } |
| 116328 | |
| 116329 | if( pItem->zAlias ){ |
| 116330 | zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); |
| 116331 | } |
| 116332 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 |
| 116333 | && ALWAYS(pLoop->u.btree.pIndex!=0) |
| 116334 | ){ |
| 116335 | const char *zFmt; |
| 116336 | Index *pIdx = pLoop->u.btree.pIndex; |
| 116337 | char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); |
| 116338 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); |
| 116339 | if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 116340 | zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s"; |
| 116341 | }else if( flags & WHERE_AUTO_INDEX ){ |
| 116342 | zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s"; |
| 116343 | }else if( flags & WHERE_IDX_ONLY ){ |
| 116344 | zFmt = "%s USING COVERING INDEX %s%s"; |
| 116345 | }else{ |
| 116346 | zFmt = "%s USING INDEX %s%s"; |
| 116347 | } |
| 116348 | zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere); |
| 116349 | sqlite3DbFree(db, zWhere); |
| 116350 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 116351 | zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); |
| 116352 | |
| 116353 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| 116354 | zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg); |
| 116355 | }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ |
| 116356 | zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg); |
| 116357 | }else if( flags&WHERE_BTM_LIMIT ){ |
| 116358 | zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg); |
| 116359 | }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){ |
| 116360 | zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg); |
| 116361 | } |
| 116362 | } |
| 116363 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 116364 | else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ |
| 116365 | zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, |
| 116366 | pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); |
| 116367 | } |
| 116368 | #endif |
| 116369 | zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg); |
| 116370 | sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC); |
| 116371 | } |
| 116372 | } |
| 116373 | #else |
| 116374 | # define explainOneScan(u,v,w,x,y,z) |
| @@ -117633,11 +117712,11 @@ | |
| 117633 | if( ppPrev==0 ){ |
| 117634 | /* There already exists a WhereLoop on the list that is better |
| 117635 | ** than pTemplate, so just ignore pTemplate */ |
| 117636 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117637 | if( sqlite3WhereTrace & 0x8 ){ |
| 117638 | sqlite3DebugPrintf("ins-noop: "); |
| 117639 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 117640 | } |
| 117641 | #endif |
| 117642 | return SQLITE_OK; |
| 117643 | }else{ |
| @@ -117649,14 +117728,14 @@ | |
| 117649 | ** WhereLoop and insert it. |
| 117650 | */ |
| 117651 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117652 | if( sqlite3WhereTrace & 0x8 ){ |
| 117653 | if( p!=0 ){ |
| 117654 | sqlite3DebugPrintf("ins-del: "); |
| 117655 | whereLoopPrint(p, pBuilder->pWC); |
| 117656 | } |
| 117657 | sqlite3DebugPrintf("ins-new: "); |
| 117658 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 117659 | } |
| 117660 | #endif |
| 117661 | if( p==0 ){ |
| 117662 | /* Allocate a new WhereLoop to add to the end of the list */ |
| @@ -117676,11 +117755,11 @@ | |
| 117676 | pToDel = *ppTail; |
| 117677 | if( pToDel==0 ) break; |
| 117678 | *ppTail = pToDel->pNextLoop; |
| 117679 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117680 | if( sqlite3WhereTrace & 0x8 ){ |
| 117681 | sqlite3DebugPrintf("ins-del: "); |
| 117682 | whereLoopPrint(pToDel, pBuilder->pWC); |
| 117683 | } |
| 117684 | #endif |
| 117685 | whereLoopDelete(db, pToDel); |
| 117686 | } |
| @@ -118843,11 +118922,11 @@ | |
| 118843 | if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; |
| 118844 | } |
| 118845 | isMatch = 1; |
| 118846 | break; |
| 118847 | } |
| 118848 | if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ |
| 118849 | /* Make sure the sort order is compatible in an ORDER BY clause. |
| 118850 | ** Sort order is irrelevant for a GROUP BY clause. */ |
| 118851 | if( revSet ){ |
| 118852 | if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; |
| 118853 | }else{ |
| @@ -119308,16 +119387,19 @@ | |
| 119308 | pWInfo->revMask = pFrom->revLoop; |
| 119309 | } |
| 119310 | if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) |
| 119311 | && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr |
| 119312 | ){ |
| 119313 | Bitmask notUsed = 0; |
| 119314 | int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, |
| 119315 | pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used |
| 119316 | ); |
| 119317 | assert( pWInfo->sorted==0 ); |
| 119318 | pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr); |
| 119319 | } |
| 119320 | } |
| 119321 | |
| 119322 | |
| 119323 | pWInfo->nRowOut = pFrom->nRow; |
| @@ -132620,10 +132702,11 @@ | |
| 132620 | assert( iIdx==nVal ); |
| 132621 | |
| 132622 | /* In case the cursor has been used before, clear it now. */ |
| 132623 | sqlite3_finalize(pCsr->pStmt); |
| 132624 | sqlite3_free(pCsr->aDoclist); |
| 132625 | sqlite3Fts3ExprFree(pCsr->pExpr); |
| 132626 | memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); |
| 132627 | |
| 132628 | /* Set the lower and upper bounds on docids to return */ |
| 132629 | pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); |
| @@ -133930,11 +134013,11 @@ | |
| 133930 | if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ |
| 133931 | iMax = a[i].iDocid; |
| 133932 | bMaxSet = 1; |
| 133933 | } |
| 133934 | } |
| 133935 | assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 ); |
| 133936 | assert( rc!=SQLITE_OK || bMaxSet ); |
| 133937 | |
| 133938 | /* Keep advancing iterators until they all point to the same document */ |
| 133939 | for(i=0; i<p->nToken; i++){ |
| 133940 | while( rc==SQLITE_OK && bEof==0 |
| @@ -136047,11 +136130,11 @@ | |
| 136047 | int i = 0; |
| 136048 | |
| 136049 | /* Set variable i to the maximum number of bytes of input to tokenize. */ |
| 136050 | for(i=0; i<n; i++){ |
| 136051 | if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break; |
| 136052 | if( z[i]=='*' || z[i]=='"' ) break; |
| 136053 | } |
| 136054 | |
| 136055 | *pnConsumed = i; |
| 136056 | rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); |
| 136057 | if( rc==SQLITE_OK ){ |
| 136058 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.7.1. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -229,13 +229,13 @@ | |
| 229 | ** |
| 230 | ** See also: [sqlite3_libversion()], |
| 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | */ |
| 234 | #define SQLITE_VERSION "3.8.7.1" |
| 235 | #define SQLITE_VERSION_NUMBER 3008007 |
| 236 | #define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52" |
| 237 | |
| 238 | /* |
| 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | ** |
| @@ -7944,11 +7944,11 @@ | |
| 7944 | ** A macro to hint to the compiler that a function should not be |
| 7945 | ** inlined. |
| 7946 | */ |
| 7947 | #if defined(__GNUC__) |
| 7948 | # define SQLITE_NOINLINE __attribute__((noinline)) |
| 7949 | #elif defined(_MSC_VER) && _MSC_VER>=1310 |
| 7950 | # define SQLITE_NOINLINE __declspec(noinline) |
| 7951 | #else |
| 7952 | # define SQLITE_NOINLINE |
| 7953 | #endif |
| 7954 | |
| @@ -11322,10 +11322,11 @@ | |
| 11322 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 11323 | int nSample; /* Number of elements in aSample[] */ |
| 11324 | int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 11325 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 11326 | IndexSample *aSample; /* Samples of the left-most key */ |
| 11327 | tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this table */ |
| 11328 | #endif |
| 11329 | }; |
| 11330 | |
| 11331 | /* |
| 11332 | ** Allowed values for Index.idxType |
| @@ -12186,11 +12187,10 @@ | |
| 12187 | #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ |
| 12188 | #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ |
| 12189 | #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ |
| 12190 | #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ |
| 12191 | #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ |
| 12192 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 12193 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 12194 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ |
| 12195 | #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ |
| 12196 | #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ |
| @@ -13320,14 +13320,13 @@ | |
| 13320 | # define sqlite3MemdebugSetType(X,Y) /* no-op */ |
| 13321 | # define sqlite3MemdebugHasType(X,Y) 1 |
| 13322 | # define sqlite3MemdebugNoType(X,Y) 1 |
| 13323 | #endif |
| 13324 | #define MEMTYPE_HEAP 0x01 /* General heap allocations */ |
| 13325 | #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ |
| 13326 | #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ |
| 13327 | #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ |
| 13328 | |
| 13329 | /* |
| 13330 | ** Threading interface |
| 13331 | */ |
| 13332 | #if SQLITE_MAX_WORKER_THREADS>0 |
| @@ -14095,21 +14094,19 @@ | |
| 14094 | #ifdef SQLITE_DEBUG |
| 14095 | u8 seekOp; /* Most recent seek operation on this cursor */ |
| 14096 | #endif |
| 14097 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 14098 | u8 nullRow; /* True if pointing to a row with no data */ |
| 14099 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 14100 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 14101 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 14102 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 14103 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 14104 | Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 14105 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 14106 | i64 seqCount; /* Sequence counter */ |
| 14107 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 14108 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| 14109 | |
| 14110 | /* Cached information about the header for the data record that the |
| 14111 | ** cursor is currently pointing to. Only valid if cacheStatus matches |
| 14112 | ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| @@ -14122,10 +14119,11 @@ | |
| 14119 | u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
| 14120 | u32 payloadSize; /* Total number of bytes in the record */ |
| 14121 | u32 szRow; /* Byte available in aRow */ |
| 14122 | u32 iHdrOffset; /* Offset to next unparsed byte of the header */ |
| 14123 | const u8 *aRow; /* Data for the current row, if all on one page */ |
| 14124 | u32 *aOffset; /* Pointer to aType[nField] */ |
| 14125 | u32 aType[1]; /* Type values for all entries in the record */ |
| 14126 | /* 2*nField extra array elements allocated for aType[], beyond the one |
| 14127 | ** static element declared in the structure. nField total array slots for |
| 14128 | ** aType[] and nField+1 array slots for aOffset[] */ |
| 14129 | }; |
| @@ -14198,11 +14196,11 @@ | |
| 14196 | int n; /* Number of characters in string value, excluding '\0' */ |
| 14197 | char *z; /* String or BLOB value */ |
| 14198 | /* ShallowCopy only needs to copy the information above */ |
| 14199 | char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ |
| 14200 | int szMalloc; /* Size of the zMalloc allocation */ |
| 14201 | u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ |
| 14202 | sqlite3 *db; /* The associated database connection */ |
| 14203 | void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ |
| 14204 | #ifdef SQLITE_DEBUG |
| 14205 | Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ |
| 14206 | void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ |
| @@ -14406,10 +14404,11 @@ | |
| 14404 | ** Function prototypes |
| 14405 | */ |
| 14406 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); |
| 14407 | void sqliteVdbePopStack(Vdbe*,int); |
| 14408 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*); |
| 14409 | SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); |
| 14410 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 14411 | SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); |
| 14412 | #endif |
| 14413 | SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); |
| 14414 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); |
| @@ -17130,11 +17129,11 @@ | |
| 17129 | ** allocation p. Also return true if p==NULL. |
| 17130 | ** |
| 17131 | ** This routine is designed for use within an assert() statement, to |
| 17132 | ** verify the type of an allocation. For example: |
| 17133 | ** |
| 17134 | ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 17135 | */ |
| 17136 | SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ |
| 17137 | int rc = 1; |
| 17138 | if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ |
| 17139 | struct MemBlockHdr *pHdr; |
| @@ -17152,11 +17151,11 @@ | |
| 17151 | ** allocation p. Also return true if p==NULL. |
| 17152 | ** |
| 17153 | ** This routine is designed for use within an assert() statement, to |
| 17154 | ** verify the type of an allocation. For example: |
| 17155 | ** |
| 17156 | ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); |
| 17157 | */ |
| 17158 | SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ |
| 17159 | int rc = 1; |
| 17160 | if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ |
| 17161 | struct MemBlockHdr *pHdr; |
| @@ -20364,39 +20363,41 @@ | |
| 20363 | ** Return the size of a memory allocation previously obtained from |
| 20364 | ** sqlite3Malloc() or sqlite3_malloc(). |
| 20365 | */ |
| 20366 | SQLITE_PRIVATE int sqlite3MallocSize(void *p){ |
| 20367 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20368 | return sqlite3GlobalConfig.m.xSize(p); |
| 20369 | } |
| 20370 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ |
| 20371 | if( db==0 ){ |
| 20372 | assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); |
| 20373 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20374 | return sqlite3MallocSize(p); |
| 20375 | }else{ |
| 20376 | assert( sqlite3_mutex_held(db->mutex) ); |
| 20377 | if( isLookaside(db, p) ){ |
| 20378 | return db->lookaside.sz; |
| 20379 | }else{ |
| 20380 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 20381 | assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 20382 | return sqlite3GlobalConfig.m.xSize(p); |
| 20383 | } |
| 20384 | } |
| 20385 | } |
| 20386 | SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ |
| 20387 | assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); |
| 20388 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20389 | return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p); |
| 20390 | } |
| 20391 | |
| 20392 | /* |
| 20393 | ** Free memory previously obtained from sqlite3Malloc(). |
| 20394 | */ |
| 20395 | SQLITE_API void sqlite3_free(void *p){ |
| 20396 | if( p==0 ) return; /* IMP: R-49053-54554 */ |
| 20397 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 20398 | assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) ); |
| 20399 | if( sqlite3GlobalConfig.bMemstat ){ |
| 20400 | sqlite3_mutex_enter(mem0.mutex); |
| 20401 | sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); |
| 20402 | sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); |
| 20403 | sqlite3GlobalConfig.m.xFree(p); |
| @@ -20436,12 +20437,12 @@ | |
| 20437 | db->lookaside.pFree = pBuf; |
| 20438 | db->lookaside.nOut--; |
| 20439 | return; |
| 20440 | } |
| 20441 | } |
| 20442 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 20443 | assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 20444 | assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); |
| 20445 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 20446 | sqlite3_free(p); |
| 20447 | } |
| 20448 | |
| @@ -20449,10 +20450,12 @@ | |
| 20450 | ** Change the size of an existing memory allocation |
| 20451 | */ |
| 20452 | SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ |
| 20453 | int nOld, nNew, nDiff; |
| 20454 | void *pNew; |
| 20455 | assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); |
| 20456 | assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); |
| 20457 | if( pOld==0 ){ |
| 20458 | return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ |
| 20459 | } |
| 20460 | if( nBytes==0 ){ |
| 20461 | sqlite3_free(pOld); /* IMP: R-26507-47431 */ |
| @@ -20475,12 +20478,10 @@ | |
| 20478 | nDiff = nNew - nOld; |
| 20479 | if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= |
| 20480 | mem0.alarmThreshold-nDiff ){ |
| 20481 | sqlite3MallocAlarm(nDiff); |
| 20482 | } |
| 20483 | pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); |
| 20484 | if( pNew==0 && mem0.alarmCallback ){ |
| 20485 | sqlite3MallocAlarm((int)nBytes); |
| 20486 | pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); |
| 20487 | } |
| @@ -20589,12 +20590,12 @@ | |
| 20590 | #endif |
| 20591 | p = sqlite3Malloc(n); |
| 20592 | if( !p && db ){ |
| 20593 | db->mallocFailed = 1; |
| 20594 | } |
| 20595 | sqlite3MemdebugSetType(p, |
| 20596 | (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); |
| 20597 | return p; |
| 20598 | } |
| 20599 | |
| 20600 | /* |
| 20601 | ** Resize the block of memory pointed to by p to n bytes. If the |
| @@ -20616,19 +20617,18 @@ | |
| 20617 | if( pNew ){ |
| 20618 | memcpy(pNew, p, db->lookaside.sz); |
| 20619 | sqlite3DbFree(db, p); |
| 20620 | } |
| 20621 | }else{ |
| 20622 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 20623 | assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 20624 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 20625 | pNew = sqlite3_realloc64(p, n); |
| 20626 | if( !pNew ){ |
| 20627 | db->mallocFailed = 1; |
| 20628 | } |
| 20629 | sqlite3MemdebugSetType(pNew, |
| 20630 | (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); |
| 20631 | } |
| 20632 | } |
| 20633 | return pNew; |
| 20634 | } |
| @@ -20754,15 +20754,11 @@ | |
| 20754 | ** HAVE_STRCHRNUL. If that routine is not available, this module |
| 20755 | ** will supply its own. The built-in version is slower than |
| 20756 | ** the glibc version so the glibc version is definitely preferred. |
| 20757 | */ |
| 20758 | #if !defined(HAVE_STRCHRNUL) |
| 20759 | # define HAVE_STRCHRNUL 0 |
| 20760 | #endif |
| 20761 | |
| 20762 | |
| 20763 | /* |
| 20764 | ** Conversion types fall into various categories as defined by the |
| @@ -22091,18 +22087,18 @@ | |
| 22087 | #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ |
| 22088 | /******************************** End Unix Pthreads *************************/ |
| 22089 | |
| 22090 | |
| 22091 | /********************************* Win32 Threads ****************************/ |
| 22092 | #if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 |
| 22093 | |
| 22094 | #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ |
| 22095 | #include <process.h> |
| 22096 | |
| 22097 | /* A running thread */ |
| 22098 | struct SQLiteThread { |
| 22099 | void *tid; /* The thread handle */ |
| 22100 | unsigned id; /* The thread identifier */ |
| 22101 | void *(*xTask)(void*); /* The routine to run as a thread */ |
| 22102 | void *pIn; /* Argument to xTask */ |
| 22103 | void *pResult; /* Result of xTask */ |
| 22104 | }; |
| @@ -22146,11 +22142,11 @@ | |
| 22142 | if( sqlite3GlobalConfig.bCoreMutex==0 ){ |
| 22143 | memset(p, 0, sizeof(*p)); |
| 22144 | }else{ |
| 22145 | p->xTask = xTask; |
| 22146 | p->pIn = pIn; |
| 22147 | p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); |
| 22148 | if( p->tid==0 ){ |
| 22149 | memset(p, 0, sizeof(*p)); |
| 22150 | } |
| 22151 | } |
| 22152 | if( p->xTask==0 ){ |
| @@ -22184,11 +22180,11 @@ | |
| 22180 | if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; |
| 22181 | sqlite3_free(p); |
| 22182 | return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; |
| 22183 | } |
| 22184 | |
| 22185 | #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */ |
| 22186 | /******************************** End Win32 Threads *************************/ |
| 22187 | |
| 22188 | |
| 22189 | /********************************* Single-Threaded **************************/ |
| 22190 | #ifndef SQLITE_THREADS_IMPLEMENTED |
| @@ -33487,11 +33483,15 @@ | |
| 33483 | #endif |
| 33484 | |
| 33485 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 33486 | DWORD))aSyscall[63].pCurrent) |
| 33487 | |
| 33488 | #if !SQLITE_OS_WINCE |
| 33489 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 33490 | #else |
| 33491 | { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 33492 | #endif |
| 33493 | |
| 33494 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 33495 | BOOL))aSyscall[64].pCurrent) |
| 33496 | |
| 33497 | #if SQLITE_OS_WINRT |
| @@ -33830,11 +33830,12 @@ | |
| 33830 | #else |
| 33831 | osSleep(milliseconds); |
| 33832 | #endif |
| 33833 | } |
| 33834 | |
| 33835 | #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 33836 | SQLITE_THREADSAFE>0 |
| 33837 | SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ |
| 33838 | DWORD rc; |
| 33839 | while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, |
| 33840 | TRUE))==WAIT_IO_COMPLETION ){} |
| 33841 | return rc; |
| @@ -39855,11 +39856,11 @@ | |
| 39856 | assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); |
| 39857 | assert( pCache->n90pct == pCache->nMax*9/10 ); |
| 39858 | if( createFlag==1 && ( |
| 39859 | nPinned>=pGroup->mxPinned |
| 39860 | || nPinned>=pCache->n90pct |
| 39861 | || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned) |
| 39862 | )){ |
| 39863 | return 0; |
| 39864 | } |
| 39865 | |
| 39866 | if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache); |
| @@ -42799,10 +42800,18 @@ | |
| 42800 | }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ |
| 42801 | if( pPager->journalOff==0 ){ |
| 42802 | rc = SQLITE_OK; |
| 42803 | }else{ |
| 42804 | rc = sqlite3OsTruncate(pPager->jfd, 0); |
| 42805 | if( rc==SQLITE_OK && pPager->fullSync ){ |
| 42806 | /* Make sure the new file size is written into the inode right away. |
| 42807 | ** Otherwise the journal might resurrect following a power loss and |
| 42808 | ** cause the last transaction to roll back. See |
| 42809 | ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 |
| 42810 | */ |
| 42811 | rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); |
| 42812 | } |
| 42813 | } |
| 42814 | pPager->journalOff = 0; |
| 42815 | }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
| 42816 | || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) |
| 42817 | ){ |
| @@ -44476,17 +44485,19 @@ | |
| 44485 | if( !pNew ) rc = SQLITE_NOMEM; |
| 44486 | } |
| 44487 | |
| 44488 | if( rc==SQLITE_OK ){ |
| 44489 | pager_reset(pPager); |
| 44490 | rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); |
| 44491 | } |
| 44492 | if( rc==SQLITE_OK ){ |
| 44493 | sqlite3PageFree(pPager->pTmpSpace); |
| 44494 | pPager->pTmpSpace = pNew; |
| 44495 | pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); |
| 44496 | pPager->pageSize = pageSize; |
| 44497 | }else{ |
| 44498 | sqlite3PageFree(pNew); |
| 44499 | } |
| 44500 | } |
| 44501 | |
| 44502 | *pPageSize = pPager->pageSize; |
| 44503 | if( rc==SQLITE_OK ){ |
| @@ -51649,11 +51660,11 @@ | |
| 51660 | int nRef; /* Number of references to this structure */ |
| 51661 | BtShared *pNext; /* Next on a list of sharable BtShared structs */ |
| 51662 | BtLock *pLock; /* List of locks held on this shared-btree struct */ |
| 51663 | Btree *pWriter; /* Btree with currently open write transaction */ |
| 51664 | #endif |
| 51665 | u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ |
| 51666 | }; |
| 51667 | |
| 51668 | /* |
| 51669 | ** Allowed values for BtShared.btsFlags |
| 51670 | */ |
| @@ -52947,11 +52958,11 @@ | |
| 52958 | ** |
| 52959 | ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor |
| 52960 | ** back to where it ought to be if this routine returns true. |
| 52961 | */ |
| 52962 | SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ |
| 52963 | return pCur->eState!=CURSOR_VALID; |
| 52964 | } |
| 52965 | |
| 52966 | /* |
| 52967 | ** This routine restores a cursor back to its original position after it |
| 52968 | ** has been moved by some outside activity (such as a btree rebalance or |
| @@ -54279,11 +54290,12 @@ | |
| 54290 | #endif |
| 54291 | } |
| 54292 | |
| 54293 | /* |
| 54294 | ** Make sure pBt->pTmpSpace points to an allocation of |
| 54295 | ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child |
| 54296 | ** pointer. |
| 54297 | */ |
| 54298 | static void allocateTempSpace(BtShared *pBt){ |
| 54299 | if( !pBt->pTmpSpace ){ |
| 54300 | pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); |
| 54301 | |
| @@ -54294,21 +54306,32 @@ | |
| 54306 | ** can mean that fillInCell() only initializes the first 2 or 3 |
| 54307 | ** bytes of pTmpSpace, but that the first 4 bytes are copied from |
| 54308 | ** it into a database page. This is not actually a problem, but it |
| 54309 | ** does cause a valgrind error when the 1 or 2 bytes of unitialized |
| 54310 | ** data is passed to system call write(). So to avoid this error, |
| 54311 | ** zero the first 4 bytes of temp space here. |
| 54312 | ** |
| 54313 | ** Also: Provide four bytes of initialized space before the |
| 54314 | ** beginning of pTmpSpace as an area available to prepend the |
| 54315 | ** left-child pointer to the beginning of a cell. |
| 54316 | */ |
| 54317 | if( pBt->pTmpSpace ){ |
| 54318 | memset(pBt->pTmpSpace, 0, 8); |
| 54319 | pBt->pTmpSpace += 4; |
| 54320 | } |
| 54321 | } |
| 54322 | } |
| 54323 | |
| 54324 | /* |
| 54325 | ** Free the pBt->pTmpSpace allocation |
| 54326 | */ |
| 54327 | static void freeTempSpace(BtShared *pBt){ |
| 54328 | if( pBt->pTmpSpace ){ |
| 54329 | pBt->pTmpSpace -= 4; |
| 54330 | sqlite3PageFree(pBt->pTmpSpace); |
| 54331 | pBt->pTmpSpace = 0; |
| 54332 | } |
| 54333 | } |
| 54334 | |
| 54335 | /* |
| 54336 | ** Close an open database and invalidate all cursors. |
| 54337 | */ |
| @@ -58016,15 +58039,10 @@ | |
| 58039 | ** pTemp is not null. Regardless of pTemp, allocate a new entry |
| 58040 | ** in pPage->apOvfl[] and make it point to the cell content (either |
| 58041 | ** in pTemp or the original pCell) and also record its index. |
| 58042 | ** Allocating a new entry in pPage->aCell[] implies that |
| 58043 | ** pPage->nOverflow is incremented. |
| 58044 | */ |
| 58045 | static void insertCell( |
| 58046 | MemPage *pPage, /* Page into which we are copying */ |
| 58047 | int i, /* New cell becomes the i-th cell of the page */ |
| 58048 | u8 *pCell, /* Content of the new cell */ |
| @@ -58037,11 +58055,10 @@ | |
| 58055 | int j; /* Loop counter */ |
| 58056 | int end; /* First byte past the last cell pointer in data[] */ |
| 58057 | int ins; /* Index in data[] where new cell pointer is inserted */ |
| 58058 | int cellOffset; /* Address of first cell pointer in data[] */ |
| 58059 | u8 *data; /* The content of the whole page */ |
| 58060 | |
| 58061 | if( *pRC ) return; |
| 58062 | |
| 58063 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); |
| 58064 | assert( MX_CELL(pPage->pBt)<=10921 ); |
| @@ -58055,11 +58072,11 @@ | |
| 58072 | ** might be less than 8 (leaf-size + pointer) on the interior node. Hence |
| 58073 | ** the term after the || in the following assert(). */ |
| 58074 | assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) ); |
| 58075 | if( pPage->nOverflow || sz+2>pPage->nFree ){ |
| 58076 | if( pTemp ){ |
| 58077 | memcpy(pTemp, pCell, sz); |
| 58078 | pCell = pTemp; |
| 58079 | } |
| 58080 | if( iChild ){ |
| 58081 | put4byte(pCell, iChild); |
| 58082 | } |
| @@ -58084,11 +58101,11 @@ | |
| 58101 | ** if it returns success */ |
| 58102 | assert( idx >= end+2 ); |
| 58103 | assert( idx+sz <= (int)pPage->pBt->usableSize ); |
| 58104 | pPage->nCell++; |
| 58105 | pPage->nFree -= (u16)(2 + sz); |
| 58106 | memcpy(&data[idx], pCell, sz); |
| 58107 | if( iChild ){ |
| 58108 | put4byte(&data[idx], iChild); |
| 58109 | } |
| 58110 | memmove(&data[ins+2], &data[ins], end-ins); |
| 58111 | put2byte(&data[ins], idx); |
| @@ -61630,11 +61647,14 @@ | |
| 61647 | /* If MEM_Dyn is set then Mem.xDel!=0. |
| 61648 | ** Mem.xDel is might not be initialized if MEM_Dyn is clear. |
| 61649 | */ |
| 61650 | assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); |
| 61651 | |
| 61652 | /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we |
| 61653 | ** ensure that if Mem.szMalloc>0 then it is safe to do |
| 61654 | ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. |
| 61655 | ** That saves a few cycles in inner loops. */ |
| 61656 | assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); |
| 61657 | |
| 61658 | /* Cannot be both MEM_Int and MEM_Real at the same time */ |
| 61659 | assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); |
| 61660 | |
| @@ -61739,11 +61759,11 @@ | |
| 61759 | }else{ |
| 61760 | pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); |
| 61761 | } |
| 61762 | } |
| 61763 | |
| 61764 | if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ |
| 61765 | memcpy(pMem->zMalloc, pMem->z, pMem->n); |
| 61766 | } |
| 61767 | if( (pMem->flags&MEM_Dyn)!=0 ){ |
| 61768 | assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); |
| 61769 | pMem->xDel((void *)(pMem->z)); |
| @@ -61766,11 +61786,12 @@ | |
| 61786 | ** |
| 61787 | ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) |
| 61788 | ** if unable to complete the resizing. |
| 61789 | */ |
| 61790 | SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ |
| 61791 | assert( szNew>0 ); |
| 61792 | assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); |
| 61793 | if( pMem->szMalloc<szNew ){ |
| 61794 | return sqlite3VdbeMemGrow(pMem, szNew, 0); |
| 61795 | } |
| 61796 | assert( (pMem->flags & MEM_Dyn)==0 ); |
| 61797 | pMem->z = pMem->zMalloc; |
| @@ -62490,11 +62511,14 @@ | |
| 62511 | nAlloc += (enc==SQLITE_UTF8?1:2); |
| 62512 | } |
| 62513 | if( nByte>iLimit ){ |
| 62514 | return SQLITE_TOOBIG; |
| 62515 | } |
| 62516 | testcase( nAlloc==0 ); |
| 62517 | testcase( nAlloc==31 ); |
| 62518 | testcase( nAlloc==32 ); |
| 62519 | if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){ |
| 62520 | return SQLITE_NOMEM; |
| 62521 | } |
| 62522 | memcpy(pMem->z, z, nAlloc); |
| 62523 | }else if( xDel==SQLITE_DYNAMIC ){ |
| 62524 | sqlite3VdbeMemRelease(pMem); |
| @@ -62593,11 +62617,11 @@ | |
| 62617 | /* |
| 62618 | ** The pVal argument is known to be a value other than NULL. |
| 62619 | ** Convert it into a string with encoding enc and return a pointer |
| 62620 | ** to a zero-terminated version of that string. |
| 62621 | */ |
| 62622 | static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ |
| 62623 | assert( pVal!=0 ); |
| 62624 | assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 62625 | assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 62626 | assert( (pVal->flags & MEM_RowSet)==0 ); |
| 62627 | assert( (pVal->flags & (MEM_Null))==0 ); |
| @@ -64913,11 +64937,11 @@ | |
| 64937 | ** the call above. */ |
| 64938 | }else if( pCx->pCursor ){ |
| 64939 | sqlite3BtreeCloseCursor(pCx->pCursor); |
| 64940 | } |
| 64941 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 64942 | else if( pCx->pVtabCursor ){ |
| 64943 | sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; |
| 64944 | const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; |
| 64945 | p->inVtabMethod = 1; |
| 64946 | pModule->xClose(pVtabCursor); |
| 64947 | p->inVtabMethod = 0; |
| @@ -64956,13 +64980,14 @@ | |
| 64980 | static void closeAllCursors(Vdbe *p){ |
| 64981 | if( p->pFrame ){ |
| 64982 | VdbeFrame *pFrame; |
| 64983 | for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); |
| 64984 | sqlite3VdbeFrameRestore(pFrame); |
| 64985 | p->pFrame = 0; |
| 64986 | p->nFrame = 0; |
| 64987 | } |
| 64988 | assert( p->nFrame==0 ); |
| 64989 | |
| 64990 | if( p->apCsr ){ |
| 64991 | int i; |
| 64992 | for(i=0; i<p->nCursor; i++){ |
| 64993 | VdbeCursor *pC = p->apCsr[i]; |
| @@ -64980,11 +65005,11 @@ | |
| 65005 | p->pDelFrame = pDel->pParent; |
| 65006 | sqlite3VdbeFrameDelete(pDel); |
| 65007 | } |
| 65008 | |
| 65009 | /* Delete any auxdata allocations made by the VM */ |
| 65010 | if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0); |
| 65011 | assert( p->pAuxData==0 ); |
| 65012 | } |
| 65013 | |
| 65014 | /* |
| 65015 | ** Clean up the VM after a single run. |
| @@ -65886,13 +65911,11 @@ | |
| 65911 | #endif |
| 65912 | assert( p->deferredMoveto ); |
| 65913 | assert( p->isTable ); |
| 65914 | rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); |
| 65915 | if( rc ) return rc; |
| 65916 | if( res!=0 ) return SQLITE_CORRUPT_BKPT; |
| 65917 | #ifdef SQLITE_TEST |
| 65918 | sqlite3_search_count++; |
| 65919 | #endif |
| 65920 | p->deferredMoveto = 0; |
| 65921 | p->cacheStatus = CACHE_STALE; |
| @@ -65913,10 +65936,21 @@ | |
| 65936 | rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow); |
| 65937 | p->cacheStatus = CACHE_STALE; |
| 65938 | if( isDifferentRow ) p->nullRow = 1; |
| 65939 | return rc; |
| 65940 | } |
| 65941 | |
| 65942 | /* |
| 65943 | ** Check to ensure that the cursor is valid. Restore the cursor |
| 65944 | ** if need be. Return any I/O error from the restore operation. |
| 65945 | */ |
| 65946 | SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ |
| 65947 | if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ |
| 65948 | return handleMovedCursor(p); |
| 65949 | } |
| 65950 | return SQLITE_OK; |
| 65951 | } |
| 65952 | |
| 65953 | /* |
| 65954 | ** Make sure the cursor p is ready to read or write the row to which it |
| 65955 | ** was last positioned. Return an error code if an OOM fault or I/O error |
| 65956 | ** prevents us from positioning the cursor to its correct position. |
| @@ -65931,11 +65965,11 @@ | |
| 65965 | */ |
| 65966 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ |
| 65967 | if( p->deferredMoveto ){ |
| 65968 | return handleDeferredMoveto(p); |
| 65969 | } |
| 65970 | if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){ |
| 65971 | return handleMovedCursor(p); |
| 65972 | } |
| 65973 | return SQLITE_OK; |
| 65974 | } |
| 65975 | |
| @@ -69095,10 +69129,11 @@ | |
| 69129 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| 69130 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; |
| 69131 | memset(pCx, 0, sizeof(VdbeCursor)); |
| 69132 | pCx->iDb = iDb; |
| 69133 | pCx->nField = nField; |
| 69134 | pCx->aOffset = &pCx->aType[nField]; |
| 69135 | if( isBtreeCursor ){ |
| 69136 | pCx->pCursor = (BtCursor*) |
| 69137 | &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; |
| 69138 | sqlite3BtreeCursorZero(pCx->pCursor); |
| 69139 | } |
| @@ -70528,11 +70563,11 @@ | |
| 70563 | ctx.pFunc = pOp->p4.pFunc; |
| 70564 | ctx.iOp = pc; |
| 70565 | ctx.pVdbe = p; |
| 70566 | MemSetTypeFlag(ctx.pOut, MEM_Null); |
| 70567 | ctx.fErrorOrAux = 0; |
| 70568 | db->lastRowid = lastRowid; |
| 70569 | (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 70570 | lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */ |
| 70571 | |
| 70572 | /* If the function returned an error, throw an exception */ |
| 70573 | if( ctx.fErrorOrAux ){ |
| @@ -71246,11 +71281,11 @@ | |
| 71281 | memAboutToChange(p, pDest); |
| 71282 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71283 | pC = p->apCsr[pOp->p1]; |
| 71284 | assert( pC!=0 ); |
| 71285 | assert( p2<pC->nField ); |
| 71286 | aOffset = pC->aOffset; |
| 71287 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 71288 | assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ |
| 71289 | #endif |
| 71290 | pCrsr = pC->pCursor; |
| 71291 | assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ |
| @@ -71257,11 +71292,11 @@ | |
| 71292 | assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ |
| 71293 | |
| 71294 | /* If the cursor cache is stale, bring it up-to-date */ |
| 71295 | rc = sqlite3VdbeCursorMoveto(pC); |
| 71296 | if( rc ) goto abort_due_to_error; |
| 71297 | if( pC->cacheStatus!=p->cacheCtr ){ |
| 71298 | if( pC->nullRow ){ |
| 71299 | if( pCrsr==0 ){ |
| 71300 | assert( pC->pseudoTableReg>0 ); |
| 71301 | pReg = &aMem[pC->pseudoTableReg]; |
| 71302 | assert( pReg->flags & MEM_Blob ); |
| @@ -71302,18 +71337,10 @@ | |
| 71337 | } |
| 71338 | pC->cacheStatus = p->cacheCtr; |
| 71339 | pC->iHdrOffset = getVarint32(pC->aRow, offset); |
| 71340 | pC->nHdrParsed = 0; |
| 71341 | aOffset[0] = offset; |
| 71342 | |
| 71343 | /* Make sure a corrupt database has not given us an oversize header. |
| 71344 | ** Do this now to avoid an oversize memory allocation. |
| 71345 | ** |
| 71346 | ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte |
| @@ -71324,19 +71351,36 @@ | |
| 71351 | */ |
| 71352 | if( offset > 98307 || offset > pC->payloadSize ){ |
| 71353 | rc = SQLITE_CORRUPT_BKPT; |
| 71354 | goto op_column_error; |
| 71355 | } |
| 71356 | |
| 71357 | if( avail<offset ){ |
| 71358 | /* pC->aRow does not have to hold the entire row, but it does at least |
| 71359 | ** need to cover the header of the record. If pC->aRow does not contain |
| 71360 | ** the complete header, then set it to zero, forcing the header to be |
| 71361 | ** dynamically allocated. */ |
| 71362 | pC->aRow = 0; |
| 71363 | pC->szRow = 0; |
| 71364 | } |
| 71365 | |
| 71366 | /* The following goto is an optimization. It can be omitted and |
| 71367 | ** everything will still work. But OP_Column is measurably faster |
| 71368 | ** by skipping the subsequent conditional, which is always true. |
| 71369 | */ |
| 71370 | assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ |
| 71371 | goto op_column_read_header; |
| 71372 | } |
| 71373 | |
| 71374 | /* Make sure at least the first p2+1 entries of the header have been |
| 71375 | ** parsed and valid information is in aOffset[] and pC->aType[]. |
| 71376 | */ |
| 71377 | if( pC->nHdrParsed<=p2 ){ |
| 71378 | /* If there is more header available for parsing in the record, try |
| 71379 | ** to extract additional fields up through the p2+1-th field |
| 71380 | */ |
| 71381 | op_column_read_header: |
| 71382 | if( pC->iHdrOffset<aOffset[0] ){ |
| 71383 | /* Make sure zData points to enough of the record to cover the header. */ |
| 71384 | if( pC->aRow==0 ){ |
| 71385 | memset(&sMem, 0, sizeof(sMem)); |
| 71386 | rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], |
| @@ -71377,19 +71421,20 @@ | |
| 71421 | if( pC->aRow==0 ){ |
| 71422 | sqlite3VdbeMemRelease(&sMem); |
| 71423 | sMem.flags = MEM_Null; |
| 71424 | } |
| 71425 | |
| 71426 | /* The record is corrupt if any of the following are true: |
| 71427 | ** (1) the bytes of the header extend past the declared header size |
| 71428 | ** (zHdr>zEndHdr) |
| 71429 | ** (2) the entire header was used but not all data was used |
| 71430 | ** (zHdr==zEndHdr && offset!=pC->payloadSize) |
| 71431 | ** (3) the end of the data extends beyond the end of the record. |
| 71432 | ** (offset > pC->payloadSize) |
| 71433 | */ |
| 71434 | if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize)) |
| 71435 | || (offset > pC->payloadSize) |
| 71436 | ){ |
| 71437 | rc = SQLITE_CORRUPT_BKPT; |
| 71438 | goto op_column_error; |
| 71439 | } |
| 71440 | } |
| @@ -71400,11 +71445,11 @@ | |
| 71445 | */ |
| 71446 | if( pC->nHdrParsed<=p2 ){ |
| 71447 | if( pOp->p4type==P4_MEM ){ |
| 71448 | sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); |
| 71449 | }else{ |
| 71450 | sqlite3VdbeMemSetNull(pDest); |
| 71451 | } |
| 71452 | goto op_column_out; |
| 71453 | } |
| 71454 | } |
| 71455 | |
| @@ -71576,11 +71621,11 @@ | |
| 71621 | ** out how much space is required for the new record. |
| 71622 | */ |
| 71623 | pRec = pLast; |
| 71624 | do{ |
| 71625 | assert( memIsValid(pRec) ); |
| 71626 | pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format); |
| 71627 | len = sqlite3VdbeSerialTypeLen(serial_type); |
| 71628 | if( pRec->flags & MEM_Zero ){ |
| 71629 | if( nData ){ |
| 71630 | sqlite3VdbeMemExpandBlob(pRec); |
| 71631 | }else{ |
| @@ -71625,11 +71670,11 @@ | |
| 71670 | i = putVarint32(zNewRecord, nHdr); |
| 71671 | j = nHdr; |
| 71672 | assert( pData0<=pLast ); |
| 71673 | pRec = pData0; |
| 71674 | do{ |
| 71675 | serial_type = pRec->uTemp; |
| 71676 | i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ |
| 71677 | j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 71678 | }while( (++pRec)<=pLast ); |
| 71679 | assert( i==nHdr ); |
| 71680 | assert( j==nByte ); |
| @@ -72524,11 +72569,10 @@ | |
| 72569 | pIn3 = &aMem[pOp->p3]; |
| 72570 | if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ |
| 72571 | applyNumericAffinity(pIn3, 0); |
| 72572 | } |
| 72573 | iKey = sqlite3VdbeIntValue(pIn3); |
| 72574 | |
| 72575 | /* If the P3 value could not be converted into an integer without |
| 72576 | ** loss of information, then special processing is required... */ |
| 72577 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 72578 | if( (pIn3->flags & MEM_Real)==0 ){ |
| @@ -72560,17 +72604,14 @@ | |
| 72604 | assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); |
| 72605 | if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; |
| 72606 | } |
| 72607 | } |
| 72608 | rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); |
| 72609 | pC->movetoTarget = iKey; /* Used by OP_Delete */ |
| 72610 | if( rc!=SQLITE_OK ){ |
| 72611 | goto abort_due_to_error; |
| 72612 | } |
| 72613 | }else{ |
| 72614 | nField = pOp->p4.i; |
| 72615 | assert( pOp->p4type==P4_INT32 ); |
| 72616 | assert( nField>0 ); |
| 72617 | r.pKeyInfo = pC->pKeyInfo; |
| @@ -72596,11 +72637,10 @@ | |
| 72637 | ExpandBlob(r.aMem); |
| 72638 | rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); |
| 72639 | if( rc!=SQLITE_OK ){ |
| 72640 | goto abort_due_to_error; |
| 72641 | } |
| 72642 | } |
| 72643 | pC->deferredMoveto = 0; |
| 72644 | pC->cacheStatus = CACHE_STALE; |
| 72645 | #ifdef SQLITE_TEST |
| 72646 | sqlite3_search_count++; |
| @@ -72608,21 +72648,19 @@ | |
| 72648 | if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); |
| 72649 | if( res<0 || (res==0 && oc==OP_SeekGT) ){ |
| 72650 | res = 0; |
| 72651 | rc = sqlite3BtreeNext(pC->pCursor, &res); |
| 72652 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 72653 | }else{ |
| 72654 | res = 0; |
| 72655 | } |
| 72656 | }else{ |
| 72657 | assert( oc==OP_SeekLT || oc==OP_SeekLE ); |
| 72658 | if( res>0 || (res==0 && oc==OP_SeekLT) ){ |
| 72659 | res = 0; |
| 72660 | rc = sqlite3BtreePrevious(pC->pCursor, &res); |
| 72661 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 72662 | }else{ |
| 72663 | /* res might be negative because the table is empty. Check to |
| 72664 | ** see if this is the case. |
| 72665 | */ |
| 72666 | res = sqlite3BtreeEof(pC->pCursor); |
| @@ -72655,11 +72693,10 @@ | |
| 72693 | assert( pC->pCursor!=0 ); |
| 72694 | assert( pC->isTable ); |
| 72695 | pC->nullRow = 0; |
| 72696 | pIn2 = &aMem[pOp->p2]; |
| 72697 | pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 72698 | pC->deferredMoveto = 1; |
| 72699 | break; |
| 72700 | } |
| 72701 | |
| 72702 | |
| @@ -72841,19 +72878,17 @@ | |
| 72878 | pCrsr = pC->pCursor; |
| 72879 | assert( pCrsr!=0 ); |
| 72880 | res = 0; |
| 72881 | iKey = pIn3->u.i; |
| 72882 | rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); |
| 72883 | pC->movetoTarget = iKey; /* Used by OP_Delete */ |
| 72884 | pC->nullRow = 0; |
| 72885 | pC->cacheStatus = CACHE_STALE; |
| 72886 | pC->deferredMoveto = 0; |
| 72887 | VdbeBranchTaken(res!=0,2); |
| 72888 | if( res!=0 ){ |
| 72889 | pc = pOp->p2 - 1; |
| 72890 | } |
| 72891 | pC->seekResult = res; |
| 72892 | break; |
| 72893 | } |
| 72894 | |
| @@ -72997,11 +73032,10 @@ | |
| 73032 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 73033 | goto abort_due_to_error; |
| 73034 | } |
| 73035 | assert( v>0 ); /* EV: R-40812-03570 */ |
| 73036 | } |
| 73037 | pC->deferredMoveto = 0; |
| 73038 | pC->cacheStatus = CACHE_STALE; |
| 73039 | } |
| 73040 | pOut->u.i = v; |
| 73041 | break; |
| @@ -73102,11 +73136,10 @@ | |
| 73136 | } |
| 73137 | rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, |
| 73138 | pData->z, pData->n, nZero, |
| 73139 | (pOp->p5 & OPFLAG_APPEND)!=0, seekResult |
| 73140 | ); |
| 73141 | pC->deferredMoveto = 0; |
| 73142 | pC->cacheStatus = CACHE_STALE; |
| 73143 | |
| 73144 | /* Invoke the update-hook if required. */ |
| 73145 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| @@ -73139,37 +73172,36 @@ | |
| 73172 | ** pointing to. The update hook will be invoked, if it exists. |
| 73173 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 73174 | ** using OP_NotFound prior to invoking this opcode. |
| 73175 | */ |
| 73176 | case OP_Delete: { |
| 73177 | VdbeCursor *pC; |
| 73178 | |
| 73179 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73180 | pC = p->apCsr[pOp->p1]; |
| 73181 | assert( pC!=0 ); |
| 73182 | assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 73183 | assert( pC->deferredMoveto==0 ); |
| 73184 | |
| 73185 | #ifdef SQLITE_DEBUG |
| 73186 | /* The seek operation that positioned the cursor prior to OP_Delete will |
| 73187 | ** have also set the pC->movetoTarget field to the rowid of the row that |
| 73188 | ** is being deleted */ |
| 73189 | if( pOp->p4.z && pC->isTable ){ |
| 73190 | i64 iKey = 0; |
| 73191 | sqlite3BtreeKeySize(pC->pCursor, &iKey); |
| 73192 | assert( pC->movetoTarget==iKey ); |
| 73193 | } |
| 73194 | #endif |
| 73195 | |
| 73196 | rc = sqlite3BtreeDelete(pC->pCursor); |
| 73197 | pC->cacheStatus = CACHE_STALE; |
| 73198 | |
| 73199 | /* Invoke the update-hook if required. */ |
| 73200 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ |
| 73201 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, |
| 73202 | db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget); |
| 73203 | assert( pC->iDb>=0 ); |
| 73204 | } |
| 73205 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 73206 | break; |
| 73207 | } |
| @@ -73218,23 +73250,32 @@ | |
| 73250 | pc = pOp->p2-1; |
| 73251 | } |
| 73252 | break; |
| 73253 | }; |
| 73254 | |
| 73255 | /* Opcode: SorterData P1 P2 P3 * * |
| 73256 | ** Synopsis: r[P2]=data |
| 73257 | ** |
| 73258 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 73259 | ** Then clear the column header cache on cursor P3. |
| 73260 | ** |
| 73261 | ** This opcode is normally use to move a record out of the sorter and into |
| 73262 | ** a register that is the source for a pseudo-table cursor created using |
| 73263 | ** OpenPseudo. That pseudo-table cursor is the one that is identified by |
| 73264 | ** parameter P3. Clearing the P3 column cache as part of this opcode saves |
| 73265 | ** us from having to issue a separate NullRow instruction to clear that cache. |
| 73266 | */ |
| 73267 | case OP_SorterData: { |
| 73268 | VdbeCursor *pC; |
| 73269 | |
| 73270 | pOut = &aMem[pOp->p2]; |
| 73271 | pC = p->apCsr[pOp->p1]; |
| 73272 | assert( isSorter(pC) ); |
| 73273 | rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 73274 | assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); |
| 73275 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73276 | p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; |
| 73277 | break; |
| 73278 | } |
| 73279 | |
| 73280 | /* Opcode: RowData P1 P2 * * * |
| 73281 | ** Synopsis: r[P2]=data |
| @@ -73277,20 +73318,24 @@ | |
| 73318 | assert( pC!=0 ); |
| 73319 | assert( pC->nullRow==0 ); |
| 73320 | assert( pC->pseudoTableReg==0 ); |
| 73321 | assert( pC->pCursor!=0 ); |
| 73322 | pCrsr = pC->pCursor; |
| 73323 | |
| 73324 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 73325 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 73326 | ** the cursor. If this where not the case, on of the following assert()s |
| 73327 | ** would fail. Should this ever change (because of changes in the code |
| 73328 | ** generator) then the fix would be to insert a call to |
| 73329 | ** sqlite3VdbeCursorMoveto(). |
| 73330 | */ |
| 73331 | assert( pC->deferredMoveto==0 ); |
| 73332 | assert( sqlite3BtreeCursorIsValid(pCrsr) ); |
| 73333 | #if 0 /* Not required due to the previous to assert() statements */ |
| 73334 | rc = sqlite3VdbeCursorMoveto(pC); |
| 73335 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 73336 | #endif |
| 73337 | |
| 73338 | if( pC->isTable==0 ){ |
| 73339 | assert( !pC->isTable ); |
| 73340 | VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); |
| 73341 | assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| @@ -73303,11 +73348,12 @@ | |
| 73348 | assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 73349 | if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 73350 | goto too_big; |
| 73351 | } |
| 73352 | } |
| 73353 | testcase( n==0 ); |
| 73354 | if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ |
| 73355 | goto no_mem; |
| 73356 | } |
| 73357 | pOut->n = n; |
| 73358 | MemSetTypeFlag(pOut, MEM_Blob); |
| 73359 | if( pC->isTable==0 ){ |
| @@ -73354,18 +73400,14 @@ | |
| 73400 | rc = pModule->xRowid(pC->pVtabCursor, &v); |
| 73401 | sqlite3VtabImportErrmsg(p, pVtab); |
| 73402 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 73403 | }else{ |
| 73404 | assert( pC->pCursor!=0 ); |
| 73405 | rc = sqlite3VdbeCursorRestore(pC); |
| 73406 | if( rc ) goto abort_due_to_error; |
| 73407 | rc = sqlite3BtreeKeySize(pC->pCursor, &v); |
| 73408 | assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */ |
| 73409 | } |
| 73410 | pOut->u.i = v; |
| 73411 | break; |
| 73412 | } |
| 73413 | |
| @@ -73380,11 +73422,10 @@ | |
| 73422 | |
| 73423 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 73424 | pC = p->apCsr[pOp->p1]; |
| 73425 | assert( pC!=0 ); |
| 73426 | pC->nullRow = 1; |
| 73427 | pC->cacheStatus = CACHE_STALE; |
| 73428 | if( pC->pCursor ){ |
| 73429 | sqlite3BtreeClearCursor(pC->pCursor); |
| 73430 | } |
| 73431 | break; |
| @@ -73414,11 +73455,10 @@ | |
| 73455 | res = 0; |
| 73456 | assert( pCrsr!=0 ); |
| 73457 | rc = sqlite3BtreeLast(pCrsr, &res); |
| 73458 | pC->nullRow = (u8)res; |
| 73459 | pC->deferredMoveto = 0; |
| 73460 | pC->cacheStatus = CACHE_STALE; |
| 73461 | #ifdef SQLITE_DEBUG |
| 73462 | pC->seekOp = OP_Last; |
| 73463 | #endif |
| 73464 | if( pOp->p2>0 ){ |
| @@ -73481,11 +73521,10 @@ | |
| 73521 | pCrsr = pC->pCursor; |
| 73522 | assert( pCrsr ); |
| 73523 | rc = sqlite3BtreeFirst(pCrsr, &res); |
| 73524 | pC->deferredMoveto = 0; |
| 73525 | pC->cacheStatus = CACHE_STALE; |
| 73526 | } |
| 73527 | pC->nullRow = (u8)res; |
| 73528 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 73529 | VdbeBranchTaken(res!=0,2); |
| 73530 | if( res ){ |
| @@ -73607,11 +73646,10 @@ | |
| 73646 | sqlite3_search_count++; |
| 73647 | #endif |
| 73648 | }else{ |
| 73649 | pC->nullRow = 1; |
| 73650 | } |
| 73651 | goto check_for_interrupt; |
| 73652 | } |
| 73653 | |
| 73654 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 73655 | ** Synopsis: key=r[P2] |
| @@ -73723,14 +73761,20 @@ | |
| 73761 | pC = p->apCsr[pOp->p1]; |
| 73762 | assert( pC!=0 ); |
| 73763 | pCrsr = pC->pCursor; |
| 73764 | assert( pCrsr!=0 ); |
| 73765 | pOut->flags = MEM_Null; |
| 73766 | assert( pC->isTable==0 ); |
| 73767 | assert( pC->deferredMoveto==0 ); |
| 73768 | |
| 73769 | /* sqlite3VbeCursorRestore() can only fail if the record has been deleted |
| 73770 | ** out from under the cursor. That will never happend for an IdxRowid |
| 73771 | ** opcode, hence the NEVER() arround the check of the return value. |
| 73772 | */ |
| 73773 | rc = sqlite3VdbeCursorRestore(pC); |
| 73774 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 73775 | |
| 73776 | if( !pC->nullRow ){ |
| 73777 | rowid = 0; /* Not needed. Only used to silence a warning. */ |
| 73778 | rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); |
| 73779 | if( rc!=SQLITE_OK ){ |
| 73780 | goto abort_due_to_error; |
| @@ -78187,11 +78231,11 @@ | |
| 78231 | if( rc==SQLITE_OK ){ |
| 78232 | #if SQLITE_MAX_WORKER_THREADS |
| 78233 | assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); |
| 78234 | if( pSorter->bUseThreads ){ |
| 78235 | int iTask; |
| 78236 | PmaReader *pReadr = 0; |
| 78237 | SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; |
| 78238 | rc = vdbeSortAllocUnpacked(pLast); |
| 78239 | if( rc==SQLITE_OK ){ |
| 78240 | pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); |
| 78241 | pSorter->pReader = pReadr; |
| @@ -87168,29 +87212,27 @@ | |
| 87212 | tRowcnt v; |
| 87213 | |
| 87214 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87215 | if( z==0 ) z = ""; |
| 87216 | #else |
| 87217 | assert( z!=0 ); |
| 87218 | #endif |
| 87219 | for(i=0; *z && i<nOut; i++){ |
| 87220 | v = 0; |
| 87221 | while( (c=z[0])>='0' && c<='9' ){ |
| 87222 | v = v*10 + c - '0'; |
| 87223 | z++; |
| 87224 | } |
| 87225 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87226 | if( aOut ) aOut[i] = v; |
| 87227 | if( aLog ) aLog[i] = sqlite3LogEst(v); |
| 87228 | #else |
| 87229 | assert( aOut==0 ); |
| 87230 | UNUSED_PARAMETER(aOut); |
| 87231 | assert( aLog!=0 ); |
| 87232 | aLog[i] = sqlite3LogEst(v); |
| 87233 | #endif |
| 87234 | if( *z==' ' ) z++; |
| 87235 | } |
| 87236 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87237 | assert( pIndex!=0 ); |
| 87238 | #else |
| @@ -87247,12 +87289,21 @@ | |
| 87289 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 87290 | } |
| 87291 | z = argv[2]; |
| 87292 | |
| 87293 | if( pIndex ){ |
| 87294 | int nCol = pIndex->nKeyCol+1; |
| 87295 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 87296 | tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero( |
| 87297 | sizeof(tRowcnt) * nCol |
| 87298 | ); |
| 87299 | if( aiRowEst==0 ) pInfo->db->mallocFailed = 1; |
| 87300 | #else |
| 87301 | tRowcnt * const aiRowEst = 0; |
| 87302 | #endif |
| 87303 | pIndex->bUnordered = 0; |
| 87304 | decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); |
| 87305 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 87306 | }else{ |
| 87307 | Index fakeIdx; |
| 87308 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 87309 | #ifdef SQLITE_ENABLE_COSTMULT |
| @@ -87307,29 +87358,42 @@ | |
| 87358 | ** unique. */ |
| 87359 | nCol = pIdx->nSampleCol-1; |
| 87360 | pIdx->aAvgEq[nCol] = 1; |
| 87361 | } |
| 87362 | for(iCol=0; iCol<nCol; iCol++){ |
| 87363 | int nSample = pIdx->nSample; |
| 87364 | int i; /* Used to iterate through samples */ |
| 87365 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 87366 | tRowcnt avgEq = 0; |
| 87367 | tRowcnt nRow; /* Number of rows in index */ |
| 87368 | i64 nSum100 = 0; /* Number of terms contributing to sumEq */ |
| 87369 | i64 nDist100; /* Number of distinct values in index */ |
| 87370 | |
| 87371 | if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){ |
| 87372 | nRow = pFinal->anLt[iCol]; |
| 87373 | nDist100 = (i64)100 * pFinal->anDLt[iCol]; |
| 87374 | nSample--; |
| 87375 | }else{ |
| 87376 | nRow = pIdx->aiRowEst[0]; |
| 87377 | nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; |
| 87378 | } |
| 87379 | |
| 87380 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 87381 | ** occur in the stat4 table for this index. Set sumEq to the sum of |
| 87382 | ** the nEq values for column iCol for the same set (adding the value |
| 87383 | ** only once where there exist duplicate prefixes). */ |
| 87384 | for(i=0; i<nSample; i++){ |
| 87385 | if( i==(pIdx->nSample-1) |
| 87386 | || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] |
| 87387 | ){ |
| 87388 | sumEq += aSample[i].anEq[iCol]; |
| 87389 | nSum100 += 100; |
| 87390 | } |
| 87391 | } |
| 87392 | |
| 87393 | if( nDist100>nSum100 ){ |
| 87394 | avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); |
| 87395 | } |
| 87396 | if( avgEq==0 ) avgEq = 1; |
| 87397 | pIdx->aAvgEq[iCol] = avgEq; |
| 87398 | } |
| 87399 | } |
| @@ -87576,10 +87640,15 @@ | |
| 87640 | if( rc==SQLITE_OK ){ |
| 87641 | int lookasideEnabled = db->lookaside.bEnabled; |
| 87642 | db->lookaside.bEnabled = 0; |
| 87643 | rc = loadStat4(db, sInfo.zDatabase); |
| 87644 | db->lookaside.bEnabled = lookasideEnabled; |
| 87645 | } |
| 87646 | for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 87647 | Index *pIdx = sqliteHashData(i); |
| 87648 | sqlite3_free(pIdx->aiRowEst); |
| 87649 | pIdx->aiRowEst = 0; |
| 87650 | } |
| 87651 | #endif |
| 87652 | |
| 87653 | if( rc==SQLITE_NOMEM ){ |
| 87654 | db->mallocFailed = 1; |
| @@ -88870,10 +88939,13 @@ | |
| 88939 | #endif |
| 88940 | if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo); |
| 88941 | sqlite3ExprDelete(db, p->pPartIdxWhere); |
| 88942 | sqlite3DbFree(db, p->zColAff); |
| 88943 | if( p->isResized ) sqlite3DbFree(db, p->azColl); |
| 88944 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 88945 | sqlite3_free(p->aiRowEst); |
| 88946 | #endif |
| 88947 | sqlite3DbFree(db, p); |
| 88948 | } |
| 88949 | |
| 88950 | /* |
| 88951 | ** For the index called zIdxName which is found in the database iDb, |
| @@ -91179,11 +91251,11 @@ | |
| 91251 | pIndex->nKeyCol); VdbeCoverage(v); |
| 91252 | sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); |
| 91253 | }else{ |
| 91254 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 91255 | } |
| 91256 | sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); |
| 91257 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); |
| 91258 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 91259 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 91260 | sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); |
| 91261 | sqlite3VdbeJumpHere(v, addr1); |
| @@ -93687,11 +93759,11 @@ | |
| 93759 | if( okOnePass ){ |
| 93760 | /* Just one row. Hence the top-of-loop is a no-op */ |
| 93761 | assert( nKey==nPk ); /* OP_Found will use an unpacked key */ |
| 93762 | assert( !IsVirtual(pTab) ); |
| 93763 | if( aToOpen[iDataCur-iTabCur] ){ |
| 93764 | assert( pPk!=0 || pTab->pSelect!=0 ); |
| 93765 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); |
| 93766 | VdbeCoverage(v); |
| 93767 | } |
| 93768 | }else if( pPk ){ |
| 93769 | addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); |
| @@ -105122,11 +105194,10 @@ | |
| 105194 | int regRow; |
| 105195 | int regRowid; |
| 105196 | int nKey; |
| 105197 | int iSortTab; /* Sorter cursor to read from */ |
| 105198 | int nSortData; /* Trailing values to read from sorter */ |
| 105199 | int i; |
| 105200 | int bSeq; /* True if sorter record includes seq. no. */ |
| 105201 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
| 105202 | struct ExprList_item *aOutEx = p->pEList->a; |
| 105203 | #endif |
| @@ -105156,23 +105227,20 @@ | |
| 105227 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); |
| 105228 | if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 105229 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 105230 | VdbeCoverage(v); |
| 105231 | codeOffset(v, p->iOffset, addrContinue); |
| 105232 | sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); |
| 105233 | bSeq = 0; |
| 105234 | }else{ |
| 105235 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); |
| 105236 | codeOffset(v, p->iOffset, addrContinue); |
| 105237 | iSortTab = iTab; |
| 105238 | bSeq = 1; |
| 105239 | } |
| 105240 | for(i=0; i<nSortData; i++){ |
| 105241 | sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i); |
| 105242 | VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); |
| 105243 | } |
| 105244 | switch( eDest ){ |
| 105245 | case SRT_Table: |
| 105246 | case SRT_EphemTab: { |
| @@ -109097,16 +109165,15 @@ | |
| 109165 | ** from the previous row currently stored in a0, a1, a2... |
| 109166 | */ |
| 109167 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 109168 | sqlite3ExprCacheClear(pParse); |
| 109169 | if( groupBySort ){ |
| 109170 | sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab); |
| 109171 | } |
| 109172 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 109173 | if( groupBySort ){ |
| 109174 | sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); |
| 109175 | }else{ |
| 109176 | sAggInfo.directMode = 1; |
| 109177 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 109178 | } |
| 109179 | } |
| @@ -111216,12 +111283,12 @@ | |
| 111283 | 0, 0); |
| 111284 | } |
| 111285 | |
| 111286 | /* Top of the update loop */ |
| 111287 | if( okOnePass ){ |
| 111288 | if( aToOpen[iDataCur-iBaseCur] && !isView ){ |
| 111289 | assert( pPk ); |
| 111290 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 111291 | VdbeCoverageNeverTaken(v); |
| 111292 | } |
| 111293 | labelContinue = labelBreak; |
| 111294 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| @@ -112450,10 +112517,11 @@ | |
| 112517 | } |
| 112518 | sqlite3DbFree(db, pVTable); |
| 112519 | }else if( ALWAYS(pVTable->pVtab) ){ |
| 112520 | /* Justification of ALWAYS(): A correct vtab constructor must allocate |
| 112521 | ** the sqlite3_vtab object if successful. */ |
| 112522 | memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); |
| 112523 | pVTable->pVtab->pModule = pMod->pModule; |
| 112524 | pVTable->nRef = 1; |
| 112525 | if( sCtx.pTab ){ |
| 112526 | const char *zFormat = "vtable constructor did not declare schema: %s"; |
| 112527 | *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); |
| @@ -115700,21 +115768,28 @@ | |
| 115768 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 115769 | whereKeyStats(pParse, p, pRec, 0, a); |
| 115770 | iLower = a[0]; |
| 115771 | iUpper = a[0] + a[1]; |
| 115772 | } |
| 115773 | |
| 115774 | assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 ); |
| 115775 | assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); |
| 115776 | assert( p->aSortOrder!=0 ); |
| 115777 | if( p->aSortOrder[nEq] ){ |
| 115778 | /* The roles of pLower and pUpper are swapped for a DESC index */ |
| 115779 | SWAP(WhereTerm*, pLower, pUpper); |
| 115780 | } |
| 115781 | |
| 115782 | /* If possible, improve on the iLower estimate using ($P:$L). */ |
| 115783 | if( pLower ){ |
| 115784 | int bOk; /* True if value is extracted from pExpr */ |
| 115785 | Expr *pExpr = pLower->pExpr->pRight; |
| 115786 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 115787 | if( rc==SQLITE_OK && bOk ){ |
| 115788 | tRowcnt iNew; |
| 115789 | whereKeyStats(pParse, p, pRec, 0, a); |
| 115790 | iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); |
| 115791 | if( iNew>iLower ) iLower = iNew; |
| 115792 | nOut--; |
| 115793 | pLower = 0; |
| 115794 | } |
| 115795 | } |
| @@ -115721,16 +115796,15 @@ | |
| 115796 | |
| 115797 | /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 115798 | if( pUpper ){ |
| 115799 | int bOk; /* True if value is extracted from pExpr */ |
| 115800 | Expr *pExpr = pUpper->pExpr->pRight; |
| 115801 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 115802 | if( rc==SQLITE_OK && bOk ){ |
| 115803 | tRowcnt iNew; |
| 115804 | whereKeyStats(pParse, p, pRec, 1, a); |
| 115805 | iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); |
| 115806 | if( iNew<iUpper ) iUpper = iNew; |
| 115807 | nOut--; |
| 115808 | pUpper = 0; |
| 115809 | } |
| 115810 | } |
| @@ -116225,65 +116299,52 @@ | |
| 116299 | sqlite3StrAccumAppend(pStr, "?", 1); |
| 116300 | } |
| 116301 | |
| 116302 | /* |
| 116303 | ** Argument pLevel describes a strategy for scanning table pTab. This |
| 116304 | ** function appends text to pStr that describes the subset of table |
| 116305 | ** rows scanned by the strategy in the form of an SQL expression. |
| 116306 | ** |
| 116307 | ** For example, if the query: |
| 116308 | ** |
| 116309 | ** SELECT * FROM t1 WHERE a=1 AND b>2; |
| 116310 | ** |
| 116311 | ** is run and there is an index on (a, b), then this function returns a |
| 116312 | ** string similar to: |
| 116313 | ** |
| 116314 | ** "a=? AND b>?" |
| 116315 | */ |
| 116316 | static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){ |
| 116317 | Index *pIndex = pLoop->u.btree.pIndex; |
| 116318 | u16 nEq = pLoop->u.btree.nEq; |
| 116319 | u16 nSkip = pLoop->u.btree.nSkip; |
| 116320 | int i, j; |
| 116321 | Column *aCol = pTab->aCol; |
| 116322 | i16 *aiColumn = pIndex->aiColumn; |
| 116323 | |
| 116324 | if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; |
| 116325 | sqlite3StrAccumAppend(pStr, " (", 2); |
| 116326 | for(i=0; i<nEq; i++){ |
| 116327 | char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName; |
| 116328 | if( i>=nSkip ){ |
| 116329 | explainAppendTerm(pStr, i, z, "="); |
| 116330 | }else{ |
| 116331 | if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); |
| 116332 | sqlite3XPrintf(pStr, 0, "ANY(%s)", z); |
| 116333 | } |
| 116334 | } |
| 116335 | |
| 116336 | j = i; |
| 116337 | if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ |
| 116338 | char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; |
| 116339 | explainAppendTerm(pStr, i++, z, ">"); |
| 116340 | } |
| 116341 | if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ |
| 116342 | char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; |
| 116343 | explainAppendTerm(pStr, i, z, "<"); |
| 116344 | } |
| 116345 | sqlite3StrAccumAppend(pStr, ")", 1); |
| 116346 | } |
| 116347 | |
| 116348 | /* |
| 116349 | ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN |
| 116350 | ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single |
| @@ -116303,72 +116364,90 @@ | |
| 116364 | #endif |
| 116365 | { |
| 116366 | struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; |
| 116367 | Vdbe *v = pParse->pVdbe; /* VM being constructed */ |
| 116368 | sqlite3 *db = pParse->db; /* Database handle */ |
| 116369 | int iId = pParse->iSelectId; /* Select id (left-most output column) */ |
| 116370 | int isSearch; /* True for a SEARCH. False for SCAN. */ |
| 116371 | WhereLoop *pLoop; /* The controlling WhereLoop object */ |
| 116372 | u32 flags; /* Flags that describe this loop */ |
| 116373 | char *zMsg; /* Text to add to EQP output */ |
| 116374 | StrAccum str; /* EQP output string */ |
| 116375 | char zBuf[100]; /* Initial space for EQP output string */ |
| 116376 | |
| 116377 | pLoop = pLevel->pWLoop; |
| 116378 | flags = pLoop->wsFlags; |
| 116379 | if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return; |
| 116380 | |
| 116381 | isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 |
| 116382 | || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) |
| 116383 | || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); |
| 116384 | |
| 116385 | sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); |
| 116386 | str.db = db; |
| 116387 | sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); |
| 116388 | if( pItem->pSelect ){ |
| 116389 | sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId); |
| 116390 | }else{ |
| 116391 | sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName); |
| 116392 | } |
| 116393 | |
| 116394 | if( pItem->zAlias ){ |
| 116395 | sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias); |
| 116396 | } |
| 116397 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ |
| 116398 | const char *zFmt = 0; |
| 116399 | Index *pIdx; |
| 116400 | |
| 116401 | assert( pLoop->u.btree.pIndex!=0 ); |
| 116402 | pIdx = pLoop->u.btree.pIndex; |
| 116403 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); |
| 116404 | if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 116405 | if( isSearch ){ |
| 116406 | zFmt = "PRIMARY KEY"; |
| 116407 | } |
| 116408 | }else if( flags & WHERE_AUTO_INDEX ){ |
| 116409 | zFmt = "AUTOMATIC COVERING INDEX"; |
| 116410 | }else if( flags & WHERE_IDX_ONLY ){ |
| 116411 | zFmt = "COVERING INDEX %s"; |
| 116412 | }else{ |
| 116413 | zFmt = "INDEX %s"; |
| 116414 | } |
| 116415 | if( zFmt ){ |
| 116416 | sqlite3StrAccumAppend(&str, " USING ", 7); |
| 116417 | sqlite3XPrintf(&str, 0, zFmt, pIdx->zName); |
| 116418 | explainIndexRange(&str, pLoop, pItem->pTab); |
| 116419 | } |
| 116420 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 116421 | const char *zRange; |
| 116422 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| 116423 | zRange = "(rowid=?)"; |
| 116424 | }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ |
| 116425 | zRange = "(rowid>? AND rowid<?)"; |
| 116426 | }else if( flags&WHERE_BTM_LIMIT ){ |
| 116427 | zRange = "(rowid>?)"; |
| 116428 | }else{ |
| 116429 | assert( flags&WHERE_TOP_LIMIT); |
| 116430 | zRange = "(rowid<?)"; |
| 116431 | } |
| 116432 | sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY "); |
| 116433 | sqlite3StrAccumAppendAll(&str, zRange); |
| 116434 | } |
| 116435 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 116436 | else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ |
| 116437 | sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s", |
| 116438 | pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); |
| 116439 | } |
| 116440 | #endif |
| 116441 | #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS |
| 116442 | if( pLoop->nOut>=10 ){ |
| 116443 | sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); |
| 116444 | }else{ |
| 116445 | sqlite3StrAccumAppend(&str, " (~1 row)", 9); |
| 116446 | } |
| 116447 | #endif |
| 116448 | zMsg = sqlite3StrAccumFinish(&str); |
| 116449 | sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC); |
| 116450 | } |
| 116451 | } |
| 116452 | #else |
| 116453 | # define explainOneScan(u,v,w,x,y,z) |
| @@ -117633,11 +117712,11 @@ | |
| 117712 | if( ppPrev==0 ){ |
| 117713 | /* There already exists a WhereLoop on the list that is better |
| 117714 | ** than pTemplate, so just ignore pTemplate */ |
| 117715 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117716 | if( sqlite3WhereTrace & 0x8 ){ |
| 117717 | sqlite3DebugPrintf(" skip: "); |
| 117718 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 117719 | } |
| 117720 | #endif |
| 117721 | return SQLITE_OK; |
| 117722 | }else{ |
| @@ -117649,14 +117728,14 @@ | |
| 117728 | ** WhereLoop and insert it. |
| 117729 | */ |
| 117730 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117731 | if( sqlite3WhereTrace & 0x8 ){ |
| 117732 | if( p!=0 ){ |
| 117733 | sqlite3DebugPrintf("replace: "); |
| 117734 | whereLoopPrint(p, pBuilder->pWC); |
| 117735 | } |
| 117736 | sqlite3DebugPrintf(" add: "); |
| 117737 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 117738 | } |
| 117739 | #endif |
| 117740 | if( p==0 ){ |
| 117741 | /* Allocate a new WhereLoop to add to the end of the list */ |
| @@ -117676,11 +117755,11 @@ | |
| 117755 | pToDel = *ppTail; |
| 117756 | if( pToDel==0 ) break; |
| 117757 | *ppTail = pToDel->pNextLoop; |
| 117758 | #if WHERETRACE_ENABLED /* 0x8 */ |
| 117759 | if( sqlite3WhereTrace & 0x8 ){ |
| 117760 | sqlite3DebugPrintf(" delete: "); |
| 117761 | whereLoopPrint(pToDel, pBuilder->pWC); |
| 117762 | } |
| 117763 | #endif |
| 117764 | whereLoopDelete(db, pToDel); |
| 117765 | } |
| @@ -118843,11 +118922,11 @@ | |
| 118922 | if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; |
| 118923 | } |
| 118924 | isMatch = 1; |
| 118925 | break; |
| 118926 | } |
| 118927 | if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ |
| 118928 | /* Make sure the sort order is compatible in an ORDER BY clause. |
| 118929 | ** Sort order is irrelevant for a GROUP BY clause. */ |
| 118930 | if( revSet ){ |
| 118931 | if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; |
| 118932 | }else{ |
| @@ -119308,16 +119387,19 @@ | |
| 119387 | pWInfo->revMask = pFrom->revLoop; |
| 119388 | } |
| 119389 | if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) |
| 119390 | && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr |
| 119391 | ){ |
| 119392 | Bitmask revMask = 0; |
| 119393 | int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, |
| 119394 | pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask |
| 119395 | ); |
| 119396 | assert( pWInfo->sorted==0 ); |
| 119397 | if( nOrder==pWInfo->pOrderBy->nExpr ){ |
| 119398 | pWInfo->sorted = 1; |
| 119399 | pWInfo->revMask = revMask; |
| 119400 | } |
| 119401 | } |
| 119402 | } |
| 119403 | |
| 119404 | |
| 119405 | pWInfo->nRowOut = pFrom->nRow; |
| @@ -132620,10 +132702,11 @@ | |
| 132702 | assert( iIdx==nVal ); |
| 132703 | |
| 132704 | /* In case the cursor has been used before, clear it now. */ |
| 132705 | sqlite3_finalize(pCsr->pStmt); |
| 132706 | sqlite3_free(pCsr->aDoclist); |
| 132707 | sqlite3_free(pCsr->aMatchinfo); |
| 132708 | sqlite3Fts3ExprFree(pCsr->pExpr); |
| 132709 | memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); |
| 132710 | |
| 132711 | /* Set the lower and upper bounds on docids to return */ |
| 132712 | pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); |
| @@ -133930,11 +134013,11 @@ | |
| 134013 | if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ |
| 134014 | iMax = a[i].iDocid; |
| 134015 | bMaxSet = 1; |
| 134016 | } |
| 134017 | } |
| 134018 | assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) ); |
| 134019 | assert( rc!=SQLITE_OK || bMaxSet ); |
| 134020 | |
| 134021 | /* Keep advancing iterators until they all point to the same document */ |
| 134022 | for(i=0; i<p->nToken; i++){ |
| 134023 | while( rc==SQLITE_OK && bEof==0 |
| @@ -136047,11 +136130,11 @@ | |
| 136130 | int i = 0; |
| 136131 | |
| 136132 | /* Set variable i to the maximum number of bytes of input to tokenize. */ |
| 136133 | for(i=0; i<n; i++){ |
| 136134 | if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break; |
| 136135 | if( z[i]=='"' ) break; |
| 136136 | } |
| 136137 | |
| 136138 | *pnConsumed = i; |
| 136139 | rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); |
| 136140 | if( rc==SQLITE_OK ){ |
| 136141 |
+2
-2
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -105,13 +105,13 @@ | ||
| 105 | 105 | ** |
| 106 | 106 | ** See also: [sqlite3_libversion()], |
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | -#define SQLITE_VERSION "3.8.7" | |
| 110 | +#define SQLITE_VERSION "3.8.7.1" | |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008007 |
| 112 | -#define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d" | |
| 112 | +#define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -105,13 +105,13 @@ | |
| 105 | ** |
| 106 | ** See also: [sqlite3_libversion()], |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.7" |
| 111 | #define SQLITE_VERSION_NUMBER 3008007 |
| 112 | #define SQLITE_SOURCE_ID "2014-10-04 19:31:53 b8f7f19dc06c59de2e194d83e6c052fb7d28c71d" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -105,13 +105,13 @@ | |
| 105 | ** |
| 106 | ** See also: [sqlite3_libversion()], |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.7.1" |
| 111 | #define SQLITE_VERSION_NUMBER 3008007 |
| 112 | #define SQLITE_SOURCE_ID "2014-10-29 01:27:43 83afe23e553e802c0947c80d0ffdd120423e7c52" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
+7
-7
| --- src/stash.c | ||
| +++ src/stash.c | ||
| @@ -23,17 +23,17 @@ | ||
| 23 | 23 | |
| 24 | 24 | /* |
| 25 | 25 | ** SQL code to implement the tables needed by the stash. |
| 26 | 26 | */ |
| 27 | 27 | static const char zStashInit[] = |
| 28 | -@ CREATE TABLE IF NOT EXISTS %s.stash( | |
| 28 | +@ CREATE TABLE IF NOT EXISTS "%w".stash( | |
| 29 | 29 | @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier |
| 30 | 30 | @ vid INTEGER, -- The baseline check-out for this stash |
| 31 | 31 | @ comment TEXT, -- Comment for this stash. Or NULL |
| 32 | 32 | @ ctime TIMESTAMP -- When the stash was created |
| 33 | 33 | @ ); |
| 34 | -@ CREATE TABLE IF NOT EXISTS %s.stashfile( | |
| 34 | +@ CREATE TABLE IF NOT EXISTS "%w".stashfile( | |
| 35 | 35 | @ stashid INTEGER REFERENCES stash, -- Stash that contains this file |
| 36 | 36 | @ rid INTEGER, -- Baseline content in BLOB table or 0. |
| 37 | 37 | @ isAdded BOOLEAN, -- True if this is an added file |
| 38 | 38 | @ isRemoved BOOLEAN, -- True if this file is deleted |
| 39 | 39 | @ isExec BOOLEAN, -- True if file is executable |
| @@ -61,24 +61,24 @@ | ||
| 61 | 61 | |
| 62 | 62 | zFile = mprintf("%/", zFName); |
| 63 | 63 | file_tree_name(zFile, &fname, 1); |
| 64 | 64 | zTreename = blob_str(&fname); |
| 65 | 65 | blob_zero(&sql); |
| 66 | - blob_appendf(&sql, | |
| 66 | + blob_append_sql(&sql, | |
| 67 | 67 | "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)" |
| 68 | 68 | " FROM vfile" |
| 69 | 69 | " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)", |
| 70 | 70 | vid |
| 71 | 71 | ); |
| 72 | 72 | if( fossil_strcmp(zTreename,".")!=0 ){ |
| 73 | - blob_appendf(&sql, | |
| 73 | + blob_append_sql(&sql, | |
| 74 | 74 | " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'" |
| 75 | 75 | " OR pathname=%Q OR origname=%Q)", |
| 76 | 76 | zTreename, zTreename, zTreename, zTreename |
| 77 | 77 | ); |
| 78 | 78 | } |
| 79 | - db_prepare(&q, blob_str(&sql)); | |
| 79 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 80 | 80 | blob_reset(&sql); |
| 81 | 81 | db_prepare(&ins, |
| 82 | 82 | "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink," |
| 83 | 83 | "origname, newname, delta)" |
| 84 | 84 | "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)", |
| @@ -481,11 +481,11 @@ | ||
| 481 | 481 | undo_capture_command_line(); |
| 482 | 482 | db_must_be_within_tree(); |
| 483 | 483 | db_open_config(0); |
| 484 | 484 | db_begin_transaction(); |
| 485 | 485 | zDb = db_name("localdb"); |
| 486 | - db_multi_exec(zStashInit, zDb, zDb); | |
| 486 | + db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb); | |
| 487 | 487 | if( g.argc<=2 ){ |
| 488 | 488 | zCmd = "save"; |
| 489 | 489 | }else{ |
| 490 | 490 | zCmd = g.argv[2]; |
| 491 | 491 | } |
| @@ -534,11 +534,11 @@ | ||
| 534 | 534 | } |
| 535 | 535 | verify_all_options(); |
| 536 | 536 | db_prepare(&q, |
| 537 | 537 | "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid)," |
| 538 | 538 | " comment, datetime(ctime) FROM stash" |
| 539 | - " ORDER BY ctime DESC" | |
| 539 | + " ORDER BY ctime" | |
| 540 | 540 | ); |
| 541 | 541 | if( verboseFlag ){ |
| 542 | 542 | db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname" |
| 543 | 543 | " FROM stashfile WHERE stashid=$id"); |
| 544 | 544 | } |
| 545 | 545 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -23,17 +23,17 @@ | |
| 23 | |
| 24 | /* |
| 25 | ** SQL code to implement the tables needed by the stash. |
| 26 | */ |
| 27 | static const char zStashInit[] = |
| 28 | @ CREATE TABLE IF NOT EXISTS %s.stash( |
| 29 | @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier |
| 30 | @ vid INTEGER, -- The baseline check-out for this stash |
| 31 | @ comment TEXT, -- Comment for this stash. Or NULL |
| 32 | @ ctime TIMESTAMP -- When the stash was created |
| 33 | @ ); |
| 34 | @ CREATE TABLE IF NOT EXISTS %s.stashfile( |
| 35 | @ stashid INTEGER REFERENCES stash, -- Stash that contains this file |
| 36 | @ rid INTEGER, -- Baseline content in BLOB table or 0. |
| 37 | @ isAdded BOOLEAN, -- True if this is an added file |
| 38 | @ isRemoved BOOLEAN, -- True if this file is deleted |
| 39 | @ isExec BOOLEAN, -- True if file is executable |
| @@ -61,24 +61,24 @@ | |
| 61 | |
| 62 | zFile = mprintf("%/", zFName); |
| 63 | file_tree_name(zFile, &fname, 1); |
| 64 | zTreename = blob_str(&fname); |
| 65 | blob_zero(&sql); |
| 66 | blob_appendf(&sql, |
| 67 | "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)" |
| 68 | " FROM vfile" |
| 69 | " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)", |
| 70 | vid |
| 71 | ); |
| 72 | if( fossil_strcmp(zTreename,".")!=0 ){ |
| 73 | blob_appendf(&sql, |
| 74 | " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'" |
| 75 | " OR pathname=%Q OR origname=%Q)", |
| 76 | zTreename, zTreename, zTreename, zTreename |
| 77 | ); |
| 78 | } |
| 79 | db_prepare(&q, blob_str(&sql)); |
| 80 | blob_reset(&sql); |
| 81 | db_prepare(&ins, |
| 82 | "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink," |
| 83 | "origname, newname, delta)" |
| 84 | "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)", |
| @@ -481,11 +481,11 @@ | |
| 481 | undo_capture_command_line(); |
| 482 | db_must_be_within_tree(); |
| 483 | db_open_config(0); |
| 484 | db_begin_transaction(); |
| 485 | zDb = db_name("localdb"); |
| 486 | db_multi_exec(zStashInit, zDb, zDb); |
| 487 | if( g.argc<=2 ){ |
| 488 | zCmd = "save"; |
| 489 | }else{ |
| 490 | zCmd = g.argv[2]; |
| 491 | } |
| @@ -534,11 +534,11 @@ | |
| 534 | } |
| 535 | verify_all_options(); |
| 536 | db_prepare(&q, |
| 537 | "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid)," |
| 538 | " comment, datetime(ctime) FROM stash" |
| 539 | " ORDER BY ctime DESC" |
| 540 | ); |
| 541 | if( verboseFlag ){ |
| 542 | db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname" |
| 543 | " FROM stashfile WHERE stashid=$id"); |
| 544 | } |
| 545 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -23,17 +23,17 @@ | |
| 23 | |
| 24 | /* |
| 25 | ** SQL code to implement the tables needed by the stash. |
| 26 | */ |
| 27 | static const char zStashInit[] = |
| 28 | @ CREATE TABLE IF NOT EXISTS "%w".stash( |
| 29 | @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier |
| 30 | @ vid INTEGER, -- The baseline check-out for this stash |
| 31 | @ comment TEXT, -- Comment for this stash. Or NULL |
| 32 | @ ctime TIMESTAMP -- When the stash was created |
| 33 | @ ); |
| 34 | @ CREATE TABLE IF NOT EXISTS "%w".stashfile( |
| 35 | @ stashid INTEGER REFERENCES stash, -- Stash that contains this file |
| 36 | @ rid INTEGER, -- Baseline content in BLOB table or 0. |
| 37 | @ isAdded BOOLEAN, -- True if this is an added file |
| 38 | @ isRemoved BOOLEAN, -- True if this file is deleted |
| 39 | @ isExec BOOLEAN, -- True if file is executable |
| @@ -61,24 +61,24 @@ | |
| 61 | |
| 62 | zFile = mprintf("%/", zFName); |
| 63 | file_tree_name(zFile, &fname, 1); |
| 64 | zTreename = blob_str(&fname); |
| 65 | blob_zero(&sql); |
| 66 | blob_append_sql(&sql, |
| 67 | "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)" |
| 68 | " FROM vfile" |
| 69 | " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)", |
| 70 | vid |
| 71 | ); |
| 72 | if( fossil_strcmp(zTreename,".")!=0 ){ |
| 73 | blob_append_sql(&sql, |
| 74 | " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'" |
| 75 | " OR pathname=%Q OR origname=%Q)", |
| 76 | zTreename, zTreename, zTreename, zTreename |
| 77 | ); |
| 78 | } |
| 79 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 80 | blob_reset(&sql); |
| 81 | db_prepare(&ins, |
| 82 | "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink," |
| 83 | "origname, newname, delta)" |
| 84 | "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)", |
| @@ -481,11 +481,11 @@ | |
| 481 | undo_capture_command_line(); |
| 482 | db_must_be_within_tree(); |
| 483 | db_open_config(0); |
| 484 | db_begin_transaction(); |
| 485 | zDb = db_name("localdb"); |
| 486 | db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb); |
| 487 | if( g.argc<=2 ){ |
| 488 | zCmd = "save"; |
| 489 | }else{ |
| 490 | zCmd = g.argv[2]; |
| 491 | } |
| @@ -534,11 +534,11 @@ | |
| 534 | } |
| 535 | verify_all_options(); |
| 536 | db_prepare(&q, |
| 537 | "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid)," |
| 538 | " comment, datetime(ctime) FROM stash" |
| 539 | " ORDER BY ctime" |
| 540 | ); |
| 541 | if( verboseFlag ){ |
| 542 | db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname" |
| 543 | " FROM stashfile WHERE stashid=$id"); |
| 544 | } |
| 545 |
+47
-24
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -137,49 +137,59 @@ | ||
| 137 | 137 | @ <tr><th>Repository Rebuilt:</th><td> |
| 138 | 138 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 139 | 139 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 140 | 140 | @ <tr><th>Database Stats:</th><td> |
| 141 | 141 | zDb = db_name("repository"); |
| 142 | - @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages, | |
| 143 | - @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page, | |
| 144 | - @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages, | |
| 145 | - @ %s(db_text(0, "PRAGMA %s.encoding", zDb)), | |
| 146 | - @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode | |
| 142 | + @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages, | |
| 143 | + @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page, | |
| 144 | + @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages, | |
| 145 | + @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)), | |
| 146 | + @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode | |
| 147 | 147 | @ </td></tr> |
| 148 | 148 | |
| 149 | 149 | @ </table> |
| 150 | 150 | style_footer(); |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | /* |
| 154 | 154 | ** COMMAND: dbstat* |
| 155 | 155 | ** |
| 156 | -** Usage: %fossil dbstat ?-brief | -b? | |
| 156 | +** Usage: %fossil dbstat OPTIONS | |
| 157 | 157 | ** |
| 158 | 158 | ** Shows statistics and global information about the repository. |
| 159 | 159 | ** |
| 160 | -** The (-brief|-b) option removes any "long-running" statistics, namely | |
| 161 | -** those whose calculations are known to slow down as the repository | |
| 162 | -** grows. | |
| 160 | +** Options: | |
| 163 | 161 | ** |
| 162 | +** --brief|-b Only show essential elements | |
| 163 | +** --db-check Run a PRAGMA quick_check on the repository database | |
| 164 | +** --omit-version-info Omit the SQLite and Fossil version information | |
| 164 | 165 | */ |
| 165 | 166 | void dbstat_cmd(void){ |
| 166 | 167 | i64 t, fsize; |
| 167 | 168 | int n, m; |
| 168 | 169 | int szMax, szAvg; |
| 169 | 170 | const char *zDb; |
| 170 | 171 | int brief; |
| 172 | + int omitVers; /* Omit Fossil and SQLite version information */ | |
| 173 | + int dbCheck; /* True for the --db-check option */ | |
| 171 | 174 | char zBuf[100]; |
| 172 | 175 | const int colWidth = -19 /* printf alignment/width for left column */; |
| 173 | - const char *p; | |
| 176 | + const char *p, *z; | |
| 174 | 177 | |
| 175 | 178 | brief = find_option("brief", "b",0)!=0; |
| 179 | + omitVers = find_option("omit-version-info", 0, 0)!=0; | |
| 180 | + dbCheck = find_option("db-check",0,0)!=0; | |
| 176 | 181 | db_find_and_open_repository(0,0); |
| 177 | 182 | |
| 178 | 183 | /* We should be done with options.. */ |
| 179 | 184 | verify_all_options(); |
| 180 | 185 | |
| 186 | + if( (z = db_get("project-name",0))!=0 | |
| 187 | + || (z = db_get("short-project-name",0))!=0 | |
| 188 | + ){ | |
| 189 | + fossil_print("%*s%s\n", colWidth, "project-name:", z); | |
| 190 | + } | |
| 181 | 191 | fsize = file_size(g.zRepositoryName); |
| 182 | 192 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 183 | 193 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 184 | 194 | if( !brief ){ |
| 185 | 195 | n = db_int(0, "SELECT count(*) FROM blob"); |
| @@ -225,38 +235,51 @@ | ||
| 225 | 235 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 226 | 236 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 227 | 237 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 228 | 238 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 229 | 239 | fossil_print("%*s%d\n", colWidth, "tagchanges:", n); |
| 240 | + z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" | |
| 241 | + " CAST(julianday('now') - mtime AS INTEGER)" | |
| 242 | + " || ' days ago' FROM event " | |
| 243 | + " ORDER BY mtime DESC LIMIT 1"); | |
| 244 | + fossil_print("%*s%s\n", colWidth, "latest-change:", z); | |
| 230 | 245 | } |
| 231 | 246 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 232 | 247 | " + 0.99"); |
| 233 | 248 | fossil_print("%*s%d days or approximately %.2f years.\n", |
| 234 | 249 | colWidth, "project-age:", n, n/365.2425); |
| 235 | 250 | p = db_get("project-code", 0); |
| 236 | 251 | if( p ){ |
| 237 | 252 | fossil_print("%*s%s\n", colWidth, "project-id:", p); |
| 238 | 253 | } |
| 254 | +#if 0 | |
| 255 | + /* Server-id is not useful information any more */ | |
| 239 | 256 | fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0)); |
| 240 | - fossil_print("%*s%s %s [%s] (%s)\n", | |
| 241 | - colWidth, "fossil-version:", | |
| 242 | - MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, | |
| 243 | - COMPILER_NAME); | |
| 244 | - fossil_print("%*s%.19s [%.10s] (%s)\n", | |
| 245 | - colWidth, "sqlite-version:", | |
| 246 | - sqlite3_sourceid(), &sqlite3_sourceid()[20], | |
| 247 | - sqlite3_libversion()); | |
| 257 | +#endif | |
| 258 | + if( !omitVers ){ | |
| 259 | + fossil_print("%*s%s %s [%s] (%s)\n", | |
| 260 | + colWidth, "fossil-version:", | |
| 261 | + MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, | |
| 262 | + COMPILER_NAME); | |
| 263 | + fossil_print("%*s%.19s [%.10s] (%s)\n", | |
| 264 | + colWidth, "sqlite-version:", | |
| 265 | + sqlite3_sourceid(), &sqlite3_sourceid()[20], | |
| 266 | + sqlite3_libversion()); | |
| 267 | + } | |
| 248 | 268 | zDb = db_name("repository"); |
| 249 | 269 | fossil_print("%*s%d pages, %d bytes/pg, %d free pages, " |
| 250 | 270 | "%s, %s mode\n", |
| 251 | 271 | colWidth, "database-stats:", |
| 252 | - db_int(0, "PRAGMA %s.page_count", zDb), | |
| 253 | - db_int(0, "PRAGMA %s.page_size", zDb), | |
| 254 | - db_int(0, "PRAGMA %s.freelist_count", zDb), | |
| 255 | - db_text(0, "PRAGMA %s.encoding", zDb), | |
| 256 | - db_text(0, "PRAGMA %s.journal_mode", zDb)); | |
| 257 | - | |
| 272 | + db_int(0, "PRAGMA \"%w\".page_count", zDb), | |
| 273 | + db_int(0, "PRAGMA \"%w\".page_size", zDb), | |
| 274 | + db_int(0, "PRAGMA \"%w\".freelist_count", zDb), | |
| 275 | + db_text(0, "PRAGMA \"%w\".encoding", zDb), | |
| 276 | + db_text(0, "PRAGMA \"%w\".journal_mode", zDb)); | |
| 277 | + if( dbCheck ){ | |
| 278 | + fossil_print("%*s%s\n", colWidth, "database-check:", | |
| 279 | + db_text(0, "PRAGMA quick_check(1)")); | |
| 280 | + } | |
| 258 | 281 | } |
| 259 | 282 | |
| 260 | 283 | /* |
| 261 | 284 | ** WEBPAGE: urllist |
| 262 | 285 | ** |
| 263 | 286 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -137,49 +137,59 @@ | |
| 137 | @ <tr><th>Repository Rebuilt:</th><td> |
| 138 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 139 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 140 | @ <tr><th>Database Stats:</th><td> |
| 141 | zDb = db_name("repository"); |
| 142 | @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages, |
| 143 | @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page, |
| 144 | @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages, |
| 145 | @ %s(db_text(0, "PRAGMA %s.encoding", zDb)), |
| 146 | @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode |
| 147 | @ </td></tr> |
| 148 | |
| 149 | @ </table> |
| 150 | style_footer(); |
| 151 | } |
| 152 | |
| 153 | /* |
| 154 | ** COMMAND: dbstat* |
| 155 | ** |
| 156 | ** Usage: %fossil dbstat ?-brief | -b? |
| 157 | ** |
| 158 | ** Shows statistics and global information about the repository. |
| 159 | ** |
| 160 | ** The (-brief|-b) option removes any "long-running" statistics, namely |
| 161 | ** those whose calculations are known to slow down as the repository |
| 162 | ** grows. |
| 163 | ** |
| 164 | */ |
| 165 | void dbstat_cmd(void){ |
| 166 | i64 t, fsize; |
| 167 | int n, m; |
| 168 | int szMax, szAvg; |
| 169 | const char *zDb; |
| 170 | int brief; |
| 171 | char zBuf[100]; |
| 172 | const int colWidth = -19 /* printf alignment/width for left column */; |
| 173 | const char *p; |
| 174 | |
| 175 | brief = find_option("brief", "b",0)!=0; |
| 176 | db_find_and_open_repository(0,0); |
| 177 | |
| 178 | /* We should be done with options.. */ |
| 179 | verify_all_options(); |
| 180 | |
| 181 | fsize = file_size(g.zRepositoryName); |
| 182 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 183 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 184 | if( !brief ){ |
| 185 | n = db_int(0, "SELECT count(*) FROM blob"); |
| @@ -225,38 +235,51 @@ | |
| 225 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 226 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 227 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 228 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 229 | fossil_print("%*s%d\n", colWidth, "tagchanges:", n); |
| 230 | } |
| 231 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 232 | " + 0.99"); |
| 233 | fossil_print("%*s%d days or approximately %.2f years.\n", |
| 234 | colWidth, "project-age:", n, n/365.2425); |
| 235 | p = db_get("project-code", 0); |
| 236 | if( p ){ |
| 237 | fossil_print("%*s%s\n", colWidth, "project-id:", p); |
| 238 | } |
| 239 | fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0)); |
| 240 | fossil_print("%*s%s %s [%s] (%s)\n", |
| 241 | colWidth, "fossil-version:", |
| 242 | MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, |
| 243 | COMPILER_NAME); |
| 244 | fossil_print("%*s%.19s [%.10s] (%s)\n", |
| 245 | colWidth, "sqlite-version:", |
| 246 | sqlite3_sourceid(), &sqlite3_sourceid()[20], |
| 247 | sqlite3_libversion()); |
| 248 | zDb = db_name("repository"); |
| 249 | fossil_print("%*s%d pages, %d bytes/pg, %d free pages, " |
| 250 | "%s, %s mode\n", |
| 251 | colWidth, "database-stats:", |
| 252 | db_int(0, "PRAGMA %s.page_count", zDb), |
| 253 | db_int(0, "PRAGMA %s.page_size", zDb), |
| 254 | db_int(0, "PRAGMA %s.freelist_count", zDb), |
| 255 | db_text(0, "PRAGMA %s.encoding", zDb), |
| 256 | db_text(0, "PRAGMA %s.journal_mode", zDb)); |
| 257 | |
| 258 | } |
| 259 | |
| 260 | /* |
| 261 | ** WEBPAGE: urllist |
| 262 | ** |
| 263 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -137,49 +137,59 @@ | |
| 137 | @ <tr><th>Repository Rebuilt:</th><td> |
| 138 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 139 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 140 | @ <tr><th>Database Stats:</th><td> |
| 141 | zDb = db_name("repository"); |
| 142 | @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages, |
| 143 | @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page, |
| 144 | @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages, |
| 145 | @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)), |
| 146 | @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode |
| 147 | @ </td></tr> |
| 148 | |
| 149 | @ </table> |
| 150 | style_footer(); |
| 151 | } |
| 152 | |
| 153 | /* |
| 154 | ** COMMAND: dbstat* |
| 155 | ** |
| 156 | ** Usage: %fossil dbstat OPTIONS |
| 157 | ** |
| 158 | ** Shows statistics and global information about the repository. |
| 159 | ** |
| 160 | ** Options: |
| 161 | ** |
| 162 | ** --brief|-b Only show essential elements |
| 163 | ** --db-check Run a PRAGMA quick_check on the repository database |
| 164 | ** --omit-version-info Omit the SQLite and Fossil version information |
| 165 | */ |
| 166 | void dbstat_cmd(void){ |
| 167 | i64 t, fsize; |
| 168 | int n, m; |
| 169 | int szMax, szAvg; |
| 170 | const char *zDb; |
| 171 | int brief; |
| 172 | int omitVers; /* Omit Fossil and SQLite version information */ |
| 173 | int dbCheck; /* True for the --db-check option */ |
| 174 | char zBuf[100]; |
| 175 | const int colWidth = -19 /* printf alignment/width for left column */; |
| 176 | const char *p, *z; |
| 177 | |
| 178 | brief = find_option("brief", "b",0)!=0; |
| 179 | omitVers = find_option("omit-version-info", 0, 0)!=0; |
| 180 | dbCheck = find_option("db-check",0,0)!=0; |
| 181 | db_find_and_open_repository(0,0); |
| 182 | |
| 183 | /* We should be done with options.. */ |
| 184 | verify_all_options(); |
| 185 | |
| 186 | if( (z = db_get("project-name",0))!=0 |
| 187 | || (z = db_get("short-project-name",0))!=0 |
| 188 | ){ |
| 189 | fossil_print("%*s%s\n", colWidth, "project-name:", z); |
| 190 | } |
| 191 | fsize = file_size(g.zRepositoryName); |
| 192 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 193 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 194 | if( !brief ){ |
| 195 | n = db_int(0, "SELECT count(*) FROM blob"); |
| @@ -225,38 +235,51 @@ | |
| 235 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 236 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 237 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 238 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 239 | fossil_print("%*s%d\n", colWidth, "tagchanges:", n); |
| 240 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 241 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 242 | " || ' days ago' FROM event " |
| 243 | " ORDER BY mtime DESC LIMIT 1"); |
| 244 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 245 | } |
| 246 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 247 | " + 0.99"); |
| 248 | fossil_print("%*s%d days or approximately %.2f years.\n", |
| 249 | colWidth, "project-age:", n, n/365.2425); |
| 250 | p = db_get("project-code", 0); |
| 251 | if( p ){ |
| 252 | fossil_print("%*s%s\n", colWidth, "project-id:", p); |
| 253 | } |
| 254 | #if 0 |
| 255 | /* Server-id is not useful information any more */ |
| 256 | fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0)); |
| 257 | #endif |
| 258 | if( !omitVers ){ |
| 259 | fossil_print("%*s%s %s [%s] (%s)\n", |
| 260 | colWidth, "fossil-version:", |
| 261 | MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, |
| 262 | COMPILER_NAME); |
| 263 | fossil_print("%*s%.19s [%.10s] (%s)\n", |
| 264 | colWidth, "sqlite-version:", |
| 265 | sqlite3_sourceid(), &sqlite3_sourceid()[20], |
| 266 | sqlite3_libversion()); |
| 267 | } |
| 268 | zDb = db_name("repository"); |
| 269 | fossil_print("%*s%d pages, %d bytes/pg, %d free pages, " |
| 270 | "%s, %s mode\n", |
| 271 | colWidth, "database-stats:", |
| 272 | db_int(0, "PRAGMA \"%w\".page_count", zDb), |
| 273 | db_int(0, "PRAGMA \"%w\".page_size", zDb), |
| 274 | db_int(0, "PRAGMA \"%w\".freelist_count", zDb), |
| 275 | db_text(0, "PRAGMA \"%w\".encoding", zDb), |
| 276 | db_text(0, "PRAGMA \"%w\".journal_mode", zDb)); |
| 277 | if( dbCheck ){ |
| 278 | fossil_print("%*s%s\n", colWidth, "database-check:", |
| 279 | db_text(0, "PRAGMA quick_check(1)")); |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | /* |
| 284 | ** WEBPAGE: urllist |
| 285 | ** |
| 286 |
+7
-3
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -175,25 +175,29 @@ | ||
| 175 | 175 | } |
| 176 | 176 | for(i=0; i<nFormAction; i++){ |
| 177 | 177 | @ gebi("form%d(i+1)").action="%s(aFormAction[i])"; |
| 178 | 178 | } |
| 179 | 179 | @ } |
| 180 | - if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){ | |
| 180 | + if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){ | |
| 181 | 181 | /* Special case for Opera Mini, which executes JS server-side */ |
| 182 | 182 | @ var isOperaMini = Object.prototype.toString.call(window.operamini) |
| 183 | 183 | @ === "[object OperaMini]"; |
| 184 | 184 | @ if( isOperaMini ){ |
| 185 | 185 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 186 | 186 | @ } |
| 187 | + }else if( db_get_boolean("auto-hyperlink-ishuman",0) && g.isHuman ){ | |
| 188 | + /* Active hyperlinks after a delay */ | |
| 189 | + @ setTimeout("setAllHrefs();",%d(nDelay)); | |
| 187 | 190 | }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){ |
| 188 | - /* Require mouse movement prior to activating hyperlinks */ | |
| 191 | + /* Require mouse movement before starting the teim that will | |
| 192 | + ** activating hyperlinks */ | |
| 189 | 193 | @ document.getElementsByTagName("body")[0].onmousemove=function(){ |
| 190 | 194 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 191 | 195 | @ this.onmousemove = null; |
| 192 | 196 | @ } |
| 193 | 197 | }else{ |
| 194 | - /* Active hyperlinks right away */ | |
| 198 | + /* Active hyperlinks after a delay */ | |
| 195 | 199 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 196 | 200 | } |
| 197 | 201 | @ </script> |
| 198 | 202 | } |
| 199 | 203 | |
| 200 | 204 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -175,25 +175,29 @@ | |
| 175 | } |
| 176 | for(i=0; i<nFormAction; i++){ |
| 177 | @ gebi("form%d(i+1)").action="%s(aFormAction[i])"; |
| 178 | } |
| 179 | @ } |
| 180 | if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){ |
| 181 | /* Special case for Opera Mini, which executes JS server-side */ |
| 182 | @ var isOperaMini = Object.prototype.toString.call(window.operamini) |
| 183 | @ === "[object OperaMini]"; |
| 184 | @ if( isOperaMini ){ |
| 185 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 186 | @ } |
| 187 | }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){ |
| 188 | /* Require mouse movement prior to activating hyperlinks */ |
| 189 | @ document.getElementsByTagName("body")[0].onmousemove=function(){ |
| 190 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 191 | @ this.onmousemove = null; |
| 192 | @ } |
| 193 | }else{ |
| 194 | /* Active hyperlinks right away */ |
| 195 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 196 | } |
| 197 | @ </script> |
| 198 | } |
| 199 | |
| 200 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -175,25 +175,29 @@ | |
| 175 | } |
| 176 | for(i=0; i<nFormAction; i++){ |
| 177 | @ gebi("form%d(i+1)").action="%s(aFormAction[i])"; |
| 178 | } |
| 179 | @ } |
| 180 | if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){ |
| 181 | /* Special case for Opera Mini, which executes JS server-side */ |
| 182 | @ var isOperaMini = Object.prototype.toString.call(window.operamini) |
| 183 | @ === "[object OperaMini]"; |
| 184 | @ if( isOperaMini ){ |
| 185 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 186 | @ } |
| 187 | }else if( db_get_boolean("auto-hyperlink-ishuman",0) && g.isHuman ){ |
| 188 | /* Active hyperlinks after a delay */ |
| 189 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 190 | }else if( db_get_boolean("auto-hyperlink-mouseover",0) ){ |
| 191 | /* Require mouse movement before starting the teim that will |
| 192 | ** activating hyperlinks */ |
| 193 | @ document.getElementsByTagName("body")[0].onmousemove=function(){ |
| 194 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 195 | @ this.onmousemove = null; |
| 196 | @ } |
| 197 | }else{ |
| 198 | /* Active hyperlinks after a delay */ |
| 199 | @ setTimeout("setAllHrefs();",%d(nDelay)); |
| 200 | } |
| 201 | @ </script> |
| 202 | } |
| 203 | |
| 204 |
+7
-6
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -213,11 +213,12 @@ | ||
| 213 | 213 | rid |
| 214 | 214 | ); |
| 215 | 215 | } |
| 216 | 216 | } |
| 217 | 217 | if( zCol ){ |
| 218 | - db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid); | |
| 218 | + db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d", | |
| 219 | + zCol, zValue, rid); | |
| 219 | 220 | if( tagid==TAG_COMMENT ){ |
| 220 | 221 | char *zCopy = mprintf("%s", zValue); |
| 221 | 222 | wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE); |
| 222 | 223 | free(zCopy); |
| 223 | 224 | } |
| @@ -437,41 +438,41 @@ | ||
| 437 | 438 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 438 | 439 | if( g.argc!=4 ){ |
| 439 | 440 | usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME"); |
| 440 | 441 | } |
| 441 | 442 | if( fRaw ){ |
| 442 | - blob_appendf(&sql, | |
| 443 | + blob_append_sql(&sql, | |
| 443 | 444 | "SELECT blob.uuid FROM tagxref, blob" |
| 444 | 445 | " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" |
| 445 | 446 | " AND tagxref.tagtype>0" |
| 446 | 447 | " AND blob.rid=tagxref.rid", |
| 447 | 448 | g.argv[3] |
| 448 | 449 | ); |
| 449 | 450 | if( nFindLimit>0 ){ |
| 450 | - blob_appendf(&sql, " LIMIT %d", nFindLimit); | |
| 451 | + blob_append_sql(&sql, " LIMIT %d", nFindLimit); | |
| 451 | 452 | } |
| 452 | - db_prepare(&q, "%s", blob_str(&sql)); | |
| 453 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 453 | 454 | blob_reset(&sql); |
| 454 | 455 | while( db_step(&q)==SQLITE_ROW ){ |
| 455 | 456 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 456 | 457 | } |
| 457 | 458 | db_finalize(&q); |
| 458 | 459 | }else{ |
| 459 | 460 | int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", |
| 460 | 461 | g.argv[3]); |
| 461 | 462 | if( tagid>0 ){ |
| 462 | - blob_appendf(&sql, | |
| 463 | + blob_append_sql(&sql, | |
| 463 | 464 | "%s" |
| 464 | 465 | " AND event.type GLOB '%q'" |
| 465 | 466 | " AND blob.rid IN (" |
| 466 | 467 | " SELECT rid FROM tagxref" |
| 467 | 468 | " WHERE tagtype>0 AND tagid=%d" |
| 468 | 469 | ")" |
| 469 | 470 | " ORDER BY event.mtime DESC", |
| 470 | 471 | timeline_query_for_tty(), zType, tagid |
| 471 | 472 | ); |
| 472 | - db_prepare(&q, "%s", blob_str(&sql)); | |
| 473 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 473 | 474 | blob_reset(&sql); |
| 474 | 475 | print_timeline(&q, nFindLimit, 79, 0); |
| 475 | 476 | db_finalize(&q); |
| 476 | 477 | } |
| 477 | 478 | } |
| 478 | 479 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -213,11 +213,12 @@ | |
| 213 | rid |
| 214 | ); |
| 215 | } |
| 216 | } |
| 217 | if( zCol ){ |
| 218 | db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid); |
| 219 | if( tagid==TAG_COMMENT ){ |
| 220 | char *zCopy = mprintf("%s", zValue); |
| 221 | wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE); |
| 222 | free(zCopy); |
| 223 | } |
| @@ -437,41 +438,41 @@ | |
| 437 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 438 | if( g.argc!=4 ){ |
| 439 | usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME"); |
| 440 | } |
| 441 | if( fRaw ){ |
| 442 | blob_appendf(&sql, |
| 443 | "SELECT blob.uuid FROM tagxref, blob" |
| 444 | " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" |
| 445 | " AND tagxref.tagtype>0" |
| 446 | " AND blob.rid=tagxref.rid", |
| 447 | g.argv[3] |
| 448 | ); |
| 449 | if( nFindLimit>0 ){ |
| 450 | blob_appendf(&sql, " LIMIT %d", nFindLimit); |
| 451 | } |
| 452 | db_prepare(&q, "%s", blob_str(&sql)); |
| 453 | blob_reset(&sql); |
| 454 | while( db_step(&q)==SQLITE_ROW ){ |
| 455 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 456 | } |
| 457 | db_finalize(&q); |
| 458 | }else{ |
| 459 | int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", |
| 460 | g.argv[3]); |
| 461 | if( tagid>0 ){ |
| 462 | blob_appendf(&sql, |
| 463 | "%s" |
| 464 | " AND event.type GLOB '%q'" |
| 465 | " AND blob.rid IN (" |
| 466 | " SELECT rid FROM tagxref" |
| 467 | " WHERE tagtype>0 AND tagid=%d" |
| 468 | ")" |
| 469 | " ORDER BY event.mtime DESC", |
| 470 | timeline_query_for_tty(), zType, tagid |
| 471 | ); |
| 472 | db_prepare(&q, "%s", blob_str(&sql)); |
| 473 | blob_reset(&sql); |
| 474 | print_timeline(&q, nFindLimit, 79, 0); |
| 475 | db_finalize(&q); |
| 476 | } |
| 477 | } |
| 478 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -213,11 +213,12 @@ | |
| 213 | rid |
| 214 | ); |
| 215 | } |
| 216 | } |
| 217 | if( zCol ){ |
| 218 | db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d", |
| 219 | zCol, zValue, rid); |
| 220 | if( tagid==TAG_COMMENT ){ |
| 221 | char *zCopy = mprintf("%s", zValue); |
| 222 | wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE); |
| 223 | free(zCopy); |
| 224 | } |
| @@ -437,41 +438,41 @@ | |
| 438 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 439 | if( g.argc!=4 ){ |
| 440 | usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME"); |
| 441 | } |
| 442 | if( fRaw ){ |
| 443 | blob_append_sql(&sql, |
| 444 | "SELECT blob.uuid FROM tagxref, blob" |
| 445 | " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" |
| 446 | " AND tagxref.tagtype>0" |
| 447 | " AND blob.rid=tagxref.rid", |
| 448 | g.argv[3] |
| 449 | ); |
| 450 | if( nFindLimit>0 ){ |
| 451 | blob_append_sql(&sql, " LIMIT %d", nFindLimit); |
| 452 | } |
| 453 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 454 | blob_reset(&sql); |
| 455 | while( db_step(&q)==SQLITE_ROW ){ |
| 456 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 457 | } |
| 458 | db_finalize(&q); |
| 459 | }else{ |
| 460 | int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", |
| 461 | g.argv[3]); |
| 462 | if( tagid>0 ){ |
| 463 | blob_append_sql(&sql, |
| 464 | "%s" |
| 465 | " AND event.type GLOB '%q'" |
| 466 | " AND blob.rid IN (" |
| 467 | " SELECT rid FROM tagxref" |
| 468 | " WHERE tagtype>0 AND tagid=%d" |
| 469 | ")" |
| 470 | " ORDER BY event.mtime DESC", |
| 471 | timeline_query_for_tty(), zType, tagid |
| 472 | ); |
| 473 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 474 | blob_reset(&sql); |
| 475 | print_timeline(&q, nFindLimit, 79, 0); |
| 476 | db_finalize(&q); |
| 477 | } |
| 478 | } |
| 479 |
+116
-83
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -393,14 +393,14 @@ | ||
| 393 | 393 | }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){ |
| 394 | 394 | Blob truncated; |
| 395 | 395 | blob_zero(&truncated); |
| 396 | 396 | blob_append(&truncated, blob_buffer(&comment), mxWikiLen); |
| 397 | 397 | blob_append(&truncated, "...", 3); |
| 398 | - @ <span class="timelineComment">%w(blob_str(&truncated))</span> | |
| 398 | + @ <span class="timelineComment">%W(blob_str(&truncated))</span> | |
| 399 | 399 | blob_reset(&truncated); |
| 400 | 400 | }else{ |
| 401 | - @ <span class="timelineComment">%w(blob_str(&comment))</span> | |
| 401 | + @ <span class="timelineComment">%W(blob_str(&comment))</span> | |
| 402 | 402 | } |
| 403 | 403 | blob_reset(&comment); |
| 404 | 404 | |
| 405 | 405 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 406 | 406 | ** with a hyperlink to another timeline for that user. |
| @@ -860,11 +860,11 @@ | ||
| 860 | 860 | @ tagid INTEGER, |
| 861 | 861 | @ short TEXT, |
| 862 | 862 | @ sortby REAL |
| 863 | 863 | @ ) |
| 864 | 864 | ; |
| 865 | - db_multi_exec(zSql); | |
| 865 | + db_multi_exec("%s", zSql/*safe-for-%s*/); | |
| 866 | 866 | } |
| 867 | 867 | |
| 868 | 868 | /* |
| 869 | 869 | ** Return a pointer to a constant string that forms the basis |
| 870 | 870 | ** for a timeline query for the WWW interface. |
| @@ -889,11 +889,11 @@ | ||
| 889 | 889 | @ event.mtime AS mtime |
| 890 | 890 | @ FROM event CROSS JOIN blob |
| 891 | 891 | @ WHERE blob.rid=event.objid |
| 892 | 892 | ; |
| 893 | 893 | if( zBase==0 ){ |
| 894 | - zBase = mprintf(zBaseSql, timeline_utc()); | |
| 894 | + zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc()); | |
| 895 | 895 | } |
| 896 | 896 | return zBase; |
| 897 | 897 | } |
| 898 | 898 | |
| 899 | 899 | /* |
| @@ -965,11 +965,11 @@ | ||
| 965 | 965 | Stmt q; |
| 966 | 966 | Blob out; |
| 967 | 967 | const char *zSep = ""; |
| 968 | 968 | db_prepare(&q, |
| 969 | 969 | "SELECT DISTINCT filename.name FROM mlink, filename" |
| 970 | - " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')" | |
| 970 | + " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)" | |
| 971 | 971 | " AND filename.fnid=mlink.fnid", |
| 972 | 972 | zUuid |
| 973 | 973 | ); |
| 974 | 974 | blob_zero(&out); |
| 975 | 975 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1129,13 +1129,15 @@ | ||
| 1129 | 1129 | if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){ |
| 1130 | 1130 | tmFlags |= TIMELINE_FCHANGES; |
| 1131 | 1131 | url_add_parameter(&url, "v", 0); |
| 1132 | 1132 | } |
| 1133 | 1133 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1134 | - blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref" | |
| 1135 | - " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", | |
| 1136 | - TAG_HIDDEN); | |
| 1134 | + blob_append_sql(&sql, | |
| 1135 | + " AND NOT EXISTS(SELECT 1 FROM tagxref" | |
| 1136 | + " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", | |
| 1137 | + TAG_HIDDEN | |
| 1138 | + ); | |
| 1137 | 1139 | } |
| 1138 | 1140 | if( !useDividers ) url_add_parameter(&url, "nd", 0); |
| 1139 | 1141 | if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){ |
| 1140 | 1142 | /* If from= and to= are present, display all nodes on a path connecting |
| 1141 | 1143 | ** the two */ |
| @@ -1154,21 +1156,21 @@ | ||
| 1154 | 1156 | zFrom = P("me"); |
| 1155 | 1157 | zTo = P("you"); |
| 1156 | 1158 | } |
| 1157 | 1159 | blob_append(&sql, " AND event.objid IN (0", -1); |
| 1158 | 1160 | while( p ){ |
| 1159 | - blob_appendf(&sql, ",%d", p->rid); | |
| 1161 | + blob_append_sql(&sql, ",%d", p->rid); | |
| 1160 | 1162 | p = p->u.pTo; |
| 1161 | 1163 | } |
| 1162 | 1164 | blob_append(&sql, ")", -1); |
| 1163 | 1165 | path_reset(); |
| 1164 | 1166 | blob_append(&desc, "All nodes on the path from ", -1); |
| 1165 | 1167 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom); |
| 1166 | 1168 | blob_append(&desc, " to ", -1); |
| 1167 | 1169 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo); |
| 1168 | 1170 | tmFlags |= TIMELINE_DISJOINT; |
| 1169 | - db_multi_exec("%s", blob_str(&sql)); | |
| 1171 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 1170 | 1172 | }else if( (p_rid || d_rid) && g.perm.Read ){ |
| 1171 | 1173 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 1172 | 1174 | char *zUuid; |
| 1173 | 1175 | int np, nd; |
| 1174 | 1176 | |
| @@ -1179,16 +1181,16 @@ | ||
| 1179 | 1181 | db_multi_exec( |
| 1180 | 1182 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 1181 | 1183 | ); |
| 1182 | 1184 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", |
| 1183 | 1185 | p_rid ? p_rid : d_rid); |
| 1184 | - blob_appendf(&sql, " AND event.objid IN ok"); | |
| 1186 | + blob_append_sql(&sql, " AND event.objid IN ok"); | |
| 1185 | 1187 | nd = 0; |
| 1186 | 1188 | if( d_rid ){ |
| 1187 | 1189 | compute_descendants(d_rid, nEntry+1); |
| 1188 | 1190 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1189 | - if( nd>=0 ) db_multi_exec("%s", blob_str(&sql)); | |
| 1191 | + if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql)); | |
| 1190 | 1192 | if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 1191 | 1193 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 1192 | 1194 | db_multi_exec("DELETE FROM ok"); |
| 1193 | 1195 | } |
| 1194 | 1196 | if( p_rid ){ |
| @@ -1195,11 +1197,11 @@ | ||
| 1195 | 1197 | compute_ancestors(p_rid, nEntry+1, 0); |
| 1196 | 1198 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1197 | 1199 | if( np>0 ){ |
| 1198 | 1200 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 1199 | 1201 | blob_appendf(&desc, "%d ancestors", np); |
| 1200 | - db_multi_exec("%s", blob_str(&sql)); | |
| 1202 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 1201 | 1203 | } |
| 1202 | 1204 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1203 | 1205 | } |
| 1204 | 1206 | blob_appendf(&desc, " of %z[%S]</a>", |
| 1205 | 1207 | href("%R/info/%s", zUuid), zUuid); |
| @@ -1235,12 +1237,12 @@ | ||
| 1235 | 1237 | "INSERT INTO ok VALUES(%d);" |
| 1236 | 1238 | "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;" |
| 1237 | 1239 | "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;", |
| 1238 | 1240 | f_rid, f_rid, f_rid |
| 1239 | 1241 | ); |
| 1240 | - blob_appendf(&sql, " AND event.objid IN ok"); | |
| 1241 | - db_multi_exec("%s", blob_str(&sql)); | |
| 1242 | + blob_append_sql(&sql, " AND event.objid IN ok"); | |
| 1243 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 1242 | 1244 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1243 | 1245 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1244 | 1246 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1245 | 1247 | blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid); |
| 1246 | 1248 | tmFlags |= TIMELINE_DISJOINT; |
| @@ -1257,25 +1259,25 @@ | ||
| 1257 | 1259 | /* Otherwise, a timeline based on a span of time */ |
| 1258 | 1260 | int n; |
| 1259 | 1261 | const char *zEType = "timeline item"; |
| 1260 | 1262 | char *zDate; |
| 1261 | 1263 | if( zUses ){ |
| 1262 | - blob_appendf(&sql, " AND event.objid IN usesfile "); | |
| 1264 | + blob_append_sql(&sql, " AND event.objid IN usesfile "); | |
| 1263 | 1265 | } |
| 1264 | 1266 | if( renameOnly ){ |
| 1265 | - blob_appendf(&sql, " AND event.objid IN rnfile "); | |
| 1267 | + blob_append_sql(&sql, " AND event.objid IN rnfile "); | |
| 1266 | 1268 | } |
| 1267 | 1269 | if( zYearMonth ){ |
| 1268 | - blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1270 | + blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1269 | 1271 | zYearMonth); |
| 1270 | 1272 | } |
| 1271 | 1273 | else if( zYearWeek ){ |
| 1272 | - blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1274 | + blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1273 | 1275 | zYearWeek); |
| 1274 | 1276 | } |
| 1275 | 1277 | if( tagid>0 ){ |
| 1276 | - blob_appendf(&sql, | |
| 1278 | + blob_append_sql(&sql, | |
| 1277 | 1279 | "AND (EXISTS(SELECT 1 FROM tagxref" |
| 1278 | 1280 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid); |
| 1279 | 1281 | |
| 1280 | 1282 | if( zBrName ){ |
| 1281 | 1283 | url_add_parameter(&url, "r", zBrName); |
| @@ -1283,40 +1285,42 @@ | ||
| 1283 | 1285 | ** are not part of the branch which are parents or children of the |
| 1284 | 1286 | ** branch to be included in the report. This related check-ins are |
| 1285 | 1287 | ** useful in helping to visualize what has happened on a quiescent |
| 1286 | 1288 | ** branch that is infrequently merged with a much more activate branch. |
| 1287 | 1289 | */ |
| 1288 | - blob_appendf(&sql, | |
| 1290 | + blob_append_sql(&sql, | |
| 1289 | 1291 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1290 | 1292 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)", |
| 1291 | 1293 | tagid |
| 1292 | 1294 | ); |
| 1293 | 1295 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1294 | - blob_appendf(&sql, | |
| 1296 | + blob_append_sql(&sql, | |
| 1295 | 1297 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1296 | 1298 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)", |
| 1297 | 1299 | TAG_HIDDEN |
| 1298 | 1300 | ); |
| 1299 | 1301 | } |
| 1300 | 1302 | if( P("mionly")==0 ){ |
| 1301 | - blob_appendf(&sql, | |
| 1303 | + blob_append_sql(&sql, | |
| 1302 | 1304 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1303 | 1305 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", |
| 1304 | 1306 | tagid |
| 1305 | 1307 | ); |
| 1306 | 1308 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1307 | - blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" | |
| 1308 | - " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", | |
| 1309 | - TAG_HIDDEN); | |
| 1309 | + blob_append_sql(&sql, | |
| 1310 | + " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" | |
| 1311 | + " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", | |
| 1312 | + TAG_HIDDEN | |
| 1313 | + ); | |
| 1310 | 1314 | } |
| 1311 | 1315 | }else{ |
| 1312 | 1316 | url_add_parameter(&url, "mionly", "1"); |
| 1313 | 1317 | } |
| 1314 | 1318 | }else{ |
| 1315 | 1319 | url_add_parameter(&url, "t", zTagName); |
| 1316 | 1320 | } |
| 1317 | - blob_appendf(&sql, ")"); | |
| 1321 | + blob_append_sql(&sql, ")"); | |
| 1318 | 1322 | } |
| 1319 | 1323 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1320 | 1324 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1321 | 1325 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1322 | 1326 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1325,27 +1329,27 @@ | ||
| 1325 | 1329 | zType = "all"; |
| 1326 | 1330 | } |
| 1327 | 1331 | if( zType[0]=='a' ){ |
| 1328 | 1332 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1329 | 1333 | char cSep = '('; |
| 1330 | - blob_appendf(&sql, " AND event.type IN "); | |
| 1334 | + blob_append_sql(&sql, " AND event.type IN "); | |
| 1331 | 1335 | if( g.perm.Read ){ |
| 1332 | - blob_appendf(&sql, "%c'ci','g'", cSep); | |
| 1336 | + blob_append_sql(&sql, "%c'ci','g'", cSep); | |
| 1333 | 1337 | cSep = ','; |
| 1334 | 1338 | } |
| 1335 | 1339 | if( g.perm.RdWiki ){ |
| 1336 | - blob_appendf(&sql, "%c'w','e'", cSep); | |
| 1340 | + blob_append_sql(&sql, "%c'w','e'", cSep); | |
| 1337 | 1341 | cSep = ','; |
| 1338 | 1342 | } |
| 1339 | 1343 | if( g.perm.RdTkt ){ |
| 1340 | - blob_appendf(&sql, "%c't'", cSep); | |
| 1344 | + blob_append_sql(&sql, "%c't'", cSep); | |
| 1341 | 1345 | cSep = ','; |
| 1342 | 1346 | } |
| 1343 | - blob_appendf(&sql, ")"); | |
| 1347 | + blob_append_sql(&sql, ")"); | |
| 1344 | 1348 | } |
| 1345 | 1349 | }else{ /* zType!="all" */ |
| 1346 | - blob_appendf(&sql, " AND event.type=%Q", zType); | |
| 1350 | + blob_append_sql(&sql, " AND event.type=%Q", zType); | |
| 1347 | 1351 | url_add_parameter(&url, "y", zType); |
| 1348 | 1352 | if( zType[0]=='c' ){ |
| 1349 | 1353 | zEType = "checkin"; |
| 1350 | 1354 | }else if( zType[0]=='w' ){ |
| 1351 | 1355 | zEType = "wiki edit"; |
| @@ -1356,64 +1360,64 @@ | ||
| 1356 | 1360 | }else if( zType[0]=='g' ){ |
| 1357 | 1361 | zEType = "tag"; |
| 1358 | 1362 | } |
| 1359 | 1363 | } |
| 1360 | 1364 | if( zUser ){ |
| 1361 | - blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1365 | + blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1362 | 1366 | zUser, zUser); |
| 1363 | 1367 | url_add_parameter(&url, "u", zUser); |
| 1364 | 1368 | zThisUser = zUser; |
| 1365 | 1369 | } |
| 1366 | 1370 | if( zSearch ){ |
| 1367 | - blob_appendf(&sql, | |
| 1371 | + blob_append_sql(&sql, | |
| 1368 | 1372 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1369 | 1373 | zSearch, zSearch); |
| 1370 | 1374 | url_add_parameter(&url, "s", zSearch); |
| 1371 | 1375 | } |
| 1372 | 1376 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1373 | 1377 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1374 | 1378 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1375 | 1379 | if( rAfter>0.0 ){ |
| 1376 | 1380 | if( rBefore>0.0 ){ |
| 1377 | - blob_appendf(&sql, | |
| 1381 | + blob_append_sql(&sql, | |
| 1378 | 1382 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1379 | 1383 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| 1380 | 1384 | url_add_parameter(&url, "a", zAfter); |
| 1381 | 1385 | url_add_parameter(&url, "b", zBefore); |
| 1382 | 1386 | nEntry = 1000000; |
| 1383 | 1387 | }else{ |
| 1384 | - blob_appendf(&sql, | |
| 1388 | + blob_append_sql(&sql, | |
| 1385 | 1389 | " AND event.mtime>=%.17g ORDER BY event.mtime ASC", |
| 1386 | 1390 | rAfter-ONE_SECOND); |
| 1387 | 1391 | url_add_parameter(&url, "a", zAfter); |
| 1388 | 1392 | } |
| 1389 | 1393 | }else if( rBefore>0.0 ){ |
| 1390 | - blob_appendf(&sql, | |
| 1394 | + blob_append_sql(&sql, | |
| 1391 | 1395 | " AND event.mtime<=%.17g ORDER BY event.mtime DESC", |
| 1392 | 1396 | rBefore+ONE_SECOND); |
| 1393 | 1397 | url_add_parameter(&url, "b", zBefore); |
| 1394 | 1398 | }else if( rCirca>0.0 ){ |
| 1395 | 1399 | Blob sql2; |
| 1396 | - blob_init(&sql2, blob_str(&sql), -1); | |
| 1397 | - blob_appendf(&sql2, | |
| 1400 | + blob_init(&sql2, blob_sql_text(&sql), -1); | |
| 1401 | + blob_append_sql(&sql2, | |
| 1398 | 1402 | " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d", |
| 1399 | 1403 | rCirca, (nEntry+1)/2 |
| 1400 | 1404 | ); |
| 1401 | - db_multi_exec("%s", blob_str(&sql2)); | |
| 1405 | + db_multi_exec("%s", blob_sql_text(&sql2)); | |
| 1402 | 1406 | blob_reset(&sql2); |
| 1403 | - blob_appendf(&sql, | |
| 1407 | + blob_append_sql(&sql, | |
| 1404 | 1408 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 1405 | 1409 | rCirca |
| 1406 | 1410 | ); |
| 1407 | 1411 | nEntry -= (nEntry+1)/2; |
| 1408 | 1412 | if( useDividers ) timeline_add_dividers(rCirca, 0); |
| 1409 | 1413 | url_add_parameter(&url, "c", zCirca); |
| 1410 | 1414 | }else{ |
| 1411 | - blob_appendf(&sql, " ORDER BY event.mtime DESC"); | |
| 1415 | + blob_append_sql(&sql, " ORDER BY event.mtime DESC"); | |
| 1412 | 1416 | } |
| 1413 | - blob_appendf(&sql, " LIMIT %d", nEntry); | |
| 1414 | - db_multi_exec("%s", blob_str(&sql)); | |
| 1417 | + blob_append_sql(&sql, " LIMIT %d", nEntry); | |
| 1418 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 1415 | 1419 | |
| 1416 | 1420 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1417 | 1421 | if( zYearMonth ){ |
| 1418 | 1422 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1419 | 1423 | }else if( zYearWeek ){ |
| @@ -1506,11 +1510,11 @@ | ||
| 1506 | 1510 | } |
| 1507 | 1511 | } |
| 1508 | 1512 | } |
| 1509 | 1513 | } |
| 1510 | 1514 | if( P("showsql") ){ |
| 1511 | - @ <blockquote>%h(blob_str(&sql))</blockquote> | |
| 1515 | + @ <blockquote>%h(blob_sql_text(&sql))</blockquote> | |
| 1512 | 1516 | } |
| 1513 | 1517 | blob_zero(&sql); |
| 1514 | 1518 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1515 | 1519 | @ <h2>%b(&desc)</h2> |
| 1516 | 1520 | blob_reset(&desc); |
| @@ -1655,11 +1659,10 @@ | ||
| 1655 | 1659 | /* |
| 1656 | 1660 | ** Return a pointer to a static string that forms the basis for |
| 1657 | 1661 | ** a timeline query for display on a TTY. |
| 1658 | 1662 | */ |
| 1659 | 1663 | const char *timeline_query_for_tty(void){ |
| 1660 | - static const char *zBase = 0; | |
| 1661 | 1664 | static const char zBaseSql[] = |
| 1662 | 1665 | @ SELECT |
| 1663 | 1666 | @ blob.rid AS rid, |
| 1664 | 1667 | @ uuid, |
| 1665 | 1668 | @ datetime(event.mtime%s) AS mDateTime, |
| @@ -1675,20 +1678,17 @@ | ||
| 1675 | 1678 | @ AS primPlinkCount, |
| 1676 | 1679 | @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount, |
| 1677 | 1680 | @ event.mtime AS mtime, |
| 1678 | 1681 | @ tagxref.value AS branch |
| 1679 | 1682 | @ FROM tag CROSS JOIN event CROSS JOIN blob |
| 1680 | - @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid | |
| 1683 | + @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid | |
| 1681 | 1684 | @ AND tagxref.tagtype>0 |
| 1682 | 1685 | @ AND tagxref.rid=blob.rid |
| 1683 | 1686 | @ WHERE blob.rid=event.objid |
| 1684 | 1687 | @ AND tag.tagname='branch' |
| 1685 | 1688 | ; |
| 1686 | - if( zBase==0 ){ | |
| 1687 | - zBase = mprintf(zBaseSql, timeline_utc()); | |
| 1688 | - } | |
| 1689 | - return zBase; | |
| 1689 | + return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc()); | |
| 1690 | 1690 | } |
| 1691 | 1691 | |
| 1692 | 1692 | /* |
| 1693 | 1693 | ** Return true if the input string is a date in the ISO 8601 format: |
| 1694 | 1694 | ** YYYY-MM-DD. |
| @@ -1702,11 +1702,11 @@ | ||
| 1702 | 1702 | } |
| 1703 | 1703 | |
| 1704 | 1704 | /* |
| 1705 | 1705 | ** COMMAND: timeline |
| 1706 | 1706 | ** |
| 1707 | -** Usage: %fossil timeline ?WHEN? ?BASELINE|DATETIME? ?OPTIONS? | |
| 1707 | +** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS? | |
| 1708 | 1708 | ** |
| 1709 | 1709 | ** Print a summary of activity going backwards in date and time |
| 1710 | 1710 | ** specified or from the current date and time if no arguments |
| 1711 | 1711 | ** are given. The WHEN argument can be any unique abbreviation |
| 1712 | 1712 | ** of one of these keywords: |
| @@ -1722,10 +1722,12 @@ | ||
| 1722 | 1722 | ** for the current version or "now" for the current time. |
| 1723 | 1723 | ** |
| 1724 | 1724 | ** Options: |
| 1725 | 1725 | ** -n|--limit N Output the first N entries (default 20 lines). |
| 1726 | 1726 | ** N=0 means no limit. |
| 1727 | +** -p|--path PATH Output items affecting PATH only. | |
| 1728 | +** PATH can be a file or a sub directory. | |
| 1727 | 1729 | ** --offset P skip P changes |
| 1728 | 1730 | ** -t|--type TYPE Output items from the given types only, such as: |
| 1729 | 1731 | ** ci = file commits only |
| 1730 | 1732 | ** e = events only |
| 1731 | 1733 | ** t = tickets only |
| @@ -1752,19 +1754,23 @@ | ||
| 1752 | 1754 | int objid = 0; |
| 1753 | 1755 | Blob uuid; |
| 1754 | 1756 | int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */ |
| 1755 | 1757 | int verboseFlag = 0 ; |
| 1756 | 1758 | int iOffset; |
| 1759 | + const char *zFilePattern = 0; | |
| 1760 | + Blob treeName; | |
| 1757 | 1761 | |
| 1758 | 1762 | verboseFlag = find_option("verbose","v", 0)!=0; |
| 1759 | 1763 | if( !verboseFlag){ |
| 1760 | 1764 | verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */ |
| 1761 | 1765 | } |
| 1762 | 1766 | db_find_and_open_repository(0, 0); |
| 1763 | 1767 | zLimit = find_option("limit","n",1); |
| 1764 | 1768 | zWidth = find_option("width","W",1); |
| 1765 | 1769 | zType = find_option("type","t",1); |
| 1770 | + zFilePattern = find_option("path","p",1); | |
| 1771 | + | |
| 1766 | 1772 | if( !zLimit ){ |
| 1767 | 1773 | zLimit = find_option("count",0,1); |
| 1768 | 1774 | } |
| 1769 | 1775 | if( zLimit ){ |
| 1770 | 1776 | n = atoi(zLimit); |
| @@ -1798,12 +1804,12 @@ | ||
| 1798 | 1804 | }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){ |
| 1799 | 1805 | mode = 4; |
| 1800 | 1806 | }else if( strncmp(g.argv[2],"parents",k)==0 ){ |
| 1801 | 1807 | mode = 4; |
| 1802 | 1808 | }else if(!zType && !zLimit){ |
| 1803 | - usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? " | |
| 1804 | - "?-W|--width WIDTH?"); | |
| 1809 | + usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? " | |
| 1810 | + "?-W|--width WIDTH? ?-p|--path PATH"); | |
| 1805 | 1811 | } |
| 1806 | 1812 | if( '-' != *g.argv[3] ){ |
| 1807 | 1813 | zOrigin = g.argv[3]; |
| 1808 | 1814 | }else{ |
| 1809 | 1815 | zOrigin = "now"; |
| @@ -1838,37 +1844,72 @@ | ||
| 1838 | 1844 | if( mode==0 ){ |
| 1839 | 1845 | if( isIsoDate(zOrigin) ) zShift = ",'+1 day'"; |
| 1840 | 1846 | } |
| 1841 | 1847 | zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift); |
| 1842 | 1848 | } |
| 1849 | + | |
| 1850 | + if( zFilePattern ){ | |
| 1851 | + if( zType==0 ){ | |
| 1852 | + /* When zFilePattern is specified and type is not specified, only show | |
| 1853 | + * file checkins */ | |
| 1854 | + zType="ci"; | |
| 1855 | + } | |
| 1856 | + file_tree_name(zFilePattern, &treeName, 1); | |
| 1857 | + if( fossil_strcmp(blob_str(&treeName), ".")==0 ){ | |
| 1858 | + /* When zTreeName refers to g.zLocalRoot, it's like not specifying | |
| 1859 | + * zFilePattern. */ | |
| 1860 | + zFilePattern = 0; | |
| 1861 | + } | |
| 1862 | + } | |
| 1863 | + | |
| 1843 | 1864 | if( mode==0 ) mode = 1; |
| 1844 | 1865 | blob_zero(&sql); |
| 1845 | 1866 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 1846 | - blob_appendf(&sql, " AND event.mtime %s %s", | |
| 1867 | + blob_append_sql(&sql, " AND event.mtime %s %s", | |
| 1847 | 1868 | (mode==1 || mode==4) ? "<=" : ">=", |
| 1848 | - zDate | |
| 1869 | + zDate /*safe-for-%s*/ | |
| 1849 | 1870 | ); |
| 1850 | 1871 | |
| 1851 | 1872 | if( mode==3 || mode==4 ){ |
| 1852 | 1873 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 1853 | 1874 | if( mode==3 ){ |
| 1854 | 1875 | compute_descendants(objid, n); |
| 1855 | 1876 | }else{ |
| 1856 | 1877 | compute_ancestors(objid, n, 0); |
| 1857 | 1878 | } |
| 1858 | - blob_appendf(&sql, " AND blob.rid IN ok"); | |
| 1879 | + blob_append_sql(&sql, "\n AND blob.rid IN ok"); | |
| 1859 | 1880 | } |
| 1860 | 1881 | if( zType && (zType[0]!='a') ){ |
| 1861 | - blob_appendf(&sql, " AND event.type=%Q ", zType); | |
| 1882 | + blob_append_sql(&sql, "\n AND event.type=%Q ", zType); | |
| 1883 | + } | |
| 1884 | + if( zFilePattern ){ | |
| 1885 | + blob_append(&sql, | |
| 1886 | + "\n AND EXISTS(SELECT 1 FROM mlink\n" | |
| 1887 | + " WHERE mlink.mid=event.objid\n" | |
| 1888 | + " AND mlink.fnid IN ", -1); | |
| 1889 | + if( filenames_are_case_sensitive() ){ | |
| 1890 | + blob_append_sql(&sql, | |
| 1891 | + "(SELECT fnid FROM filename" | |
| 1892 | + " WHERE name=%Q" | |
| 1893 | + " OR name GLOB '%q/*')", | |
| 1894 | + blob_str(&treeName), blob_str(&treeName)); | |
| 1895 | + }else{ | |
| 1896 | + blob_append_sql(&sql, | |
| 1897 | + "(SELECT fnid FROM filename" | |
| 1898 | + " WHERE name=%Q COLLATE nocase" | |
| 1899 | + " OR lower(name) GLOB lower('%q/*'))", | |
| 1900 | + blob_str(&treeName), blob_str(&treeName)); | |
| 1901 | + } | |
| 1902 | + blob_append(&sql, ")", -1); | |
| 1862 | 1903 | } |
| 1863 | - blob_appendf(&sql, " ORDER BY event.mtime DESC"); | |
| 1904 | + blob_append_sql(&sql, "\nORDER BY event.mtime DESC"); | |
| 1864 | 1905 | if( iOffset>0 ){ |
| 1865 | 1906 | /* Don't handle LIMIT here, otherwise print_timeline() |
| 1866 | 1907 | * will not determine the end-marker correctly! */ |
| 1867 | - blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset); | |
| 1908 | + blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset); | |
| 1868 | 1909 | } |
| 1869 | - db_prepare(&q, blob_str(&sql)); | |
| 1910 | + db_prepare(&q, "%s", blob_sql_text(&sql)); | |
| 1870 | 1911 | blob_reset(&sql); |
| 1871 | 1912 | print_timeline(&q, n, width, verboseFlag); |
| 1872 | 1913 | db_finalize(&q); |
| 1873 | 1914 | } |
| 1874 | 1915 | |
| @@ -2178,24 +2219,24 @@ | ||
| 2178 | 2219 | stats_report_init_view(); |
| 2179 | 2220 | stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL ); |
| 2180 | 2221 | blob_appendf(&header, "Timeline Events (%s) by year%s", |
| 2181 | 2222 | stats_report_label_for_type(), |
| 2182 | 2223 | (includeMonth ? "/month" : "")); |
| 2183 | - blob_appendf(&sql, | |
| 2224 | + blob_append_sql(&sql, | |
| 2184 | 2225 | "SELECT substr(date(mtime),1,%d) AS timeframe, " |
| 2185 | 2226 | "count(*) AS eventCount " |
| 2186 | 2227 | "FROM v_reports ", |
| 2187 | 2228 | includeMonth ? 7 : 4); |
| 2188 | 2229 | if(zUserName&&*zUserName){ |
| 2189 | - blob_appendf(&sql, " WHERE user=%Q ", zUserName); | |
| 2230 | + blob_append_sql(&sql, " WHERE user=%Q ", zUserName); | |
| 2190 | 2231 | blob_appendf(&header," for user %q", zUserName); |
| 2191 | 2232 | } |
| 2192 | 2233 | blob_append(&sql, |
| 2193 | 2234 | " GROUP BY timeframe" |
| 2194 | 2235 | " ORDER BY timeframe DESC", |
| 2195 | 2236 | -1); |
| 2196 | - db_prepare(&query, blob_str(&sql)); | |
| 2237 | + db_prepare(&query, "%s", blob_sql_text(&sql)); | |
| 2197 | 2238 | blob_reset(&sql); |
| 2198 | 2239 | @ <h1>%b(&header)</h1> |
| 2199 | 2240 | @ <table class='statistics-report-table-events' border='0' cellpadding='2' |
| 2200 | 2241 | @ cellspacing='0' id='statsTable'> |
| 2201 | 2242 | @ <thead> |
| @@ -2321,23 +2362,19 @@ | ||
| 2321 | 2362 | Stmt query = empty_Stmt; |
| 2322 | 2363 | int nRowNumber = 0; /* current TR number */ |
| 2323 | 2364 | int nEventTotal = 0; /* Total event count */ |
| 2324 | 2365 | int rowClass = 0; /* counter for alternating |
| 2325 | 2366 | row colors */ |
| 2326 | - Blob sql = empty_blob; /* SQL */ | |
| 2327 | 2367 | int nMaxEvents = 1; /* max number of events for |
| 2328 | 2368 | all rows. */ |
| 2329 | 2369 | stats_report_init_view(); |
| 2330 | 2370 | stats_report_event_types_menu("byuser", NULL); |
| 2331 | - blob_append(&sql, | |
| 2371 | + db_prepare(&query, | |
| 2332 | 2372 | "SELECT user, " |
| 2333 | 2373 | "COUNT(*) AS eventCount " |
| 2334 | 2374 | "FROM v_reports " |
| 2335 | - "GROUP BY user ORDER BY eventCount DESC", | |
| 2336 | - -1); | |
| 2337 | - db_prepare(&query, blob_str(&sql)); | |
| 2338 | - blob_reset(&sql); | |
| 2375 | + "GROUP BY user ORDER BY eventCount DESC"); | |
| 2339 | 2376 | @ <h1>Timeline Events |
| 2340 | 2377 | @ (%s(stats_report_label_for_type())) by User</h1> |
| 2341 | 2378 | @ <table class='statistics-report-table-events' border='0' |
| 2342 | 2379 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2343 | 2380 | @ <thead><tr> |
| @@ -2388,28 +2425,24 @@ | ||
| 2388 | 2425 | Stmt query = empty_Stmt; |
| 2389 | 2426 | int nRowNumber = 0; /* current TR number */ |
| 2390 | 2427 | int nEventTotal = 0; /* Total event count */ |
| 2391 | 2428 | int rowClass = 0; /* counter for alternating |
| 2392 | 2429 | row colors */ |
| 2393 | - Blob sql = empty_blob; /* SQL */ | |
| 2394 | 2430 | int nMaxEvents = 1; /* max number of events for |
| 2395 | 2431 | all rows. */ |
| 2396 | 2432 | static const char *const daysOfWeek[] = { |
| 2397 | 2433 | "Monday", "Tuesday", "Wednesday", "Thursday", |
| 2398 | 2434 | "Friday", "Saturday", "Sunday" |
| 2399 | 2435 | }; |
| 2400 | 2436 | |
| 2401 | 2437 | stats_report_init_view(); |
| 2402 | 2438 | stats_report_event_types_menu("byweekday", NULL); |
| 2403 | - blob_append(&sql, | |
| 2439 | + db_prepare(&query, | |
| 2404 | 2440 | "SELECT cast(mtime %% 7 AS INTEGER) dow, " |
| 2405 | 2441 | "COUNT(*) AS eventCount " |
| 2406 | 2442 | "FROM v_reports " |
| 2407 | - "GROUP BY dow ORDER BY dow", | |
| 2408 | - -1); | |
| 2409 | - db_prepare(&query, blob_str(&sql)); | |
| 2410 | - blob_reset(&sql); | |
| 2443 | + "GROUP BY dow ORDER BY dow"); | |
| 2411 | 2444 | @ <h1>Timeline Events |
| 2412 | 2445 | @ (%s(stats_report_label_for_type())) by Day of the Week</h1> |
| 2413 | 2446 | @ <table class='statistics-report-table-events' border='0' |
| 2414 | 2447 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2415 | 2448 | @ <thead><tr> |
| @@ -2477,14 +2510,14 @@ | ||
| 2477 | 2510 | } |
| 2478 | 2511 | blob_append(&sql, |
| 2479 | 2512 | "SELECT DISTINCT substr(date(mtime),1,4) AS y " |
| 2480 | 2513 | "FROM v_reports WHERE 1 ", -1); |
| 2481 | 2514 | if(zUserName&&*zUserName){ |
| 2482 | - blob_appendf(&sql,"AND user=%Q ", zUserName); | |
| 2515 | + blob_append_sql(&sql,"AND user=%Q ", zUserName); | |
| 2483 | 2516 | } |
| 2484 | 2517 | blob_append(&sql,"GROUP BY y ORDER BY y", -1); |
| 2485 | - db_prepare(&qYears, blob_str(&sql)); | |
| 2518 | + db_prepare(&qYears, "%s", blob_sql_text(&sql)); | |
| 2486 | 2519 | blob_reset(&sql); |
| 2487 | 2520 | cgi_printf("Select year: "); |
| 2488 | 2521 | while( SQLITE_ROW == db_step(&qYears) ){ |
| 2489 | 2522 | const char *zT = db_column_text(&qYears, 0); |
| 2490 | 2523 | if( i++ ){ |
| @@ -2510,22 +2543,22 @@ | ||
| 2510 | 2543 | int total = 0; |
| 2511 | 2544 | Blob header = empty_blob; |
| 2512 | 2545 | blob_appendf(&header, "Timeline events (%s) for the calendar weeks " |
| 2513 | 2546 | "of %h", stats_report_label_for_type(), |
| 2514 | 2547 | zYear); |
| 2515 | - blob_appendf(&sql, | |
| 2548 | + blob_append_sql(&sql, | |
| 2516 | 2549 | "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, " |
| 2517 | 2550 | "count(*) AS n " |
| 2518 | 2551 | "FROM v_reports " |
| 2519 | 2552 | "WHERE %Q=substr(date(mtime),1,4) " |
| 2520 | 2553 | "AND mtime < current_timestamp ", |
| 2521 | 2554 | zYear); |
| 2522 | 2555 | if(zUserName&&*zUserName){ |
| 2523 | - blob_appendf(&sql, " AND user=%Q ", zUserName); | |
| 2556 | + blob_append_sql(&sql, " AND user=%Q ", zUserName); | |
| 2524 | 2557 | blob_appendf(&header," for user %h", zUserName); |
| 2525 | 2558 | } |
| 2526 | - blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC"); | |
| 2559 | + blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC"); | |
| 2527 | 2560 | cgi_printf("<h1>%h</h1>", blob_str(&header)); |
| 2528 | 2561 | blob_reset(&header); |
| 2529 | 2562 | cgi_printf("<table class='statistics-report-table-events' " |
| 2530 | 2563 | "border='0' cellpadding='2' width='100%%' " |
| 2531 | 2564 | "cellspacing='0' id='statsTable'>"); |
| @@ -2533,11 +2566,11 @@ | ||
| 2533 | 2566 | "<th>Week</th>" |
| 2534 | 2567 | "<th>Events</th>" |
| 2535 | 2568 | "<th width='90%%'><!-- relative commits graph --></th>" |
| 2536 | 2569 | "</tr></thead>" |
| 2537 | 2570 | "<tbody>"); |
| 2538 | - db_prepare(&stWeek, blob_str(&sql)); | |
| 2571 | + db_prepare(&stWeek, "%s", blob_sql_text(&sql)); | |
| 2539 | 2572 | blob_reset(&sql); |
| 2540 | 2573 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2541 | 2574 | const int nCount = db_column_int(&stWeek, 1); |
| 2542 | 2575 | if(nCount>nMaxEvents){ |
| 2543 | 2576 | nMaxEvents = nCount; |
| 2544 | 2577 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -393,14 +393,14 @@ | |
| 393 | }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){ |
| 394 | Blob truncated; |
| 395 | blob_zero(&truncated); |
| 396 | blob_append(&truncated, blob_buffer(&comment), mxWikiLen); |
| 397 | blob_append(&truncated, "...", 3); |
| 398 | @ <span class="timelineComment">%w(blob_str(&truncated))</span> |
| 399 | blob_reset(&truncated); |
| 400 | }else{ |
| 401 | @ <span class="timelineComment">%w(blob_str(&comment))</span> |
| 402 | } |
| 403 | blob_reset(&comment); |
| 404 | |
| 405 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 406 | ** with a hyperlink to another timeline for that user. |
| @@ -860,11 +860,11 @@ | |
| 860 | @ tagid INTEGER, |
| 861 | @ short TEXT, |
| 862 | @ sortby REAL |
| 863 | @ ) |
| 864 | ; |
| 865 | db_multi_exec(zSql); |
| 866 | } |
| 867 | |
| 868 | /* |
| 869 | ** Return a pointer to a constant string that forms the basis |
| 870 | ** for a timeline query for the WWW interface. |
| @@ -889,11 +889,11 @@ | |
| 889 | @ event.mtime AS mtime |
| 890 | @ FROM event CROSS JOIN blob |
| 891 | @ WHERE blob.rid=event.objid |
| 892 | ; |
| 893 | if( zBase==0 ){ |
| 894 | zBase = mprintf(zBaseSql, timeline_utc()); |
| 895 | } |
| 896 | return zBase; |
| 897 | } |
| 898 | |
| 899 | /* |
| @@ -965,11 +965,11 @@ | |
| 965 | Stmt q; |
| 966 | Blob out; |
| 967 | const char *zSep = ""; |
| 968 | db_prepare(&q, |
| 969 | "SELECT DISTINCT filename.name FROM mlink, filename" |
| 970 | " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')" |
| 971 | " AND filename.fnid=mlink.fnid", |
| 972 | zUuid |
| 973 | ); |
| 974 | blob_zero(&out); |
| 975 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1129,13 +1129,15 @@ | |
| 1129 | if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){ |
| 1130 | tmFlags |= TIMELINE_FCHANGES; |
| 1131 | url_add_parameter(&url, "v", 0); |
| 1132 | } |
| 1133 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1134 | blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref" |
| 1135 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", |
| 1136 | TAG_HIDDEN); |
| 1137 | } |
| 1138 | if( !useDividers ) url_add_parameter(&url, "nd", 0); |
| 1139 | if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){ |
| 1140 | /* If from= and to= are present, display all nodes on a path connecting |
| 1141 | ** the two */ |
| @@ -1154,21 +1156,21 @@ | |
| 1154 | zFrom = P("me"); |
| 1155 | zTo = P("you"); |
| 1156 | } |
| 1157 | blob_append(&sql, " AND event.objid IN (0", -1); |
| 1158 | while( p ){ |
| 1159 | blob_appendf(&sql, ",%d", p->rid); |
| 1160 | p = p->u.pTo; |
| 1161 | } |
| 1162 | blob_append(&sql, ")", -1); |
| 1163 | path_reset(); |
| 1164 | blob_append(&desc, "All nodes on the path from ", -1); |
| 1165 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom); |
| 1166 | blob_append(&desc, " to ", -1); |
| 1167 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo); |
| 1168 | tmFlags |= TIMELINE_DISJOINT; |
| 1169 | db_multi_exec("%s", blob_str(&sql)); |
| 1170 | }else if( (p_rid || d_rid) && g.perm.Read ){ |
| 1171 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 1172 | char *zUuid; |
| 1173 | int np, nd; |
| 1174 | |
| @@ -1179,16 +1181,16 @@ | |
| 1179 | db_multi_exec( |
| 1180 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 1181 | ); |
| 1182 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", |
| 1183 | p_rid ? p_rid : d_rid); |
| 1184 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1185 | nd = 0; |
| 1186 | if( d_rid ){ |
| 1187 | compute_descendants(d_rid, nEntry+1); |
| 1188 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1189 | if( nd>=0 ) db_multi_exec("%s", blob_str(&sql)); |
| 1190 | if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 1191 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 1192 | db_multi_exec("DELETE FROM ok"); |
| 1193 | } |
| 1194 | if( p_rid ){ |
| @@ -1195,11 +1197,11 @@ | |
| 1195 | compute_ancestors(p_rid, nEntry+1, 0); |
| 1196 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1197 | if( np>0 ){ |
| 1198 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 1199 | blob_appendf(&desc, "%d ancestors", np); |
| 1200 | db_multi_exec("%s", blob_str(&sql)); |
| 1201 | } |
| 1202 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1203 | } |
| 1204 | blob_appendf(&desc, " of %z[%S]</a>", |
| 1205 | href("%R/info/%s", zUuid), zUuid); |
| @@ -1235,12 +1237,12 @@ | |
| 1235 | "INSERT INTO ok VALUES(%d);" |
| 1236 | "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;" |
| 1237 | "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;", |
| 1238 | f_rid, f_rid, f_rid |
| 1239 | ); |
| 1240 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1241 | db_multi_exec("%s", blob_str(&sql)); |
| 1242 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1243 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1244 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1245 | blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid); |
| 1246 | tmFlags |= TIMELINE_DISJOINT; |
| @@ -1257,25 +1259,25 @@ | |
| 1257 | /* Otherwise, a timeline based on a span of time */ |
| 1258 | int n; |
| 1259 | const char *zEType = "timeline item"; |
| 1260 | char *zDate; |
| 1261 | if( zUses ){ |
| 1262 | blob_appendf(&sql, " AND event.objid IN usesfile "); |
| 1263 | } |
| 1264 | if( renameOnly ){ |
| 1265 | blob_appendf(&sql, " AND event.objid IN rnfile "); |
| 1266 | } |
| 1267 | if( zYearMonth ){ |
| 1268 | blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1269 | zYearMonth); |
| 1270 | } |
| 1271 | else if( zYearWeek ){ |
| 1272 | blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1273 | zYearWeek); |
| 1274 | } |
| 1275 | if( tagid>0 ){ |
| 1276 | blob_appendf(&sql, |
| 1277 | "AND (EXISTS(SELECT 1 FROM tagxref" |
| 1278 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid); |
| 1279 | |
| 1280 | if( zBrName ){ |
| 1281 | url_add_parameter(&url, "r", zBrName); |
| @@ -1283,40 +1285,42 @@ | |
| 1283 | ** are not part of the branch which are parents or children of the |
| 1284 | ** branch to be included in the report. This related check-ins are |
| 1285 | ** useful in helping to visualize what has happened on a quiescent |
| 1286 | ** branch that is infrequently merged with a much more activate branch. |
| 1287 | */ |
| 1288 | blob_appendf(&sql, |
| 1289 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1290 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)", |
| 1291 | tagid |
| 1292 | ); |
| 1293 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1294 | blob_appendf(&sql, |
| 1295 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1296 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)", |
| 1297 | TAG_HIDDEN |
| 1298 | ); |
| 1299 | } |
| 1300 | if( P("mionly")==0 ){ |
| 1301 | blob_appendf(&sql, |
| 1302 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1303 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", |
| 1304 | tagid |
| 1305 | ); |
| 1306 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1307 | blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1308 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", |
| 1309 | TAG_HIDDEN); |
| 1310 | } |
| 1311 | }else{ |
| 1312 | url_add_parameter(&url, "mionly", "1"); |
| 1313 | } |
| 1314 | }else{ |
| 1315 | url_add_parameter(&url, "t", zTagName); |
| 1316 | } |
| 1317 | blob_appendf(&sql, ")"); |
| 1318 | } |
| 1319 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1320 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1321 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1322 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1325,27 +1329,27 @@ | |
| 1325 | zType = "all"; |
| 1326 | } |
| 1327 | if( zType[0]=='a' ){ |
| 1328 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1329 | char cSep = '('; |
| 1330 | blob_appendf(&sql, " AND event.type IN "); |
| 1331 | if( g.perm.Read ){ |
| 1332 | blob_appendf(&sql, "%c'ci','g'", cSep); |
| 1333 | cSep = ','; |
| 1334 | } |
| 1335 | if( g.perm.RdWiki ){ |
| 1336 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1337 | cSep = ','; |
| 1338 | } |
| 1339 | if( g.perm.RdTkt ){ |
| 1340 | blob_appendf(&sql, "%c't'", cSep); |
| 1341 | cSep = ','; |
| 1342 | } |
| 1343 | blob_appendf(&sql, ")"); |
| 1344 | } |
| 1345 | }else{ /* zType!="all" */ |
| 1346 | blob_appendf(&sql, " AND event.type=%Q", zType); |
| 1347 | url_add_parameter(&url, "y", zType); |
| 1348 | if( zType[0]=='c' ){ |
| 1349 | zEType = "checkin"; |
| 1350 | }else if( zType[0]=='w' ){ |
| 1351 | zEType = "wiki edit"; |
| @@ -1356,64 +1360,64 @@ | |
| 1356 | }else if( zType[0]=='g' ){ |
| 1357 | zEType = "tag"; |
| 1358 | } |
| 1359 | } |
| 1360 | if( zUser ){ |
| 1361 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1362 | zUser, zUser); |
| 1363 | url_add_parameter(&url, "u", zUser); |
| 1364 | zThisUser = zUser; |
| 1365 | } |
| 1366 | if( zSearch ){ |
| 1367 | blob_appendf(&sql, |
| 1368 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1369 | zSearch, zSearch); |
| 1370 | url_add_parameter(&url, "s", zSearch); |
| 1371 | } |
| 1372 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1373 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1374 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1375 | if( rAfter>0.0 ){ |
| 1376 | if( rBefore>0.0 ){ |
| 1377 | blob_appendf(&sql, |
| 1378 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1379 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| 1380 | url_add_parameter(&url, "a", zAfter); |
| 1381 | url_add_parameter(&url, "b", zBefore); |
| 1382 | nEntry = 1000000; |
| 1383 | }else{ |
| 1384 | blob_appendf(&sql, |
| 1385 | " AND event.mtime>=%.17g ORDER BY event.mtime ASC", |
| 1386 | rAfter-ONE_SECOND); |
| 1387 | url_add_parameter(&url, "a", zAfter); |
| 1388 | } |
| 1389 | }else if( rBefore>0.0 ){ |
| 1390 | blob_appendf(&sql, |
| 1391 | " AND event.mtime<=%.17g ORDER BY event.mtime DESC", |
| 1392 | rBefore+ONE_SECOND); |
| 1393 | url_add_parameter(&url, "b", zBefore); |
| 1394 | }else if( rCirca>0.0 ){ |
| 1395 | Blob sql2; |
| 1396 | blob_init(&sql2, blob_str(&sql), -1); |
| 1397 | blob_appendf(&sql2, |
| 1398 | " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d", |
| 1399 | rCirca, (nEntry+1)/2 |
| 1400 | ); |
| 1401 | db_multi_exec("%s", blob_str(&sql2)); |
| 1402 | blob_reset(&sql2); |
| 1403 | blob_appendf(&sql, |
| 1404 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 1405 | rCirca |
| 1406 | ); |
| 1407 | nEntry -= (nEntry+1)/2; |
| 1408 | if( useDividers ) timeline_add_dividers(rCirca, 0); |
| 1409 | url_add_parameter(&url, "c", zCirca); |
| 1410 | }else{ |
| 1411 | blob_appendf(&sql, " ORDER BY event.mtime DESC"); |
| 1412 | } |
| 1413 | blob_appendf(&sql, " LIMIT %d", nEntry); |
| 1414 | db_multi_exec("%s", blob_str(&sql)); |
| 1415 | |
| 1416 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1417 | if( zYearMonth ){ |
| 1418 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1419 | }else if( zYearWeek ){ |
| @@ -1506,11 +1510,11 @@ | |
| 1506 | } |
| 1507 | } |
| 1508 | } |
| 1509 | } |
| 1510 | if( P("showsql") ){ |
| 1511 | @ <blockquote>%h(blob_str(&sql))</blockquote> |
| 1512 | } |
| 1513 | blob_zero(&sql); |
| 1514 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1515 | @ <h2>%b(&desc)</h2> |
| 1516 | blob_reset(&desc); |
| @@ -1655,11 +1659,10 @@ | |
| 1655 | /* |
| 1656 | ** Return a pointer to a static string that forms the basis for |
| 1657 | ** a timeline query for display on a TTY. |
| 1658 | */ |
| 1659 | const char *timeline_query_for_tty(void){ |
| 1660 | static const char *zBase = 0; |
| 1661 | static const char zBaseSql[] = |
| 1662 | @ SELECT |
| 1663 | @ blob.rid AS rid, |
| 1664 | @ uuid, |
| 1665 | @ datetime(event.mtime%s) AS mDateTime, |
| @@ -1675,20 +1678,17 @@ | |
| 1675 | @ AS primPlinkCount, |
| 1676 | @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount, |
| 1677 | @ event.mtime AS mtime, |
| 1678 | @ tagxref.value AS branch |
| 1679 | @ FROM tag CROSS JOIN event CROSS JOIN blob |
| 1680 | @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid |
| 1681 | @ AND tagxref.tagtype>0 |
| 1682 | @ AND tagxref.rid=blob.rid |
| 1683 | @ WHERE blob.rid=event.objid |
| 1684 | @ AND tag.tagname='branch' |
| 1685 | ; |
| 1686 | if( zBase==0 ){ |
| 1687 | zBase = mprintf(zBaseSql, timeline_utc()); |
| 1688 | } |
| 1689 | return zBase; |
| 1690 | } |
| 1691 | |
| 1692 | /* |
| 1693 | ** Return true if the input string is a date in the ISO 8601 format: |
| 1694 | ** YYYY-MM-DD. |
| @@ -1702,11 +1702,11 @@ | |
| 1702 | } |
| 1703 | |
| 1704 | /* |
| 1705 | ** COMMAND: timeline |
| 1706 | ** |
| 1707 | ** Usage: %fossil timeline ?WHEN? ?BASELINE|DATETIME? ?OPTIONS? |
| 1708 | ** |
| 1709 | ** Print a summary of activity going backwards in date and time |
| 1710 | ** specified or from the current date and time if no arguments |
| 1711 | ** are given. The WHEN argument can be any unique abbreviation |
| 1712 | ** of one of these keywords: |
| @@ -1722,10 +1722,12 @@ | |
| 1722 | ** for the current version or "now" for the current time. |
| 1723 | ** |
| 1724 | ** Options: |
| 1725 | ** -n|--limit N Output the first N entries (default 20 lines). |
| 1726 | ** N=0 means no limit. |
| 1727 | ** --offset P skip P changes |
| 1728 | ** -t|--type TYPE Output items from the given types only, such as: |
| 1729 | ** ci = file commits only |
| 1730 | ** e = events only |
| 1731 | ** t = tickets only |
| @@ -1752,19 +1754,23 @@ | |
| 1752 | int objid = 0; |
| 1753 | Blob uuid; |
| 1754 | int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */ |
| 1755 | int verboseFlag = 0 ; |
| 1756 | int iOffset; |
| 1757 | |
| 1758 | verboseFlag = find_option("verbose","v", 0)!=0; |
| 1759 | if( !verboseFlag){ |
| 1760 | verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */ |
| 1761 | } |
| 1762 | db_find_and_open_repository(0, 0); |
| 1763 | zLimit = find_option("limit","n",1); |
| 1764 | zWidth = find_option("width","W",1); |
| 1765 | zType = find_option("type","t",1); |
| 1766 | if( !zLimit ){ |
| 1767 | zLimit = find_option("count",0,1); |
| 1768 | } |
| 1769 | if( zLimit ){ |
| 1770 | n = atoi(zLimit); |
| @@ -1798,12 +1804,12 @@ | |
| 1798 | }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){ |
| 1799 | mode = 4; |
| 1800 | }else if( strncmp(g.argv[2],"parents",k)==0 ){ |
| 1801 | mode = 4; |
| 1802 | }else if(!zType && !zLimit){ |
| 1803 | usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? " |
| 1804 | "?-W|--width WIDTH?"); |
| 1805 | } |
| 1806 | if( '-' != *g.argv[3] ){ |
| 1807 | zOrigin = g.argv[3]; |
| 1808 | }else{ |
| 1809 | zOrigin = "now"; |
| @@ -1838,37 +1844,72 @@ | |
| 1838 | if( mode==0 ){ |
| 1839 | if( isIsoDate(zOrigin) ) zShift = ",'+1 day'"; |
| 1840 | } |
| 1841 | zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift); |
| 1842 | } |
| 1843 | if( mode==0 ) mode = 1; |
| 1844 | blob_zero(&sql); |
| 1845 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 1846 | blob_appendf(&sql, " AND event.mtime %s %s", |
| 1847 | (mode==1 || mode==4) ? "<=" : ">=", |
| 1848 | zDate |
| 1849 | ); |
| 1850 | |
| 1851 | if( mode==3 || mode==4 ){ |
| 1852 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 1853 | if( mode==3 ){ |
| 1854 | compute_descendants(objid, n); |
| 1855 | }else{ |
| 1856 | compute_ancestors(objid, n, 0); |
| 1857 | } |
| 1858 | blob_appendf(&sql, " AND blob.rid IN ok"); |
| 1859 | } |
| 1860 | if( zType && (zType[0]!='a') ){ |
| 1861 | blob_appendf(&sql, " AND event.type=%Q ", zType); |
| 1862 | } |
| 1863 | blob_appendf(&sql, " ORDER BY event.mtime DESC"); |
| 1864 | if( iOffset>0 ){ |
| 1865 | /* Don't handle LIMIT here, otherwise print_timeline() |
| 1866 | * will not determine the end-marker correctly! */ |
| 1867 | blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset); |
| 1868 | } |
| 1869 | db_prepare(&q, blob_str(&sql)); |
| 1870 | blob_reset(&sql); |
| 1871 | print_timeline(&q, n, width, verboseFlag); |
| 1872 | db_finalize(&q); |
| 1873 | } |
| 1874 | |
| @@ -2178,24 +2219,24 @@ | |
| 2178 | stats_report_init_view(); |
| 2179 | stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL ); |
| 2180 | blob_appendf(&header, "Timeline Events (%s) by year%s", |
| 2181 | stats_report_label_for_type(), |
| 2182 | (includeMonth ? "/month" : "")); |
| 2183 | blob_appendf(&sql, |
| 2184 | "SELECT substr(date(mtime),1,%d) AS timeframe, " |
| 2185 | "count(*) AS eventCount " |
| 2186 | "FROM v_reports ", |
| 2187 | includeMonth ? 7 : 4); |
| 2188 | if(zUserName&&*zUserName){ |
| 2189 | blob_appendf(&sql, " WHERE user=%Q ", zUserName); |
| 2190 | blob_appendf(&header," for user %q", zUserName); |
| 2191 | } |
| 2192 | blob_append(&sql, |
| 2193 | " GROUP BY timeframe" |
| 2194 | " ORDER BY timeframe DESC", |
| 2195 | -1); |
| 2196 | db_prepare(&query, blob_str(&sql)); |
| 2197 | blob_reset(&sql); |
| 2198 | @ <h1>%b(&header)</h1> |
| 2199 | @ <table class='statistics-report-table-events' border='0' cellpadding='2' |
| 2200 | @ cellspacing='0' id='statsTable'> |
| 2201 | @ <thead> |
| @@ -2321,23 +2362,19 @@ | |
| 2321 | Stmt query = empty_Stmt; |
| 2322 | int nRowNumber = 0; /* current TR number */ |
| 2323 | int nEventTotal = 0; /* Total event count */ |
| 2324 | int rowClass = 0; /* counter for alternating |
| 2325 | row colors */ |
| 2326 | Blob sql = empty_blob; /* SQL */ |
| 2327 | int nMaxEvents = 1; /* max number of events for |
| 2328 | all rows. */ |
| 2329 | stats_report_init_view(); |
| 2330 | stats_report_event_types_menu("byuser", NULL); |
| 2331 | blob_append(&sql, |
| 2332 | "SELECT user, " |
| 2333 | "COUNT(*) AS eventCount " |
| 2334 | "FROM v_reports " |
| 2335 | "GROUP BY user ORDER BY eventCount DESC", |
| 2336 | -1); |
| 2337 | db_prepare(&query, blob_str(&sql)); |
| 2338 | blob_reset(&sql); |
| 2339 | @ <h1>Timeline Events |
| 2340 | @ (%s(stats_report_label_for_type())) by User</h1> |
| 2341 | @ <table class='statistics-report-table-events' border='0' |
| 2342 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2343 | @ <thead><tr> |
| @@ -2388,28 +2425,24 @@ | |
| 2388 | Stmt query = empty_Stmt; |
| 2389 | int nRowNumber = 0; /* current TR number */ |
| 2390 | int nEventTotal = 0; /* Total event count */ |
| 2391 | int rowClass = 0; /* counter for alternating |
| 2392 | row colors */ |
| 2393 | Blob sql = empty_blob; /* SQL */ |
| 2394 | int nMaxEvents = 1; /* max number of events for |
| 2395 | all rows. */ |
| 2396 | static const char *const daysOfWeek[] = { |
| 2397 | "Monday", "Tuesday", "Wednesday", "Thursday", |
| 2398 | "Friday", "Saturday", "Sunday" |
| 2399 | }; |
| 2400 | |
| 2401 | stats_report_init_view(); |
| 2402 | stats_report_event_types_menu("byweekday", NULL); |
| 2403 | blob_append(&sql, |
| 2404 | "SELECT cast(mtime %% 7 AS INTEGER) dow, " |
| 2405 | "COUNT(*) AS eventCount " |
| 2406 | "FROM v_reports " |
| 2407 | "GROUP BY dow ORDER BY dow", |
| 2408 | -1); |
| 2409 | db_prepare(&query, blob_str(&sql)); |
| 2410 | blob_reset(&sql); |
| 2411 | @ <h1>Timeline Events |
| 2412 | @ (%s(stats_report_label_for_type())) by Day of the Week</h1> |
| 2413 | @ <table class='statistics-report-table-events' border='0' |
| 2414 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2415 | @ <thead><tr> |
| @@ -2477,14 +2510,14 @@ | |
| 2477 | } |
| 2478 | blob_append(&sql, |
| 2479 | "SELECT DISTINCT substr(date(mtime),1,4) AS y " |
| 2480 | "FROM v_reports WHERE 1 ", -1); |
| 2481 | if(zUserName&&*zUserName){ |
| 2482 | blob_appendf(&sql,"AND user=%Q ", zUserName); |
| 2483 | } |
| 2484 | blob_append(&sql,"GROUP BY y ORDER BY y", -1); |
| 2485 | db_prepare(&qYears, blob_str(&sql)); |
| 2486 | blob_reset(&sql); |
| 2487 | cgi_printf("Select year: "); |
| 2488 | while( SQLITE_ROW == db_step(&qYears) ){ |
| 2489 | const char *zT = db_column_text(&qYears, 0); |
| 2490 | if( i++ ){ |
| @@ -2510,22 +2543,22 @@ | |
| 2510 | int total = 0; |
| 2511 | Blob header = empty_blob; |
| 2512 | blob_appendf(&header, "Timeline events (%s) for the calendar weeks " |
| 2513 | "of %h", stats_report_label_for_type(), |
| 2514 | zYear); |
| 2515 | blob_appendf(&sql, |
| 2516 | "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, " |
| 2517 | "count(*) AS n " |
| 2518 | "FROM v_reports " |
| 2519 | "WHERE %Q=substr(date(mtime),1,4) " |
| 2520 | "AND mtime < current_timestamp ", |
| 2521 | zYear); |
| 2522 | if(zUserName&&*zUserName){ |
| 2523 | blob_appendf(&sql, " AND user=%Q ", zUserName); |
| 2524 | blob_appendf(&header," for user %h", zUserName); |
| 2525 | } |
| 2526 | blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC"); |
| 2527 | cgi_printf("<h1>%h</h1>", blob_str(&header)); |
| 2528 | blob_reset(&header); |
| 2529 | cgi_printf("<table class='statistics-report-table-events' " |
| 2530 | "border='0' cellpadding='2' width='100%%' " |
| 2531 | "cellspacing='0' id='statsTable'>"); |
| @@ -2533,11 +2566,11 @@ | |
| 2533 | "<th>Week</th>" |
| 2534 | "<th>Events</th>" |
| 2535 | "<th width='90%%'><!-- relative commits graph --></th>" |
| 2536 | "</tr></thead>" |
| 2537 | "<tbody>"); |
| 2538 | db_prepare(&stWeek, blob_str(&sql)); |
| 2539 | blob_reset(&sql); |
| 2540 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2541 | const int nCount = db_column_int(&stWeek, 1); |
| 2542 | if(nCount>nMaxEvents){ |
| 2543 | nMaxEvents = nCount; |
| 2544 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -393,14 +393,14 @@ | |
| 393 | }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){ |
| 394 | Blob truncated; |
| 395 | blob_zero(&truncated); |
| 396 | blob_append(&truncated, blob_buffer(&comment), mxWikiLen); |
| 397 | blob_append(&truncated, "...", 3); |
| 398 | @ <span class="timelineComment">%W(blob_str(&truncated))</span> |
| 399 | blob_reset(&truncated); |
| 400 | }else{ |
| 401 | @ <span class="timelineComment">%W(blob_str(&comment))</span> |
| 402 | } |
| 403 | blob_reset(&comment); |
| 404 | |
| 405 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 406 | ** with a hyperlink to another timeline for that user. |
| @@ -860,11 +860,11 @@ | |
| 860 | @ tagid INTEGER, |
| 861 | @ short TEXT, |
| 862 | @ sortby REAL |
| 863 | @ ) |
| 864 | ; |
| 865 | db_multi_exec("%s", zSql/*safe-for-%s*/); |
| 866 | } |
| 867 | |
| 868 | /* |
| 869 | ** Return a pointer to a constant string that forms the basis |
| 870 | ** for a timeline query for the WWW interface. |
| @@ -889,11 +889,11 @@ | |
| 889 | @ event.mtime AS mtime |
| 890 | @ FROM event CROSS JOIN blob |
| 891 | @ WHERE blob.rid=event.objid |
| 892 | ; |
| 893 | if( zBase==0 ){ |
| 894 | zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc()); |
| 895 | } |
| 896 | return zBase; |
| 897 | } |
| 898 | |
| 899 | /* |
| @@ -965,11 +965,11 @@ | |
| 965 | Stmt q; |
| 966 | Blob out; |
| 967 | const char *zSep = ""; |
| 968 | db_prepare(&q, |
| 969 | "SELECT DISTINCT filename.name FROM mlink, filename" |
| 970 | " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)" |
| 971 | " AND filename.fnid=mlink.fnid", |
| 972 | zUuid |
| 973 | ); |
| 974 | blob_zero(&out); |
| 975 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1129,13 +1129,15 @@ | |
| 1129 | if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){ |
| 1130 | tmFlags |= TIMELINE_FCHANGES; |
| 1131 | url_add_parameter(&url, "v", 0); |
| 1132 | } |
| 1133 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1134 | blob_append_sql(&sql, |
| 1135 | " AND NOT EXISTS(SELECT 1 FROM tagxref" |
| 1136 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", |
| 1137 | TAG_HIDDEN |
| 1138 | ); |
| 1139 | } |
| 1140 | if( !useDividers ) url_add_parameter(&url, "nd", 0); |
| 1141 | if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){ |
| 1142 | /* If from= and to= are present, display all nodes on a path connecting |
| 1143 | ** the two */ |
| @@ -1154,21 +1156,21 @@ | |
| 1156 | zFrom = P("me"); |
| 1157 | zTo = P("you"); |
| 1158 | } |
| 1159 | blob_append(&sql, " AND event.objid IN (0", -1); |
| 1160 | while( p ){ |
| 1161 | blob_append_sql(&sql, ",%d", p->rid); |
| 1162 | p = p->u.pTo; |
| 1163 | } |
| 1164 | blob_append(&sql, ")", -1); |
| 1165 | path_reset(); |
| 1166 | blob_append(&desc, "All nodes on the path from ", -1); |
| 1167 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom); |
| 1168 | blob_append(&desc, " to ", -1); |
| 1169 | blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo); |
| 1170 | tmFlags |= TIMELINE_DISJOINT; |
| 1171 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1172 | }else if( (p_rid || d_rid) && g.perm.Read ){ |
| 1173 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 1174 | char *zUuid; |
| 1175 | int np, nd; |
| 1176 | |
| @@ -1179,16 +1181,16 @@ | |
| 1181 | db_multi_exec( |
| 1182 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 1183 | ); |
| 1184 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", |
| 1185 | p_rid ? p_rid : d_rid); |
| 1186 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| 1187 | nd = 0; |
| 1188 | if( d_rid ){ |
| 1189 | compute_descendants(d_rid, nEntry+1); |
| 1190 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1191 | if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql)); |
| 1192 | if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 1193 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 1194 | db_multi_exec("DELETE FROM ok"); |
| 1195 | } |
| 1196 | if( p_rid ){ |
| @@ -1195,11 +1197,11 @@ | |
| 1197 | compute_ancestors(p_rid, nEntry+1, 0); |
| 1198 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1199 | if( np>0 ){ |
| 1200 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 1201 | blob_appendf(&desc, "%d ancestors", np); |
| 1202 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1203 | } |
| 1204 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 1205 | } |
| 1206 | blob_appendf(&desc, " of %z[%S]</a>", |
| 1207 | href("%R/info/%s", zUuid), zUuid); |
| @@ -1235,12 +1237,12 @@ | |
| 1237 | "INSERT INTO ok VALUES(%d);" |
| 1238 | "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;" |
| 1239 | "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;", |
| 1240 | f_rid, f_rid, f_rid |
| 1241 | ); |
| 1242 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| 1243 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1244 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 1245 | blob_appendf(&desc, "Parents and children of check-in "); |
| 1246 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 1247 | blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid); |
| 1248 | tmFlags |= TIMELINE_DISJOINT; |
| @@ -1257,25 +1259,25 @@ | |
| 1259 | /* Otherwise, a timeline based on a span of time */ |
| 1260 | int n; |
| 1261 | const char *zEType = "timeline item"; |
| 1262 | char *zDate; |
| 1263 | if( zUses ){ |
| 1264 | blob_append_sql(&sql, " AND event.objid IN usesfile "); |
| 1265 | } |
| 1266 | if( renameOnly ){ |
| 1267 | blob_append_sql(&sql, " AND event.objid IN rnfile "); |
| 1268 | } |
| 1269 | if( zYearMonth ){ |
| 1270 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1271 | zYearMonth); |
| 1272 | } |
| 1273 | else if( zYearWeek ){ |
| 1274 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1275 | zYearWeek); |
| 1276 | } |
| 1277 | if( tagid>0 ){ |
| 1278 | blob_append_sql(&sql, |
| 1279 | "AND (EXISTS(SELECT 1 FROM tagxref" |
| 1280 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid); |
| 1281 | |
| 1282 | if( zBrName ){ |
| 1283 | url_add_parameter(&url, "r", zBrName); |
| @@ -1283,40 +1285,42 @@ | |
| 1285 | ** are not part of the branch which are parents or children of the |
| 1286 | ** branch to be included in the report. This related check-ins are |
| 1287 | ** useful in helping to visualize what has happened on a quiescent |
| 1288 | ** branch that is infrequently merged with a much more activate branch. |
| 1289 | */ |
| 1290 | blob_append_sql(&sql, |
| 1291 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1292 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)", |
| 1293 | tagid |
| 1294 | ); |
| 1295 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1296 | blob_append_sql(&sql, |
| 1297 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1298 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)", |
| 1299 | TAG_HIDDEN |
| 1300 | ); |
| 1301 | } |
| 1302 | if( P("mionly")==0 ){ |
| 1303 | blob_append_sql(&sql, |
| 1304 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1305 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", |
| 1306 | tagid |
| 1307 | ); |
| 1308 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1309 | blob_append_sql(&sql, |
| 1310 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1311 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)", |
| 1312 | TAG_HIDDEN |
| 1313 | ); |
| 1314 | } |
| 1315 | }else{ |
| 1316 | url_add_parameter(&url, "mionly", "1"); |
| 1317 | } |
| 1318 | }else{ |
| 1319 | url_add_parameter(&url, "t", zTagName); |
| 1320 | } |
| 1321 | blob_append_sql(&sql, ")"); |
| 1322 | } |
| 1323 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1324 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1325 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1326 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1325,27 +1329,27 @@ | |
| 1329 | zType = "all"; |
| 1330 | } |
| 1331 | if( zType[0]=='a' ){ |
| 1332 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1333 | char cSep = '('; |
| 1334 | blob_append_sql(&sql, " AND event.type IN "); |
| 1335 | if( g.perm.Read ){ |
| 1336 | blob_append_sql(&sql, "%c'ci','g'", cSep); |
| 1337 | cSep = ','; |
| 1338 | } |
| 1339 | if( g.perm.RdWiki ){ |
| 1340 | blob_append_sql(&sql, "%c'w','e'", cSep); |
| 1341 | cSep = ','; |
| 1342 | } |
| 1343 | if( g.perm.RdTkt ){ |
| 1344 | blob_append_sql(&sql, "%c't'", cSep); |
| 1345 | cSep = ','; |
| 1346 | } |
| 1347 | blob_append_sql(&sql, ")"); |
| 1348 | } |
| 1349 | }else{ /* zType!="all" */ |
| 1350 | blob_append_sql(&sql, " AND event.type=%Q", zType); |
| 1351 | url_add_parameter(&url, "y", zType); |
| 1352 | if( zType[0]=='c' ){ |
| 1353 | zEType = "checkin"; |
| 1354 | }else if( zType[0]=='w' ){ |
| 1355 | zEType = "wiki edit"; |
| @@ -1356,64 +1360,64 @@ | |
| 1360 | }else if( zType[0]=='g' ){ |
| 1361 | zEType = "tag"; |
| 1362 | } |
| 1363 | } |
| 1364 | if( zUser ){ |
| 1365 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1366 | zUser, zUser); |
| 1367 | url_add_parameter(&url, "u", zUser); |
| 1368 | zThisUser = zUser; |
| 1369 | } |
| 1370 | if( zSearch ){ |
| 1371 | blob_append_sql(&sql, |
| 1372 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1373 | zSearch, zSearch); |
| 1374 | url_add_parameter(&url, "s", zSearch); |
| 1375 | } |
| 1376 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1377 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1378 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1379 | if( rAfter>0.0 ){ |
| 1380 | if( rBefore>0.0 ){ |
| 1381 | blob_append_sql(&sql, |
| 1382 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1383 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| 1384 | url_add_parameter(&url, "a", zAfter); |
| 1385 | url_add_parameter(&url, "b", zBefore); |
| 1386 | nEntry = 1000000; |
| 1387 | }else{ |
| 1388 | blob_append_sql(&sql, |
| 1389 | " AND event.mtime>=%.17g ORDER BY event.mtime ASC", |
| 1390 | rAfter-ONE_SECOND); |
| 1391 | url_add_parameter(&url, "a", zAfter); |
| 1392 | } |
| 1393 | }else if( rBefore>0.0 ){ |
| 1394 | blob_append_sql(&sql, |
| 1395 | " AND event.mtime<=%.17g ORDER BY event.mtime DESC", |
| 1396 | rBefore+ONE_SECOND); |
| 1397 | url_add_parameter(&url, "b", zBefore); |
| 1398 | }else if( rCirca>0.0 ){ |
| 1399 | Blob sql2; |
| 1400 | blob_init(&sql2, blob_sql_text(&sql), -1); |
| 1401 | blob_append_sql(&sql2, |
| 1402 | " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d", |
| 1403 | rCirca, (nEntry+1)/2 |
| 1404 | ); |
| 1405 | db_multi_exec("%s", blob_sql_text(&sql2)); |
| 1406 | blob_reset(&sql2); |
| 1407 | blob_append_sql(&sql, |
| 1408 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 1409 | rCirca |
| 1410 | ); |
| 1411 | nEntry -= (nEntry+1)/2; |
| 1412 | if( useDividers ) timeline_add_dividers(rCirca, 0); |
| 1413 | url_add_parameter(&url, "c", zCirca); |
| 1414 | }else{ |
| 1415 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1416 | } |
| 1417 | blob_append_sql(&sql, " LIMIT %d", nEntry); |
| 1418 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1419 | |
| 1420 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1421 | if( zYearMonth ){ |
| 1422 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1423 | }else if( zYearWeek ){ |
| @@ -1506,11 +1510,11 @@ | |
| 1510 | } |
| 1511 | } |
| 1512 | } |
| 1513 | } |
| 1514 | if( P("showsql") ){ |
| 1515 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1516 | } |
| 1517 | blob_zero(&sql); |
| 1518 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1519 | @ <h2>%b(&desc)</h2> |
| 1520 | blob_reset(&desc); |
| @@ -1655,11 +1659,10 @@ | |
| 1659 | /* |
| 1660 | ** Return a pointer to a static string that forms the basis for |
| 1661 | ** a timeline query for display on a TTY. |
| 1662 | */ |
| 1663 | const char *timeline_query_for_tty(void){ |
| 1664 | static const char zBaseSql[] = |
| 1665 | @ SELECT |
| 1666 | @ blob.rid AS rid, |
| 1667 | @ uuid, |
| 1668 | @ datetime(event.mtime%s) AS mDateTime, |
| @@ -1675,20 +1678,17 @@ | |
| 1678 | @ AS primPlinkCount, |
| 1679 | @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount, |
| 1680 | @ event.mtime AS mtime, |
| 1681 | @ tagxref.value AS branch |
| 1682 | @ FROM tag CROSS JOIN event CROSS JOIN blob |
| 1683 | @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid |
| 1684 | @ AND tagxref.tagtype>0 |
| 1685 | @ AND tagxref.rid=blob.rid |
| 1686 | @ WHERE blob.rid=event.objid |
| 1687 | @ AND tag.tagname='branch' |
| 1688 | ; |
| 1689 | return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc()); |
| 1690 | } |
| 1691 | |
| 1692 | /* |
| 1693 | ** Return true if the input string is a date in the ISO 8601 format: |
| 1694 | ** YYYY-MM-DD. |
| @@ -1702,11 +1702,11 @@ | |
| 1702 | } |
| 1703 | |
| 1704 | /* |
| 1705 | ** COMMAND: timeline |
| 1706 | ** |
| 1707 | ** Usage: %fossil timeline ?WHEN? ?CHECKIN|DATETIME? ?OPTIONS? |
| 1708 | ** |
| 1709 | ** Print a summary of activity going backwards in date and time |
| 1710 | ** specified or from the current date and time if no arguments |
| 1711 | ** are given. The WHEN argument can be any unique abbreviation |
| 1712 | ** of one of these keywords: |
| @@ -1722,10 +1722,12 @@ | |
| 1722 | ** for the current version or "now" for the current time. |
| 1723 | ** |
| 1724 | ** Options: |
| 1725 | ** -n|--limit N Output the first N entries (default 20 lines). |
| 1726 | ** N=0 means no limit. |
| 1727 | ** -p|--path PATH Output items affecting PATH only. |
| 1728 | ** PATH can be a file or a sub directory. |
| 1729 | ** --offset P skip P changes |
| 1730 | ** -t|--type TYPE Output items from the given types only, such as: |
| 1731 | ** ci = file commits only |
| 1732 | ** e = events only |
| 1733 | ** t = tickets only |
| @@ -1752,19 +1754,23 @@ | |
| 1754 | int objid = 0; |
| 1755 | Blob uuid; |
| 1756 | int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */ |
| 1757 | int verboseFlag = 0 ; |
| 1758 | int iOffset; |
| 1759 | const char *zFilePattern = 0; |
| 1760 | Blob treeName; |
| 1761 | |
| 1762 | verboseFlag = find_option("verbose","v", 0)!=0; |
| 1763 | if( !verboseFlag){ |
| 1764 | verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */ |
| 1765 | } |
| 1766 | db_find_and_open_repository(0, 0); |
| 1767 | zLimit = find_option("limit","n",1); |
| 1768 | zWidth = find_option("width","W",1); |
| 1769 | zType = find_option("type","t",1); |
| 1770 | zFilePattern = find_option("path","p",1); |
| 1771 | |
| 1772 | if( !zLimit ){ |
| 1773 | zLimit = find_option("count",0,1); |
| 1774 | } |
| 1775 | if( zLimit ){ |
| 1776 | n = atoi(zLimit); |
| @@ -1798,12 +1804,12 @@ | |
| 1804 | }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){ |
| 1805 | mode = 4; |
| 1806 | }else if( strncmp(g.argv[2],"parents",k)==0 ){ |
| 1807 | mode = 4; |
| 1808 | }else if(!zType && !zLimit){ |
| 1809 | usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? " |
| 1810 | "?-W|--width WIDTH? ?-p|--path PATH"); |
| 1811 | } |
| 1812 | if( '-' != *g.argv[3] ){ |
| 1813 | zOrigin = g.argv[3]; |
| 1814 | }else{ |
| 1815 | zOrigin = "now"; |
| @@ -1838,37 +1844,72 @@ | |
| 1844 | if( mode==0 ){ |
| 1845 | if( isIsoDate(zOrigin) ) zShift = ",'+1 day'"; |
| 1846 | } |
| 1847 | zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift); |
| 1848 | } |
| 1849 | |
| 1850 | if( zFilePattern ){ |
| 1851 | if( zType==0 ){ |
| 1852 | /* When zFilePattern is specified and type is not specified, only show |
| 1853 | * file checkins */ |
| 1854 | zType="ci"; |
| 1855 | } |
| 1856 | file_tree_name(zFilePattern, &treeName, 1); |
| 1857 | if( fossil_strcmp(blob_str(&treeName), ".")==0 ){ |
| 1858 | /* When zTreeName refers to g.zLocalRoot, it's like not specifying |
| 1859 | * zFilePattern. */ |
| 1860 | zFilePattern = 0; |
| 1861 | } |
| 1862 | } |
| 1863 | |
| 1864 | if( mode==0 ) mode = 1; |
| 1865 | blob_zero(&sql); |
| 1866 | blob_append(&sql, timeline_query_for_tty(), -1); |
| 1867 | blob_append_sql(&sql, " AND event.mtime %s %s", |
| 1868 | (mode==1 || mode==4) ? "<=" : ">=", |
| 1869 | zDate /*safe-for-%s*/ |
| 1870 | ); |
| 1871 | |
| 1872 | if( mode==3 || mode==4 ){ |
| 1873 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 1874 | if( mode==3 ){ |
| 1875 | compute_descendants(objid, n); |
| 1876 | }else{ |
| 1877 | compute_ancestors(objid, n, 0); |
| 1878 | } |
| 1879 | blob_append_sql(&sql, "\n AND blob.rid IN ok"); |
| 1880 | } |
| 1881 | if( zType && (zType[0]!='a') ){ |
| 1882 | blob_append_sql(&sql, "\n AND event.type=%Q ", zType); |
| 1883 | } |
| 1884 | if( zFilePattern ){ |
| 1885 | blob_append(&sql, |
| 1886 | "\n AND EXISTS(SELECT 1 FROM mlink\n" |
| 1887 | " WHERE mlink.mid=event.objid\n" |
| 1888 | " AND mlink.fnid IN ", -1); |
| 1889 | if( filenames_are_case_sensitive() ){ |
| 1890 | blob_append_sql(&sql, |
| 1891 | "(SELECT fnid FROM filename" |
| 1892 | " WHERE name=%Q" |
| 1893 | " OR name GLOB '%q/*')", |
| 1894 | blob_str(&treeName), blob_str(&treeName)); |
| 1895 | }else{ |
| 1896 | blob_append_sql(&sql, |
| 1897 | "(SELECT fnid FROM filename" |
| 1898 | " WHERE name=%Q COLLATE nocase" |
| 1899 | " OR lower(name) GLOB lower('%q/*'))", |
| 1900 | blob_str(&treeName), blob_str(&treeName)); |
| 1901 | } |
| 1902 | blob_append(&sql, ")", -1); |
| 1903 | } |
| 1904 | blob_append_sql(&sql, "\nORDER BY event.mtime DESC"); |
| 1905 | if( iOffset>0 ){ |
| 1906 | /* Don't handle LIMIT here, otherwise print_timeline() |
| 1907 | * will not determine the end-marker correctly! */ |
| 1908 | blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset); |
| 1909 | } |
| 1910 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 1911 | blob_reset(&sql); |
| 1912 | print_timeline(&q, n, width, verboseFlag); |
| 1913 | db_finalize(&q); |
| 1914 | } |
| 1915 | |
| @@ -2178,24 +2219,24 @@ | |
| 2219 | stats_report_init_view(); |
| 2220 | stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL ); |
| 2221 | blob_appendf(&header, "Timeline Events (%s) by year%s", |
| 2222 | stats_report_label_for_type(), |
| 2223 | (includeMonth ? "/month" : "")); |
| 2224 | blob_append_sql(&sql, |
| 2225 | "SELECT substr(date(mtime),1,%d) AS timeframe, " |
| 2226 | "count(*) AS eventCount " |
| 2227 | "FROM v_reports ", |
| 2228 | includeMonth ? 7 : 4); |
| 2229 | if(zUserName&&*zUserName){ |
| 2230 | blob_append_sql(&sql, " WHERE user=%Q ", zUserName); |
| 2231 | blob_appendf(&header," for user %q", zUserName); |
| 2232 | } |
| 2233 | blob_append(&sql, |
| 2234 | " GROUP BY timeframe" |
| 2235 | " ORDER BY timeframe DESC", |
| 2236 | -1); |
| 2237 | db_prepare(&query, "%s", blob_sql_text(&sql)); |
| 2238 | blob_reset(&sql); |
| 2239 | @ <h1>%b(&header)</h1> |
| 2240 | @ <table class='statistics-report-table-events' border='0' cellpadding='2' |
| 2241 | @ cellspacing='0' id='statsTable'> |
| 2242 | @ <thead> |
| @@ -2321,23 +2362,19 @@ | |
| 2362 | Stmt query = empty_Stmt; |
| 2363 | int nRowNumber = 0; /* current TR number */ |
| 2364 | int nEventTotal = 0; /* Total event count */ |
| 2365 | int rowClass = 0; /* counter for alternating |
| 2366 | row colors */ |
| 2367 | int nMaxEvents = 1; /* max number of events for |
| 2368 | all rows. */ |
| 2369 | stats_report_init_view(); |
| 2370 | stats_report_event_types_menu("byuser", NULL); |
| 2371 | db_prepare(&query, |
| 2372 | "SELECT user, " |
| 2373 | "COUNT(*) AS eventCount " |
| 2374 | "FROM v_reports " |
| 2375 | "GROUP BY user ORDER BY eventCount DESC"); |
| 2376 | @ <h1>Timeline Events |
| 2377 | @ (%s(stats_report_label_for_type())) by User</h1> |
| 2378 | @ <table class='statistics-report-table-events' border='0' |
| 2379 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2380 | @ <thead><tr> |
| @@ -2388,28 +2425,24 @@ | |
| 2425 | Stmt query = empty_Stmt; |
| 2426 | int nRowNumber = 0; /* current TR number */ |
| 2427 | int nEventTotal = 0; /* Total event count */ |
| 2428 | int rowClass = 0; /* counter for alternating |
| 2429 | row colors */ |
| 2430 | int nMaxEvents = 1; /* max number of events for |
| 2431 | all rows. */ |
| 2432 | static const char *const daysOfWeek[] = { |
| 2433 | "Monday", "Tuesday", "Wednesday", "Thursday", |
| 2434 | "Friday", "Saturday", "Sunday" |
| 2435 | }; |
| 2436 | |
| 2437 | stats_report_init_view(); |
| 2438 | stats_report_event_types_menu("byweekday", NULL); |
| 2439 | db_prepare(&query, |
| 2440 | "SELECT cast(mtime %% 7 AS INTEGER) dow, " |
| 2441 | "COUNT(*) AS eventCount " |
| 2442 | "FROM v_reports " |
| 2443 | "GROUP BY dow ORDER BY dow"); |
| 2444 | @ <h1>Timeline Events |
| 2445 | @ (%s(stats_report_label_for_type())) by Day of the Week</h1> |
| 2446 | @ <table class='statistics-report-table-events' border='0' |
| 2447 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2448 | @ <thead><tr> |
| @@ -2477,14 +2510,14 @@ | |
| 2510 | } |
| 2511 | blob_append(&sql, |
| 2512 | "SELECT DISTINCT substr(date(mtime),1,4) AS y " |
| 2513 | "FROM v_reports WHERE 1 ", -1); |
| 2514 | if(zUserName&&*zUserName){ |
| 2515 | blob_append_sql(&sql,"AND user=%Q ", zUserName); |
| 2516 | } |
| 2517 | blob_append(&sql,"GROUP BY y ORDER BY y", -1); |
| 2518 | db_prepare(&qYears, "%s", blob_sql_text(&sql)); |
| 2519 | blob_reset(&sql); |
| 2520 | cgi_printf("Select year: "); |
| 2521 | while( SQLITE_ROW == db_step(&qYears) ){ |
| 2522 | const char *zT = db_column_text(&qYears, 0); |
| 2523 | if( i++ ){ |
| @@ -2510,22 +2543,22 @@ | |
| 2543 | int total = 0; |
| 2544 | Blob header = empty_blob; |
| 2545 | blob_appendf(&header, "Timeline events (%s) for the calendar weeks " |
| 2546 | "of %h", stats_report_label_for_type(), |
| 2547 | zYear); |
| 2548 | blob_append_sql(&sql, |
| 2549 | "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, " |
| 2550 | "count(*) AS n " |
| 2551 | "FROM v_reports " |
| 2552 | "WHERE %Q=substr(date(mtime),1,4) " |
| 2553 | "AND mtime < current_timestamp ", |
| 2554 | zYear); |
| 2555 | if(zUserName&&*zUserName){ |
| 2556 | blob_append_sql(&sql, " AND user=%Q ", zUserName); |
| 2557 | blob_appendf(&header," for user %h", zUserName); |
| 2558 | } |
| 2559 | blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC"); |
| 2560 | cgi_printf("<h1>%h</h1>", blob_str(&header)); |
| 2561 | blob_reset(&header); |
| 2562 | cgi_printf("<table class='statistics-report-table-events' " |
| 2563 | "border='0' cellpadding='2' width='100%%' " |
| 2564 | "cellspacing='0' id='statsTable'>"); |
| @@ -2533,11 +2566,11 @@ | |
| 2566 | "<th>Week</th>" |
| 2567 | "<th>Events</th>" |
| 2568 | "<th width='90%%'><!-- relative commits graph --></th>" |
| 2569 | "</tr></thead>" |
| 2570 | "<tbody>"); |
| 2571 | db_prepare(&stWeek, "%s", blob_sql_text(&sql)); |
| 2572 | blob_reset(&sql); |
| 2573 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2574 | const int nCount = db_column_int(&stWeek, 1); |
| 2575 | if(nCount>nMaxEvents){ |
| 2576 | nMaxEvents = nCount; |
| 2577 |
+21
-23
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -203,13 +203,13 @@ | ||
| 203 | 203 | tktid = db_last_insert_rowid(); |
| 204 | 204 | } |
| 205 | 205 | blob_zero(&sql1); |
| 206 | 206 | blob_zero(&sql2); |
| 207 | 207 | blob_zero(&sql3); |
| 208 | - blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); | |
| 208 | + blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); | |
| 209 | 209 | if( haveTicketCTime ){ |
| 210 | - blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)"); | |
| 210 | + blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)"); | |
| 211 | 211 | } |
| 212 | 212 | aUsed = fossil_malloc( nField ); |
| 213 | 213 | memset(aUsed, 0, nField); |
| 214 | 214 | for(i=0; i<p->nField; i++){ |
| 215 | 215 | const char *zName = p->aField[i].zName; |
| @@ -218,55 +218,56 @@ | ||
| 218 | 218 | if( j<0 ) continue; |
| 219 | 219 | aUsed[j] = 1; |
| 220 | 220 | if( aField[j].mUsed & USEDBY_TICKET ){ |
| 221 | 221 | if( zName[0]=='+' ){ |
| 222 | 222 | zName++; |
| 223 | - blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q", | |
| 223 | + blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q", | |
| 224 | 224 | zName, zName, p->aField[i].zValue); |
| 225 | 225 | }else{ |
| 226 | - blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue); | |
| 226 | + blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue); | |
| 227 | 227 | } |
| 228 | 228 | } |
| 229 | 229 | if( aField[j].mUsed & USEDBY_TICKETCHNG ){ |
| 230 | - blob_appendf(&sql2, ",%s", zName); | |
| 231 | - blob_appendf(&sql3, ",%Q", p->aField[i].zValue); | |
| 230 | + blob_append_sql(&sql2, ",\"%w\"", zName); | |
| 231 | + blob_append_sql(&sql3, ",%Q", p->aField[i].zValue); | |
| 232 | 232 | } |
| 233 | 233 | if( rid>0 ){ |
| 234 | 234 | wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0); |
| 235 | 235 | } |
| 236 | 236 | } |
| 237 | - blob_appendf(&sql1, " WHERE tkt_id=%d", tktid); | |
| 238 | - db_prepare(&q, "%s", blob_str(&sql1)); | |
| 237 | + blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid); | |
| 238 | + db_prepare(&q, "%s", blob_sql_text(&sql1)); | |
| 239 | 239 | db_bind_double(&q, ":mtime", p->rDate); |
| 240 | 240 | db_step(&q); |
| 241 | 241 | db_finalize(&q); |
| 242 | 242 | blob_reset(&sql1); |
| 243 | 243 | if( blob_size(&sql2)>0 || haveTicketChngRid ){ |
| 244 | 244 | int fromTkt = 0; |
| 245 | 245 | if( haveTicketChngRid ){ |
| 246 | 246 | blob_append(&sql2, ",tkt_rid", -1); |
| 247 | - blob_appendf(&sql3, ",%d", rid); | |
| 247 | + blob_append_sql(&sql3, ",%d", rid); | |
| 248 | 248 | } |
| 249 | 249 | for(i=0; i<nField; i++){ |
| 250 | 250 | if( aUsed[i]==0 |
| 251 | 251 | && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH |
| 252 | 252 | ){ |
| 253 | 253 | const char *z = aField[i].zName; |
| 254 | 254 | if( z[0]=='+' ) z++; |
| 255 | 255 | fromTkt = 1; |
| 256 | - blob_appendf(&sql2, ",%s", z); | |
| 257 | - blob_appendf(&sql3, ",%s", z); | |
| 256 | + blob_append_sql(&sql2, ",\"%w\"", z); | |
| 257 | + blob_append_sql(&sql3, ",\"%w\"", z); | |
| 258 | 258 | } |
| 259 | 259 | } |
| 260 | 260 | if( fromTkt ){ |
| 261 | 261 | db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)" |
| 262 | 262 | "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d", |
| 263 | - blob_str(&sql2), tktid, blob_str(&sql3), tktid); | |
| 263 | + blob_sql_text(&sql2), tktid, | |
| 264 | + blob_sql_text(&sql3), tktid); | |
| 264 | 265 | }else{ |
| 265 | 266 | db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)" |
| 266 | 267 | "VALUES(%d,:mtime%s)", |
| 267 | - blob_str(&sql2), tktid, blob_str(&sql3)); | |
| 268 | + blob_sql_text(&sql2), tktid, blob_sql_text(&sql3)); | |
| 268 | 269 | } |
| 269 | 270 | db_bind_double(&q, ":mtime", p->rDate); |
| 270 | 271 | db_step(&q); |
| 271 | 272 | db_finalize(&q); |
| 272 | 273 | } |
| @@ -368,11 +369,11 @@ | ||
| 368 | 369 | zSql = ticket_table_schema(); |
| 369 | 370 | if( separateConnection ){ |
| 370 | 371 | db_end_transaction(0); |
| 371 | 372 | db_init_database(g.zRepositoryName, zSql, 0); |
| 372 | 373 | }else{ |
| 373 | - db_multi_exec("%s", zSql); | |
| 374 | + db_multi_exec("%s", zSql/*safe-for-%s*/); | |
| 374 | 375 | } |
| 375 | 376 | } |
| 376 | 377 | |
| 377 | 378 | /* |
| 378 | 379 | ** Repopulate the TICKET and TICKETCHNG tables from scratch using all |
| @@ -551,11 +552,11 @@ | ||
| 551 | 552 | fossil_fatal("trouble committing ticket: %s", g.zErrMsg); |
| 552 | 553 | } |
| 553 | 554 | if( needMod ){ |
| 554 | 555 | moderation_table_create(); |
| 555 | 556 | db_multi_exec( |
| 556 | - "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')", | |
| 557 | + "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)", | |
| 557 | 558 | rid, zTktId |
| 558 | 559 | ); |
| 559 | 560 | }else{ |
| 560 | 561 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid); |
| 561 | 562 | db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid); |
| @@ -855,12 +856,11 @@ | ||
| 855 | 856 | if( zType[0]=='c' ){ |
| 856 | 857 | zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid); |
| 857 | 858 | }else{ |
| 858 | 859 | zTitle = mprintf("Timeline Of Ticket %h", zUuid); |
| 859 | 860 | } |
| 860 | - style_header(zTitle); | |
| 861 | - free(zTitle); | |
| 861 | + style_header("%z", zTitle); | |
| 862 | 862 | |
| 863 | 863 | sqlite3_snprintf(6, zGlobPattern, "%s", zUuid); |
| 864 | 864 | canonical16(zGlobPattern, strlen(zGlobPattern)); |
| 865 | 865 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| 866 | 866 | if( tagid==0 ){ |
| @@ -889,12 +889,11 @@ | ||
| 889 | 889 | " WHERE target=%Q) " |
| 890 | 890 | "ORDER BY mtime DESC", |
| 891 | 891 | timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid |
| 892 | 892 | ); |
| 893 | 893 | } |
| 894 | - db_prepare(&q, zSQL); | |
| 895 | - free(zSQL); | |
| 894 | + db_prepare(&q, "%z", zSQL/*safe-for-%s*/); | |
| 896 | 895 | www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH, |
| 897 | 896 | 0, 0, 0); |
| 898 | 897 | db_finalize(&q); |
| 899 | 898 | style_footer(); |
| 900 | 899 | } |
| @@ -927,12 +926,11 @@ | ||
| 927 | 926 | "%R/tkthistory/%s", zUuid); |
| 928 | 927 | }else{ |
| 929 | 928 | style_submenu_element("Plaintext", "Plaintext", |
| 930 | 929 | "%R/tkthistory/%s?plaintext", zUuid); |
| 931 | 930 | } |
| 932 | - style_header(zTitle); | |
| 933 | - free(zTitle); | |
| 931 | + style_header("%z", zTitle); | |
| 934 | 932 | |
| 935 | 933 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| 936 | 934 | if( tagid==0 ){ |
| 937 | 935 | @ No such ticket: %h(zUuid) |
| 938 | 936 | style_footer(); |
| @@ -1213,11 +1211,11 @@ | ||
| 1213 | 1211 | } |
| 1214 | 1212 | if( g.argc==3 ){ |
| 1215 | 1213 | usage("set|change|history TICKETUUID"); |
| 1216 | 1214 | } |
| 1217 | 1215 | zTktUuid = db_text(0, |
| 1218 | - "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3] | |
| 1216 | + "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3] | |
| 1219 | 1217 | ); |
| 1220 | 1218 | if( !zTktUuid ){ |
| 1221 | 1219 | fossil_fatal("unknown ticket: '%s'!",g.argv[3]); |
| 1222 | 1220 | } |
| 1223 | 1221 | i=4; |
| @@ -1292,11 +1290,11 @@ | ||
| 1292 | 1290 | }else{ |
| 1293 | 1291 | fossil_print(" Change "); |
| 1294 | 1292 | } |
| 1295 | 1293 | fossil_print("%h: ",z); |
| 1296 | 1294 | if( blob_size(&val)>50 || contains_newline(&val)) { |
| 1297 | - fossil_print("\n ",blob_str(&val)); | |
| 1295 | + fossil_print("\n "); | |
| 1298 | 1296 | comment_print(blob_str(&val),0,4,-1,g.comFmtFlags); |
| 1299 | 1297 | }else{ |
| 1300 | 1298 | fossil_print("%s\n",blob_str(&val)); |
| 1301 | 1299 | } |
| 1302 | 1300 | blob_reset(&val); |
| 1303 | 1301 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -203,13 +203,13 @@ | |
| 203 | tktid = db_last_insert_rowid(); |
| 204 | } |
| 205 | blob_zero(&sql1); |
| 206 | blob_zero(&sql2); |
| 207 | blob_zero(&sql3); |
| 208 | blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 209 | if( haveTicketCTime ){ |
| 210 | blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)"); |
| 211 | } |
| 212 | aUsed = fossil_malloc( nField ); |
| 213 | memset(aUsed, 0, nField); |
| 214 | for(i=0; i<p->nField; i++){ |
| 215 | const char *zName = p->aField[i].zName; |
| @@ -218,55 +218,56 @@ | |
| 218 | if( j<0 ) continue; |
| 219 | aUsed[j] = 1; |
| 220 | if( aField[j].mUsed & USEDBY_TICKET ){ |
| 221 | if( zName[0]=='+' ){ |
| 222 | zName++; |
| 223 | blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q", |
| 224 | zName, zName, p->aField[i].zValue); |
| 225 | }else{ |
| 226 | blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue); |
| 227 | } |
| 228 | } |
| 229 | if( aField[j].mUsed & USEDBY_TICKETCHNG ){ |
| 230 | blob_appendf(&sql2, ",%s", zName); |
| 231 | blob_appendf(&sql3, ",%Q", p->aField[i].zValue); |
| 232 | } |
| 233 | if( rid>0 ){ |
| 234 | wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0); |
| 235 | } |
| 236 | } |
| 237 | blob_appendf(&sql1, " WHERE tkt_id=%d", tktid); |
| 238 | db_prepare(&q, "%s", blob_str(&sql1)); |
| 239 | db_bind_double(&q, ":mtime", p->rDate); |
| 240 | db_step(&q); |
| 241 | db_finalize(&q); |
| 242 | blob_reset(&sql1); |
| 243 | if( blob_size(&sql2)>0 || haveTicketChngRid ){ |
| 244 | int fromTkt = 0; |
| 245 | if( haveTicketChngRid ){ |
| 246 | blob_append(&sql2, ",tkt_rid", -1); |
| 247 | blob_appendf(&sql3, ",%d", rid); |
| 248 | } |
| 249 | for(i=0; i<nField; i++){ |
| 250 | if( aUsed[i]==0 |
| 251 | && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH |
| 252 | ){ |
| 253 | const char *z = aField[i].zName; |
| 254 | if( z[0]=='+' ) z++; |
| 255 | fromTkt = 1; |
| 256 | blob_appendf(&sql2, ",%s", z); |
| 257 | blob_appendf(&sql3, ",%s", z); |
| 258 | } |
| 259 | } |
| 260 | if( fromTkt ){ |
| 261 | db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)" |
| 262 | "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d", |
| 263 | blob_str(&sql2), tktid, blob_str(&sql3), tktid); |
| 264 | }else{ |
| 265 | db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)" |
| 266 | "VALUES(%d,:mtime%s)", |
| 267 | blob_str(&sql2), tktid, blob_str(&sql3)); |
| 268 | } |
| 269 | db_bind_double(&q, ":mtime", p->rDate); |
| 270 | db_step(&q); |
| 271 | db_finalize(&q); |
| 272 | } |
| @@ -368,11 +369,11 @@ | |
| 368 | zSql = ticket_table_schema(); |
| 369 | if( separateConnection ){ |
| 370 | db_end_transaction(0); |
| 371 | db_init_database(g.zRepositoryName, zSql, 0); |
| 372 | }else{ |
| 373 | db_multi_exec("%s", zSql); |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | /* |
| 378 | ** Repopulate the TICKET and TICKETCHNG tables from scratch using all |
| @@ -551,11 +552,11 @@ | |
| 551 | fossil_fatal("trouble committing ticket: %s", g.zErrMsg); |
| 552 | } |
| 553 | if( needMod ){ |
| 554 | moderation_table_create(); |
| 555 | db_multi_exec( |
| 556 | "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')", |
| 557 | rid, zTktId |
| 558 | ); |
| 559 | }else{ |
| 560 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid); |
| 561 | db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid); |
| @@ -855,12 +856,11 @@ | |
| 855 | if( zType[0]=='c' ){ |
| 856 | zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid); |
| 857 | }else{ |
| 858 | zTitle = mprintf("Timeline Of Ticket %h", zUuid); |
| 859 | } |
| 860 | style_header(zTitle); |
| 861 | free(zTitle); |
| 862 | |
| 863 | sqlite3_snprintf(6, zGlobPattern, "%s", zUuid); |
| 864 | canonical16(zGlobPattern, strlen(zGlobPattern)); |
| 865 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| 866 | if( tagid==0 ){ |
| @@ -889,12 +889,11 @@ | |
| 889 | " WHERE target=%Q) " |
| 890 | "ORDER BY mtime DESC", |
| 891 | timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid |
| 892 | ); |
| 893 | } |
| 894 | db_prepare(&q, zSQL); |
| 895 | free(zSQL); |
| 896 | www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH, |
| 897 | 0, 0, 0); |
| 898 | db_finalize(&q); |
| 899 | style_footer(); |
| 900 | } |
| @@ -927,12 +926,11 @@ | |
| 927 | "%R/tkthistory/%s", zUuid); |
| 928 | }else{ |
| 929 | style_submenu_element("Plaintext", "Plaintext", |
| 930 | "%R/tkthistory/%s?plaintext", zUuid); |
| 931 | } |
| 932 | style_header(zTitle); |
| 933 | free(zTitle); |
| 934 | |
| 935 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| 936 | if( tagid==0 ){ |
| 937 | @ No such ticket: %h(zUuid) |
| 938 | style_footer(); |
| @@ -1213,11 +1211,11 @@ | |
| 1213 | } |
| 1214 | if( g.argc==3 ){ |
| 1215 | usage("set|change|history TICKETUUID"); |
| 1216 | } |
| 1217 | zTktUuid = db_text(0, |
| 1218 | "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3] |
| 1219 | ); |
| 1220 | if( !zTktUuid ){ |
| 1221 | fossil_fatal("unknown ticket: '%s'!",g.argv[3]); |
| 1222 | } |
| 1223 | i=4; |
| @@ -1292,11 +1290,11 @@ | |
| 1292 | }else{ |
| 1293 | fossil_print(" Change "); |
| 1294 | } |
| 1295 | fossil_print("%h: ",z); |
| 1296 | if( blob_size(&val)>50 || contains_newline(&val)) { |
| 1297 | fossil_print("\n ",blob_str(&val)); |
| 1298 | comment_print(blob_str(&val),0,4,-1,g.comFmtFlags); |
| 1299 | }else{ |
| 1300 | fossil_print("%s\n",blob_str(&val)); |
| 1301 | } |
| 1302 | blob_reset(&val); |
| 1303 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -203,13 +203,13 @@ | |
| 203 | tktid = db_last_insert_rowid(); |
| 204 | } |
| 205 | blob_zero(&sql1); |
| 206 | blob_zero(&sql2); |
| 207 | blob_zero(&sql3); |
| 208 | blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 209 | if( haveTicketCTime ){ |
| 210 | blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)"); |
| 211 | } |
| 212 | aUsed = fossil_malloc( nField ); |
| 213 | memset(aUsed, 0, nField); |
| 214 | for(i=0; i<p->nField; i++){ |
| 215 | const char *zName = p->aField[i].zName; |
| @@ -218,55 +218,56 @@ | |
| 218 | if( j<0 ) continue; |
| 219 | aUsed[j] = 1; |
| 220 | if( aField[j].mUsed & USEDBY_TICKET ){ |
| 221 | if( zName[0]=='+' ){ |
| 222 | zName++; |
| 223 | blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q", |
| 224 | zName, zName, p->aField[i].zValue); |
| 225 | }else{ |
| 226 | blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue); |
| 227 | } |
| 228 | } |
| 229 | if( aField[j].mUsed & USEDBY_TICKETCHNG ){ |
| 230 | blob_append_sql(&sql2, ",\"%w\"", zName); |
| 231 | blob_append_sql(&sql3, ",%Q", p->aField[i].zValue); |
| 232 | } |
| 233 | if( rid>0 ){ |
| 234 | wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0); |
| 235 | } |
| 236 | } |
| 237 | blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid); |
| 238 | db_prepare(&q, "%s", blob_sql_text(&sql1)); |
| 239 | db_bind_double(&q, ":mtime", p->rDate); |
| 240 | db_step(&q); |
| 241 | db_finalize(&q); |
| 242 | blob_reset(&sql1); |
| 243 | if( blob_size(&sql2)>0 || haveTicketChngRid ){ |
| 244 | int fromTkt = 0; |
| 245 | if( haveTicketChngRid ){ |
| 246 | blob_append(&sql2, ",tkt_rid", -1); |
| 247 | blob_append_sql(&sql3, ",%d", rid); |
| 248 | } |
| 249 | for(i=0; i<nField; i++){ |
| 250 | if( aUsed[i]==0 |
| 251 | && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH |
| 252 | ){ |
| 253 | const char *z = aField[i].zName; |
| 254 | if( z[0]=='+' ) z++; |
| 255 | fromTkt = 1; |
| 256 | blob_append_sql(&sql2, ",\"%w\"", z); |
| 257 | blob_append_sql(&sql3, ",\"%w\"", z); |
| 258 | } |
| 259 | } |
| 260 | if( fromTkt ){ |
| 261 | db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)" |
| 262 | "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d", |
| 263 | blob_sql_text(&sql2), tktid, |
| 264 | blob_sql_text(&sql3), tktid); |
| 265 | }else{ |
| 266 | db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)" |
| 267 | "VALUES(%d,:mtime%s)", |
| 268 | blob_sql_text(&sql2), tktid, blob_sql_text(&sql3)); |
| 269 | } |
| 270 | db_bind_double(&q, ":mtime", p->rDate); |
| 271 | db_step(&q); |
| 272 | db_finalize(&q); |
| 273 | } |
| @@ -368,11 +369,11 @@ | |
| 369 | zSql = ticket_table_schema(); |
| 370 | if( separateConnection ){ |
| 371 | db_end_transaction(0); |
| 372 | db_init_database(g.zRepositoryName, zSql, 0); |
| 373 | }else{ |
| 374 | db_multi_exec("%s", zSql/*safe-for-%s*/); |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | /* |
| 379 | ** Repopulate the TICKET and TICKETCHNG tables from scratch using all |
| @@ -551,11 +552,11 @@ | |
| 552 | fossil_fatal("trouble committing ticket: %s", g.zErrMsg); |
| 553 | } |
| 554 | if( needMod ){ |
| 555 | moderation_table_create(); |
| 556 | db_multi_exec( |
| 557 | "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)", |
| 558 | rid, zTktId |
| 559 | ); |
| 560 | }else{ |
| 561 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid); |
| 562 | db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid); |
| @@ -855,12 +856,11 @@ | |
| 856 | if( zType[0]=='c' ){ |
| 857 | zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid); |
| 858 | }else{ |
| 859 | zTitle = mprintf("Timeline Of Ticket %h", zUuid); |
| 860 | } |
| 861 | style_header("%z", zTitle); |
| 862 | |
| 863 | sqlite3_snprintf(6, zGlobPattern, "%s", zUuid); |
| 864 | canonical16(zGlobPattern, strlen(zGlobPattern)); |
| 865 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| 866 | if( tagid==0 ){ |
| @@ -889,12 +889,11 @@ | |
| 889 | " WHERE target=%Q) " |
| 890 | "ORDER BY mtime DESC", |
| 891 | timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid |
| 892 | ); |
| 893 | } |
| 894 | db_prepare(&q, "%z", zSQL/*safe-for-%s*/); |
| 895 | www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH, |
| 896 | 0, 0, 0); |
| 897 | db_finalize(&q); |
| 898 | style_footer(); |
| 899 | } |
| @@ -927,12 +926,11 @@ | |
| 926 | "%R/tkthistory/%s", zUuid); |
| 927 | }else{ |
| 928 | style_submenu_element("Plaintext", "Plaintext", |
| 929 | "%R/tkthistory/%s?plaintext", zUuid); |
| 930 | } |
| 931 | style_header("%z", zTitle); |
| 932 | |
| 933 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| 934 | if( tagid==0 ){ |
| 935 | @ No such ticket: %h(zUuid) |
| 936 | style_footer(); |
| @@ -1213,11 +1211,11 @@ | |
| 1211 | } |
| 1212 | if( g.argc==3 ){ |
| 1213 | usage("set|change|history TICKETUUID"); |
| 1214 | } |
| 1215 | zTktUuid = db_text(0, |
| 1216 | "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3] |
| 1217 | ); |
| 1218 | if( !zTktUuid ){ |
| 1219 | fossil_fatal("unknown ticket: '%s'!",g.argv[3]); |
| 1220 | } |
| 1221 | i=4; |
| @@ -1292,11 +1290,11 @@ | |
| 1290 | }else{ |
| 1291 | fossil_print(" Change "); |
| 1292 | } |
| 1293 | fossil_print("%h: ",z); |
| 1294 | if( blob_size(&val)>50 || contains_newline(&val)) { |
| 1295 | fossil_print("\n "); |
| 1296 | comment_print(blob_str(&val),0,4,-1,g.comFmtFlags); |
| 1297 | }else{ |
| 1298 | fossil_print("%s\n",blob_str(&val)); |
| 1299 | } |
| 1300 | blob_reset(&val); |
| 1301 |
+7
-7
| --- src/translate.c | ||
| +++ src/translate.c | ||
| @@ -13,11 +13,11 @@ | ||
| 13 | 13 | ** [email protected] |
| 14 | 14 | ** http://www.hwaci.com/drh/ |
| 15 | 15 | ** |
| 16 | 16 | ******************************************************************************* |
| 17 | 17 | ** |
| 18 | -** SYNOPSIS: | |
| 18 | +** SYNOPSIS: | |
| 19 | 19 | ** |
| 20 | 20 | ** Input lines that begin with the "@" character are translated into |
| 21 | 21 | ** either cgi_printf() statements or string literals and the |
| 22 | 22 | ** translated code is written on standard output. |
| 23 | 23 | ** |
| @@ -34,22 +34,22 @@ | ||
| 34 | 34 | ** punctuation. |
| 35 | 35 | ** |
| 36 | 36 | ** Enhancement #1: |
| 37 | 37 | ** |
| 38 | 38 | ** If the last non-whitespace character prior to the first "@" of a |
| 39 | -** @-block is "=" or "," then the @-block is a string literal initializer | |
| 39 | +** @-block is "=" or "," then the @-block is a string literal initializer | |
| 40 | 40 | ** rather than text that is to be output via cgi_printf(). Render it |
| 41 | 41 | ** as such. |
| 42 | 42 | ** |
| 43 | 43 | ** Enhancement #2: |
| 44 | 44 | ** |
| 45 | -** Comments of the form: "/* @-comment: CC" cause CC to become a | |
| 45 | +** Comments of the form: "/* @-comment: CC" cause CC to become a | |
| 46 | 46 | ** comment character for the @-substitution. Typical values for CC are |
| 47 | 47 | ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code). |
| 48 | 48 | ** Lines of subsequent @-blocks that begin with CC are omitted from the |
| 49 | 49 | ** output. |
| 50 | -** | |
| 50 | +** | |
| 51 | 51 | */ |
| 52 | 52 | #include <stdio.h> |
| 53 | 53 | #include <ctype.h> |
| 54 | 54 | #include <stdlib.h> |
| 55 | 55 | #include <string.h> |
| @@ -122,11 +122,11 @@ | ||
| 122 | 122 | indent = i - 2; |
| 123 | 123 | if( indent<0 ) indent = 0; |
| 124 | 124 | omitline = 0; |
| 125 | 125 | for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){ |
| 126 | 126 | if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){ |
| 127 | - omitline = 1; break; | |
| 127 | + omitline = 1; break; | |
| 128 | 128 | } |
| 129 | 129 | if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; } |
| 130 | 130 | zOut[j++] = zLine[i]; |
| 131 | 131 | } |
| 132 | 132 | while( j>0 && isspace(zOut[j-1]) ){ j--; } |
| @@ -137,11 +137,11 @@ | ||
| 137 | 137 | fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut); |
| 138 | 138 | } |
| 139 | 139 | }else{ |
| 140 | 140 | /* Otherwise (if the last non-whitespace was not '=') then generate |
| 141 | 141 | ** a cgi_printf() statement whose format is the text following the '@'. |
| 142 | - ** Substrings of the form "%C(...)" (where C is any sequence of | |
| 142 | + ** Substrings of the form "%C(...)" (where C is any sequence of | |
| 143 | 143 | ** characters other than \000 and '(') will put "%C" in the |
| 144 | 144 | ** format and add the "(...)" as an argument to the cgi_printf call. |
| 145 | 145 | */ |
| 146 | 146 | int indent; |
| 147 | 147 | int nC; |
| @@ -174,11 +174,11 @@ | ||
| 174 | 174 | fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut); |
| 175 | 175 | inPrint = 1; |
| 176 | 176 | }else{ |
| 177 | 177 | fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut); |
| 178 | 178 | } |
| 179 | - } | |
| 179 | + } | |
| 180 | 180 | } |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | int main(int argc, char **argv){ |
| 184 | 184 | if( argc==2 ){ |
| 185 | 185 |
| --- src/translate.c | |
| +++ src/translate.c | |
| @@ -13,11 +13,11 @@ | |
| 13 | ** [email protected] |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** SYNOPSIS: |
| 19 | ** |
| 20 | ** Input lines that begin with the "@" character are translated into |
| 21 | ** either cgi_printf() statements or string literals and the |
| 22 | ** translated code is written on standard output. |
| 23 | ** |
| @@ -34,22 +34,22 @@ | |
| 34 | ** punctuation. |
| 35 | ** |
| 36 | ** Enhancement #1: |
| 37 | ** |
| 38 | ** If the last non-whitespace character prior to the first "@" of a |
| 39 | ** @-block is "=" or "," then the @-block is a string literal initializer |
| 40 | ** rather than text that is to be output via cgi_printf(). Render it |
| 41 | ** as such. |
| 42 | ** |
| 43 | ** Enhancement #2: |
| 44 | ** |
| 45 | ** Comments of the form: "/* @-comment: CC" cause CC to become a |
| 46 | ** comment character for the @-substitution. Typical values for CC are |
| 47 | ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code). |
| 48 | ** Lines of subsequent @-blocks that begin with CC are omitted from the |
| 49 | ** output. |
| 50 | ** |
| 51 | */ |
| 52 | #include <stdio.h> |
| 53 | #include <ctype.h> |
| 54 | #include <stdlib.h> |
| 55 | #include <string.h> |
| @@ -122,11 +122,11 @@ | |
| 122 | indent = i - 2; |
| 123 | if( indent<0 ) indent = 0; |
| 124 | omitline = 0; |
| 125 | for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){ |
| 126 | if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){ |
| 127 | omitline = 1; break; |
| 128 | } |
| 129 | if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; } |
| 130 | zOut[j++] = zLine[i]; |
| 131 | } |
| 132 | while( j>0 && isspace(zOut[j-1]) ){ j--; } |
| @@ -137,11 +137,11 @@ | |
| 137 | fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut); |
| 138 | } |
| 139 | }else{ |
| 140 | /* Otherwise (if the last non-whitespace was not '=') then generate |
| 141 | ** a cgi_printf() statement whose format is the text following the '@'. |
| 142 | ** Substrings of the form "%C(...)" (where C is any sequence of |
| 143 | ** characters other than \000 and '(') will put "%C" in the |
| 144 | ** format and add the "(...)" as an argument to the cgi_printf call. |
| 145 | */ |
| 146 | int indent; |
| 147 | int nC; |
| @@ -174,11 +174,11 @@ | |
| 174 | fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut); |
| 175 | inPrint = 1; |
| 176 | }else{ |
| 177 | fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut); |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | int main(int argc, char **argv){ |
| 184 | if( argc==2 ){ |
| 185 |
| --- src/translate.c | |
| +++ src/translate.c | |
| @@ -13,11 +13,11 @@ | |
| 13 | ** [email protected] |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** SYNOPSIS: |
| 19 | ** |
| 20 | ** Input lines that begin with the "@" character are translated into |
| 21 | ** either cgi_printf() statements or string literals and the |
| 22 | ** translated code is written on standard output. |
| 23 | ** |
| @@ -34,22 +34,22 @@ | |
| 34 | ** punctuation. |
| 35 | ** |
| 36 | ** Enhancement #1: |
| 37 | ** |
| 38 | ** If the last non-whitespace character prior to the first "@" of a |
| 39 | ** @-block is "=" or "," then the @-block is a string literal initializer |
| 40 | ** rather than text that is to be output via cgi_printf(). Render it |
| 41 | ** as such. |
| 42 | ** |
| 43 | ** Enhancement #2: |
| 44 | ** |
| 45 | ** Comments of the form: "/* @-comment: CC" cause CC to become a |
| 46 | ** comment character for the @-substitution. Typical values for CC are |
| 47 | ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code). |
| 48 | ** Lines of subsequent @-blocks that begin with CC are omitted from the |
| 49 | ** output. |
| 50 | ** |
| 51 | */ |
| 52 | #include <stdio.h> |
| 53 | #include <ctype.h> |
| 54 | #include <stdlib.h> |
| 55 | #include <string.h> |
| @@ -122,11 +122,11 @@ | |
| 122 | indent = i - 2; |
| 123 | if( indent<0 ) indent = 0; |
| 124 | omitline = 0; |
| 125 | for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){ |
| 126 | if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){ |
| 127 | omitline = 1; break; |
| 128 | } |
| 129 | if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; } |
| 130 | zOut[j++] = zLine[i]; |
| 131 | } |
| 132 | while( j>0 && isspace(zOut[j-1]) ){ j--; } |
| @@ -137,11 +137,11 @@ | |
| 137 | fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut); |
| 138 | } |
| 139 | }else{ |
| 140 | /* Otherwise (if the last non-whitespace was not '=') then generate |
| 141 | ** a cgi_printf() statement whose format is the text following the '@'. |
| 142 | ** Substrings of the form "%C(...)" (where C is any sequence of |
| 143 | ** characters other than \000 and '(') will put "%C" in the |
| 144 | ** format and add the "(...)" as an argument to the cgi_printf call. |
| 145 | */ |
| 146 | int indent; |
| 147 | int nC; |
| @@ -174,11 +174,11 @@ | |
| 174 | fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut); |
| 175 | inPrint = 1; |
| 176 | }else{ |
| 177 | fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut); |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | int main(int argc, char **argv){ |
| 184 | if( argc==2 ){ |
| 185 |
+9
-8
| --- src/undo.c | ||
| +++ src/undo.c | ||
| @@ -143,11 +143,12 @@ | ||
| 143 | 143 | "INSERT INTO vmerge SELECT * FROM undo_vmerge;" |
| 144 | 144 | "DELETE FROM undo_vmerge;" |
| 145 | 145 | "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;" |
| 146 | 146 | "DROP TABLE undo_vmerge_2;" |
| 147 | 147 | ); |
| 148 | - if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){ | |
| 148 | + if(db_exists("SELECT 1 FROM \"%w\".sqlite_master" | |
| 149 | + " WHERE name='undo_stash'", zDb) ){ | |
| 149 | 150 | if( redoFlag ){ |
| 150 | 151 | db_multi_exec( |
| 151 | 152 | "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);" |
| 152 | 153 | "DELETE FROM stashfile" |
| 153 | 154 | " WHERE stashid NOT IN (SELECT stashid FROM stash);" |
| @@ -174,11 +175,11 @@ | ||
| 174 | 175 | @ DROP TABLE IF EXISTS undo_vfile; |
| 175 | 176 | @ DROP TABLE IF EXISTS undo_vmerge; |
| 176 | 177 | @ DROP TABLE IF EXISTS undo_stash; |
| 177 | 178 | @ DROP TABLE IF EXISTS undo_stashfile; |
| 178 | 179 | ; |
| 179 | - db_multi_exec(zSql); | |
| 180 | + db_multi_exec(zSql /*works-like:""*/); | |
| 180 | 181 | db_lset_int("undo_available", 0); |
| 181 | 182 | db_lset_int("undo_checkout", 0); |
| 182 | 183 | } |
| 183 | 184 | |
| 184 | 185 | /* |
| @@ -219,24 +220,24 @@ | ||
| 219 | 220 | */ |
| 220 | 221 | void undo_begin(void){ |
| 221 | 222 | int cid; |
| 222 | 223 | const char *zDb = db_name("localdb"); |
| 223 | 224 | static const char zSql[] = |
| 224 | - @ CREATE TABLE %s.undo( | |
| 225 | + @ CREATE TABLE "%w".undo( | |
| 225 | 226 | @ pathname TEXT UNIQUE, -- Name of the file |
| 226 | 227 | @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable |
| 227 | 228 | @ existsflag BOOLEAN, -- True if the file exists |
| 228 | 229 | @ isExe BOOLEAN, -- True if the file is executable |
| 229 | 230 | @ isLink BOOLEAN, -- True if the file is symlink |
| 230 | 231 | @ content BLOB -- Saved content |
| 231 | 232 | @ ); |
| 232 | - @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile; | |
| 233 | - @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge; | |
| 233 | + @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile; | |
| 234 | + @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge; | |
| 234 | 235 | ; |
| 235 | 236 | if( undoDisable ) return; |
| 236 | 237 | undo_reset(); |
| 237 | - db_multi_exec(zSql, zDb, zDb, zDb); | |
| 238 | + db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb); | |
| 238 | 239 | cid = db_lget_int("checkout", 0); |
| 239 | 240 | db_lset_int("undo_checkout", cid); |
| 240 | 241 | db_lset_int("undo_available", 1); |
| 241 | 242 | db_lset("undo_cmdline", undoCmd); |
| 242 | 243 | undoActive = 1; |
| @@ -301,18 +302,18 @@ | ||
| 301 | 302 | ** Make the current state of stashid undoable. |
| 302 | 303 | */ |
| 303 | 304 | void undo_save_stash(int stashid){ |
| 304 | 305 | const char *zDb = db_name("localdb"); |
| 305 | 306 | db_multi_exec( |
| 306 | - "CREATE TABLE IF NOT EXISTS %s.undo_stash" | |
| 307 | + "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash" | |
| 307 | 308 | " AS SELECT * FROM stash WHERE 0;" |
| 308 | 309 | "INSERT INTO undo_stash" |
| 309 | 310 | " SELECT * FROM stash WHERE stashid=%d;", |
| 310 | 311 | zDb, stashid |
| 311 | 312 | ); |
| 312 | 313 | db_multi_exec( |
| 313 | - "CREATE TABLE IF NOT EXISTS %s.undo_stashfile" | |
| 314 | + "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile" | |
| 314 | 315 | " AS SELECT * FROM stashfile WHERE 0;" |
| 315 | 316 | "INSERT INTO undo_stashfile" |
| 316 | 317 | " SELECT * FROM stashfile WHERE stashid=%d;", |
| 317 | 318 | zDb, stashid |
| 318 | 319 | ); |
| 319 | 320 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -143,11 +143,12 @@ | |
| 143 | "INSERT INTO vmerge SELECT * FROM undo_vmerge;" |
| 144 | "DELETE FROM undo_vmerge;" |
| 145 | "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;" |
| 146 | "DROP TABLE undo_vmerge_2;" |
| 147 | ); |
| 148 | if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){ |
| 149 | if( redoFlag ){ |
| 150 | db_multi_exec( |
| 151 | "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);" |
| 152 | "DELETE FROM stashfile" |
| 153 | " WHERE stashid NOT IN (SELECT stashid FROM stash);" |
| @@ -174,11 +175,11 @@ | |
| 174 | @ DROP TABLE IF EXISTS undo_vfile; |
| 175 | @ DROP TABLE IF EXISTS undo_vmerge; |
| 176 | @ DROP TABLE IF EXISTS undo_stash; |
| 177 | @ DROP TABLE IF EXISTS undo_stashfile; |
| 178 | ; |
| 179 | db_multi_exec(zSql); |
| 180 | db_lset_int("undo_available", 0); |
| 181 | db_lset_int("undo_checkout", 0); |
| 182 | } |
| 183 | |
| 184 | /* |
| @@ -219,24 +220,24 @@ | |
| 219 | */ |
| 220 | void undo_begin(void){ |
| 221 | int cid; |
| 222 | const char *zDb = db_name("localdb"); |
| 223 | static const char zSql[] = |
| 224 | @ CREATE TABLE %s.undo( |
| 225 | @ pathname TEXT UNIQUE, -- Name of the file |
| 226 | @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable |
| 227 | @ existsflag BOOLEAN, -- True if the file exists |
| 228 | @ isExe BOOLEAN, -- True if the file is executable |
| 229 | @ isLink BOOLEAN, -- True if the file is symlink |
| 230 | @ content BLOB -- Saved content |
| 231 | @ ); |
| 232 | @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile; |
| 233 | @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge; |
| 234 | ; |
| 235 | if( undoDisable ) return; |
| 236 | undo_reset(); |
| 237 | db_multi_exec(zSql, zDb, zDb, zDb); |
| 238 | cid = db_lget_int("checkout", 0); |
| 239 | db_lset_int("undo_checkout", cid); |
| 240 | db_lset_int("undo_available", 1); |
| 241 | db_lset("undo_cmdline", undoCmd); |
| 242 | undoActive = 1; |
| @@ -301,18 +302,18 @@ | |
| 301 | ** Make the current state of stashid undoable. |
| 302 | */ |
| 303 | void undo_save_stash(int stashid){ |
| 304 | const char *zDb = db_name("localdb"); |
| 305 | db_multi_exec( |
| 306 | "CREATE TABLE IF NOT EXISTS %s.undo_stash" |
| 307 | " AS SELECT * FROM stash WHERE 0;" |
| 308 | "INSERT INTO undo_stash" |
| 309 | " SELECT * FROM stash WHERE stashid=%d;", |
| 310 | zDb, stashid |
| 311 | ); |
| 312 | db_multi_exec( |
| 313 | "CREATE TABLE IF NOT EXISTS %s.undo_stashfile" |
| 314 | " AS SELECT * FROM stashfile WHERE 0;" |
| 315 | "INSERT INTO undo_stashfile" |
| 316 | " SELECT * FROM stashfile WHERE stashid=%d;", |
| 317 | zDb, stashid |
| 318 | ); |
| 319 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -143,11 +143,12 @@ | |
| 143 | "INSERT INTO vmerge SELECT * FROM undo_vmerge;" |
| 144 | "DELETE FROM undo_vmerge;" |
| 145 | "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;" |
| 146 | "DROP TABLE undo_vmerge_2;" |
| 147 | ); |
| 148 | if(db_exists("SELECT 1 FROM \"%w\".sqlite_master" |
| 149 | " WHERE name='undo_stash'", zDb) ){ |
| 150 | if( redoFlag ){ |
| 151 | db_multi_exec( |
| 152 | "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);" |
| 153 | "DELETE FROM stashfile" |
| 154 | " WHERE stashid NOT IN (SELECT stashid FROM stash);" |
| @@ -174,11 +175,11 @@ | |
| 175 | @ DROP TABLE IF EXISTS undo_vfile; |
| 176 | @ DROP TABLE IF EXISTS undo_vmerge; |
| 177 | @ DROP TABLE IF EXISTS undo_stash; |
| 178 | @ DROP TABLE IF EXISTS undo_stashfile; |
| 179 | ; |
| 180 | db_multi_exec(zSql /*works-like:""*/); |
| 181 | db_lset_int("undo_available", 0); |
| 182 | db_lset_int("undo_checkout", 0); |
| 183 | } |
| 184 | |
| 185 | /* |
| @@ -219,24 +220,24 @@ | |
| 220 | */ |
| 221 | void undo_begin(void){ |
| 222 | int cid; |
| 223 | const char *zDb = db_name("localdb"); |
| 224 | static const char zSql[] = |
| 225 | @ CREATE TABLE "%w".undo( |
| 226 | @ pathname TEXT UNIQUE, -- Name of the file |
| 227 | @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable |
| 228 | @ existsflag BOOLEAN, -- True if the file exists |
| 229 | @ isExe BOOLEAN, -- True if the file is executable |
| 230 | @ isLink BOOLEAN, -- True if the file is symlink |
| 231 | @ content BLOB -- Saved content |
| 232 | @ ); |
| 233 | @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile; |
| 234 | @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge; |
| 235 | ; |
| 236 | if( undoDisable ) return; |
| 237 | undo_reset(); |
| 238 | db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb); |
| 239 | cid = db_lget_int("checkout", 0); |
| 240 | db_lset_int("undo_checkout", cid); |
| 241 | db_lset_int("undo_available", 1); |
| 242 | db_lset("undo_cmdline", undoCmd); |
| 243 | undoActive = 1; |
| @@ -301,18 +302,18 @@ | |
| 302 | ** Make the current state of stashid undoable. |
| 303 | */ |
| 304 | void undo_save_stash(int stashid){ |
| 305 | const char *zDb = db_name("localdb"); |
| 306 | db_multi_exec( |
| 307 | "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash" |
| 308 | " AS SELECT * FROM stash WHERE 0;" |
| 309 | "INSERT INTO undo_stash" |
| 310 | " SELECT * FROM stash WHERE stashid=%d;", |
| 311 | zDb, stashid |
| 312 | ); |
| 313 | db_multi_exec( |
| 314 | "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile" |
| 315 | " AS SELECT * FROM stashfile WHERE 0;" |
| 316 | "INSERT INTO undo_stashfile" |
| 317 | " SELECT * FROM stashfile WHERE stashid=%d;", |
| 318 | zDb, stashid |
| 319 | ); |
| 320 |
+5
-3
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -357,22 +357,24 @@ | ||
| 357 | 357 | zSep = ""; |
| 358 | 358 | for(i=3; i<g.argc; i++){ |
| 359 | 359 | file_tree_name(g.argv[i], &treename, 1); |
| 360 | 360 | if( file_wd_isdir(g.argv[i])==1 ){ |
| 361 | 361 | if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){ |
| 362 | - blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename); | |
| 362 | + blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", | |
| 363 | + zSep /*safe-for-%s*/, blob_str(&treename)); | |
| 363 | 364 | }else{ |
| 364 | 365 | blob_reset(&sql); |
| 365 | 366 | break; |
| 366 | 367 | } |
| 367 | 368 | }else{ |
| 368 | - blob_appendf(&sql, "%sfn<>%B ", zSep, &treename); | |
| 369 | + blob_append_sql(&sql, "%sfn<>%Q ", | |
| 370 | + zSep /*safe-for-%s*/, blob_str(&treename)); | |
| 369 | 371 | } |
| 370 | 372 | zSep = "AND "; |
| 371 | 373 | blob_reset(&treename); |
| 372 | 374 | } |
| 373 | - db_multi_exec(blob_str(&sql)); | |
| 375 | + db_multi_exec("%s", blob_sql_text(&sql)); | |
| 374 | 376 | blob_reset(&sql); |
| 375 | 377 | } |
| 376 | 378 | |
| 377 | 379 | /* |
| 378 | 380 | ** Alter the content of the checkout so that it conforms with the |
| 379 | 381 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -357,22 +357,24 @@ | |
| 357 | zSep = ""; |
| 358 | for(i=3; i<g.argc; i++){ |
| 359 | file_tree_name(g.argv[i], &treename, 1); |
| 360 | if( file_wd_isdir(g.argv[i])==1 ){ |
| 361 | if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){ |
| 362 | blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename); |
| 363 | }else{ |
| 364 | blob_reset(&sql); |
| 365 | break; |
| 366 | } |
| 367 | }else{ |
| 368 | blob_appendf(&sql, "%sfn<>%B ", zSep, &treename); |
| 369 | } |
| 370 | zSep = "AND "; |
| 371 | blob_reset(&treename); |
| 372 | } |
| 373 | db_multi_exec(blob_str(&sql)); |
| 374 | blob_reset(&sql); |
| 375 | } |
| 376 | |
| 377 | /* |
| 378 | ** Alter the content of the checkout so that it conforms with the |
| 379 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -357,22 +357,24 @@ | |
| 357 | zSep = ""; |
| 358 | for(i=3; i<g.argc; i++){ |
| 359 | file_tree_name(g.argv[i], &treename, 1); |
| 360 | if( file_wd_isdir(g.argv[i])==1 ){ |
| 361 | if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){ |
| 362 | blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", |
| 363 | zSep /*safe-for-%s*/, blob_str(&treename)); |
| 364 | }else{ |
| 365 | blob_reset(&sql); |
| 366 | break; |
| 367 | } |
| 368 | }else{ |
| 369 | blob_append_sql(&sql, "%sfn<>%Q ", |
| 370 | zSep /*safe-for-%s*/, blob_str(&treename)); |
| 371 | } |
| 372 | zSep = "AND "; |
| 373 | blob_reset(&treename); |
| 374 | } |
| 375 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 376 | blob_reset(&sql); |
| 377 | } |
| 378 | |
| 379 | /* |
| 380 | ** Alter the content of the checkout so that it conforms with the |
| 381 |
+3
-3
| --- src/user.c | ||
| +++ src/user.c | ||
| @@ -451,26 +451,26 @@ | ||
| 451 | 451 | cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n); |
| 452 | 452 | return; |
| 453 | 453 | } |
| 454 | 454 | style_header("Access Log"); |
| 455 | 455 | blob_zero(&sql); |
| 456 | - blob_appendf(&sql, | |
| 456 | + blob_append_sql(&sql, | |
| 457 | 457 | "SELECT uname, ipaddr, datetime(mtime%s), success" |
| 458 | 458 | " FROM accesslog", timeline_utc() |
| 459 | 459 | ); |
| 460 | 460 | if( y==1 ){ |
| 461 | 461 | blob_append(&sql, " WHERE success", -1); |
| 462 | 462 | }else if( y==2 ){ |
| 463 | 463 | blob_append(&sql, " WHERE NOT success", -1); |
| 464 | 464 | } |
| 465 | - blob_appendf(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip); | |
| 465 | + blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip); | |
| 466 | 466 | if( skip ){ |
| 467 | 467 | style_submenu_element("Newer", "Newer entries", |
| 468 | 468 | "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0, |
| 469 | 469 | n, y); |
| 470 | 470 | } |
| 471 | - rc = db_prepare_ignore_error(&q, blob_str(&sql)); | |
| 471 | + rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql)); | |
| 472 | 472 | @ <center><table border="1" cellpadding="5"> |
| 473 | 473 | @ <tr><th width="33%%">Date</th><th width="34%%">User</th> |
| 474 | 474 | @ <th width="33%%">IP Address</th></tr> |
| 475 | 475 | while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){ |
| 476 | 476 | const char *zName = db_column_text(&q, 0); |
| 477 | 477 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -451,26 +451,26 @@ | |
| 451 | cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n); |
| 452 | return; |
| 453 | } |
| 454 | style_header("Access Log"); |
| 455 | blob_zero(&sql); |
| 456 | blob_appendf(&sql, |
| 457 | "SELECT uname, ipaddr, datetime(mtime%s), success" |
| 458 | " FROM accesslog", timeline_utc() |
| 459 | ); |
| 460 | if( y==1 ){ |
| 461 | blob_append(&sql, " WHERE success", -1); |
| 462 | }else if( y==2 ){ |
| 463 | blob_append(&sql, " WHERE NOT success", -1); |
| 464 | } |
| 465 | blob_appendf(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip); |
| 466 | if( skip ){ |
| 467 | style_submenu_element("Newer", "Newer entries", |
| 468 | "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0, |
| 469 | n, y); |
| 470 | } |
| 471 | rc = db_prepare_ignore_error(&q, blob_str(&sql)); |
| 472 | @ <center><table border="1" cellpadding="5"> |
| 473 | @ <tr><th width="33%%">Date</th><th width="34%%">User</th> |
| 474 | @ <th width="33%%">IP Address</th></tr> |
| 475 | while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){ |
| 476 | const char *zName = db_column_text(&q, 0); |
| 477 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -451,26 +451,26 @@ | |
| 451 | cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n); |
| 452 | return; |
| 453 | } |
| 454 | style_header("Access Log"); |
| 455 | blob_zero(&sql); |
| 456 | blob_append_sql(&sql, |
| 457 | "SELECT uname, ipaddr, datetime(mtime%s), success" |
| 458 | " FROM accesslog", timeline_utc() |
| 459 | ); |
| 460 | if( y==1 ){ |
| 461 | blob_append(&sql, " WHERE success", -1); |
| 462 | }else if( y==2 ){ |
| 463 | blob_append(&sql, " WHERE NOT success", -1); |
| 464 | } |
| 465 | blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip); |
| 466 | if( skip ){ |
| 467 | style_submenu_element("Newer", "Newer entries", |
| 468 | "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0, |
| 469 | n, y); |
| 470 | } |
| 471 | rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql)); |
| 472 | @ <center><table border="1" cellpadding="5"> |
| 473 | @ <tr><th width="33%%">Date</th><th width="34%%">User</th> |
| 474 | @ <th width="33%%">IP Address</th></tr> |
| 475 | while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){ |
| 476 | const char *zName = db_column_text(&q, 0); |
| 477 |
+2
-2
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -397,13 +397,13 @@ | ||
| 397 | 397 | "original", |
| 398 | 398 | "output", |
| 399 | 399 | }; |
| 400 | 400 | int i, j, n; |
| 401 | 401 | |
| 402 | - if( strglob("ci-comment-????????????.txt", zName) ) return 1; | |
| 402 | + if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1; | |
| 403 | 403 | for(; zName[0]!=0; zName++){ |
| 404 | - if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){ | |
| 404 | + if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){ | |
| 405 | 405 | return 1; |
| 406 | 406 | } |
| 407 | 407 | if( zName[0]!='-' ) continue; |
| 408 | 408 | for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){ |
| 409 | 409 | n = (int)strlen(azTemp[i]); |
| 410 | 410 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -397,13 +397,13 @@ | |
| 397 | "original", |
| 398 | "output", |
| 399 | }; |
| 400 | int i, j, n; |
| 401 | |
| 402 | if( strglob("ci-comment-????????????.txt", zName) ) return 1; |
| 403 | for(; zName[0]!=0; zName++){ |
| 404 | if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){ |
| 405 | return 1; |
| 406 | } |
| 407 | if( zName[0]!='-' ) continue; |
| 408 | for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){ |
| 409 | n = (int)strlen(azTemp[i]); |
| 410 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -397,13 +397,13 @@ | |
| 397 | "original", |
| 398 | "output", |
| 399 | }; |
| 400 | int i, j, n; |
| 401 | |
| 402 | if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1; |
| 403 | for(; zName[0]!=0; zName++){ |
| 404 | if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){ |
| 405 | return 1; |
| 406 | } |
| 407 | if( zName[0]!='-' ) continue; |
| 408 | for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){ |
| 409 | n = (int)strlen(azTemp[i]); |
| 410 |
+5
-14
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -292,11 +292,11 @@ | ||
| 292 | 292 | style_submenu_element("History", "History", "%s/whistory?name=%T", |
| 293 | 293 | g.zTop, zPageName); |
| 294 | 294 | } |
| 295 | 295 | } |
| 296 | 296 | style_set_current_page("%T?name=%T", g.zPath, zPageName); |
| 297 | - style_header(zPageName); | |
| 297 | + style_header("%s", zPageName); | |
| 298 | 298 | blob_init(&wiki, zBody, -1); |
| 299 | 299 | wiki_render_by_mimetype(&wiki, zMimetype); |
| 300 | 300 | blob_reset(&wiki); |
| 301 | 301 | attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>"); |
| 302 | 302 | manifest_destroy(pWiki); |
| @@ -649,11 +649,11 @@ | ||
| 649 | 649 | Blob wiki; |
| 650 | 650 | Manifest *pWiki = 0; |
| 651 | 651 | |
| 652 | 652 | blob_zero(&body); |
| 653 | 653 | if( isSandbox ){ |
| 654 | - blob_appendf(&body, db_get("sandbox","")); | |
| 654 | + blob_append(&body, db_get("sandbox",""), -1); | |
| 655 | 655 | appendRemark(&body, zMimetype); |
| 656 | 656 | db_set("sandbox", blob_str(&body), 0); |
| 657 | 657 | }else{ |
| 658 | 658 | login_verify_csrf_secret(); |
| 659 | 659 | pWiki = manifest_get(rid, CFTYPE_WIKI, 0); |
| @@ -746,29 +746,23 @@ | ||
| 746 | 746 | ** |
| 747 | 747 | ** Show the complete change history for a single wiki page. |
| 748 | 748 | */ |
| 749 | 749 | void whistory_page(void){ |
| 750 | 750 | Stmt q; |
| 751 | - char *zTitle; | |
| 752 | - char *zSQL; | |
| 753 | 751 | const char *zPageName; |
| 754 | 752 | login_check_credentials(); |
| 755 | 753 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 756 | 754 | zPageName = PD("name",""); |
| 757 | - zTitle = mprintf("History Of %s", zPageName); | |
| 758 | - style_header(zTitle); | |
| 759 | - free(zTitle); | |
| 755 | + style_header("History Of %s", zPageName); | |
| 760 | 756 | |
| 761 | - zSQL = mprintf("%s AND event.objid IN " | |
| 757 | + db_prepare(&q, "%s AND event.objid IN " | |
| 762 | 758 | " (SELECT rid FROM tagxref WHERE tagid=" |
| 763 | 759 | "(SELECT tagid FROM tag WHERE tagname='wiki-%q')" |
| 764 | 760 | " UNION SELECT attachid FROM attachment" |
| 765 | 761 | " WHERE target=%Q)" |
| 766 | 762 | "ORDER BY mtime DESC", |
| 767 | 763 | timeline_query_for_www(), zPageName, zPageName); |
| 768 | - db_prepare(&q, zSQL); | |
| 769 | - free(zSQL); | |
| 770 | 764 | zWikiPageName = zPageName; |
| 771 | 765 | www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra); |
| 772 | 766 | db_finalize(&q); |
| 773 | 767 | style_footer(); |
| 774 | 768 | } |
| @@ -778,11 +772,10 @@ | ||
| 778 | 772 | ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2 |
| 779 | 773 | ** |
| 780 | 774 | ** Show the difference between two wiki pages. |
| 781 | 775 | */ |
| 782 | 776 | void wdiff_page(void){ |
| 783 | - char *zTitle; | |
| 784 | 777 | int rid1, rid2; |
| 785 | 778 | const char *zPageName; |
| 786 | 779 | Manifest *pW1, *pW2 = 0; |
| 787 | 780 | Blob w1, w2, d; |
| 788 | 781 | u64 diffFlags; |
| @@ -791,13 +784,11 @@ | ||
| 791 | 784 | rid1 = atoi(PD("a","0")); |
| 792 | 785 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 793 | 786 | if( rid1==0 ) fossil_redirect_home(); |
| 794 | 787 | rid2 = atoi(PD("b","0")); |
| 795 | 788 | zPageName = PD("name",""); |
| 796 | - zTitle = mprintf("Changes To %s", zPageName); | |
| 797 | - style_header(zTitle); | |
| 798 | - free(zTitle); | |
| 789 | + style_header("Changes To %s", zPageName); | |
| 799 | 790 | |
| 800 | 791 | if( rid2==0 ){ |
| 801 | 792 | rid2 = db_int(0, |
| 802 | 793 | "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid=" |
| 803 | 794 | "(SELECT tagid FROM tag WHERE tagname='wiki-%q')" |
| 804 | 795 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -292,11 +292,11 @@ | |
| 292 | style_submenu_element("History", "History", "%s/whistory?name=%T", |
| 293 | g.zTop, zPageName); |
| 294 | } |
| 295 | } |
| 296 | style_set_current_page("%T?name=%T", g.zPath, zPageName); |
| 297 | style_header(zPageName); |
| 298 | blob_init(&wiki, zBody, -1); |
| 299 | wiki_render_by_mimetype(&wiki, zMimetype); |
| 300 | blob_reset(&wiki); |
| 301 | attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>"); |
| 302 | manifest_destroy(pWiki); |
| @@ -649,11 +649,11 @@ | |
| 649 | Blob wiki; |
| 650 | Manifest *pWiki = 0; |
| 651 | |
| 652 | blob_zero(&body); |
| 653 | if( isSandbox ){ |
| 654 | blob_appendf(&body, db_get("sandbox","")); |
| 655 | appendRemark(&body, zMimetype); |
| 656 | db_set("sandbox", blob_str(&body), 0); |
| 657 | }else{ |
| 658 | login_verify_csrf_secret(); |
| 659 | pWiki = manifest_get(rid, CFTYPE_WIKI, 0); |
| @@ -746,29 +746,23 @@ | |
| 746 | ** |
| 747 | ** Show the complete change history for a single wiki page. |
| 748 | */ |
| 749 | void whistory_page(void){ |
| 750 | Stmt q; |
| 751 | char *zTitle; |
| 752 | char *zSQL; |
| 753 | const char *zPageName; |
| 754 | login_check_credentials(); |
| 755 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 756 | zPageName = PD("name",""); |
| 757 | zTitle = mprintf("History Of %s", zPageName); |
| 758 | style_header(zTitle); |
| 759 | free(zTitle); |
| 760 | |
| 761 | zSQL = mprintf("%s AND event.objid IN " |
| 762 | " (SELECT rid FROM tagxref WHERE tagid=" |
| 763 | "(SELECT tagid FROM tag WHERE tagname='wiki-%q')" |
| 764 | " UNION SELECT attachid FROM attachment" |
| 765 | " WHERE target=%Q)" |
| 766 | "ORDER BY mtime DESC", |
| 767 | timeline_query_for_www(), zPageName, zPageName); |
| 768 | db_prepare(&q, zSQL); |
| 769 | free(zSQL); |
| 770 | zWikiPageName = zPageName; |
| 771 | www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra); |
| 772 | db_finalize(&q); |
| 773 | style_footer(); |
| 774 | } |
| @@ -778,11 +772,10 @@ | |
| 778 | ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2 |
| 779 | ** |
| 780 | ** Show the difference between two wiki pages. |
| 781 | */ |
| 782 | void wdiff_page(void){ |
| 783 | char *zTitle; |
| 784 | int rid1, rid2; |
| 785 | const char *zPageName; |
| 786 | Manifest *pW1, *pW2 = 0; |
| 787 | Blob w1, w2, d; |
| 788 | u64 diffFlags; |
| @@ -791,13 +784,11 @@ | |
| 791 | rid1 = atoi(PD("a","0")); |
| 792 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 793 | if( rid1==0 ) fossil_redirect_home(); |
| 794 | rid2 = atoi(PD("b","0")); |
| 795 | zPageName = PD("name",""); |
| 796 | zTitle = mprintf("Changes To %s", zPageName); |
| 797 | style_header(zTitle); |
| 798 | free(zTitle); |
| 799 | |
| 800 | if( rid2==0 ){ |
| 801 | rid2 = db_int(0, |
| 802 | "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid=" |
| 803 | "(SELECT tagid FROM tag WHERE tagname='wiki-%q')" |
| 804 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -292,11 +292,11 @@ | |
| 292 | style_submenu_element("History", "History", "%s/whistory?name=%T", |
| 293 | g.zTop, zPageName); |
| 294 | } |
| 295 | } |
| 296 | style_set_current_page("%T?name=%T", g.zPath, zPageName); |
| 297 | style_header("%s", zPageName); |
| 298 | blob_init(&wiki, zBody, -1); |
| 299 | wiki_render_by_mimetype(&wiki, zMimetype); |
| 300 | blob_reset(&wiki); |
| 301 | attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>"); |
| 302 | manifest_destroy(pWiki); |
| @@ -649,11 +649,11 @@ | |
| 649 | Blob wiki; |
| 650 | Manifest *pWiki = 0; |
| 651 | |
| 652 | blob_zero(&body); |
| 653 | if( isSandbox ){ |
| 654 | blob_append(&body, db_get("sandbox",""), -1); |
| 655 | appendRemark(&body, zMimetype); |
| 656 | db_set("sandbox", blob_str(&body), 0); |
| 657 | }else{ |
| 658 | login_verify_csrf_secret(); |
| 659 | pWiki = manifest_get(rid, CFTYPE_WIKI, 0); |
| @@ -746,29 +746,23 @@ | |
| 746 | ** |
| 747 | ** Show the complete change history for a single wiki page. |
| 748 | */ |
| 749 | void whistory_page(void){ |
| 750 | Stmt q; |
| 751 | const char *zPageName; |
| 752 | login_check_credentials(); |
| 753 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 754 | zPageName = PD("name",""); |
| 755 | style_header("History Of %s", zPageName); |
| 756 | |
| 757 | db_prepare(&q, "%s AND event.objid IN " |
| 758 | " (SELECT rid FROM tagxref WHERE tagid=" |
| 759 | "(SELECT tagid FROM tag WHERE tagname='wiki-%q')" |
| 760 | " UNION SELECT attachid FROM attachment" |
| 761 | " WHERE target=%Q)" |
| 762 | "ORDER BY mtime DESC", |
| 763 | timeline_query_for_www(), zPageName, zPageName); |
| 764 | zWikiPageName = zPageName; |
| 765 | www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra); |
| 766 | db_finalize(&q); |
| 767 | style_footer(); |
| 768 | } |
| @@ -778,11 +772,10 @@ | |
| 772 | ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2 |
| 773 | ** |
| 774 | ** Show the difference between two wiki pages. |
| 775 | */ |
| 776 | void wdiff_page(void){ |
| 777 | int rid1, rid2; |
| 778 | const char *zPageName; |
| 779 | Manifest *pW1, *pW2 = 0; |
| 780 | Blob w1, w2, d; |
| 781 | u64 diffFlags; |
| @@ -791,13 +784,11 @@ | |
| 784 | rid1 = atoi(PD("a","0")); |
| 785 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 786 | if( rid1==0 ) fossil_redirect_home(); |
| 787 | rid2 = atoi(PD("b","0")); |
| 788 | zPageName = PD("name",""); |
| 789 | style_header("Changes To %s", zPageName); |
| 790 | |
| 791 | if( rid2==0 ){ |
| 792 | rid2 = db_int(0, |
| 793 | "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid=" |
| 794 | "(SELECT tagid FROM tag WHERE tagname='wiki-%q')" |
| 795 |
+4
-4
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -1046,11 +1046,11 @@ | ||
| 1046 | 1046 | */ |
| 1047 | 1047 | static void startAutoParagraph(Renderer *p){ |
| 1048 | 1048 | if( p->wantAutoParagraph==0 ) return; |
| 1049 | 1049 | if( p->state & WIKI_LINKSONLY ) return; |
| 1050 | 1050 | if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; |
| 1051 | - blob_appendf(p->pOut, "<p>", -1); | |
| 1051 | + blob_append(p->pOut, "<p>", -1); | |
| 1052 | 1052 | p->wantAutoParagraph = 0; |
| 1053 | 1053 | p->inAutoParagraph = 1; |
| 1054 | 1054 | } |
| 1055 | 1055 | |
| 1056 | 1056 | /* |
| @@ -1121,11 +1121,11 @@ | ||
| 1121 | 1121 | if( once ){ |
| 1122 | 1122 | const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'"); |
| 1123 | 1123 | db_static_prepare(&q, |
| 1124 | 1124 | "SELECT %s FROM ticket " |
| 1125 | 1125 | " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr", |
| 1126 | - zClosedExpr | |
| 1126 | + zClosedExpr /*safe-for-%s*/ | |
| 1127 | 1127 | ); |
| 1128 | 1128 | once = 0; |
| 1129 | 1129 | } |
| 1130 | 1130 | db_bind_text(&q, ":lwr", zLower); |
| 1131 | 1131 | db_bind_text(&q, ":upr", zUpper); |
| @@ -1243,11 +1243,11 @@ | ||
| 1243 | 1243 | } |
| 1244 | 1244 | }else if( !in_this_repo(zTarget) ){ |
| 1245 | 1245 | if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){ |
| 1246 | 1246 | zTerm = ""; |
| 1247 | 1247 | }else{ |
| 1248 | - blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget); | |
| 1248 | + blob_appendf(p->pOut, "<span class=\"brokenlink\">["); | |
| 1249 | 1249 | zTerm = "]</span>"; |
| 1250 | 1250 | } |
| 1251 | 1251 | }else if( g.perm.Hyperlink ){ |
| 1252 | 1252 | blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget)); |
| 1253 | 1253 | zTerm = "]</a>"; |
| @@ -1328,11 +1328,11 @@ | ||
| 1328 | 1328 | if( p->wikiList ){ |
| 1329 | 1329 | popStackToTag(p, p->wikiList); |
| 1330 | 1330 | p->wikiList = 0; |
| 1331 | 1331 | } |
| 1332 | 1332 | endAutoParagraph(p); |
| 1333 | - blob_appendf(p->pOut, "\n\n", 1); | |
| 1333 | + blob_append(p->pOut, "\n\n", 1); | |
| 1334 | 1334 | p->wantAutoParagraph = 1; |
| 1335 | 1335 | } |
| 1336 | 1336 | p->state |= AT_PARAGRAPH|AT_NEWLINE; |
| 1337 | 1337 | break; |
| 1338 | 1338 | } |
| 1339 | 1339 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1046,11 +1046,11 @@ | |
| 1046 | */ |
| 1047 | static void startAutoParagraph(Renderer *p){ |
| 1048 | if( p->wantAutoParagraph==0 ) return; |
| 1049 | if( p->state & WIKI_LINKSONLY ) return; |
| 1050 | if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; |
| 1051 | blob_appendf(p->pOut, "<p>", -1); |
| 1052 | p->wantAutoParagraph = 0; |
| 1053 | p->inAutoParagraph = 1; |
| 1054 | } |
| 1055 | |
| 1056 | /* |
| @@ -1121,11 +1121,11 @@ | |
| 1121 | if( once ){ |
| 1122 | const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'"); |
| 1123 | db_static_prepare(&q, |
| 1124 | "SELECT %s FROM ticket " |
| 1125 | " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr", |
| 1126 | zClosedExpr |
| 1127 | ); |
| 1128 | once = 0; |
| 1129 | } |
| 1130 | db_bind_text(&q, ":lwr", zLower); |
| 1131 | db_bind_text(&q, ":upr", zUpper); |
| @@ -1243,11 +1243,11 @@ | |
| 1243 | } |
| 1244 | }else if( !in_this_repo(zTarget) ){ |
| 1245 | if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){ |
| 1246 | zTerm = ""; |
| 1247 | }else{ |
| 1248 | blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget); |
| 1249 | zTerm = "]</span>"; |
| 1250 | } |
| 1251 | }else if( g.perm.Hyperlink ){ |
| 1252 | blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget)); |
| 1253 | zTerm = "]</a>"; |
| @@ -1328,11 +1328,11 @@ | |
| 1328 | if( p->wikiList ){ |
| 1329 | popStackToTag(p, p->wikiList); |
| 1330 | p->wikiList = 0; |
| 1331 | } |
| 1332 | endAutoParagraph(p); |
| 1333 | blob_appendf(p->pOut, "\n\n", 1); |
| 1334 | p->wantAutoParagraph = 1; |
| 1335 | } |
| 1336 | p->state |= AT_PARAGRAPH|AT_NEWLINE; |
| 1337 | break; |
| 1338 | } |
| 1339 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1046,11 +1046,11 @@ | |
| 1046 | */ |
| 1047 | static void startAutoParagraph(Renderer *p){ |
| 1048 | if( p->wantAutoParagraph==0 ) return; |
| 1049 | if( p->state & WIKI_LINKSONLY ) return; |
| 1050 | if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return; |
| 1051 | blob_append(p->pOut, "<p>", -1); |
| 1052 | p->wantAutoParagraph = 0; |
| 1053 | p->inAutoParagraph = 1; |
| 1054 | } |
| 1055 | |
| 1056 | /* |
| @@ -1121,11 +1121,11 @@ | |
| 1121 | if( once ){ |
| 1122 | const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'"); |
| 1123 | db_static_prepare(&q, |
| 1124 | "SELECT %s FROM ticket " |
| 1125 | " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr", |
| 1126 | zClosedExpr /*safe-for-%s*/ |
| 1127 | ); |
| 1128 | once = 0; |
| 1129 | } |
| 1130 | db_bind_text(&q, ":lwr", zLower); |
| 1131 | db_bind_text(&q, ":upr", zUpper); |
| @@ -1243,11 +1243,11 @@ | |
| 1243 | } |
| 1244 | }else if( !in_this_repo(zTarget) ){ |
| 1245 | if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){ |
| 1246 | zTerm = ""; |
| 1247 | }else{ |
| 1248 | blob_appendf(p->pOut, "<span class=\"brokenlink\">["); |
| 1249 | zTerm = "]</span>"; |
| 1250 | } |
| 1251 | }else if( g.perm.Hyperlink ){ |
| 1252 | blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget)); |
| 1253 | zTerm = "]</a>"; |
| @@ -1328,11 +1328,11 @@ | |
| 1328 | if( p->wikiList ){ |
| 1329 | popStackToTag(p, p->wikiList); |
| 1330 | p->wikiList = 0; |
| 1331 | } |
| 1332 | endAutoParagraph(p); |
| 1333 | blob_append(p->pOut, "\n\n", 1); |
| 1334 | p->wantAutoParagraph = 1; |
| 1335 | } |
| 1336 | p->state |= AT_PARAGRAPH|AT_NEWLINE; |
| 1337 | break; |
| 1338 | } |
| 1339 |
+33
-27
| --- src/winhttp.c | ||
| +++ src/winhttp.c | ||
| @@ -58,10 +58,21 @@ | ||
| 58 | 58 | } |
| 59 | 59 | zHdr++; |
| 60 | 60 | } |
| 61 | 61 | return 0; |
| 62 | 62 | } |
| 63 | + | |
| 64 | +/* | |
| 65 | +** Issue a fatal error. | |
| 66 | +*/ | |
| 67 | +static NORETURN void winhttp_fatal( | |
| 68 | + const char *zOp, | |
| 69 | + const char *zService, | |
| 70 | + const char *zErr | |
| 71 | +){ | |
| 72 | + fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr); | |
| 73 | +} | |
| 63 | 74 | |
| 64 | 75 | /* |
| 65 | 76 | ** Process a single incoming HTTP request. |
| 66 | 77 | */ |
| 67 | 78 | static void win32_http_request(void *pAppData){ |
| @@ -297,11 +308,11 @@ | ||
| 297 | 308 | zTempPrefix = mprintf("%sfossil_server_P%d_", |
| 298 | 309 | fossil_unicode_to_utf8(zTmpPath), iPort); |
| 299 | 310 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 300 | 311 | (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 301 | 312 | if( zBrowser ){ |
| 302 | - zBrowser = mprintf(zBrowser, iPort); | |
| 313 | + zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort); | |
| 303 | 314 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 304 | 315 | fossil_system(zBrowser); |
| 305 | 316 | } |
| 306 | 317 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 307 | 318 | /* Set the service status to running and pass the listener socket to the |
| @@ -679,11 +690,10 @@ | ||
| 679 | 690 | if( strncmp(zMethod, "create", n)==0 ){ |
| 680 | 691 | SC_HANDLE hScm; |
| 681 | 692 | SC_HANDLE hSvc; |
| 682 | 693 | SERVICE_DESCRIPTIONW |
| 683 | 694 | svcDescr = {L"Fossil - Distributed Software Configuration Management"}; |
| 684 | - char *zErrFmt = "unable to create service '%s': %s"; | |
| 685 | 695 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 686 | 696 | const char *zDisplay = find_option("display", "D", 1); |
| 687 | 697 | const char *zStart = find_option("start", "S", 1); |
| 688 | 698 | const char *zUsername = find_option("username", "U", 1); |
| 689 | 699 | const char *zPassword = find_option("password", "W", 1); |
| @@ -714,17 +724,17 @@ | ||
| 714 | 724 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 715 | 725 | dwStartType = SERVICE_AUTO_START; |
| 716 | 726 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| 717 | 727 | dwStartType = SERVICE_DEMAND_START; |
| 718 | 728 | }else{ |
| 719 | - fossil_fatal(zErrFmt, zSvcName, | |
| 729 | + winhttp_fatal("create", zSvcName, | |
| 720 | 730 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 721 | 731 | } |
| 722 | 732 | } |
| 723 | 733 | /* Process options for Fossil running as server. */ |
| 724 | 734 | if( zPort && (atoi(zPort)<=0) ){ |
| 725 | - fossil_fatal(zErrFmt, zSvcName, | |
| 735 | + winhttp_fatal("create", zSvcName, | |
| 726 | 736 | "port number must be in the range 1 - 65535."); |
| 727 | 737 | } |
| 728 | 738 | if( !zRepository ){ |
| 729 | 739 | db_must_be_within_tree(); |
| 730 | 740 | }else if( file_isdir(zRepository)==1 ){ |
| @@ -743,11 +753,11 @@ | ||
| 743 | 753 | if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob); |
| 744 | 754 | if( zLocalAuth ) blob_append(&binPath, " --localauth", -1); |
| 745 | 755 | blob_appendf(&binPath, " \"%s\"", g.zRepositoryName); |
| 746 | 756 | /* Create the service. */ |
| 747 | 757 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 748 | - if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 758 | + if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg()); | |
| 749 | 759 | hSvc = CreateServiceW( |
| 750 | 760 | hScm, /* Handle to the SCM */ |
| 751 | 761 | fossil_utf8_to_unicode(zSvcName), /* Name of the service */ |
| 752 | 762 | fossil_utf8_to_unicode(zDisplay), /* Display name */ |
| 753 | 763 | SERVICE_ALL_ACCESS, /* Desired access */ |
| @@ -759,11 +769,11 @@ | ||
| 759 | 769 | NULL, /* Tag value */ |
| 760 | 770 | NULL, /* Service dependencies */ |
| 761 | 771 | zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */ |
| 762 | 772 | fossil_utf8_to_unicode(zPassword) /* Account password */ |
| 763 | 773 | ); |
| 764 | - if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 774 | + if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg()); | |
| 765 | 775 | /* Set the service description. */ |
| 766 | 776 | ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| 767 | 777 | fossil_print("Service '%s' successfully created.\n", zSvcName); |
| 768 | 778 | CloseServiceHandle(hSvc); |
| 769 | 779 | CloseServiceHandle(hScm); |
| @@ -770,29 +780,28 @@ | ||
| 770 | 780 | }else |
| 771 | 781 | if( strncmp(zMethod, "delete", n)==0 ){ |
| 772 | 782 | SC_HANDLE hScm; |
| 773 | 783 | SC_HANDLE hSvc; |
| 774 | 784 | SERVICE_STATUS sstat; |
| 775 | - char *zErrFmt = "unable to delete service '%s': %s"; | |
| 776 | 785 | |
| 777 | 786 | verify_all_options(); |
| 778 | 787 | if( g.argc==4 ){ |
| 779 | 788 | zSvcName = g.argv[3]; |
| 780 | 789 | }else if( g.argc>4 ){ |
| 781 | 790 | fossil_fatal("too many arguments for delete method."); |
| 782 | 791 | } |
| 783 | 792 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 784 | - if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 793 | + if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); | |
| 785 | 794 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 786 | 795 | SERVICE_ALL_ACCESS); |
| 787 | - if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 796 | + if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); | |
| 788 | 797 | QueryServiceStatus(hSvc, &sstat); |
| 789 | 798 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 790 | 799 | fossil_print("Stopping service '%s'", zSvcName); |
| 791 | 800 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 792 | 801 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 793 | - fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 802 | + winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); | |
| 794 | 803 | } |
| 795 | 804 | } |
| 796 | 805 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 797 | 806 | Sleep(100); |
| 798 | 807 | fossil_print("."); |
| @@ -802,11 +811,11 @@ | ||
| 802 | 811 | } |
| 803 | 812 | if( !DeleteService(hSvc) ){ |
| 804 | 813 | if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){ |
| 805 | 814 | fossil_warning("Service '%s' already marked for delete.\n", zSvcName); |
| 806 | 815 | }else{ |
| 807 | - fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 816 | + winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); | |
| 808 | 817 | } |
| 809 | 818 | }else{ |
| 810 | 819 | fossil_print("Service '%s' successfully deleted.\n", zSvcName); |
| 811 | 820 | } |
| 812 | 821 | CloseServiceHandle(hSvc); |
| @@ -818,11 +827,10 @@ | ||
| 818 | 827 | SERVICE_STATUS sstat; |
| 819 | 828 | LPQUERY_SERVICE_CONFIGW pSvcConfig; |
| 820 | 829 | LPSERVICE_DESCRIPTIONW pSvcDescr; |
| 821 | 830 | BOOL bStatus; |
| 822 | 831 | DWORD nRequired; |
| 823 | - const char *zErrFmt = "unable to show service '%s': %s"; | |
| 824 | 832 | static const char *const zSvcTypes[] = { |
| 825 | 833 | "Driver service", |
| 826 | 834 | "File system driver service", |
| 827 | 835 | "Service runs in its own process", |
| 828 | 836 | "Service shares a process with other services", |
| @@ -848,21 +856,21 @@ | ||
| 848 | 856 | zSvcName = g.argv[3]; |
| 849 | 857 | }else if( g.argc>4 ){ |
| 850 | 858 | fossil_fatal("too many arguments for show method."); |
| 851 | 859 | } |
| 852 | 860 | hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ); |
| 853 | - if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 861 | + if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 854 | 862 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ); |
| 855 | - if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 863 | + if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 856 | 864 | /* Get the service configuration */ |
| 857 | 865 | bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired); |
| 858 | 866 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 859 | - fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 867 | + winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 860 | 868 | } |
| 861 | 869 | pSvcConfig = fossil_malloc(nRequired); |
| 862 | 870 | bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired); |
| 863 | - if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 871 | + if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 864 | 872 | /* Translate the service type */ |
| 865 | 873 | switch( pSvcConfig->dwServiceType ){ |
| 866 | 874 | case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break; |
| 867 | 875 | case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break; |
| 868 | 876 | case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break; |
| @@ -879,19 +887,19 @@ | ||
| 879 | 887 | } |
| 880 | 888 | /* Get the service description. */ |
| 881 | 889 | bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 882 | 890 | NULL, 0, &nRequired); |
| 883 | 891 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 884 | - fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 892 | + winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 885 | 893 | } |
| 886 | 894 | pSvcDescr = fossil_malloc(nRequired); |
| 887 | 895 | bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 888 | 896 | (LPBYTE)pSvcDescr, nRequired, &nRequired); |
| 889 | - if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 897 | + if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 890 | 898 | /* Retrieves the current status of the specified service. */ |
| 891 | 899 | bStatus = QueryServiceStatus(hSvc, &sstat); |
| 892 | - if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 900 | + if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); | |
| 893 | 901 | /* Translate the current state. */ |
| 894 | 902 | switch( sstat.dwCurrentState ){ |
| 895 | 903 | case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break; |
| 896 | 904 | case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break; |
| 897 | 905 | case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break; |
| @@ -921,29 +929,28 @@ | ||
| 921 | 929 | }else |
| 922 | 930 | if( strncmp(zMethod, "start", n)==0 ){ |
| 923 | 931 | SC_HANDLE hScm; |
| 924 | 932 | SC_HANDLE hSvc; |
| 925 | 933 | SERVICE_STATUS sstat; |
| 926 | - char *zErrFmt = "unable to start service '%s': %s"; | |
| 927 | 934 | |
| 928 | 935 | verify_all_options(); |
| 929 | 936 | if( g.argc==4 ){ |
| 930 | 937 | zSvcName = g.argv[3]; |
| 931 | 938 | }else if( g.argc>4 ){ |
| 932 | 939 | fossil_fatal("too many arguments for start method."); |
| 933 | 940 | } |
| 934 | 941 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 935 | - if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 942 | + if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg()); | |
| 936 | 943 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 937 | 944 | SERVICE_ALL_ACCESS); |
| 938 | - if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 945 | + if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg()); | |
| 939 | 946 | QueryServiceStatus(hSvc, &sstat); |
| 940 | 947 | if( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 941 | 948 | fossil_print("Starting service '%s'", zSvcName); |
| 942 | 949 | if( sstat.dwCurrentState!=SERVICE_START_PENDING ){ |
| 943 | 950 | if( !StartServiceW(hSvc, 0, NULL) ){ |
| 944 | - fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 951 | + winhttp_fatal("start", zSvcName, win32_get_last_errmsg()); | |
| 945 | 952 | } |
| 946 | 953 | } |
| 947 | 954 | while( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 948 | 955 | Sleep(100); |
| 949 | 956 | fossil_print("."); |
| @@ -958,29 +965,28 @@ | ||
| 958 | 965 | }else |
| 959 | 966 | if( strncmp(zMethod, "stop", n)==0 ){ |
| 960 | 967 | SC_HANDLE hScm; |
| 961 | 968 | SC_HANDLE hSvc; |
| 962 | 969 | SERVICE_STATUS sstat; |
| 963 | - char *zErrFmt = "unable to stop service '%s': %s"; | |
| 964 | 970 | |
| 965 | 971 | verify_all_options(); |
| 966 | 972 | if( g.argc==4 ){ |
| 967 | 973 | zSvcName = g.argv[3]; |
| 968 | 974 | }else if( g.argc>4 ){ |
| 969 | 975 | fossil_fatal("too many arguments for stop method."); |
| 970 | 976 | } |
| 971 | 977 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 972 | - if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 978 | + if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg()); | |
| 973 | 979 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 974 | 980 | SERVICE_ALL_ACCESS); |
| 975 | - if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 981 | + if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg()); | |
| 976 | 982 | QueryServiceStatus(hSvc, &sstat); |
| 977 | 983 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 978 | 984 | fossil_print("Stopping service '%s'", zSvcName); |
| 979 | 985 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 980 | 986 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 981 | - fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); | |
| 987 | + winhttp_fatal("stop", zSvcName, win32_get_last_errmsg()); | |
| 982 | 988 | } |
| 983 | 989 | } |
| 984 | 990 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 985 | 991 | Sleep(100); |
| 986 | 992 | fossil_print("."); |
| 987 | 993 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -58,10 +58,21 @@ | |
| 58 | } |
| 59 | zHdr++; |
| 60 | } |
| 61 | return 0; |
| 62 | } |
| 63 | |
| 64 | /* |
| 65 | ** Process a single incoming HTTP request. |
| 66 | */ |
| 67 | static void win32_http_request(void *pAppData){ |
| @@ -297,11 +308,11 @@ | |
| 297 | zTempPrefix = mprintf("%sfossil_server_P%d_", |
| 298 | fossil_unicode_to_utf8(zTmpPath), iPort); |
| 299 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 300 | (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 301 | if( zBrowser ){ |
| 302 | zBrowser = mprintf(zBrowser, iPort); |
| 303 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 304 | fossil_system(zBrowser); |
| 305 | } |
| 306 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 307 | /* Set the service status to running and pass the listener socket to the |
| @@ -679,11 +690,10 @@ | |
| 679 | if( strncmp(zMethod, "create", n)==0 ){ |
| 680 | SC_HANDLE hScm; |
| 681 | SC_HANDLE hSvc; |
| 682 | SERVICE_DESCRIPTIONW |
| 683 | svcDescr = {L"Fossil - Distributed Software Configuration Management"}; |
| 684 | char *zErrFmt = "unable to create service '%s': %s"; |
| 685 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 686 | const char *zDisplay = find_option("display", "D", 1); |
| 687 | const char *zStart = find_option("start", "S", 1); |
| 688 | const char *zUsername = find_option("username", "U", 1); |
| 689 | const char *zPassword = find_option("password", "W", 1); |
| @@ -714,17 +724,17 @@ | |
| 714 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 715 | dwStartType = SERVICE_AUTO_START; |
| 716 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| 717 | dwStartType = SERVICE_DEMAND_START; |
| 718 | }else{ |
| 719 | fossil_fatal(zErrFmt, zSvcName, |
| 720 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 721 | } |
| 722 | } |
| 723 | /* Process options for Fossil running as server. */ |
| 724 | if( zPort && (atoi(zPort)<=0) ){ |
| 725 | fossil_fatal(zErrFmt, zSvcName, |
| 726 | "port number must be in the range 1 - 65535."); |
| 727 | } |
| 728 | if( !zRepository ){ |
| 729 | db_must_be_within_tree(); |
| 730 | }else if( file_isdir(zRepository)==1 ){ |
| @@ -743,11 +753,11 @@ | |
| 743 | if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob); |
| 744 | if( zLocalAuth ) blob_append(&binPath, " --localauth", -1); |
| 745 | blob_appendf(&binPath, " \"%s\"", g.zRepositoryName); |
| 746 | /* Create the service. */ |
| 747 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 748 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 749 | hSvc = CreateServiceW( |
| 750 | hScm, /* Handle to the SCM */ |
| 751 | fossil_utf8_to_unicode(zSvcName), /* Name of the service */ |
| 752 | fossil_utf8_to_unicode(zDisplay), /* Display name */ |
| 753 | SERVICE_ALL_ACCESS, /* Desired access */ |
| @@ -759,11 +769,11 @@ | |
| 759 | NULL, /* Tag value */ |
| 760 | NULL, /* Service dependencies */ |
| 761 | zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */ |
| 762 | fossil_utf8_to_unicode(zPassword) /* Account password */ |
| 763 | ); |
| 764 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 765 | /* Set the service description. */ |
| 766 | ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| 767 | fossil_print("Service '%s' successfully created.\n", zSvcName); |
| 768 | CloseServiceHandle(hSvc); |
| 769 | CloseServiceHandle(hScm); |
| @@ -770,29 +780,28 @@ | |
| 770 | }else |
| 771 | if( strncmp(zMethod, "delete", n)==0 ){ |
| 772 | SC_HANDLE hScm; |
| 773 | SC_HANDLE hSvc; |
| 774 | SERVICE_STATUS sstat; |
| 775 | char *zErrFmt = "unable to delete service '%s': %s"; |
| 776 | |
| 777 | verify_all_options(); |
| 778 | if( g.argc==4 ){ |
| 779 | zSvcName = g.argv[3]; |
| 780 | }else if( g.argc>4 ){ |
| 781 | fossil_fatal("too many arguments for delete method."); |
| 782 | } |
| 783 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 784 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 785 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 786 | SERVICE_ALL_ACCESS); |
| 787 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 788 | QueryServiceStatus(hSvc, &sstat); |
| 789 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 790 | fossil_print("Stopping service '%s'", zSvcName); |
| 791 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 792 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 793 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 794 | } |
| 795 | } |
| 796 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 797 | Sleep(100); |
| 798 | fossil_print("."); |
| @@ -802,11 +811,11 @@ | |
| 802 | } |
| 803 | if( !DeleteService(hSvc) ){ |
| 804 | if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){ |
| 805 | fossil_warning("Service '%s' already marked for delete.\n", zSvcName); |
| 806 | }else{ |
| 807 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 808 | } |
| 809 | }else{ |
| 810 | fossil_print("Service '%s' successfully deleted.\n", zSvcName); |
| 811 | } |
| 812 | CloseServiceHandle(hSvc); |
| @@ -818,11 +827,10 @@ | |
| 818 | SERVICE_STATUS sstat; |
| 819 | LPQUERY_SERVICE_CONFIGW pSvcConfig; |
| 820 | LPSERVICE_DESCRIPTIONW pSvcDescr; |
| 821 | BOOL bStatus; |
| 822 | DWORD nRequired; |
| 823 | const char *zErrFmt = "unable to show service '%s': %s"; |
| 824 | static const char *const zSvcTypes[] = { |
| 825 | "Driver service", |
| 826 | "File system driver service", |
| 827 | "Service runs in its own process", |
| 828 | "Service shares a process with other services", |
| @@ -848,21 +856,21 @@ | |
| 848 | zSvcName = g.argv[3]; |
| 849 | }else if( g.argc>4 ){ |
| 850 | fossil_fatal("too many arguments for show method."); |
| 851 | } |
| 852 | hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ); |
| 853 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 854 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ); |
| 855 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 856 | /* Get the service configuration */ |
| 857 | bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired); |
| 858 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 859 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 860 | } |
| 861 | pSvcConfig = fossil_malloc(nRequired); |
| 862 | bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired); |
| 863 | if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 864 | /* Translate the service type */ |
| 865 | switch( pSvcConfig->dwServiceType ){ |
| 866 | case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break; |
| 867 | case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break; |
| 868 | case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break; |
| @@ -879,19 +887,19 @@ | |
| 879 | } |
| 880 | /* Get the service description. */ |
| 881 | bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 882 | NULL, 0, &nRequired); |
| 883 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 884 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 885 | } |
| 886 | pSvcDescr = fossil_malloc(nRequired); |
| 887 | bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 888 | (LPBYTE)pSvcDescr, nRequired, &nRequired); |
| 889 | if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 890 | /* Retrieves the current status of the specified service. */ |
| 891 | bStatus = QueryServiceStatus(hSvc, &sstat); |
| 892 | if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 893 | /* Translate the current state. */ |
| 894 | switch( sstat.dwCurrentState ){ |
| 895 | case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break; |
| 896 | case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break; |
| 897 | case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break; |
| @@ -921,29 +929,28 @@ | |
| 921 | }else |
| 922 | if( strncmp(zMethod, "start", n)==0 ){ |
| 923 | SC_HANDLE hScm; |
| 924 | SC_HANDLE hSvc; |
| 925 | SERVICE_STATUS sstat; |
| 926 | char *zErrFmt = "unable to start service '%s': %s"; |
| 927 | |
| 928 | verify_all_options(); |
| 929 | if( g.argc==4 ){ |
| 930 | zSvcName = g.argv[3]; |
| 931 | }else if( g.argc>4 ){ |
| 932 | fossil_fatal("too many arguments for start method."); |
| 933 | } |
| 934 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 935 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 936 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 937 | SERVICE_ALL_ACCESS); |
| 938 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 939 | QueryServiceStatus(hSvc, &sstat); |
| 940 | if( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 941 | fossil_print("Starting service '%s'", zSvcName); |
| 942 | if( sstat.dwCurrentState!=SERVICE_START_PENDING ){ |
| 943 | if( !StartServiceW(hSvc, 0, NULL) ){ |
| 944 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 945 | } |
| 946 | } |
| 947 | while( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 948 | Sleep(100); |
| 949 | fossil_print("."); |
| @@ -958,29 +965,28 @@ | |
| 958 | }else |
| 959 | if( strncmp(zMethod, "stop", n)==0 ){ |
| 960 | SC_HANDLE hScm; |
| 961 | SC_HANDLE hSvc; |
| 962 | SERVICE_STATUS sstat; |
| 963 | char *zErrFmt = "unable to stop service '%s': %s"; |
| 964 | |
| 965 | verify_all_options(); |
| 966 | if( g.argc==4 ){ |
| 967 | zSvcName = g.argv[3]; |
| 968 | }else if( g.argc>4 ){ |
| 969 | fossil_fatal("too many arguments for stop method."); |
| 970 | } |
| 971 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 972 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 973 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 974 | SERVICE_ALL_ACCESS); |
| 975 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 976 | QueryServiceStatus(hSvc, &sstat); |
| 977 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 978 | fossil_print("Stopping service '%s'", zSvcName); |
| 979 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 980 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 981 | fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 982 | } |
| 983 | } |
| 984 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 985 | Sleep(100); |
| 986 | fossil_print("."); |
| 987 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -58,10 +58,21 @@ | |
| 58 | } |
| 59 | zHdr++; |
| 60 | } |
| 61 | return 0; |
| 62 | } |
| 63 | |
| 64 | /* |
| 65 | ** Issue a fatal error. |
| 66 | */ |
| 67 | static NORETURN void winhttp_fatal( |
| 68 | const char *zOp, |
| 69 | const char *zService, |
| 70 | const char *zErr |
| 71 | ){ |
| 72 | fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr); |
| 73 | } |
| 74 | |
| 75 | /* |
| 76 | ** Process a single incoming HTTP request. |
| 77 | */ |
| 78 | static void win32_http_request(void *pAppData){ |
| @@ -297,11 +308,11 @@ | |
| 308 | zTempPrefix = mprintf("%sfossil_server_P%d_", |
| 309 | fossil_unicode_to_utf8(zTmpPath), iPort); |
| 310 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 311 | (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 312 | if( zBrowser ){ |
| 313 | zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort); |
| 314 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 315 | fossil_system(zBrowser); |
| 316 | } |
| 317 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 318 | /* Set the service status to running and pass the listener socket to the |
| @@ -679,11 +690,10 @@ | |
| 690 | if( strncmp(zMethod, "create", n)==0 ){ |
| 691 | SC_HANDLE hScm; |
| 692 | SC_HANDLE hSvc; |
| 693 | SERVICE_DESCRIPTIONW |
| 694 | svcDescr = {L"Fossil - Distributed Software Configuration Management"}; |
| 695 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 696 | const char *zDisplay = find_option("display", "D", 1); |
| 697 | const char *zStart = find_option("start", "S", 1); |
| 698 | const char *zUsername = find_option("username", "U", 1); |
| 699 | const char *zPassword = find_option("password", "W", 1); |
| @@ -714,17 +724,17 @@ | |
| 724 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 725 | dwStartType = SERVICE_AUTO_START; |
| 726 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| 727 | dwStartType = SERVICE_DEMAND_START; |
| 728 | }else{ |
| 729 | winhttp_fatal("create", zSvcName, |
| 730 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 731 | } |
| 732 | } |
| 733 | /* Process options for Fossil running as server. */ |
| 734 | if( zPort && (atoi(zPort)<=0) ){ |
| 735 | winhttp_fatal("create", zSvcName, |
| 736 | "port number must be in the range 1 - 65535."); |
| 737 | } |
| 738 | if( !zRepository ){ |
| 739 | db_must_be_within_tree(); |
| 740 | }else if( file_isdir(zRepository)==1 ){ |
| @@ -743,11 +753,11 @@ | |
| 753 | if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob); |
| 754 | if( zLocalAuth ) blob_append(&binPath, " --localauth", -1); |
| 755 | blob_appendf(&binPath, " \"%s\"", g.zRepositoryName); |
| 756 | /* Create the service. */ |
| 757 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 758 | if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg()); |
| 759 | hSvc = CreateServiceW( |
| 760 | hScm, /* Handle to the SCM */ |
| 761 | fossil_utf8_to_unicode(zSvcName), /* Name of the service */ |
| 762 | fossil_utf8_to_unicode(zDisplay), /* Display name */ |
| 763 | SERVICE_ALL_ACCESS, /* Desired access */ |
| @@ -759,11 +769,11 @@ | |
| 769 | NULL, /* Tag value */ |
| 770 | NULL, /* Service dependencies */ |
| 771 | zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */ |
| 772 | fossil_utf8_to_unicode(zPassword) /* Account password */ |
| 773 | ); |
| 774 | if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg()); |
| 775 | /* Set the service description. */ |
| 776 | ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr); |
| 777 | fossil_print("Service '%s' successfully created.\n", zSvcName); |
| 778 | CloseServiceHandle(hSvc); |
| 779 | CloseServiceHandle(hScm); |
| @@ -770,29 +780,28 @@ | |
| 780 | }else |
| 781 | if( strncmp(zMethod, "delete", n)==0 ){ |
| 782 | SC_HANDLE hScm; |
| 783 | SC_HANDLE hSvc; |
| 784 | SERVICE_STATUS sstat; |
| 785 | |
| 786 | verify_all_options(); |
| 787 | if( g.argc==4 ){ |
| 788 | zSvcName = g.argv[3]; |
| 789 | }else if( g.argc>4 ){ |
| 790 | fossil_fatal("too many arguments for delete method."); |
| 791 | } |
| 792 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 793 | if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); |
| 794 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 795 | SERVICE_ALL_ACCESS); |
| 796 | if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); |
| 797 | QueryServiceStatus(hSvc, &sstat); |
| 798 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 799 | fossil_print("Stopping service '%s'", zSvcName); |
| 800 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 801 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 802 | winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); |
| 803 | } |
| 804 | } |
| 805 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 806 | Sleep(100); |
| 807 | fossil_print("."); |
| @@ -802,11 +811,11 @@ | |
| 811 | } |
| 812 | if( !DeleteService(hSvc) ){ |
| 813 | if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){ |
| 814 | fossil_warning("Service '%s' already marked for delete.\n", zSvcName); |
| 815 | }else{ |
| 816 | winhttp_fatal("delete", zSvcName, win32_get_last_errmsg()); |
| 817 | } |
| 818 | }else{ |
| 819 | fossil_print("Service '%s' successfully deleted.\n", zSvcName); |
| 820 | } |
| 821 | CloseServiceHandle(hSvc); |
| @@ -818,11 +827,10 @@ | |
| 827 | SERVICE_STATUS sstat; |
| 828 | LPQUERY_SERVICE_CONFIGW pSvcConfig; |
| 829 | LPSERVICE_DESCRIPTIONW pSvcDescr; |
| 830 | BOOL bStatus; |
| 831 | DWORD nRequired; |
| 832 | static const char *const zSvcTypes[] = { |
| 833 | "Driver service", |
| 834 | "File system driver service", |
| 835 | "Service runs in its own process", |
| 836 | "Service shares a process with other services", |
| @@ -848,21 +856,21 @@ | |
| 856 | zSvcName = g.argv[3]; |
| 857 | }else if( g.argc>4 ){ |
| 858 | fossil_fatal("too many arguments for show method."); |
| 859 | } |
| 860 | hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ); |
| 861 | if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 862 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ); |
| 863 | if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 864 | /* Get the service configuration */ |
| 865 | bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired); |
| 866 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 867 | winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 868 | } |
| 869 | pSvcConfig = fossil_malloc(nRequired); |
| 870 | bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired); |
| 871 | if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 872 | /* Translate the service type */ |
| 873 | switch( pSvcConfig->dwServiceType ){ |
| 874 | case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break; |
| 875 | case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break; |
| 876 | case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break; |
| @@ -879,19 +887,19 @@ | |
| 887 | } |
| 888 | /* Get the service description. */ |
| 889 | bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 890 | NULL, 0, &nRequired); |
| 891 | if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 892 | winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 893 | } |
| 894 | pSvcDescr = fossil_malloc(nRequired); |
| 895 | bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, |
| 896 | (LPBYTE)pSvcDescr, nRequired, &nRequired); |
| 897 | if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 898 | /* Retrieves the current status of the specified service. */ |
| 899 | bStatus = QueryServiceStatus(hSvc, &sstat); |
| 900 | if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg()); |
| 901 | /* Translate the current state. */ |
| 902 | switch( sstat.dwCurrentState ){ |
| 903 | case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break; |
| 904 | case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break; |
| 905 | case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break; |
| @@ -921,29 +929,28 @@ | |
| 929 | }else |
| 930 | if( strncmp(zMethod, "start", n)==0 ){ |
| 931 | SC_HANDLE hScm; |
| 932 | SC_HANDLE hSvc; |
| 933 | SERVICE_STATUS sstat; |
| 934 | |
| 935 | verify_all_options(); |
| 936 | if( g.argc==4 ){ |
| 937 | zSvcName = g.argv[3]; |
| 938 | }else if( g.argc>4 ){ |
| 939 | fossil_fatal("too many arguments for start method."); |
| 940 | } |
| 941 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 942 | if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg()); |
| 943 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 944 | SERVICE_ALL_ACCESS); |
| 945 | if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg()); |
| 946 | QueryServiceStatus(hSvc, &sstat); |
| 947 | if( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 948 | fossil_print("Starting service '%s'", zSvcName); |
| 949 | if( sstat.dwCurrentState!=SERVICE_START_PENDING ){ |
| 950 | if( !StartServiceW(hSvc, 0, NULL) ){ |
| 951 | winhttp_fatal("start", zSvcName, win32_get_last_errmsg()); |
| 952 | } |
| 953 | } |
| 954 | while( sstat.dwCurrentState!=SERVICE_RUNNING ){ |
| 955 | Sleep(100); |
| 956 | fossil_print("."); |
| @@ -958,29 +965,28 @@ | |
| 965 | }else |
| 966 | if( strncmp(zMethod, "stop", n)==0 ){ |
| 967 | SC_HANDLE hScm; |
| 968 | SC_HANDLE hSvc; |
| 969 | SERVICE_STATUS sstat; |
| 970 | |
| 971 | verify_all_options(); |
| 972 | if( g.argc==4 ){ |
| 973 | zSvcName = g.argv[3]; |
| 974 | }else if( g.argc>4 ){ |
| 975 | fossil_fatal("too many arguments for stop method."); |
| 976 | } |
| 977 | hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 978 | if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg()); |
| 979 | hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), |
| 980 | SERVICE_ALL_ACCESS); |
| 981 | if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg()); |
| 982 | QueryServiceStatus(hSvc, &sstat); |
| 983 | if( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 984 | fossil_print("Stopping service '%s'", zSvcName); |
| 985 | if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){ |
| 986 | if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){ |
| 987 | winhttp_fatal("stop", zSvcName, win32_get_last_errmsg()); |
| 988 | } |
| 989 | } |
| 990 | while( sstat.dwCurrentState!=SERVICE_STOPPED ){ |
| 991 | Sleep(100); |
| 992 | fossil_print("."); |
| 993 |
+16
-13
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -201,11 +201,11 @@ | ||
| 201 | 201 | if( rid==0 ){ |
| 202 | 202 | blob_appendf(&pXfer->err, "%s", g.zErrMsg); |
| 203 | 203 | blob_reset(&content); |
| 204 | 204 | }else{ |
| 205 | 205 | if( !isPriv ) content_make_public(rid); |
| 206 | - manifest_crosslink(rid, &content, MC_NONE); | |
| 206 | + manifest_crosslink(rid, &content, MC_NO_ERRORS); | |
| 207 | 207 | } |
| 208 | 208 | assert( blob_is_reset(&content) ); |
| 209 | 209 | remote_has(rid); |
| 210 | 210 | } |
| 211 | 211 | |
| @@ -311,11 +311,11 @@ | ||
| 311 | 311 | Blob src, delta; |
| 312 | 312 | int size = 0; |
| 313 | 313 | int srcId = 0; |
| 314 | 314 | |
| 315 | 315 | for(i=0; srcId==0 && i<count(azQuery); i++){ |
| 316 | - srcId = db_int(0, azQuery[i], rid); | |
| 316 | + srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid); | |
| 317 | 317 | } |
| 318 | 318 | if( srcId>0 |
| 319 | 319 | && (pXfer->syncPrivate || !content_is_private(srcId)) |
| 320 | 320 | && content_get(srcId, &src) |
| 321 | 321 | ){ |
| @@ -422,11 +422,11 @@ | ||
| 422 | 422 | return; |
| 423 | 423 | } |
| 424 | 424 | if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 425 | 425 | pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 426 | 426 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 427 | - blob_appendf(pXfer->pOut, zFormat, pUuid); | |
| 427 | + blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid); | |
| 428 | 428 | pXfer->nIGotSent++; |
| 429 | 429 | blob_reset(&uuid); |
| 430 | 430 | return; |
| 431 | 431 | } |
| 432 | 432 | if( nativeDelta ){ |
| @@ -454,11 +454,11 @@ | ||
| 454 | 454 | } |
| 455 | 455 | remote_has(rid); |
| 456 | 456 | blob_reset(&uuid); |
| 457 | 457 | #if 0 |
| 458 | 458 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 459 | - blob_appendf(pXfer->pOut, "\n", 1); | |
| 459 | + blob_append(pXfer->pOut, "\n", 1); | |
| 460 | 460 | } |
| 461 | 461 | #endif |
| 462 | 462 | } |
| 463 | 463 | |
| 464 | 464 | /* |
| @@ -514,11 +514,11 @@ | ||
| 514 | 514 | pXfer->nFileSent++; |
| 515 | 515 | } |
| 516 | 516 | blob_appendf(pXfer->pOut, "%d %d\n", szU, szC); |
| 517 | 517 | blob_append(pXfer->pOut, zContent, szC); |
| 518 | 518 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 519 | - blob_appendf(pXfer->pOut, "\n", 1); | |
| 519 | + blob_append(pXfer->pOut, "\n", 1); | |
| 520 | 520 | } |
| 521 | 521 | if( !isPrivate && srcIsPrivate ){ |
| 522 | 522 | blob_reset(&fullContent); |
| 523 | 523 | } |
| 524 | 524 | } |
| @@ -711,18 +711,18 @@ | ||
| 711 | 711 | blob_reset(&cksum); |
| 712 | 712 | rid = content_put(&cluster); |
| 713 | 713 | blob_reset(&cluster); |
| 714 | 714 | nUncl -= nRow; |
| 715 | 715 | nRow = 0; |
| 716 | - blob_appendf(&deleteWhere, ",%d", rid); | |
| 716 | + blob_append_sql(&deleteWhere, ",%d", rid); | |
| 717 | 717 | } |
| 718 | 718 | } |
| 719 | 719 | db_finalize(&q); |
| 720 | 720 | db_multi_exec( |
| 721 | 721 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 722 | 722 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 723 | - blob_str(&deleteWhere) | |
| 723 | + blob_sql_text(&deleteWhere) | |
| 724 | 724 | ); |
| 725 | 725 | blob_reset(&deleteWhere); |
| 726 | 726 | if( nRow>0 ){ |
| 727 | 727 | md5sum_blob(&cluster, &cksum); |
| 728 | 728 | blob_appendf(&cluster, "Z %b\n", &cksum); |
| @@ -1501,11 +1501,12 @@ | ||
| 1501 | 1501 | nCardSent++; |
| 1502 | 1502 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1503 | 1503 | if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff; |
| 1504 | 1504 | } |
| 1505 | 1505 | if( syncFlags & SYNC_VERBOSE ){ |
| 1506 | - fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1506 | + fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/, | |
| 1507 | + "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1507 | 1508 | } |
| 1508 | 1509 | |
| 1509 | 1510 | while( go ){ |
| 1510 | 1511 | int newPhantom = 0; |
| 1511 | 1512 | char *zRandomness; |
| @@ -1598,17 +1599,18 @@ | ||
| 1598 | 1599 | break; |
| 1599 | 1600 | } |
| 1600 | 1601 | |
| 1601 | 1602 | /* Output current stats */ |
| 1602 | 1603 | if( syncFlags & SYNC_VERBOSE ){ |
| 1603 | - fossil_print(zValueFormat, "Sent:", | |
| 1604 | + fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:", | |
| 1604 | 1605 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1605 | 1606 | xfer.nFileSent, xfer.nDeltaSent); |
| 1606 | 1607 | }else{ |
| 1607 | 1608 | nRoundtrip++; |
| 1608 | 1609 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1609 | - fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1610 | + fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, | |
| 1611 | + nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1610 | 1612 | } |
| 1611 | 1613 | nCardSent = 0; |
| 1612 | 1614 | nCardRcvd = 0; |
| 1613 | 1615 | xfer.nFileSent = 0; |
| 1614 | 1616 | xfer.nDeltaSent = 0; |
| @@ -1819,11 +1821,11 @@ | ||
| 1819 | 1821 | ** to the next cycle. |
| 1820 | 1822 | */ |
| 1821 | 1823 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1822 | 1824 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1823 | 1825 | defossilize(zMsg); |
| 1824 | - if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ | |
| 1826 | + if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){ | |
| 1825 | 1827 | syncFlags &= ~SYNC_PUSH; |
| 1826 | 1828 | zMsg = 0; |
| 1827 | 1829 | } |
| 1828 | 1830 | if( zMsg && zMsg[0] ){ |
| 1829 | 1831 | fossil_force_newline(); |
| @@ -1905,15 +1907,16 @@ | ||
| 1905 | 1907 | ){ |
| 1906 | 1908 | configure_finalize_receive(); |
| 1907 | 1909 | } |
| 1908 | 1910 | origConfigRcvMask = 0; |
| 1909 | 1911 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1910 | - fossil_print(zValueFormat, "Received:", | |
| 1912 | + fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:", | |
| 1911 | 1913 | blob_size(&recv), nCardRcvd, |
| 1912 | 1914 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1913 | 1915 | }else{ |
| 1914 | - fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1916 | + fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, | |
| 1917 | + nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1915 | 1918 | } |
| 1916 | 1919 | blob_reset(&recv); |
| 1917 | 1920 | nCycle++; |
| 1918 | 1921 | |
| 1919 | 1922 | /* If we received one or more files on the previous exchange but |
| 1920 | 1923 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -201,11 +201,11 @@ | |
| 201 | if( rid==0 ){ |
| 202 | blob_appendf(&pXfer->err, "%s", g.zErrMsg); |
| 203 | blob_reset(&content); |
| 204 | }else{ |
| 205 | if( !isPriv ) content_make_public(rid); |
| 206 | manifest_crosslink(rid, &content, MC_NONE); |
| 207 | } |
| 208 | assert( blob_is_reset(&content) ); |
| 209 | remote_has(rid); |
| 210 | } |
| 211 | |
| @@ -311,11 +311,11 @@ | |
| 311 | Blob src, delta; |
| 312 | int size = 0; |
| 313 | int srcId = 0; |
| 314 | |
| 315 | for(i=0; srcId==0 && i<count(azQuery); i++){ |
| 316 | srcId = db_int(0, azQuery[i], rid); |
| 317 | } |
| 318 | if( srcId>0 |
| 319 | && (pXfer->syncPrivate || !content_is_private(srcId)) |
| 320 | && content_get(srcId, &src) |
| 321 | ){ |
| @@ -422,11 +422,11 @@ | |
| 422 | return; |
| 423 | } |
| 424 | if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 425 | pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 426 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 427 | blob_appendf(pXfer->pOut, zFormat, pUuid); |
| 428 | pXfer->nIGotSent++; |
| 429 | blob_reset(&uuid); |
| 430 | return; |
| 431 | } |
| 432 | if( nativeDelta ){ |
| @@ -454,11 +454,11 @@ | |
| 454 | } |
| 455 | remote_has(rid); |
| 456 | blob_reset(&uuid); |
| 457 | #if 0 |
| 458 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 459 | blob_appendf(pXfer->pOut, "\n", 1); |
| 460 | } |
| 461 | #endif |
| 462 | } |
| 463 | |
| 464 | /* |
| @@ -514,11 +514,11 @@ | |
| 514 | pXfer->nFileSent++; |
| 515 | } |
| 516 | blob_appendf(pXfer->pOut, "%d %d\n", szU, szC); |
| 517 | blob_append(pXfer->pOut, zContent, szC); |
| 518 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 519 | blob_appendf(pXfer->pOut, "\n", 1); |
| 520 | } |
| 521 | if( !isPrivate && srcIsPrivate ){ |
| 522 | blob_reset(&fullContent); |
| 523 | } |
| 524 | } |
| @@ -711,18 +711,18 @@ | |
| 711 | blob_reset(&cksum); |
| 712 | rid = content_put(&cluster); |
| 713 | blob_reset(&cluster); |
| 714 | nUncl -= nRow; |
| 715 | nRow = 0; |
| 716 | blob_appendf(&deleteWhere, ",%d", rid); |
| 717 | } |
| 718 | } |
| 719 | db_finalize(&q); |
| 720 | db_multi_exec( |
| 721 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 722 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 723 | blob_str(&deleteWhere) |
| 724 | ); |
| 725 | blob_reset(&deleteWhere); |
| 726 | if( nRow>0 ){ |
| 727 | md5sum_blob(&cluster, &cksum); |
| 728 | blob_appendf(&cluster, "Z %b\n", &cksum); |
| @@ -1501,11 +1501,12 @@ | |
| 1501 | nCardSent++; |
| 1502 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1503 | if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff; |
| 1504 | } |
| 1505 | if( syncFlags & SYNC_VERBOSE ){ |
| 1506 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1507 | } |
| 1508 | |
| 1509 | while( go ){ |
| 1510 | int newPhantom = 0; |
| 1511 | char *zRandomness; |
| @@ -1598,17 +1599,18 @@ | |
| 1598 | break; |
| 1599 | } |
| 1600 | |
| 1601 | /* Output current stats */ |
| 1602 | if( syncFlags & SYNC_VERBOSE ){ |
| 1603 | fossil_print(zValueFormat, "Sent:", |
| 1604 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1605 | xfer.nFileSent, xfer.nDeltaSent); |
| 1606 | }else{ |
| 1607 | nRoundtrip++; |
| 1608 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1609 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1610 | } |
| 1611 | nCardSent = 0; |
| 1612 | nCardRcvd = 0; |
| 1613 | xfer.nFileSent = 0; |
| 1614 | xfer.nDeltaSent = 0; |
| @@ -1819,11 +1821,11 @@ | |
| 1819 | ** to the next cycle. |
| 1820 | */ |
| 1821 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1822 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1823 | defossilize(zMsg); |
| 1824 | if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ |
| 1825 | syncFlags &= ~SYNC_PUSH; |
| 1826 | zMsg = 0; |
| 1827 | } |
| 1828 | if( zMsg && zMsg[0] ){ |
| 1829 | fossil_force_newline(); |
| @@ -1905,15 +1907,16 @@ | |
| 1905 | ){ |
| 1906 | configure_finalize_receive(); |
| 1907 | } |
| 1908 | origConfigRcvMask = 0; |
| 1909 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1910 | fossil_print(zValueFormat, "Received:", |
| 1911 | blob_size(&recv), nCardRcvd, |
| 1912 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1913 | }else{ |
| 1914 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1915 | } |
| 1916 | blob_reset(&recv); |
| 1917 | nCycle++; |
| 1918 | |
| 1919 | /* If we received one or more files on the previous exchange but |
| 1920 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -201,11 +201,11 @@ | |
| 201 | if( rid==0 ){ |
| 202 | blob_appendf(&pXfer->err, "%s", g.zErrMsg); |
| 203 | blob_reset(&content); |
| 204 | }else{ |
| 205 | if( !isPriv ) content_make_public(rid); |
| 206 | manifest_crosslink(rid, &content, MC_NO_ERRORS); |
| 207 | } |
| 208 | assert( blob_is_reset(&content) ); |
| 209 | remote_has(rid); |
| 210 | } |
| 211 | |
| @@ -311,11 +311,11 @@ | |
| 311 | Blob src, delta; |
| 312 | int size = 0; |
| 313 | int srcId = 0; |
| 314 | |
| 315 | for(i=0; srcId==0 && i<count(azQuery); i++){ |
| 316 | srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid); |
| 317 | } |
| 318 | if( srcId>0 |
| 319 | && (pXfer->syncPrivate || !content_is_private(srcId)) |
| 320 | && content_get(srcId, &src) |
| 321 | ){ |
| @@ -422,11 +422,11 @@ | |
| 422 | return; |
| 423 | } |
| 424 | if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 425 | pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 426 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 427 | blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid); |
| 428 | pXfer->nIGotSent++; |
| 429 | blob_reset(&uuid); |
| 430 | return; |
| 431 | } |
| 432 | if( nativeDelta ){ |
| @@ -454,11 +454,11 @@ | |
| 454 | } |
| 455 | remote_has(rid); |
| 456 | blob_reset(&uuid); |
| 457 | #if 0 |
| 458 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 459 | blob_append(pXfer->pOut, "\n", 1); |
| 460 | } |
| 461 | #endif |
| 462 | } |
| 463 | |
| 464 | /* |
| @@ -514,11 +514,11 @@ | |
| 514 | pXfer->nFileSent++; |
| 515 | } |
| 516 | blob_appendf(pXfer->pOut, "%d %d\n", szU, szC); |
| 517 | blob_append(pXfer->pOut, zContent, szC); |
| 518 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 519 | blob_append(pXfer->pOut, "\n", 1); |
| 520 | } |
| 521 | if( !isPrivate && srcIsPrivate ){ |
| 522 | blob_reset(&fullContent); |
| 523 | } |
| 524 | } |
| @@ -711,18 +711,18 @@ | |
| 711 | blob_reset(&cksum); |
| 712 | rid = content_put(&cluster); |
| 713 | blob_reset(&cluster); |
| 714 | nUncl -= nRow; |
| 715 | nRow = 0; |
| 716 | blob_append_sql(&deleteWhere, ",%d", rid); |
| 717 | } |
| 718 | } |
| 719 | db_finalize(&q); |
| 720 | db_multi_exec( |
| 721 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 722 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 723 | blob_sql_text(&deleteWhere) |
| 724 | ); |
| 725 | blob_reset(&deleteWhere); |
| 726 | if( nRow>0 ){ |
| 727 | md5sum_blob(&cluster, &cksum); |
| 728 | blob_appendf(&cluster, "Z %b\n", &cksum); |
| @@ -1501,11 +1501,12 @@ | |
| 1501 | nCardSent++; |
| 1502 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1503 | if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff; |
| 1504 | } |
| 1505 | if( syncFlags & SYNC_VERBOSE ){ |
| 1506 | fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/, |
| 1507 | "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1508 | } |
| 1509 | |
| 1510 | while( go ){ |
| 1511 | int newPhantom = 0; |
| 1512 | char *zRandomness; |
| @@ -1598,17 +1599,18 @@ | |
| 1599 | break; |
| 1600 | } |
| 1601 | |
| 1602 | /* Output current stats */ |
| 1603 | if( syncFlags & SYNC_VERBOSE ){ |
| 1604 | fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:", |
| 1605 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1606 | xfer.nFileSent, xfer.nDeltaSent); |
| 1607 | }else{ |
| 1608 | nRoundtrip++; |
| 1609 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1610 | fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, |
| 1611 | nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1612 | } |
| 1613 | nCardSent = 0; |
| 1614 | nCardRcvd = 0; |
| 1615 | xfer.nFileSent = 0; |
| 1616 | xfer.nDeltaSent = 0; |
| @@ -1819,11 +1821,11 @@ | |
| 1821 | ** to the next cycle. |
| 1822 | */ |
| 1823 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1824 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1825 | defossilize(zMsg); |
| 1826 | if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){ |
| 1827 | syncFlags &= ~SYNC_PUSH; |
| 1828 | zMsg = 0; |
| 1829 | } |
| 1830 | if( zMsg && zMsg[0] ){ |
| 1831 | fossil_force_newline(); |
| @@ -1905,15 +1907,16 @@ | |
| 1907 | ){ |
| 1908 | configure_finalize_receive(); |
| 1909 | } |
| 1910 | origConfigRcvMask = 0; |
| 1911 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1912 | fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:", |
| 1913 | blob_size(&recv), nCardRcvd, |
| 1914 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1915 | }else{ |
| 1916 | fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, |
| 1917 | nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1918 | } |
| 1919 | blob_reset(&recv); |
| 1920 | nCycle++; |
| 1921 | |
| 1922 | /* If we received one or more files on the previous exchange but |
| 1923 |
+16
-13
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -201,11 +201,11 @@ | ||
| 201 | 201 | if( rid==0 ){ |
| 202 | 202 | blob_appendf(&pXfer->err, "%s", g.zErrMsg); |
| 203 | 203 | blob_reset(&content); |
| 204 | 204 | }else{ |
| 205 | 205 | if( !isPriv ) content_make_public(rid); |
| 206 | - manifest_crosslink(rid, &content, MC_NONE); | |
| 206 | + manifest_crosslink(rid, &content, MC_NO_ERRORS); | |
| 207 | 207 | } |
| 208 | 208 | assert( blob_is_reset(&content) ); |
| 209 | 209 | remote_has(rid); |
| 210 | 210 | } |
| 211 | 211 | |
| @@ -311,11 +311,11 @@ | ||
| 311 | 311 | Blob src, delta; |
| 312 | 312 | int size = 0; |
| 313 | 313 | int srcId = 0; |
| 314 | 314 | |
| 315 | 315 | for(i=0; srcId==0 && i<count(azQuery); i++){ |
| 316 | - srcId = db_int(0, azQuery[i], rid); | |
| 316 | + srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid); | |
| 317 | 317 | } |
| 318 | 318 | if( srcId>0 |
| 319 | 319 | && (pXfer->syncPrivate || !content_is_private(srcId)) |
| 320 | 320 | && content_get(srcId, &src) |
| 321 | 321 | ){ |
| @@ -422,11 +422,11 @@ | ||
| 422 | 422 | return; |
| 423 | 423 | } |
| 424 | 424 | if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 425 | 425 | pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 426 | 426 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 427 | - blob_appendf(pXfer->pOut, zFormat, pUuid); | |
| 427 | + blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid); | |
| 428 | 428 | pXfer->nIGotSent++; |
| 429 | 429 | blob_reset(&uuid); |
| 430 | 430 | return; |
| 431 | 431 | } |
| 432 | 432 | if( nativeDelta ){ |
| @@ -454,11 +454,11 @@ | ||
| 454 | 454 | } |
| 455 | 455 | remote_has(rid); |
| 456 | 456 | blob_reset(&uuid); |
| 457 | 457 | #if 0 |
| 458 | 458 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 459 | - blob_appendf(pXfer->pOut, "\n", 1); | |
| 459 | + blob_append(pXfer->pOut, "\n", 1); | |
| 460 | 460 | } |
| 461 | 461 | #endif |
| 462 | 462 | } |
| 463 | 463 | |
| 464 | 464 | /* |
| @@ -514,11 +514,11 @@ | ||
| 514 | 514 | pXfer->nFileSent++; |
| 515 | 515 | } |
| 516 | 516 | blob_appendf(pXfer->pOut, "%d %d\n", szU, szC); |
| 517 | 517 | blob_append(pXfer->pOut, zContent, szC); |
| 518 | 518 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 519 | - blob_appendf(pXfer->pOut, "\n", 1); | |
| 519 | + blob_append(pXfer->pOut, "\n", 1); | |
| 520 | 520 | } |
| 521 | 521 | if( !isPrivate && srcIsPrivate ){ |
| 522 | 522 | blob_reset(&fullContent); |
| 523 | 523 | } |
| 524 | 524 | } |
| @@ -711,18 +711,18 @@ | ||
| 711 | 711 | blob_reset(&cksum); |
| 712 | 712 | rid = content_put(&cluster); |
| 713 | 713 | blob_reset(&cluster); |
| 714 | 714 | nUncl -= nRow; |
| 715 | 715 | nRow = 0; |
| 716 | - blob_appendf(&deleteWhere, ",%d", rid); | |
| 716 | + blob_append_sql(&deleteWhere, ",%d", rid); | |
| 717 | 717 | } |
| 718 | 718 | } |
| 719 | 719 | db_finalize(&q); |
| 720 | 720 | db_multi_exec( |
| 721 | 721 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 722 | 722 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 723 | - blob_str(&deleteWhere) | |
| 723 | + blob_sql_text(&deleteWhere) | |
| 724 | 724 | ); |
| 725 | 725 | blob_reset(&deleteWhere); |
| 726 | 726 | if( nRow>0 ){ |
| 727 | 727 | md5sum_blob(&cluster, &cksum); |
| 728 | 728 | blob_appendf(&cluster, "Z %b\n", &cksum); |
| @@ -1501,11 +1501,12 @@ | ||
| 1501 | 1501 | nCardSent++; |
| 1502 | 1502 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1503 | 1503 | if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff; |
| 1504 | 1504 | } |
| 1505 | 1505 | if( syncFlags & SYNC_VERBOSE ){ |
| 1506 | - fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1506 | + fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/, | |
| 1507 | + "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1507 | 1508 | } |
| 1508 | 1509 | |
| 1509 | 1510 | while( go ){ |
| 1510 | 1511 | int newPhantom = 0; |
| 1511 | 1512 | char *zRandomness; |
| @@ -1598,17 +1599,18 @@ | ||
| 1598 | 1599 | break; |
| 1599 | 1600 | } |
| 1600 | 1601 | |
| 1601 | 1602 | /* Output current stats */ |
| 1602 | 1603 | if( syncFlags & SYNC_VERBOSE ){ |
| 1603 | - fossil_print(zValueFormat, "Sent:", | |
| 1604 | + fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:", | |
| 1604 | 1605 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1605 | 1606 | xfer.nFileSent, xfer.nDeltaSent); |
| 1606 | 1607 | }else{ |
| 1607 | 1608 | nRoundtrip++; |
| 1608 | 1609 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1609 | - fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1610 | + fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, | |
| 1611 | + nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1610 | 1612 | } |
| 1611 | 1613 | nCardSent = 0; |
| 1612 | 1614 | nCardRcvd = 0; |
| 1613 | 1615 | xfer.nFileSent = 0; |
| 1614 | 1616 | xfer.nDeltaSent = 0; |
| @@ -1819,11 +1821,11 @@ | ||
| 1819 | 1821 | ** to the next cycle. |
| 1820 | 1822 | */ |
| 1821 | 1823 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1822 | 1824 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1823 | 1825 | defossilize(zMsg); |
| 1824 | - if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ | |
| 1826 | + if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){ | |
| 1825 | 1827 | syncFlags &= ~SYNC_PUSH; |
| 1826 | 1828 | zMsg = 0; |
| 1827 | 1829 | } |
| 1828 | 1830 | if( zMsg && zMsg[0] ){ |
| 1829 | 1831 | fossil_force_newline(); |
| @@ -1905,15 +1907,16 @@ | ||
| 1905 | 1907 | ){ |
| 1906 | 1908 | configure_finalize_receive(); |
| 1907 | 1909 | } |
| 1908 | 1910 | origConfigRcvMask = 0; |
| 1909 | 1911 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1910 | - fossil_print(zValueFormat, "Received:", | |
| 1912 | + fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:", | |
| 1911 | 1913 | blob_size(&recv), nCardRcvd, |
| 1912 | 1914 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1913 | 1915 | }else{ |
| 1914 | - fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1916 | + fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, | |
| 1917 | + nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1915 | 1918 | } |
| 1916 | 1919 | blob_reset(&recv); |
| 1917 | 1920 | nCycle++; |
| 1918 | 1921 | |
| 1919 | 1922 | /* If we received one or more files on the previous exchange but |
| 1920 | 1923 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -201,11 +201,11 @@ | |
| 201 | if( rid==0 ){ |
| 202 | blob_appendf(&pXfer->err, "%s", g.zErrMsg); |
| 203 | blob_reset(&content); |
| 204 | }else{ |
| 205 | if( !isPriv ) content_make_public(rid); |
| 206 | manifest_crosslink(rid, &content, MC_NONE); |
| 207 | } |
| 208 | assert( blob_is_reset(&content) ); |
| 209 | remote_has(rid); |
| 210 | } |
| 211 | |
| @@ -311,11 +311,11 @@ | |
| 311 | Blob src, delta; |
| 312 | int size = 0; |
| 313 | int srcId = 0; |
| 314 | |
| 315 | for(i=0; srcId==0 && i<count(azQuery); i++){ |
| 316 | srcId = db_int(0, azQuery[i], rid); |
| 317 | } |
| 318 | if( srcId>0 |
| 319 | && (pXfer->syncPrivate || !content_is_private(srcId)) |
| 320 | && content_get(srcId, &src) |
| 321 | ){ |
| @@ -422,11 +422,11 @@ | |
| 422 | return; |
| 423 | } |
| 424 | if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 425 | pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 426 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 427 | blob_appendf(pXfer->pOut, zFormat, pUuid); |
| 428 | pXfer->nIGotSent++; |
| 429 | blob_reset(&uuid); |
| 430 | return; |
| 431 | } |
| 432 | if( nativeDelta ){ |
| @@ -454,11 +454,11 @@ | |
| 454 | } |
| 455 | remote_has(rid); |
| 456 | blob_reset(&uuid); |
| 457 | #if 0 |
| 458 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 459 | blob_appendf(pXfer->pOut, "\n", 1); |
| 460 | } |
| 461 | #endif |
| 462 | } |
| 463 | |
| 464 | /* |
| @@ -514,11 +514,11 @@ | |
| 514 | pXfer->nFileSent++; |
| 515 | } |
| 516 | blob_appendf(pXfer->pOut, "%d %d\n", szU, szC); |
| 517 | blob_append(pXfer->pOut, zContent, szC); |
| 518 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 519 | blob_appendf(pXfer->pOut, "\n", 1); |
| 520 | } |
| 521 | if( !isPrivate && srcIsPrivate ){ |
| 522 | blob_reset(&fullContent); |
| 523 | } |
| 524 | } |
| @@ -711,18 +711,18 @@ | |
| 711 | blob_reset(&cksum); |
| 712 | rid = content_put(&cluster); |
| 713 | blob_reset(&cluster); |
| 714 | nUncl -= nRow; |
| 715 | nRow = 0; |
| 716 | blob_appendf(&deleteWhere, ",%d", rid); |
| 717 | } |
| 718 | } |
| 719 | db_finalize(&q); |
| 720 | db_multi_exec( |
| 721 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 722 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 723 | blob_str(&deleteWhere) |
| 724 | ); |
| 725 | blob_reset(&deleteWhere); |
| 726 | if( nRow>0 ){ |
| 727 | md5sum_blob(&cluster, &cksum); |
| 728 | blob_appendf(&cluster, "Z %b\n", &cksum); |
| @@ -1501,11 +1501,12 @@ | |
| 1501 | nCardSent++; |
| 1502 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1503 | if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff; |
| 1504 | } |
| 1505 | if( syncFlags & SYNC_VERBOSE ){ |
| 1506 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1507 | } |
| 1508 | |
| 1509 | while( go ){ |
| 1510 | int newPhantom = 0; |
| 1511 | char *zRandomness; |
| @@ -1598,17 +1599,18 @@ | |
| 1598 | break; |
| 1599 | } |
| 1600 | |
| 1601 | /* Output current stats */ |
| 1602 | if( syncFlags & SYNC_VERBOSE ){ |
| 1603 | fossil_print(zValueFormat, "Sent:", |
| 1604 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1605 | xfer.nFileSent, xfer.nDeltaSent); |
| 1606 | }else{ |
| 1607 | nRoundtrip++; |
| 1608 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1609 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1610 | } |
| 1611 | nCardSent = 0; |
| 1612 | nCardRcvd = 0; |
| 1613 | xfer.nFileSent = 0; |
| 1614 | xfer.nDeltaSent = 0; |
| @@ -1819,11 +1821,11 @@ | |
| 1819 | ** to the next cycle. |
| 1820 | */ |
| 1821 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1822 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1823 | defossilize(zMsg); |
| 1824 | if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ |
| 1825 | syncFlags &= ~SYNC_PUSH; |
| 1826 | zMsg = 0; |
| 1827 | } |
| 1828 | if( zMsg && zMsg[0] ){ |
| 1829 | fossil_force_newline(); |
| @@ -1905,15 +1907,16 @@ | |
| 1905 | ){ |
| 1906 | configure_finalize_receive(); |
| 1907 | } |
| 1908 | origConfigRcvMask = 0; |
| 1909 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1910 | fossil_print(zValueFormat, "Received:", |
| 1911 | blob_size(&recv), nCardRcvd, |
| 1912 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1913 | }else{ |
| 1914 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1915 | } |
| 1916 | blob_reset(&recv); |
| 1917 | nCycle++; |
| 1918 | |
| 1919 | /* If we received one or more files on the previous exchange but |
| 1920 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -201,11 +201,11 @@ | |
| 201 | if( rid==0 ){ |
| 202 | blob_appendf(&pXfer->err, "%s", g.zErrMsg); |
| 203 | blob_reset(&content); |
| 204 | }else{ |
| 205 | if( !isPriv ) content_make_public(rid); |
| 206 | manifest_crosslink(rid, &content, MC_NO_ERRORS); |
| 207 | } |
| 208 | assert( blob_is_reset(&content) ); |
| 209 | remote_has(rid); |
| 210 | } |
| 211 | |
| @@ -311,11 +311,11 @@ | |
| 311 | Blob src, delta; |
| 312 | int size = 0; |
| 313 | int srcId = 0; |
| 314 | |
| 315 | for(i=0; srcId==0 && i<count(azQuery); i++){ |
| 316 | srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid); |
| 317 | } |
| 318 | if( srcId>0 |
| 319 | && (pXfer->syncPrivate || !content_is_private(srcId)) |
| 320 | && content_get(srcId, &src) |
| 321 | ){ |
| @@ -422,11 +422,11 @@ | |
| 422 | return; |
| 423 | } |
| 424 | if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 425 | pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 426 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 427 | blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid); |
| 428 | pXfer->nIGotSent++; |
| 429 | blob_reset(&uuid); |
| 430 | return; |
| 431 | } |
| 432 | if( nativeDelta ){ |
| @@ -454,11 +454,11 @@ | |
| 454 | } |
| 455 | remote_has(rid); |
| 456 | blob_reset(&uuid); |
| 457 | #if 0 |
| 458 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 459 | blob_append(pXfer->pOut, "\n", 1); |
| 460 | } |
| 461 | #endif |
| 462 | } |
| 463 | |
| 464 | /* |
| @@ -514,11 +514,11 @@ | |
| 514 | pXfer->nFileSent++; |
| 515 | } |
| 516 | blob_appendf(pXfer->pOut, "%d %d\n", szU, szC); |
| 517 | blob_append(pXfer->pOut, zContent, szC); |
| 518 | if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){ |
| 519 | blob_append(pXfer->pOut, "\n", 1); |
| 520 | } |
| 521 | if( !isPrivate && srcIsPrivate ){ |
| 522 | blob_reset(&fullContent); |
| 523 | } |
| 524 | } |
| @@ -711,18 +711,18 @@ | |
| 711 | blob_reset(&cksum); |
| 712 | rid = content_put(&cluster); |
| 713 | blob_reset(&cluster); |
| 714 | nUncl -= nRow; |
| 715 | nRow = 0; |
| 716 | blob_append_sql(&deleteWhere, ",%d", rid); |
| 717 | } |
| 718 | } |
| 719 | db_finalize(&q); |
| 720 | db_multi_exec( |
| 721 | "DELETE FROM unclustered WHERE rid NOT IN (0 %s)" |
| 722 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)", |
| 723 | blob_sql_text(&deleteWhere) |
| 724 | ); |
| 725 | blob_reset(&deleteWhere); |
| 726 | if( nRow>0 ){ |
| 727 | md5sum_blob(&cluster, &cksum); |
| 728 | blob_appendf(&cluster, "Z %b\n", &cksum); |
| @@ -1501,11 +1501,12 @@ | |
| 1501 | nCardSent++; |
| 1502 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1503 | if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff; |
| 1504 | } |
| 1505 | if( syncFlags & SYNC_VERBOSE ){ |
| 1506 | fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/, |
| 1507 | "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1508 | } |
| 1509 | |
| 1510 | while( go ){ |
| 1511 | int newPhantom = 0; |
| 1512 | char *zRandomness; |
| @@ -1598,17 +1599,18 @@ | |
| 1599 | break; |
| 1600 | } |
| 1601 | |
| 1602 | /* Output current stats */ |
| 1603 | if( syncFlags & SYNC_VERBOSE ){ |
| 1604 | fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:", |
| 1605 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1606 | xfer.nFileSent, xfer.nDeltaSent); |
| 1607 | }else{ |
| 1608 | nRoundtrip++; |
| 1609 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1610 | fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, |
| 1611 | nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1612 | } |
| 1613 | nCardSent = 0; |
| 1614 | nCardRcvd = 0; |
| 1615 | xfer.nFileSent = 0; |
| 1616 | xfer.nDeltaSent = 0; |
| @@ -1819,11 +1821,11 @@ | |
| 1821 | ** to the next cycle. |
| 1822 | */ |
| 1823 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1824 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1825 | defossilize(zMsg); |
| 1826 | if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){ |
| 1827 | syncFlags &= ~SYNC_PUSH; |
| 1828 | zMsg = 0; |
| 1829 | } |
| 1830 | if( zMsg && zMsg[0] ){ |
| 1831 | fossil_force_newline(); |
| @@ -1905,15 +1907,16 @@ | |
| 1907 | ){ |
| 1908 | configure_finalize_receive(); |
| 1909 | } |
| 1910 | origConfigRcvMask = 0; |
| 1911 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1912 | fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:", |
| 1913 | blob_size(&recv), nCardRcvd, |
| 1914 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1915 | }else{ |
| 1916 | fossil_print(zBriefFormat /*works-like:"%d%d%d"*/, |
| 1917 | nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1918 | } |
| 1919 | blob_reset(&recv); |
| 1920 | nCycle++; |
| 1921 | |
| 1922 | /* If we received one or more files on the previous exchange but |
| 1923 |
+6
-3
| --- win/Makefile.PellesCGMake | ||
| +++ win/Makefile.PellesCGMake | ||
| @@ -75,11 +75,11 @@ | ||
| 75 | 75 | RC=$(PellesCDir)\bin\porc.exe |
| 76 | 76 | RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION) |
| 77 | 77 | |
| 78 | 78 | # define the special utilities files, needed to generate |
| 79 | 79 | # the automatically generated source files |
| 80 | -UTILS=translate.exe mkindex.exe makeheaders.exe | |
| 80 | +UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe | |
| 81 | 81 | UTILS_OBJ=$(UTILS:.exe=.obj) |
| 82 | 82 | UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) |
| 83 | 83 | |
| 84 | 84 | # define the SQLite files, which need special flags on compile |
| 85 | 85 | SQLITESRC=sqlite3.c |
| @@ -114,11 +114,11 @@ | ||
| 114 | 114 | # main target file is the application |
| 115 | 115 | APPLICATION=fossil.exe |
| 116 | 116 | |
| 117 | 117 | # define the standard make target |
| 118 | 118 | .PHONY: default |
| 119 | -default: page_index.h headers $(APPLICATION) | |
| 119 | +default: page_index.h builtin_data.h headers $(APPLICATION) | |
| 120 | 120 | |
| 121 | 121 | # symbolic target to generate the source generate utils |
| 122 | 122 | .PHONY: utils |
| 123 | 123 | utils: $(UTILS) |
| 124 | 124 | |
| @@ -139,17 +139,20 @@ | ||
| 139 | 139 | translate.exe $< >$@ |
| 140 | 140 | |
| 141 | 141 | # generate the index source, containing all web references,.. |
| 142 | 142 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 143 | 143 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 144 | + | |
| 145 | +builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe | |
| 146 | + mkbuiltin.exe $(EXTRA_FILES) >$@ | |
| 144 | 147 | |
| 145 | 148 | # extracting version info from manifest |
| 146 | 149 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 147 | 150 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 148 | 151 | |
| 149 | 152 | # generate the simplified headers |
| 150 | -headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h | |
| 153 | +headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h | |
| 151 | 154 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 152 | 155 | echo Done >$@ |
| 153 | 156 | |
| 154 | 157 | # compile C sources with relevant options |
| 155 | 158 | |
| 156 | 159 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -75,11 +75,11 @@ | |
| 75 | RC=$(PellesCDir)\bin\porc.exe |
| 76 | RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION) |
| 77 | |
| 78 | # define the special utilities files, needed to generate |
| 79 | # the automatically generated source files |
| 80 | UTILS=translate.exe mkindex.exe makeheaders.exe |
| 81 | UTILS_OBJ=$(UTILS:.exe=.obj) |
| 82 | UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) |
| 83 | |
| 84 | # define the SQLite files, which need special flags on compile |
| 85 | SQLITESRC=sqlite3.c |
| @@ -114,11 +114,11 @@ | |
| 114 | # main target file is the application |
| 115 | APPLICATION=fossil.exe |
| 116 | |
| 117 | # define the standard make target |
| 118 | .PHONY: default |
| 119 | default: page_index.h headers $(APPLICATION) |
| 120 | |
| 121 | # symbolic target to generate the source generate utils |
| 122 | .PHONY: utils |
| 123 | utils: $(UTILS) |
| 124 | |
| @@ -139,17 +139,20 @@ | |
| 139 | translate.exe $< >$@ |
| 140 | |
| 141 | # generate the index source, containing all web references,.. |
| 142 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 143 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 144 | |
| 145 | # extracting version info from manifest |
| 146 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 147 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 148 | |
| 149 | # generate the simplified headers |
| 150 | headers: makeheaders.exe page_index.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 151 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 152 | echo Done >$@ |
| 153 | |
| 154 | # compile C sources with relevant options |
| 155 | |
| 156 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -75,11 +75,11 @@ | |
| 75 | RC=$(PellesCDir)\bin\porc.exe |
| 76 | RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION) |
| 77 | |
| 78 | # define the special utilities files, needed to generate |
| 79 | # the automatically generated source files |
| 80 | UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe |
| 81 | UTILS_OBJ=$(UTILS:.exe=.obj) |
| 82 | UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) |
| 83 | |
| 84 | # define the SQLite files, which need special flags on compile |
| 85 | SQLITESRC=sqlite3.c |
| @@ -114,11 +114,11 @@ | |
| 114 | # main target file is the application |
| 115 | APPLICATION=fossil.exe |
| 116 | |
| 117 | # define the standard make target |
| 118 | .PHONY: default |
| 119 | default: page_index.h builtin_data.h headers $(APPLICATION) |
| 120 | |
| 121 | # symbolic target to generate the source generate utils |
| 122 | .PHONY: utils |
| 123 | utils: $(UTILS) |
| 124 | |
| @@ -139,17 +139,20 @@ | |
| 139 | translate.exe $< >$@ |
| 140 | |
| 141 | # generate the index source, containing all web references,.. |
| 142 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 143 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 144 | |
| 145 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 146 | mkbuiltin.exe $(EXTRA_FILES) >$@ |
| 147 | |
| 148 | # extracting version info from manifest |
| 149 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 150 | version.exe ..\manifest.uuid ..\manifest ..\VERSION > $@ |
| 151 | |
| 152 | # generate the simplified headers |
| 153 | headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/sqlite3.h ../src/th.h VERSION.h |
| 154 | makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/sqlite3.h ../src/th.h VERSION.h |
| 155 | echo Done >$@ |
| 156 | |
| 157 | # compile C sources with relevant options |
| 158 | |
| 159 |
+25
-9
| --- win/Makefile.dmc | ||
| +++ win/Makefile.dmc | ||
| @@ -28,31 +28,32 @@ | ||
| 28 | 28 | |
| 29 | 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | 30 | |
| 31 | 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | 32 | |
| 33 | -SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c | |
| 33 | +SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c | |
| 34 | 34 | |
| 35 | -OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O | |
| 35 | +OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O | |
| 36 | 36 | |
| 37 | 37 | |
| 38 | 38 | RC=$(DMDIR)\bin\rcc |
| 39 | 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | 40 | |
| 41 | 41 | APPNAME = $(OBJDIR)\fossil$(E) |
| 42 | 42 | |
| 43 | 43 | all: $(APPNAME) |
| 44 | 44 | |
| 45 | -$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link | |
| 45 | +$(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link | |
| 46 | 46 | cd $(OBJDIR) |
| 47 | + codecheck1$E $(SRC) | |
| 47 | 48 | $(DMDIR)\bin\link @link |
| 48 | 49 | |
| 49 | 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 50 | 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 51 | 52 | |
| 52 | 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 53 | - +echo add allrepo attach bag bisect blob branch browse cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ | |
| 54 | + +echo add allrepo attach bag bisect blob branch browse builtin cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ | |
| 54 | 55 | +echo fossil >> $@ |
| 55 | 56 | +echo fossil >> $@ |
| 56 | 57 | +echo $(LIBS) >> $@ |
| 57 | 58 | +echo. >> $@ |
| 58 | 59 | +echo fossil >> $@ |
| @@ -64,11 +65,17 @@ | ||
| 64 | 65 | $(BCC) -o$@ $** |
| 65 | 66 | |
| 66 | 67 | mkindex$E: $(SRCDIR)\mkindex.c |
| 67 | 68 | $(BCC) -o$@ $** |
| 68 | 69 | |
| 69 | -version$E: $B\src\mkversion.c | |
| 70 | +mkbuiltin$E: $(SRCDIR)\mkbuiltin.c | |
| 71 | + $(BCC) -o$@ $** | |
| 72 | + | |
| 73 | +mkversion$E: $(SRCDIR)\mkversion.c | |
| 74 | + $(BCC) -o$@ $** | |
| 75 | + | |
| 76 | +codecheck1$E: $(SRCDIR)\codecheck1.c | |
| 70 | 77 | $(BCC) -o$@ $** |
| 71 | 78 | |
| 72 | 79 | $(OBJDIR)\shell$O : $(SRCDIR)\shell.c |
| 73 | 80 | $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $** |
| 74 | 81 | |
| @@ -82,22 +89,25 @@ | ||
| 82 | 89 | $(TCC) -o$@ -c $** |
| 83 | 90 | |
| 84 | 91 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 85 | 92 | cp $@ $@ |
| 86 | 93 | |
| 87 | -VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 94 | +VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION | |
| 88 | 95 | +$** > $@ |
| 89 | 96 | |
| 90 | 97 | page_index.h: mkindex$E $(SRC) |
| 91 | 98 | +$** > $@ |
| 99 | + | |
| 100 | +builtin_data.h: mkbuiltin$E $(EXTRA_FILES) | |
| 101 | + +$** > $@ | |
| 92 | 102 | |
| 93 | 103 | clean: |
| 94 | 104 | -del $(OBJDIR)\*.obj |
| 95 | 105 | -del *.obj *_.c *.h *.map |
| 96 | 106 | |
| 97 | 107 | realclean: |
| 98 | - -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E | |
| 108 | + -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E | |
| 99 | 109 | |
| 100 | 110 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 101 | 111 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 102 | 112 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 103 | 113 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -160,10 +170,16 @@ | ||
| 160 | 170 | $(OBJDIR)\browse$O : browse_.c browse.h |
| 161 | 171 | $(TCC) -o$@ -c browse_.c |
| 162 | 172 | |
| 163 | 173 | browse_.c : $(SRCDIR)\browse.c |
| 164 | 174 | +translate$E $** > $@ |
| 175 | + | |
| 176 | +$(OBJDIR)\builtin$O : builtin_.c builtin.h | |
| 177 | + $(TCC) -o$@ -c builtin_.c | |
| 178 | + | |
| 179 | +builtin_.c : $(SRCDIR)\builtin.c | |
| 180 | + +translate$E $** > $@ | |
| 165 | 181 | |
| 166 | 182 | $(OBJDIR)\cache$O : cache_.c cache.h |
| 167 | 183 | $(TCC) -o$@ -c cache_.c |
| 168 | 184 | |
| 169 | 185 | cache_.c : $(SRCDIR)\cache.c |
| @@ -779,8 +795,8 @@ | ||
| 779 | 795 | $(TCC) -o$@ -c zip_.c |
| 780 | 796 | |
| 781 | 797 | zip_.c : $(SRCDIR)\zip.c |
| 782 | 798 | +translate$E $** > $@ |
| 783 | 799 | |
| 784 | -headers: makeheaders$E page_index.h VERSION.h | |
| 785 | - +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h | |
| 800 | +headers: makeheaders$E page_index.h builtin_data.h VERSION.h | |
| 801 | + +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h | |
| 786 | 802 | @copy /Y nul: headers |
| 787 | 803 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -28,31 +28,32 @@ | |
| 28 | |
| 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | |
| 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | |
| 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | |
| 37 | |
| 38 | RC=$(DMDIR)\bin\rcc |
| 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | |
| 41 | APPNAME = $(OBJDIR)\fossil$(E) |
| 42 | |
| 43 | all: $(APPNAME) |
| 44 | |
| 45 | $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link |
| 46 | cd $(OBJDIR) |
| 47 | $(DMDIR)\bin\link @link |
| 48 | |
| 49 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 50 | $(RC) $(RCFLAGS) -o$@ $** |
| 51 | |
| 52 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 53 | +echo add allrepo attach bag bisect blob branch browse cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ |
| 54 | +echo fossil >> $@ |
| 55 | +echo fossil >> $@ |
| 56 | +echo $(LIBS) >> $@ |
| 57 | +echo. >> $@ |
| 58 | +echo fossil >> $@ |
| @@ -64,11 +65,17 @@ | |
| 64 | $(BCC) -o$@ $** |
| 65 | |
| 66 | mkindex$E: $(SRCDIR)\mkindex.c |
| 67 | $(BCC) -o$@ $** |
| 68 | |
| 69 | version$E: $B\src\mkversion.c |
| 70 | $(BCC) -o$@ $** |
| 71 | |
| 72 | $(OBJDIR)\shell$O : $(SRCDIR)\shell.c |
| 73 | $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $** |
| 74 | |
| @@ -82,22 +89,25 @@ | |
| 82 | $(TCC) -o$@ -c $** |
| 83 | |
| 84 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 85 | cp $@ $@ |
| 86 | |
| 87 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 88 | +$** > $@ |
| 89 | |
| 90 | page_index.h: mkindex$E $(SRC) |
| 91 | +$** > $@ |
| 92 | |
| 93 | clean: |
| 94 | -del $(OBJDIR)\*.obj |
| 95 | -del *.obj *_.c *.h *.map |
| 96 | |
| 97 | realclean: |
| 98 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 99 | |
| 100 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 101 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 102 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 103 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -160,10 +170,16 @@ | |
| 160 | $(OBJDIR)\browse$O : browse_.c browse.h |
| 161 | $(TCC) -o$@ -c browse_.c |
| 162 | |
| 163 | browse_.c : $(SRCDIR)\browse.c |
| 164 | +translate$E $** > $@ |
| 165 | |
| 166 | $(OBJDIR)\cache$O : cache_.c cache.h |
| 167 | $(TCC) -o$@ -c cache_.c |
| 168 | |
| 169 | cache_.c : $(SRCDIR)\cache.c |
| @@ -779,8 +795,8 @@ | |
| 779 | $(TCC) -o$@ -c zip_.c |
| 780 | |
| 781 | zip_.c : $(SRCDIR)\zip.c |
| 782 | +translate$E $** > $@ |
| 783 | |
| 784 | headers: makeheaders$E page_index.h VERSION.h |
| 785 | +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h |
| 786 | @copy /Y nul: headers |
| 787 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -28,31 +28,32 @@ | |
| 28 | |
| 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | |
| 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | |
| 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | |
| 37 | |
| 38 | RC=$(DMDIR)\bin\rcc |
| 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | |
| 41 | APPNAME = $(OBJDIR)\fossil$(E) |
| 42 | |
| 43 | all: $(APPNAME) |
| 44 | |
| 45 | $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link |
| 46 | cd $(OBJDIR) |
| 47 | codecheck1$E $(SRC) |
| 48 | $(DMDIR)\bin\link @link |
| 49 | |
| 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | |
| 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | +echo add allrepo attach bag bisect blob branch browse builtin cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ |
| 55 | +echo fossil >> $@ |
| 56 | +echo fossil >> $@ |
| 57 | +echo $(LIBS) >> $@ |
| 58 | +echo. >> $@ |
| 59 | +echo fossil >> $@ |
| @@ -64,11 +65,17 @@ | |
| 65 | $(BCC) -o$@ $** |
| 66 | |
| 67 | mkindex$E: $(SRCDIR)\mkindex.c |
| 68 | $(BCC) -o$@ $** |
| 69 | |
| 70 | mkbuiltin$E: $(SRCDIR)\mkbuiltin.c |
| 71 | $(BCC) -o$@ $** |
| 72 | |
| 73 | mkversion$E: $(SRCDIR)\mkversion.c |
| 74 | $(BCC) -o$@ $** |
| 75 | |
| 76 | codecheck1$E: $(SRCDIR)\codecheck1.c |
| 77 | $(BCC) -o$@ $** |
| 78 | |
| 79 | $(OBJDIR)\shell$O : $(SRCDIR)\shell.c |
| 80 | $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $** |
| 81 | |
| @@ -82,22 +89,25 @@ | |
| 89 | $(TCC) -o$@ -c $** |
| 90 | |
| 91 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 92 | cp $@ $@ |
| 93 | |
| 94 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 95 | +$** > $@ |
| 96 | |
| 97 | page_index.h: mkindex$E $(SRC) |
| 98 | +$** > $@ |
| 99 | |
| 100 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 101 | +$** > $@ |
| 102 | |
| 103 | clean: |
| 104 | -del $(OBJDIR)\*.obj |
| 105 | -del *.obj *_.c *.h *.map |
| 106 | |
| 107 | realclean: |
| 108 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E mkbuiltin$E |
| 109 | |
| 110 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 111 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 112 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 113 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -160,10 +170,16 @@ | |
| 170 | $(OBJDIR)\browse$O : browse_.c browse.h |
| 171 | $(TCC) -o$@ -c browse_.c |
| 172 | |
| 173 | browse_.c : $(SRCDIR)\browse.c |
| 174 | +translate$E $** > $@ |
| 175 | |
| 176 | $(OBJDIR)\builtin$O : builtin_.c builtin.h |
| 177 | $(TCC) -o$@ -c builtin_.c |
| 178 | |
| 179 | builtin_.c : $(SRCDIR)\builtin.c |
| 180 | +translate$E $** > $@ |
| 181 | |
| 182 | $(OBJDIR)\cache$O : cache_.c cache.h |
| 183 | $(TCC) -o$@ -c cache_.c |
| 184 | |
| 185 | cache_.c : $(SRCDIR)\cache.c |
| @@ -779,8 +795,8 @@ | |
| 795 | $(TCC) -o$@ -c zip_.c |
| 796 | |
| 797 | zip_.c : $(SRCDIR)\zip.c |
| 798 | +translate$E $** > $@ |
| 799 | |
| 800 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 801 | +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h |
| 802 | @copy /Y nul: headers |
| 803 |
+42
-10
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -113,12 +113,12 @@ | ||
| 113 | 113 | #### The directories where the OpenSSL include and library files are located. |
| 114 | 114 | # The recommended usage here is to use the Sysinternals junction tool |
| 115 | 115 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 116 | 116 | # Fossil source code directory and the target OpenSSL source directory. |
| 117 | 117 | # |
| 118 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include | |
| 119 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i | |
| 118 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include | |
| 119 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j | |
| 120 | 120 | |
| 121 | 121 | #### Either the directory where the Tcl library is installed or the Tcl |
| 122 | 122 | # source code directory resides (depending on the value of the macro |
| 123 | 123 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 124 | 124 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -339,10 +339,11 @@ | ||
| 339 | 339 | $(SRCDIR)/bag.c \ |
| 340 | 340 | $(SRCDIR)/bisect.c \ |
| 341 | 341 | $(SRCDIR)/blob.c \ |
| 342 | 342 | $(SRCDIR)/branch.c \ |
| 343 | 343 | $(SRCDIR)/browse.c \ |
| 344 | + $(SRCDIR)/builtin.c \ | |
| 344 | 345 | $(SRCDIR)/cache.c \ |
| 345 | 346 | $(SRCDIR)/captcha.c \ |
| 346 | 347 | $(SRCDIR)/cgi.c \ |
| 347 | 348 | $(SRCDIR)/checkin.c \ |
| 348 | 349 | $(SRCDIR)/checkout.c \ |
| @@ -443,19 +444,23 @@ | ||
| 443 | 444 | $(SRCDIR)/wysiwyg.c \ |
| 444 | 445 | $(SRCDIR)/xfer.c \ |
| 445 | 446 | $(SRCDIR)/xfersetup.c \ |
| 446 | 447 | $(SRCDIR)/zip.c |
| 447 | 448 | |
| 449 | +EXTRA_FILES = \ | |
| 450 | + $(SRCDIR)/diff.tcl | |
| 451 | + | |
| 448 | 452 | TRANS_SRC = \ |
| 449 | 453 | $(OBJDIR)/add_.c \ |
| 450 | 454 | $(OBJDIR)/allrepo_.c \ |
| 451 | 455 | $(OBJDIR)/attach_.c \ |
| 452 | 456 | $(OBJDIR)/bag_.c \ |
| 453 | 457 | $(OBJDIR)/bisect_.c \ |
| 454 | 458 | $(OBJDIR)/blob_.c \ |
| 455 | 459 | $(OBJDIR)/branch_.c \ |
| 456 | 460 | $(OBJDIR)/browse_.c \ |
| 461 | + $(OBJDIR)/builtin_.c \ | |
| 457 | 462 | $(OBJDIR)/cache_.c \ |
| 458 | 463 | $(OBJDIR)/captcha_.c \ |
| 459 | 464 | $(OBJDIR)/cgi_.c \ |
| 460 | 465 | $(OBJDIR)/checkin_.c \ |
| 461 | 466 | $(OBJDIR)/checkout_.c \ |
| @@ -565,10 +570,11 @@ | ||
| 565 | 570 | $(OBJDIR)/bag.o \ |
| 566 | 571 | $(OBJDIR)/bisect.o \ |
| 567 | 572 | $(OBJDIR)/blob.o \ |
| 568 | 573 | $(OBJDIR)/branch.o \ |
| 569 | 574 | $(OBJDIR)/browse.o \ |
| 575 | + $(OBJDIR)/builtin.o \ | |
| 570 | 576 | $(OBJDIR)/cache.o \ |
| 571 | 577 | $(OBJDIR)/captcha.o \ |
| 572 | 578 | $(OBJDIR)/cgi.o \ |
| 573 | 579 | $(OBJDIR)/checkin.o \ |
| 574 | 580 | $(OBJDIR)/checkout.o \ |
| @@ -684,11 +690,13 @@ | ||
| 684 | 690 | # |
| 685 | 691 | ifdef USE_WINDOWS |
| 686 | 692 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 687 | 693 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 688 | 694 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 689 | -VERSION = $(subst /,\,$(OBJDIR)/version.exe) | |
| 695 | +MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe) | |
| 696 | +MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe) | |
| 697 | +CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe) | |
| 690 | 698 | CAT = type |
| 691 | 699 | CP = copy |
| 692 | 700 | GREP = find |
| 693 | 701 | MV = copy |
| 694 | 702 | RM = del /Q |
| @@ -696,11 +704,13 @@ | ||
| 696 | 704 | RMDIR = rmdir /S /Q |
| 697 | 705 | else |
| 698 | 706 | TRANSLATE = $(OBJDIR)/translate.exe |
| 699 | 707 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 700 | 708 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 701 | -VERSION = $(OBJDIR)/version.exe | |
| 709 | +MKBUILTIN = $(OBJDIR)/mkbuiltin.exe | |
| 710 | +MKVERSION = $(OBJDIR)/mkversion.exe | |
| 711 | +CODECHECK1 = $(OBJDIR)/codecheck1.exe | |
| 702 | 712 | CAT = cat |
| 703 | 713 | CP = cp |
| 704 | 714 | GREP = grep |
| 705 | 715 | MV = mv |
| 706 | 716 | RM = rm -f |
| @@ -747,21 +757,27 @@ | ||
| 747 | 757 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 748 | 758 | |
| 749 | 759 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 750 | 760 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 751 | 761 | |
| 752 | -$(VERSION): $(SRCDIR)/mkversion.c | |
| 753 | - $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c | |
| 762 | +$(MKBUILTIN): $(SRCDIR)/mkbuiltin.c | |
| 763 | + $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c | |
| 764 | + | |
| 765 | +$(MKVERSION): $(SRCDIR)/mkversion.c | |
| 766 | + $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c | |
| 767 | + | |
| 768 | +$(CODECHECK1): $(SRCDIR)/codecheck1.c | |
| 769 | + $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c | |
| 754 | 770 | |
| 755 | 771 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 756 | 772 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 757 | 773 | # the repository after running the tests. |
| 758 | 774 | test: $(OBJDIR) $(APPNAME) |
| 759 | 775 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 760 | 776 | |
| 761 | -$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) | |
| 762 | - $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 777 | +$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION) | |
| 778 | + $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 763 | 779 | |
| 764 | 780 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 765 | 781 | # to 1. If it is set to 1, then there is no need to build or link |
| 766 | 782 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 767 | 783 | # using -lsqlite3. |
| @@ -815,11 +831,12 @@ | ||
| 815 | 831 | |
| 816 | 832 | ifdef FOSSIL_BUILD_SSL |
| 817 | 833 | APPTARGETS += openssl |
| 818 | 834 | endif |
| 819 | 835 | |
| 820 | -$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) | |
| 836 | +$(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) | |
| 837 | + $(CODECHECK1) $(TRANS_SRC) | |
| 821 | 838 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 822 | 839 | |
| 823 | 840 | # This rule prevents make from using its default rules to try build |
| 824 | 841 | # an executable named "manifest" out of the file named "manifest.c" |
| 825 | 842 | # |
| @@ -842,19 +859,23 @@ | ||
| 842 | 859 | $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION) |
| 843 | 860 | |
| 844 | 861 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 845 | 862 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 846 | 863 | |
| 847 | -$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h | |
| 864 | +$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) | |
| 865 | + $(MKBUILTIN) $(EXTRA_FILES) >$@ | |
| 866 | + | |
| 867 | +$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h | |
| 848 | 868 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 849 | 869 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 850 | 870 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 851 | 871 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 852 | 872 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 853 | 873 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 854 | 874 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 855 | 875 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 876 | + $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ | |
| 856 | 877 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 857 | 878 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 858 | 879 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 859 | 880 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 860 | 881 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -963,10 +984,13 @@ | ||
| 963 | 984 | |
| 964 | 985 | $(OBJDIR)/headers: Makefile |
| 965 | 986 | |
| 966 | 987 | Makefile: |
| 967 | 988 | |
| 989 | +$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) | |
| 990 | + $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h | |
| 991 | + | |
| 968 | 992 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) |
| 969 | 993 | $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 970 | 994 | |
| 971 | 995 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| 972 | 996 | $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c |
| @@ -1026,10 +1050,18 @@ | ||
| 1026 | 1050 | |
| 1027 | 1051 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 1028 | 1052 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 1029 | 1053 | |
| 1030 | 1054 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 1055 | + | |
| 1056 | +$(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE) | |
| 1057 | + $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c | |
| 1058 | + | |
| 1059 | +$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h | |
| 1060 | + $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c | |
| 1061 | + | |
| 1062 | +$(OBJDIR)/builtin.h: $(OBJDIR)/headers | |
| 1031 | 1063 | |
| 1032 | 1064 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1033 | 1065 | $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 1034 | 1066 | |
| 1035 | 1067 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 1036 | 1068 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -113,12 +113,12 @@ | |
| 113 | #### The directories where the OpenSSL include and library files are located. |
| 114 | # The recommended usage here is to use the Sysinternals junction tool |
| 115 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 116 | # Fossil source code directory and the target OpenSSL source directory. |
| 117 | # |
| 118 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include |
| 119 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i |
| 120 | |
| 121 | #### Either the directory where the Tcl library is installed or the Tcl |
| 122 | # source code directory resides (depending on the value of the macro |
| 123 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 124 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -339,10 +339,11 @@ | |
| 339 | $(SRCDIR)/bag.c \ |
| 340 | $(SRCDIR)/bisect.c \ |
| 341 | $(SRCDIR)/blob.c \ |
| 342 | $(SRCDIR)/branch.c \ |
| 343 | $(SRCDIR)/browse.c \ |
| 344 | $(SRCDIR)/cache.c \ |
| 345 | $(SRCDIR)/captcha.c \ |
| 346 | $(SRCDIR)/cgi.c \ |
| 347 | $(SRCDIR)/checkin.c \ |
| 348 | $(SRCDIR)/checkout.c \ |
| @@ -443,19 +444,23 @@ | |
| 443 | $(SRCDIR)/wysiwyg.c \ |
| 444 | $(SRCDIR)/xfer.c \ |
| 445 | $(SRCDIR)/xfersetup.c \ |
| 446 | $(SRCDIR)/zip.c |
| 447 | |
| 448 | TRANS_SRC = \ |
| 449 | $(OBJDIR)/add_.c \ |
| 450 | $(OBJDIR)/allrepo_.c \ |
| 451 | $(OBJDIR)/attach_.c \ |
| 452 | $(OBJDIR)/bag_.c \ |
| 453 | $(OBJDIR)/bisect_.c \ |
| 454 | $(OBJDIR)/blob_.c \ |
| 455 | $(OBJDIR)/branch_.c \ |
| 456 | $(OBJDIR)/browse_.c \ |
| 457 | $(OBJDIR)/cache_.c \ |
| 458 | $(OBJDIR)/captcha_.c \ |
| 459 | $(OBJDIR)/cgi_.c \ |
| 460 | $(OBJDIR)/checkin_.c \ |
| 461 | $(OBJDIR)/checkout_.c \ |
| @@ -565,10 +570,11 @@ | |
| 565 | $(OBJDIR)/bag.o \ |
| 566 | $(OBJDIR)/bisect.o \ |
| 567 | $(OBJDIR)/blob.o \ |
| 568 | $(OBJDIR)/branch.o \ |
| 569 | $(OBJDIR)/browse.o \ |
| 570 | $(OBJDIR)/cache.o \ |
| 571 | $(OBJDIR)/captcha.o \ |
| 572 | $(OBJDIR)/cgi.o \ |
| 573 | $(OBJDIR)/checkin.o \ |
| 574 | $(OBJDIR)/checkout.o \ |
| @@ -684,11 +690,13 @@ | |
| 684 | # |
| 685 | ifdef USE_WINDOWS |
| 686 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 687 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 688 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 689 | VERSION = $(subst /,\,$(OBJDIR)/version.exe) |
| 690 | CAT = type |
| 691 | CP = copy |
| 692 | GREP = find |
| 693 | MV = copy |
| 694 | RM = del /Q |
| @@ -696,11 +704,13 @@ | |
| 696 | RMDIR = rmdir /S /Q |
| 697 | else |
| 698 | TRANSLATE = $(OBJDIR)/translate.exe |
| 699 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 700 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 701 | VERSION = $(OBJDIR)/version.exe |
| 702 | CAT = cat |
| 703 | CP = cp |
| 704 | GREP = grep |
| 705 | MV = mv |
| 706 | RM = rm -f |
| @@ -747,21 +757,27 @@ | |
| 747 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 748 | |
| 749 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 750 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 751 | |
| 752 | $(VERSION): $(SRCDIR)/mkversion.c |
| 753 | $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c |
| 754 | |
| 755 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 756 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 757 | # the repository after running the tests. |
| 758 | test: $(OBJDIR) $(APPNAME) |
| 759 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 760 | |
| 761 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 762 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 763 | |
| 764 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 765 | # to 1. If it is set to 1, then there is no need to build or link |
| 766 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 767 | # using -lsqlite3. |
| @@ -815,11 +831,12 @@ | |
| 815 | |
| 816 | ifdef FOSSIL_BUILD_SSL |
| 817 | APPTARGETS += openssl |
| 818 | endif |
| 819 | |
| 820 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) |
| 821 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 822 | |
| 823 | # This rule prevents make from using its default rules to try build |
| 824 | # an executable named "manifest" out of the file named "manifest.c" |
| 825 | # |
| @@ -842,19 +859,23 @@ | |
| 842 | $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION) |
| 843 | |
| 844 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 845 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 846 | |
| 847 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 848 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 849 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 850 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 851 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 852 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 853 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 854 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 855 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 856 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 857 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 858 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 859 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 860 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -963,10 +984,13 @@ | |
| 963 | |
| 964 | $(OBJDIR)/headers: Makefile |
| 965 | |
| 966 | Makefile: |
| 967 | |
| 968 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) |
| 969 | $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 970 | |
| 971 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| 972 | $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c |
| @@ -1026,10 +1050,18 @@ | |
| 1026 | |
| 1027 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 1028 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 1029 | |
| 1030 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 1031 | |
| 1032 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1033 | $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 1034 | |
| 1035 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 1036 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -113,12 +113,12 @@ | |
| 113 | #### The directories where the OpenSSL include and library files are located. |
| 114 | # The recommended usage here is to use the Sysinternals junction tool |
| 115 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 116 | # Fossil source code directory and the target OpenSSL source directory. |
| 117 | # |
| 118 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include |
| 119 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j |
| 120 | |
| 121 | #### Either the directory where the Tcl library is installed or the Tcl |
| 122 | # source code directory resides (depending on the value of the macro |
| 123 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 124 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -339,10 +339,11 @@ | |
| 339 | $(SRCDIR)/bag.c \ |
| 340 | $(SRCDIR)/bisect.c \ |
| 341 | $(SRCDIR)/blob.c \ |
| 342 | $(SRCDIR)/branch.c \ |
| 343 | $(SRCDIR)/browse.c \ |
| 344 | $(SRCDIR)/builtin.c \ |
| 345 | $(SRCDIR)/cache.c \ |
| 346 | $(SRCDIR)/captcha.c \ |
| 347 | $(SRCDIR)/cgi.c \ |
| 348 | $(SRCDIR)/checkin.c \ |
| 349 | $(SRCDIR)/checkout.c \ |
| @@ -443,19 +444,23 @@ | |
| 444 | $(SRCDIR)/wysiwyg.c \ |
| 445 | $(SRCDIR)/xfer.c \ |
| 446 | $(SRCDIR)/xfersetup.c \ |
| 447 | $(SRCDIR)/zip.c |
| 448 | |
| 449 | EXTRA_FILES = \ |
| 450 | $(SRCDIR)/diff.tcl |
| 451 | |
| 452 | TRANS_SRC = \ |
| 453 | $(OBJDIR)/add_.c \ |
| 454 | $(OBJDIR)/allrepo_.c \ |
| 455 | $(OBJDIR)/attach_.c \ |
| 456 | $(OBJDIR)/bag_.c \ |
| 457 | $(OBJDIR)/bisect_.c \ |
| 458 | $(OBJDIR)/blob_.c \ |
| 459 | $(OBJDIR)/branch_.c \ |
| 460 | $(OBJDIR)/browse_.c \ |
| 461 | $(OBJDIR)/builtin_.c \ |
| 462 | $(OBJDIR)/cache_.c \ |
| 463 | $(OBJDIR)/captcha_.c \ |
| 464 | $(OBJDIR)/cgi_.c \ |
| 465 | $(OBJDIR)/checkin_.c \ |
| 466 | $(OBJDIR)/checkout_.c \ |
| @@ -565,10 +570,11 @@ | |
| 570 | $(OBJDIR)/bag.o \ |
| 571 | $(OBJDIR)/bisect.o \ |
| 572 | $(OBJDIR)/blob.o \ |
| 573 | $(OBJDIR)/branch.o \ |
| 574 | $(OBJDIR)/browse.o \ |
| 575 | $(OBJDIR)/builtin.o \ |
| 576 | $(OBJDIR)/cache.o \ |
| 577 | $(OBJDIR)/captcha.o \ |
| 578 | $(OBJDIR)/cgi.o \ |
| 579 | $(OBJDIR)/checkin.o \ |
| 580 | $(OBJDIR)/checkout.o \ |
| @@ -684,11 +690,13 @@ | |
| 690 | # |
| 691 | ifdef USE_WINDOWS |
| 692 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 693 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 694 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 695 | MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe) |
| 696 | MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe) |
| 697 | CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe) |
| 698 | CAT = type |
| 699 | CP = copy |
| 700 | GREP = find |
| 701 | MV = copy |
| 702 | RM = del /Q |
| @@ -696,11 +704,13 @@ | |
| 704 | RMDIR = rmdir /S /Q |
| 705 | else |
| 706 | TRANSLATE = $(OBJDIR)/translate.exe |
| 707 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 708 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 709 | MKBUILTIN = $(OBJDIR)/mkbuiltin.exe |
| 710 | MKVERSION = $(OBJDIR)/mkversion.exe |
| 711 | CODECHECK1 = $(OBJDIR)/codecheck1.exe |
| 712 | CAT = cat |
| 713 | CP = cp |
| 714 | GREP = grep |
| 715 | MV = mv |
| 716 | RM = rm -f |
| @@ -747,21 +757,27 @@ | |
| 757 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 758 | |
| 759 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 760 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 761 | |
| 762 | $(MKBUILTIN): $(SRCDIR)/mkbuiltin.c |
| 763 | $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c |
| 764 | |
| 765 | $(MKVERSION): $(SRCDIR)/mkversion.c |
| 766 | $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c |
| 767 | |
| 768 | $(CODECHECK1): $(SRCDIR)/codecheck1.c |
| 769 | $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c |
| 770 | |
| 771 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 772 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 773 | # the repository after running the tests. |
| 774 | test: $(OBJDIR) $(APPNAME) |
| 775 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 776 | |
| 777 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION) |
| 778 | $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 779 | |
| 780 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 781 | # to 1. If it is set to 1, then there is no need to build or link |
| 782 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 783 | # using -lsqlite3. |
| @@ -815,11 +831,12 @@ | |
| 831 | |
| 832 | ifdef FOSSIL_BUILD_SSL |
| 833 | APPTARGETS += openssl |
| 834 | endif |
| 835 | |
| 836 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) |
| 837 | $(CODECHECK1) $(TRANS_SRC) |
| 838 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 839 | |
| 840 | # This rule prevents make from using its default rules to try build |
| 841 | # an executable named "manifest" out of the file named "manifest.c" |
| 842 | # |
| @@ -842,19 +859,23 @@ | |
| 859 | $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION) |
| 860 | |
| 861 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 862 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 863 | |
| 864 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 865 | $(MKBUILTIN) $(EXTRA_FILES) >$@ |
| 866 | |
| 867 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 868 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 869 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 870 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 871 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 872 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 873 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 874 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 875 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 876 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 877 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 878 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 879 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 880 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 881 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -963,10 +984,13 @@ | |
| 984 | |
| 985 | $(OBJDIR)/headers: Makefile |
| 986 | |
| 987 | Makefile: |
| 988 | |
| 989 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 990 | $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h |
| 991 | |
| 992 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) |
| 993 | $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 994 | |
| 995 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| 996 | $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c |
| @@ -1026,10 +1050,18 @@ | |
| 1050 | |
| 1051 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 1052 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 1053 | |
| 1054 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 1055 | |
| 1056 | $(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE) |
| 1057 | $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c |
| 1058 | |
| 1059 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 1060 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 1061 | |
| 1062 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 1063 | |
| 1064 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1065 | $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 1066 | |
| 1067 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 1068 |
+42
-10
| --- win/Makefile.mingw.mistachkin | ||
| +++ win/Makefile.mingw.mistachkin | ||
| @@ -113,12 +113,12 @@ | ||
| 113 | 113 | #### The directories where the OpenSSL include and library files are located. |
| 114 | 114 | # The recommended usage here is to use the Sysinternals junction tool |
| 115 | 115 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 116 | 116 | # Fossil source code directory and the target OpenSSL source directory. |
| 117 | 117 | # |
| 118 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include | |
| 119 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i | |
| 118 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include | |
| 119 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j | |
| 120 | 120 | |
| 121 | 121 | #### Either the directory where the Tcl library is installed or the Tcl |
| 122 | 122 | # source code directory resides (depending on the value of the macro |
| 123 | 123 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 124 | 124 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -339,10 +339,11 @@ | ||
| 339 | 339 | $(SRCDIR)/bag.c \ |
| 340 | 340 | $(SRCDIR)/bisect.c \ |
| 341 | 341 | $(SRCDIR)/blob.c \ |
| 342 | 342 | $(SRCDIR)/branch.c \ |
| 343 | 343 | $(SRCDIR)/browse.c \ |
| 344 | + $(SRCDIR)/builtin.c \ | |
| 344 | 345 | $(SRCDIR)/cache.c \ |
| 345 | 346 | $(SRCDIR)/captcha.c \ |
| 346 | 347 | $(SRCDIR)/cgi.c \ |
| 347 | 348 | $(SRCDIR)/checkin.c \ |
| 348 | 349 | $(SRCDIR)/checkout.c \ |
| @@ -443,19 +444,23 @@ | ||
| 443 | 444 | $(SRCDIR)/wysiwyg.c \ |
| 444 | 445 | $(SRCDIR)/xfer.c \ |
| 445 | 446 | $(SRCDIR)/xfersetup.c \ |
| 446 | 447 | $(SRCDIR)/zip.c |
| 447 | 448 | |
| 449 | +EXTRA_FILES = \ | |
| 450 | + $(SRCDIR)/diff.tcl | |
| 451 | + | |
| 448 | 452 | TRANS_SRC = \ |
| 449 | 453 | $(OBJDIR)/add_.c \ |
| 450 | 454 | $(OBJDIR)/allrepo_.c \ |
| 451 | 455 | $(OBJDIR)/attach_.c \ |
| 452 | 456 | $(OBJDIR)/bag_.c \ |
| 453 | 457 | $(OBJDIR)/bisect_.c \ |
| 454 | 458 | $(OBJDIR)/blob_.c \ |
| 455 | 459 | $(OBJDIR)/branch_.c \ |
| 456 | 460 | $(OBJDIR)/browse_.c \ |
| 461 | + $(OBJDIR)/builtin_.c \ | |
| 457 | 462 | $(OBJDIR)/cache_.c \ |
| 458 | 463 | $(OBJDIR)/captcha_.c \ |
| 459 | 464 | $(OBJDIR)/cgi_.c \ |
| 460 | 465 | $(OBJDIR)/checkin_.c \ |
| 461 | 466 | $(OBJDIR)/checkout_.c \ |
| @@ -565,10 +570,11 @@ | ||
| 565 | 570 | $(OBJDIR)/bag.o \ |
| 566 | 571 | $(OBJDIR)/bisect.o \ |
| 567 | 572 | $(OBJDIR)/blob.o \ |
| 568 | 573 | $(OBJDIR)/branch.o \ |
| 569 | 574 | $(OBJDIR)/browse.o \ |
| 575 | + $(OBJDIR)/builtin.o \ | |
| 570 | 576 | $(OBJDIR)/cache.o \ |
| 571 | 577 | $(OBJDIR)/captcha.o \ |
| 572 | 578 | $(OBJDIR)/cgi.o \ |
| 573 | 579 | $(OBJDIR)/checkin.o \ |
| 574 | 580 | $(OBJDIR)/checkout.o \ |
| @@ -684,11 +690,13 @@ | ||
| 684 | 690 | # |
| 685 | 691 | ifdef USE_WINDOWS |
| 686 | 692 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 687 | 693 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 688 | 694 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 689 | -VERSION = $(subst /,\,$(OBJDIR)/version.exe) | |
| 695 | +MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe) | |
| 696 | +MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe) | |
| 697 | +CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe) | |
| 690 | 698 | CAT = type |
| 691 | 699 | CP = copy |
| 692 | 700 | GREP = find |
| 693 | 701 | MV = copy |
| 694 | 702 | RM = del /Q |
| @@ -696,11 +704,13 @@ | ||
| 696 | 704 | RMDIR = rmdir /S /Q |
| 697 | 705 | else |
| 698 | 706 | TRANSLATE = $(OBJDIR)/translate.exe |
| 699 | 707 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 700 | 708 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 701 | -VERSION = $(OBJDIR)/version.exe | |
| 709 | +MKBUILTIN = $(OBJDIR)/mkbuiltin.exe | |
| 710 | +MKVERSION = $(OBJDIR)/mkversion.exe | |
| 711 | +CODECHECK1 = $(OBJDIR)/codecheck1.exe | |
| 702 | 712 | CAT = cat |
| 703 | 713 | CP = cp |
| 704 | 714 | GREP = grep |
| 705 | 715 | MV = mv |
| 706 | 716 | RM = rm -f |
| @@ -747,21 +757,27 @@ | ||
| 747 | 757 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 748 | 758 | |
| 749 | 759 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 750 | 760 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 751 | 761 | |
| 752 | -$(VERSION): $(SRCDIR)/mkversion.c | |
| 753 | - $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c | |
| 762 | +$(MKBUILTIN): $(SRCDIR)/mkbuiltin.c | |
| 763 | + $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c | |
| 764 | + | |
| 765 | +$(MKVERSION): $(SRCDIR)/mkversion.c | |
| 766 | + $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c | |
| 767 | + | |
| 768 | +$(CODECHECK1): $(SRCDIR)/codecheck1.c | |
| 769 | + $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c | |
| 754 | 770 | |
| 755 | 771 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 756 | 772 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 757 | 773 | # the repository after running the tests. |
| 758 | 774 | test: $(OBJDIR) $(APPNAME) |
| 759 | 775 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 760 | 776 | |
| 761 | -$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) | |
| 762 | - $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 777 | +$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION) | |
| 778 | + $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h | |
| 763 | 779 | |
| 764 | 780 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 765 | 781 | # to 1. If it is set to 1, then there is no need to build or link |
| 766 | 782 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 767 | 783 | # using -lsqlite3. |
| @@ -815,11 +831,12 @@ | ||
| 815 | 831 | |
| 816 | 832 | ifdef FOSSIL_BUILD_SSL |
| 817 | 833 | APPTARGETS += openssl |
| 818 | 834 | endif |
| 819 | 835 | |
| 820 | -$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) | |
| 836 | +$(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) | |
| 837 | + $(CODECHECK1) $(TRANS_SRC) | |
| 821 | 838 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 822 | 839 | |
| 823 | 840 | # This rule prevents make from using its default rules to try build |
| 824 | 841 | # an executable named "manifest" out of the file named "manifest.c" |
| 825 | 842 | # |
| @@ -842,19 +859,23 @@ | ||
| 842 | 859 | $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION) |
| 843 | 860 | |
| 844 | 861 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 845 | 862 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 846 | 863 | |
| 847 | -$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h | |
| 864 | +$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) | |
| 865 | + $(MKBUILTIN) $(EXTRA_FILES) >$@ | |
| 866 | + | |
| 867 | +$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h | |
| 848 | 868 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 849 | 869 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 850 | 870 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 851 | 871 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 852 | 872 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 853 | 873 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 854 | 874 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 855 | 875 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 876 | + $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ | |
| 856 | 877 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 857 | 878 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 858 | 879 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 859 | 880 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 860 | 881 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -963,10 +984,13 @@ | ||
| 963 | 984 | |
| 964 | 985 | $(OBJDIR)/headers: Makefile |
| 965 | 986 | |
| 966 | 987 | Makefile: |
| 967 | 988 | |
| 989 | +$(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) | |
| 990 | + $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h | |
| 991 | + | |
| 968 | 992 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) |
| 969 | 993 | $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 970 | 994 | |
| 971 | 995 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| 972 | 996 | $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c |
| @@ -1026,10 +1050,18 @@ | ||
| 1026 | 1050 | |
| 1027 | 1051 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 1028 | 1052 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 1029 | 1053 | |
| 1030 | 1054 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 1055 | + | |
| 1056 | +$(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE) | |
| 1057 | + $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c | |
| 1058 | + | |
| 1059 | +$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h | |
| 1060 | + $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c | |
| 1061 | + | |
| 1062 | +$(OBJDIR)/builtin.h: $(OBJDIR)/headers | |
| 1031 | 1063 | |
| 1032 | 1064 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1033 | 1065 | $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 1034 | 1066 | |
| 1035 | 1067 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 1036 | 1068 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -113,12 +113,12 @@ | |
| 113 | #### The directories where the OpenSSL include and library files are located. |
| 114 | # The recommended usage here is to use the Sysinternals junction tool |
| 115 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 116 | # Fossil source code directory and the target OpenSSL source directory. |
| 117 | # |
| 118 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include |
| 119 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i |
| 120 | |
| 121 | #### Either the directory where the Tcl library is installed or the Tcl |
| 122 | # source code directory resides (depending on the value of the macro |
| 123 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 124 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -339,10 +339,11 @@ | |
| 339 | $(SRCDIR)/bag.c \ |
| 340 | $(SRCDIR)/bisect.c \ |
| 341 | $(SRCDIR)/blob.c \ |
| 342 | $(SRCDIR)/branch.c \ |
| 343 | $(SRCDIR)/browse.c \ |
| 344 | $(SRCDIR)/cache.c \ |
| 345 | $(SRCDIR)/captcha.c \ |
| 346 | $(SRCDIR)/cgi.c \ |
| 347 | $(SRCDIR)/checkin.c \ |
| 348 | $(SRCDIR)/checkout.c \ |
| @@ -443,19 +444,23 @@ | |
| 443 | $(SRCDIR)/wysiwyg.c \ |
| 444 | $(SRCDIR)/xfer.c \ |
| 445 | $(SRCDIR)/xfersetup.c \ |
| 446 | $(SRCDIR)/zip.c |
| 447 | |
| 448 | TRANS_SRC = \ |
| 449 | $(OBJDIR)/add_.c \ |
| 450 | $(OBJDIR)/allrepo_.c \ |
| 451 | $(OBJDIR)/attach_.c \ |
| 452 | $(OBJDIR)/bag_.c \ |
| 453 | $(OBJDIR)/bisect_.c \ |
| 454 | $(OBJDIR)/blob_.c \ |
| 455 | $(OBJDIR)/branch_.c \ |
| 456 | $(OBJDIR)/browse_.c \ |
| 457 | $(OBJDIR)/cache_.c \ |
| 458 | $(OBJDIR)/captcha_.c \ |
| 459 | $(OBJDIR)/cgi_.c \ |
| 460 | $(OBJDIR)/checkin_.c \ |
| 461 | $(OBJDIR)/checkout_.c \ |
| @@ -565,10 +570,11 @@ | |
| 565 | $(OBJDIR)/bag.o \ |
| 566 | $(OBJDIR)/bisect.o \ |
| 567 | $(OBJDIR)/blob.o \ |
| 568 | $(OBJDIR)/branch.o \ |
| 569 | $(OBJDIR)/browse.o \ |
| 570 | $(OBJDIR)/cache.o \ |
| 571 | $(OBJDIR)/captcha.o \ |
| 572 | $(OBJDIR)/cgi.o \ |
| 573 | $(OBJDIR)/checkin.o \ |
| 574 | $(OBJDIR)/checkout.o \ |
| @@ -684,11 +690,13 @@ | |
| 684 | # |
| 685 | ifdef USE_WINDOWS |
| 686 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 687 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 688 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 689 | VERSION = $(subst /,\,$(OBJDIR)/version.exe) |
| 690 | CAT = type |
| 691 | CP = copy |
| 692 | GREP = find |
| 693 | MV = copy |
| 694 | RM = del /Q |
| @@ -696,11 +704,13 @@ | |
| 696 | RMDIR = rmdir /S /Q |
| 697 | else |
| 698 | TRANSLATE = $(OBJDIR)/translate.exe |
| 699 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 700 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 701 | VERSION = $(OBJDIR)/version.exe |
| 702 | CAT = cat |
| 703 | CP = cp |
| 704 | GREP = grep |
| 705 | MV = mv |
| 706 | RM = rm -f |
| @@ -747,21 +757,27 @@ | |
| 747 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 748 | |
| 749 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 750 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 751 | |
| 752 | $(VERSION): $(SRCDIR)/mkversion.c |
| 753 | $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c |
| 754 | |
| 755 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 756 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 757 | # the repository after running the tests. |
| 758 | test: $(OBJDIR) $(APPNAME) |
| 759 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 760 | |
| 761 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 762 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 763 | |
| 764 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 765 | # to 1. If it is set to 1, then there is no need to build or link |
| 766 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 767 | # using -lsqlite3. |
| @@ -815,11 +831,12 @@ | |
| 815 | |
| 816 | ifdef FOSSIL_BUILD_SSL |
| 817 | APPTARGETS += openssl |
| 818 | endif |
| 819 | |
| 820 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) |
| 821 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 822 | |
| 823 | # This rule prevents make from using its default rules to try build |
| 824 | # an executable named "manifest" out of the file named "manifest.c" |
| 825 | # |
| @@ -842,19 +859,23 @@ | |
| 842 | $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION) |
| 843 | |
| 844 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 845 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 846 | |
| 847 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 848 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 849 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 850 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 851 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 852 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 853 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 854 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 855 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 856 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 857 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 858 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 859 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 860 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -963,10 +984,13 @@ | |
| 963 | |
| 964 | $(OBJDIR)/headers: Makefile |
| 965 | |
| 966 | Makefile: |
| 967 | |
| 968 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) |
| 969 | $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 970 | |
| 971 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| 972 | $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c |
| @@ -1026,10 +1050,18 @@ | |
| 1026 | |
| 1027 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 1028 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 1029 | |
| 1030 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 1031 | |
| 1032 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1033 | $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 1034 | |
| 1035 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 1036 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -113,12 +113,12 @@ | |
| 113 | #### The directories where the OpenSSL include and library files are located. |
| 114 | # The recommended usage here is to use the Sysinternals junction tool |
| 115 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 116 | # Fossil source code directory and the target OpenSSL source directory. |
| 117 | # |
| 118 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include |
| 119 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j |
| 120 | |
| 121 | #### Either the directory where the Tcl library is installed or the Tcl |
| 122 | # source code directory resides (depending on the value of the macro |
| 123 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 124 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -339,10 +339,11 @@ | |
| 339 | $(SRCDIR)/bag.c \ |
| 340 | $(SRCDIR)/bisect.c \ |
| 341 | $(SRCDIR)/blob.c \ |
| 342 | $(SRCDIR)/branch.c \ |
| 343 | $(SRCDIR)/browse.c \ |
| 344 | $(SRCDIR)/builtin.c \ |
| 345 | $(SRCDIR)/cache.c \ |
| 346 | $(SRCDIR)/captcha.c \ |
| 347 | $(SRCDIR)/cgi.c \ |
| 348 | $(SRCDIR)/checkin.c \ |
| 349 | $(SRCDIR)/checkout.c \ |
| @@ -443,19 +444,23 @@ | |
| 444 | $(SRCDIR)/wysiwyg.c \ |
| 445 | $(SRCDIR)/xfer.c \ |
| 446 | $(SRCDIR)/xfersetup.c \ |
| 447 | $(SRCDIR)/zip.c |
| 448 | |
| 449 | EXTRA_FILES = \ |
| 450 | $(SRCDIR)/diff.tcl |
| 451 | |
| 452 | TRANS_SRC = \ |
| 453 | $(OBJDIR)/add_.c \ |
| 454 | $(OBJDIR)/allrepo_.c \ |
| 455 | $(OBJDIR)/attach_.c \ |
| 456 | $(OBJDIR)/bag_.c \ |
| 457 | $(OBJDIR)/bisect_.c \ |
| 458 | $(OBJDIR)/blob_.c \ |
| 459 | $(OBJDIR)/branch_.c \ |
| 460 | $(OBJDIR)/browse_.c \ |
| 461 | $(OBJDIR)/builtin_.c \ |
| 462 | $(OBJDIR)/cache_.c \ |
| 463 | $(OBJDIR)/captcha_.c \ |
| 464 | $(OBJDIR)/cgi_.c \ |
| 465 | $(OBJDIR)/checkin_.c \ |
| 466 | $(OBJDIR)/checkout_.c \ |
| @@ -565,10 +570,11 @@ | |
| 570 | $(OBJDIR)/bag.o \ |
| 571 | $(OBJDIR)/bisect.o \ |
| 572 | $(OBJDIR)/blob.o \ |
| 573 | $(OBJDIR)/branch.o \ |
| 574 | $(OBJDIR)/browse.o \ |
| 575 | $(OBJDIR)/builtin.o \ |
| 576 | $(OBJDIR)/cache.o \ |
| 577 | $(OBJDIR)/captcha.o \ |
| 578 | $(OBJDIR)/cgi.o \ |
| 579 | $(OBJDIR)/checkin.o \ |
| 580 | $(OBJDIR)/checkout.o \ |
| @@ -684,11 +690,13 @@ | |
| 690 | # |
| 691 | ifdef USE_WINDOWS |
| 692 | TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe) |
| 693 | MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe) |
| 694 | MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe) |
| 695 | MKBUILTIN = $(subst /,\,$(OBJDIR)/mkbuiltin.exe) |
| 696 | MKVERSION = $(subst /,\,$(OBJDIR)/mkversion.exe) |
| 697 | CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe) |
| 698 | CAT = type |
| 699 | CP = copy |
| 700 | GREP = find |
| 701 | MV = copy |
| 702 | RM = del /Q |
| @@ -696,11 +704,13 @@ | |
| 704 | RMDIR = rmdir /S /Q |
| 705 | else |
| 706 | TRANSLATE = $(OBJDIR)/translate.exe |
| 707 | MAKEHEADERS = $(OBJDIR)/makeheaders.exe |
| 708 | MKINDEX = $(OBJDIR)/mkindex.exe |
| 709 | MKBUILTIN = $(OBJDIR)/mkbuiltin.exe |
| 710 | MKVERSION = $(OBJDIR)/mkversion.exe |
| 711 | CODECHECK1 = $(OBJDIR)/codecheck1.exe |
| 712 | CAT = cat |
| 713 | CP = cp |
| 714 | GREP = grep |
| 715 | MV = mv |
| 716 | RM = rm -f |
| @@ -747,21 +757,27 @@ | |
| 757 | $(BCC) -o $(MAKEHEADERS) $(SRCDIR)/makeheaders.c |
| 758 | |
| 759 | $(MKINDEX): $(SRCDIR)/mkindex.c |
| 760 | $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c |
| 761 | |
| 762 | $(MKBUILTIN): $(SRCDIR)/mkbuiltin.c |
| 763 | $(BCC) -o $(MKBUILTIN) $(SRCDIR)/mkbuiltin.c |
| 764 | |
| 765 | $(MKVERSION): $(SRCDIR)/mkversion.c |
| 766 | $(BCC) -o $(MKVERSION) $(SRCDIR)/mkversion.c |
| 767 | |
| 768 | $(CODECHECK1): $(SRCDIR)/codecheck1.c |
| 769 | $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c |
| 770 | |
| 771 | # WARNING. DANGER. Running the test suite modifies the repository the |
| 772 | # build is done from, i.e. the checkout belongs to. Do not sync/push |
| 773 | # the repository after running the tests. |
| 774 | test: $(OBJDIR) $(APPNAME) |
| 775 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 776 | |
| 777 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(MKVERSION) |
| 778 | $(MKVERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 779 | |
| 780 | # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set |
| 781 | # to 1. If it is set to 1, then there is no need to build or link |
| 782 | # the sqlite3.o object. Instead, the system SQLite will be linked |
| 783 | # using -lsqlite3. |
| @@ -815,11 +831,12 @@ | |
| 831 | |
| 832 | ifdef FOSSIL_BUILD_SSL |
| 833 | APPTARGETS += openssl |
| 834 | endif |
| 835 | |
| 836 | $(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS) |
| 837 | $(CODECHECK1) $(TRANS_SRC) |
| 838 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o |
| 839 | |
| 840 | # This rule prevents make from using its default rules to try build |
| 841 | # an executable named "manifest" out of the file named "manifest.c" |
| 842 | # |
| @@ -842,19 +859,23 @@ | |
| 859 | $(INNOSETUP) ./setup/fossil.iss -DAppVersion=$(shell $(CAT) ./VERSION) |
| 860 | |
| 861 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 862 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 863 | |
| 864 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 865 | $(MKBUILTIN) $(EXTRA_FILES) >$@ |
| 866 | |
| 867 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 868 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 869 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 870 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| 871 | $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ |
| 872 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 873 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 874 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 875 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 876 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 877 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 878 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 879 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 880 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 881 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -963,10 +984,13 @@ | |
| 984 | |
| 985 | $(OBJDIR)/headers: Makefile |
| 986 | |
| 987 | Makefile: |
| 988 | |
| 989 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 990 | $(MKBUILTIN) $(EXTRA_FILES) >$(OBJDIR)/builtin_data.h |
| 991 | |
| 992 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) |
| 993 | $(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 994 | |
| 995 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| 996 | $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c |
| @@ -1026,10 +1050,18 @@ | |
| 1050 | |
| 1051 | $(OBJDIR)/browse.o: $(OBJDIR)/browse_.c $(OBJDIR)/browse.h $(SRCDIR)/config.h |
| 1052 | $(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c |
| 1053 | |
| 1054 | $(OBJDIR)/browse.h: $(OBJDIR)/headers |
| 1055 | |
| 1056 | $(OBJDIR)/builtin_.c: $(SRCDIR)/builtin.c $(TRANSLATE) |
| 1057 | $(TRANSLATE) $(SRCDIR)/builtin.c >$(OBJDIR)/builtin_.c |
| 1058 | |
| 1059 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 1060 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 1061 | |
| 1062 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 1063 | |
| 1064 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1065 | $(TRANSLATE) $(SRCDIR)/cache.c >$(OBJDIR)/cache_.c |
| 1066 | |
| 1067 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| 1068 |
+53
-4
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -29,10 +29,13 @@ | ||
| 29 | 29 | PERLDIR = C:\Perl\bin |
| 30 | 30 | PERL = perl.exe |
| 31 | 31 | |
| 32 | 32 | # Uncomment to enable debug symbols |
| 33 | 33 | # DEBUG = 1 |
| 34 | + | |
| 35 | +# Uncomment to support Windows XP with Visual Studio 201x | |
| 36 | +# FOSSIL_ENABLE_WINXP = 1 | |
| 34 | 37 | |
| 35 | 38 | # Uncomment to enable JSON API |
| 36 | 39 | # FOSSIL_ENABLE_JSON = 1 |
| 37 | 40 | |
| 38 | 41 | # Uncomment to enable miniz usage |
| @@ -52,13 +55,14 @@ | ||
| 52 | 55 | |
| 53 | 56 | # Uncomment to enable Tcl support |
| 54 | 57 | # FOSSIL_ENABLE_TCL = 1 |
| 55 | 58 | |
| 56 | 59 | !ifdef FOSSIL_ENABLE_SSL |
| 57 | -SSLDIR = $(B)\compat\openssl-1.0.1i | |
| 60 | +SSLDIR = $(B)\compat\openssl-1.0.1j | |
| 58 | 61 | SSLINCDIR = $(SSLDIR)\inc32 |
| 59 | 62 | SSLLIBDIR = $(SSLDIR)\out32 |
| 63 | +SSLLFLAGS = /nologo /opt:ref /debug | |
| 60 | 64 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 61 | 65 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 62 | 66 | !message Using 'x64' platform for OpenSSL... |
| 63 | 67 | SSLCONFIG = VC-WIN64A no-asm |
| 64 | 68 | SSLSETUP = ms\do_win64a.bat |
| @@ -101,10 +105,21 @@ | ||
| 101 | 105 | INCL = $(INCL) /I$(TCLINCDIR) |
| 102 | 106 | !endif |
| 103 | 107 | |
| 104 | 108 | CFLAGS = /nologo |
| 105 | 109 | LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO |
| 110 | + | |
| 111 | +!ifdef FOSSIL_ENABLE_WINXP | |
| 112 | +XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1 | |
| 113 | +CFLAGS = $(CFLAGS) $(XPCFLAGS) | |
| 114 | +!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" | |
| 115 | +XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02 | |
| 116 | +!else | |
| 117 | +XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01 | |
| 118 | +!endif | |
| 119 | +LDFLAGS = $(LDFLAGS) $(XPLDFLAGS) | |
| 120 | +!endif | |
| 106 | 121 | |
| 107 | 122 | !ifdef DEBUG |
| 108 | 123 | CFLAGS = $(CFLAGS) /Zi /MTd /Od |
| 109 | 124 | LDFLAGS = $(LDFLAGS) /DEBUG |
| 110 | 125 | !else |
| @@ -188,10 +203,11 @@ | ||
| 188 | 203 | bag_.c \ |
| 189 | 204 | bisect_.c \ |
| 190 | 205 | blob_.c \ |
| 191 | 206 | branch_.c \ |
| 192 | 207 | browse_.c \ |
| 208 | + builtin_.c \ | |
| 193 | 209 | cache_.c \ |
| 194 | 210 | captcha_.c \ |
| 195 | 211 | cgi_.c \ |
| 196 | 212 | checkin_.c \ |
| 197 | 213 | checkout_.c \ |
| @@ -292,18 +308,21 @@ | ||
| 292 | 308 | wysiwyg_.c \ |
| 293 | 309 | xfer_.c \ |
| 294 | 310 | xfersetup_.c \ |
| 295 | 311 | zip_.c |
| 296 | 312 | |
| 313 | +EXTRA_FILES = $(SRCDIR)\diff.tcl | |
| 314 | + | |
| 297 | 315 | OBJ = $(OX)\add$O \ |
| 298 | 316 | $(OX)\allrepo$O \ |
| 299 | 317 | $(OX)\attach$O \ |
| 300 | 318 | $(OX)\bag$O \ |
| 301 | 319 | $(OX)\bisect$O \ |
| 302 | 320 | $(OX)\blob$O \ |
| 303 | 321 | $(OX)\branch$O \ |
| 304 | 322 | $(OX)\browse$O \ |
| 323 | + $(OX)\builtin$O \ | |
| 305 | 324 | $(OX)\cache$O \ |
| 306 | 325 | $(OX)\captcha$O \ |
| 307 | 326 | $(OX)\cgi$O \ |
| 308 | 327 | $(OX)\checkin$O \ |
| 309 | 328 | $(OX)\checkout$O \ |
| @@ -423,21 +442,29 @@ | ||
| 423 | 442 | |
| 424 | 443 | all: $(OX) $(APPNAME) |
| 425 | 444 | |
| 426 | 445 | zlib: |
| 427 | 446 | @echo Building zlib from "$(ZLIBDIR)"... |
| 447 | +!ifdef FOSSIL_ENABLE_WINXP | |
| 448 | + @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd | |
| 449 | +!else | |
| 428 | 450 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd |
| 451 | +!endif | |
| 429 | 452 | |
| 430 | 453 | !ifdef FOSSIL_ENABLE_SSL |
| 431 | 454 | openssl: |
| 432 | 455 | @echo Building OpenSSL from "$(SSLDIR)"... |
| 433 | 456 | !if "$(PERLDIR)" != "" |
| 434 | 457 | @set PATH=$(PERLDIR);$(PATH) |
| 435 | 458 | !endif |
| 436 | 459 | @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd |
| 437 | 460 | @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd |
| 461 | +!ifdef FOSSIL_ENABLE_WINXP | |
| 462 | + @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd | |
| 463 | +!else | |
| 438 | 464 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd |
| 465 | +!endif | |
| 439 | 466 | !endif |
| 440 | 467 | |
| 441 | 468 | !ifndef FOSSIL_ENABLE_MINIZ |
| 442 | 469 | APPTARGETS = $(APPTARGETS) zlib |
| 443 | 470 | !endif |
| @@ -446,12 +473,13 @@ | ||
| 446 | 473 | !ifdef FOSSIL_BUILD_SSL |
| 447 | 474 | APPTARGETS = $(APPTARGETS) openssl |
| 448 | 475 | !endif |
| 449 | 476 | !endif |
| 450 | 477 | |
| 451 | -$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts | |
| 478 | +$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts | |
| 452 | 479 | cd $(OX) |
| 480 | + codecheck1$E $(SRC) | |
| 453 | 481 | link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts |
| 454 | 482 | |
| 455 | 483 | $(OX)\linkopts: $B\win\Makefile.msc |
| 456 | 484 | echo $(OX)\add.obj > $@ |
| 457 | 485 | echo $(OX)\allrepo.obj >> $@ |
| @@ -459,10 +487,11 @@ | ||
| 459 | 487 | echo $(OX)\bag.obj >> $@ |
| 460 | 488 | echo $(OX)\bisect.obj >> $@ |
| 461 | 489 | echo $(OX)\blob.obj >> $@ |
| 462 | 490 | echo $(OX)\branch.obj >> $@ |
| 463 | 491 | echo $(OX)\browse.obj >> $@ |
| 492 | + echo $(OX)\builtin.obj >> $@ | |
| 464 | 493 | echo $(OX)\cache.obj >> $@ |
| 465 | 494 | echo $(OX)\captcha.obj >> $@ |
| 466 | 495 | echo $(OX)\cgi.obj >> $@ |
| 467 | 496 | echo $(OX)\checkin.obj >> $@ |
| 468 | 497 | echo $(OX)\checkout.obj >> $@ |
| @@ -585,11 +614,17 @@ | ||
| 585 | 614 | $(BCC) $** |
| 586 | 615 | |
| 587 | 616 | mkindex$E: $(SRCDIR)\mkindex.c |
| 588 | 617 | $(BCC) $** |
| 589 | 618 | |
| 590 | -mkversion$E: $B\src\mkversion.c | |
| 619 | +mkbuiltin$E: $(SRCDIR)\mkbuiltin.c | |
| 620 | + $(BCC) $** | |
| 621 | + | |
| 622 | +mkversion$E: $(SRCDIR)\mkversion.c | |
| 623 | + $(BCC) $** | |
| 624 | + | |
| 625 | +codecheck1$E: $(SRCDIR)\codecheck1.c | |
| 591 | 626 | $(BCC) $** |
| 592 | 627 | |
| 593 | 628 | $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc |
| 594 | 629 | $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c |
| 595 | 630 | |
| @@ -614,10 +649,13 @@ | ||
| 614 | 649 | $(TCC) /Fo$@ /c $** |
| 615 | 650 | |
| 616 | 651 | page_index.h: mkindex$E $(SRC) |
| 617 | 652 | $** > $@ |
| 618 | 653 | |
| 654 | +builtin_data.h: mkbuiltin$E $(EXTRA_FILES) | |
| 655 | + $** > $@ | |
| 656 | + | |
| 619 | 657 | clean: |
| 620 | 658 | -del $(OX)\*.obj |
| 621 | 659 | -del *.obj |
| 622 | 660 | -del *_.c |
| 623 | 661 | -del *.h |
| @@ -637,10 +675,14 @@ | ||
| 637 | 675 | -del mkindex$P |
| 638 | 676 | -del makeheaders$E |
| 639 | 677 | -del makeheaders$P |
| 640 | 678 | -del mkversion$E |
| 641 | 679 | -del mkversion$P |
| 680 | + -del codecheck1$E | |
| 681 | + -del codecheck1$P | |
| 682 | + -del mkbuiltin$E | |
| 683 | + -del mkbuiltin$P | |
| 642 | 684 | |
| 643 | 685 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 644 | 686 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 645 | 687 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 646 | 688 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -701,10 +743,16 @@ | ||
| 701 | 743 | $(OX)\browse$O : browse_.c browse.h |
| 702 | 744 | $(TCC) /Fo$@ -c browse_.c |
| 703 | 745 | |
| 704 | 746 | browse_.c : $(SRCDIR)\browse.c |
| 705 | 747 | translate$E $** > $@ |
| 748 | + | |
| 749 | +$(OX)\builtin$O : builtin_.c builtin.h | |
| 750 | + $(TCC) /Fo$@ -c builtin_.c | |
| 751 | + | |
| 752 | +builtin_.c : $(SRCDIR)\builtin.c | |
| 753 | + translate$E $** > $@ | |
| 706 | 754 | |
| 707 | 755 | $(OX)\cache$O : cache_.c cache.h |
| 708 | 756 | $(TCC) /Fo$@ -c cache_.c |
| 709 | 757 | |
| 710 | 758 | cache_.c : $(SRCDIR)\cache.c |
| @@ -1323,19 +1371,20 @@ | ||
| 1323 | 1371 | translate$E $** > $@ |
| 1324 | 1372 | |
| 1325 | 1373 | fossil.res : $B\win\fossil.rc |
| 1326 | 1374 | $(RCC) /fo $@ $** |
| 1327 | 1375 | |
| 1328 | -headers: makeheaders$E page_index.h VERSION.h | |
| 1376 | +headers: makeheaders$E page_index.h builtin_data.h VERSION.h | |
| 1329 | 1377 | makeheaders$E add_.c:add.h \ |
| 1330 | 1378 | allrepo_.c:allrepo.h \ |
| 1331 | 1379 | attach_.c:attach.h \ |
| 1332 | 1380 | bag_.c:bag.h \ |
| 1333 | 1381 | bisect_.c:bisect.h \ |
| 1334 | 1382 | blob_.c:blob.h \ |
| 1335 | 1383 | branch_.c:branch.h \ |
| 1336 | 1384 | browse_.c:browse.h \ |
| 1385 | + builtin_.c:builtin.h \ | |
| 1337 | 1386 | cache_.c:cache.h \ |
| 1338 | 1387 | captcha_.c:captcha.h \ |
| 1339 | 1388 | cgi_.c:cgi.h \ |
| 1340 | 1389 | checkin_.c:checkin.h \ |
| 1341 | 1390 | checkout_.c:checkout.h \ |
| 1342 | 1391 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -29,10 +29,13 @@ | |
| 29 | PERLDIR = C:\Perl\bin |
| 30 | PERL = perl.exe |
| 31 | |
| 32 | # Uncomment to enable debug symbols |
| 33 | # DEBUG = 1 |
| 34 | |
| 35 | # Uncomment to enable JSON API |
| 36 | # FOSSIL_ENABLE_JSON = 1 |
| 37 | |
| 38 | # Uncomment to enable miniz usage |
| @@ -52,13 +55,14 @@ | |
| 52 | |
| 53 | # Uncomment to enable Tcl support |
| 54 | # FOSSIL_ENABLE_TCL = 1 |
| 55 | |
| 56 | !ifdef FOSSIL_ENABLE_SSL |
| 57 | SSLDIR = $(B)\compat\openssl-1.0.1i |
| 58 | SSLINCDIR = $(SSLDIR)\inc32 |
| 59 | SSLLIBDIR = $(SSLDIR)\out32 |
| 60 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 61 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 62 | !message Using 'x64' platform for OpenSSL... |
| 63 | SSLCONFIG = VC-WIN64A no-asm |
| 64 | SSLSETUP = ms\do_win64a.bat |
| @@ -101,10 +105,21 @@ | |
| 101 | INCL = $(INCL) /I$(TCLINCDIR) |
| 102 | !endif |
| 103 | |
| 104 | CFLAGS = /nologo |
| 105 | LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO |
| 106 | |
| 107 | !ifdef DEBUG |
| 108 | CFLAGS = $(CFLAGS) /Zi /MTd /Od |
| 109 | LDFLAGS = $(LDFLAGS) /DEBUG |
| 110 | !else |
| @@ -188,10 +203,11 @@ | |
| 188 | bag_.c \ |
| 189 | bisect_.c \ |
| 190 | blob_.c \ |
| 191 | branch_.c \ |
| 192 | browse_.c \ |
| 193 | cache_.c \ |
| 194 | captcha_.c \ |
| 195 | cgi_.c \ |
| 196 | checkin_.c \ |
| 197 | checkout_.c \ |
| @@ -292,18 +308,21 @@ | |
| 292 | wysiwyg_.c \ |
| 293 | xfer_.c \ |
| 294 | xfersetup_.c \ |
| 295 | zip_.c |
| 296 | |
| 297 | OBJ = $(OX)\add$O \ |
| 298 | $(OX)\allrepo$O \ |
| 299 | $(OX)\attach$O \ |
| 300 | $(OX)\bag$O \ |
| 301 | $(OX)\bisect$O \ |
| 302 | $(OX)\blob$O \ |
| 303 | $(OX)\branch$O \ |
| 304 | $(OX)\browse$O \ |
| 305 | $(OX)\cache$O \ |
| 306 | $(OX)\captcha$O \ |
| 307 | $(OX)\cgi$O \ |
| 308 | $(OX)\checkin$O \ |
| 309 | $(OX)\checkout$O \ |
| @@ -423,21 +442,29 @@ | |
| 423 | |
| 424 | all: $(OX) $(APPNAME) |
| 425 | |
| 426 | zlib: |
| 427 | @echo Building zlib from "$(ZLIBDIR)"... |
| 428 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd |
| 429 | |
| 430 | !ifdef FOSSIL_ENABLE_SSL |
| 431 | openssl: |
| 432 | @echo Building OpenSSL from "$(SSLDIR)"... |
| 433 | !if "$(PERLDIR)" != "" |
| 434 | @set PATH=$(PERLDIR);$(PATH) |
| 435 | !endif |
| 436 | @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd |
| 437 | @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd |
| 438 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd |
| 439 | !endif |
| 440 | |
| 441 | !ifndef FOSSIL_ENABLE_MINIZ |
| 442 | APPTARGETS = $(APPTARGETS) zlib |
| 443 | !endif |
| @@ -446,12 +473,13 @@ | |
| 446 | !ifdef FOSSIL_BUILD_SSL |
| 447 | APPTARGETS = $(APPTARGETS) openssl |
| 448 | !endif |
| 449 | !endif |
| 450 | |
| 451 | $(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts |
| 452 | cd $(OX) |
| 453 | link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts |
| 454 | |
| 455 | $(OX)\linkopts: $B\win\Makefile.msc |
| 456 | echo $(OX)\add.obj > $@ |
| 457 | echo $(OX)\allrepo.obj >> $@ |
| @@ -459,10 +487,11 @@ | |
| 459 | echo $(OX)\bag.obj >> $@ |
| 460 | echo $(OX)\bisect.obj >> $@ |
| 461 | echo $(OX)\blob.obj >> $@ |
| 462 | echo $(OX)\branch.obj >> $@ |
| 463 | echo $(OX)\browse.obj >> $@ |
| 464 | echo $(OX)\cache.obj >> $@ |
| 465 | echo $(OX)\captcha.obj >> $@ |
| 466 | echo $(OX)\cgi.obj >> $@ |
| 467 | echo $(OX)\checkin.obj >> $@ |
| 468 | echo $(OX)\checkout.obj >> $@ |
| @@ -585,11 +614,17 @@ | |
| 585 | $(BCC) $** |
| 586 | |
| 587 | mkindex$E: $(SRCDIR)\mkindex.c |
| 588 | $(BCC) $** |
| 589 | |
| 590 | mkversion$E: $B\src\mkversion.c |
| 591 | $(BCC) $** |
| 592 | |
| 593 | $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc |
| 594 | $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c |
| 595 | |
| @@ -614,10 +649,13 @@ | |
| 614 | $(TCC) /Fo$@ /c $** |
| 615 | |
| 616 | page_index.h: mkindex$E $(SRC) |
| 617 | $** > $@ |
| 618 | |
| 619 | clean: |
| 620 | -del $(OX)\*.obj |
| 621 | -del *.obj |
| 622 | -del *_.c |
| 623 | -del *.h |
| @@ -637,10 +675,14 @@ | |
| 637 | -del mkindex$P |
| 638 | -del makeheaders$E |
| 639 | -del makeheaders$P |
| 640 | -del mkversion$E |
| 641 | -del mkversion$P |
| 642 | |
| 643 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 644 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 645 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 646 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -701,10 +743,16 @@ | |
| 701 | $(OX)\browse$O : browse_.c browse.h |
| 702 | $(TCC) /Fo$@ -c browse_.c |
| 703 | |
| 704 | browse_.c : $(SRCDIR)\browse.c |
| 705 | translate$E $** > $@ |
| 706 | |
| 707 | $(OX)\cache$O : cache_.c cache.h |
| 708 | $(TCC) /Fo$@ -c cache_.c |
| 709 | |
| 710 | cache_.c : $(SRCDIR)\cache.c |
| @@ -1323,19 +1371,20 @@ | |
| 1323 | translate$E $** > $@ |
| 1324 | |
| 1325 | fossil.res : $B\win\fossil.rc |
| 1326 | $(RCC) /fo $@ $** |
| 1327 | |
| 1328 | headers: makeheaders$E page_index.h VERSION.h |
| 1329 | makeheaders$E add_.c:add.h \ |
| 1330 | allrepo_.c:allrepo.h \ |
| 1331 | attach_.c:attach.h \ |
| 1332 | bag_.c:bag.h \ |
| 1333 | bisect_.c:bisect.h \ |
| 1334 | blob_.c:blob.h \ |
| 1335 | branch_.c:branch.h \ |
| 1336 | browse_.c:browse.h \ |
| 1337 | cache_.c:cache.h \ |
| 1338 | captcha_.c:captcha.h \ |
| 1339 | cgi_.c:cgi.h \ |
| 1340 | checkin_.c:checkin.h \ |
| 1341 | checkout_.c:checkout.h \ |
| 1342 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -29,10 +29,13 @@ | |
| 29 | PERLDIR = C:\Perl\bin |
| 30 | PERL = perl.exe |
| 31 | |
| 32 | # Uncomment to enable debug symbols |
| 33 | # DEBUG = 1 |
| 34 | |
| 35 | # Uncomment to support Windows XP with Visual Studio 201x |
| 36 | # FOSSIL_ENABLE_WINXP = 1 |
| 37 | |
| 38 | # Uncomment to enable JSON API |
| 39 | # FOSSIL_ENABLE_JSON = 1 |
| 40 | |
| 41 | # Uncomment to enable miniz usage |
| @@ -52,13 +55,14 @@ | |
| 55 | |
| 56 | # Uncomment to enable Tcl support |
| 57 | # FOSSIL_ENABLE_TCL = 1 |
| 58 | |
| 59 | !ifdef FOSSIL_ENABLE_SSL |
| 60 | SSLDIR = $(B)\compat\openssl-1.0.1j |
| 61 | SSLINCDIR = $(SSLDIR)\inc32 |
| 62 | SSLLIBDIR = $(SSLDIR)\out32 |
| 63 | SSLLFLAGS = /nologo /opt:ref /debug |
| 64 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 65 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 66 | !message Using 'x64' platform for OpenSSL... |
| 67 | SSLCONFIG = VC-WIN64A no-asm |
| 68 | SSLSETUP = ms\do_win64a.bat |
| @@ -101,10 +105,21 @@ | |
| 105 | INCL = $(INCL) /I$(TCLINCDIR) |
| 106 | !endif |
| 107 | |
| 108 | CFLAGS = /nologo |
| 109 | LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO |
| 110 | |
| 111 | !ifdef FOSSIL_ENABLE_WINXP |
| 112 | XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1 |
| 113 | CFLAGS = $(CFLAGS) $(XPCFLAGS) |
| 114 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 115 | XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02 |
| 116 | !else |
| 117 | XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01 |
| 118 | !endif |
| 119 | LDFLAGS = $(LDFLAGS) $(XPLDFLAGS) |
| 120 | !endif |
| 121 | |
| 122 | !ifdef DEBUG |
| 123 | CFLAGS = $(CFLAGS) /Zi /MTd /Od |
| 124 | LDFLAGS = $(LDFLAGS) /DEBUG |
| 125 | !else |
| @@ -188,10 +203,11 @@ | |
| 203 | bag_.c \ |
| 204 | bisect_.c \ |
| 205 | blob_.c \ |
| 206 | branch_.c \ |
| 207 | browse_.c \ |
| 208 | builtin_.c \ |
| 209 | cache_.c \ |
| 210 | captcha_.c \ |
| 211 | cgi_.c \ |
| 212 | checkin_.c \ |
| 213 | checkout_.c \ |
| @@ -292,18 +308,21 @@ | |
| 308 | wysiwyg_.c \ |
| 309 | xfer_.c \ |
| 310 | xfersetup_.c \ |
| 311 | zip_.c |
| 312 | |
| 313 | EXTRA_FILES = $(SRCDIR)\diff.tcl |
| 314 | |
| 315 | OBJ = $(OX)\add$O \ |
| 316 | $(OX)\allrepo$O \ |
| 317 | $(OX)\attach$O \ |
| 318 | $(OX)\bag$O \ |
| 319 | $(OX)\bisect$O \ |
| 320 | $(OX)\blob$O \ |
| 321 | $(OX)\branch$O \ |
| 322 | $(OX)\browse$O \ |
| 323 | $(OX)\builtin$O \ |
| 324 | $(OX)\cache$O \ |
| 325 | $(OX)\captcha$O \ |
| 326 | $(OX)\cgi$O \ |
| 327 | $(OX)\checkin$O \ |
| 328 | $(OX)\checkout$O \ |
| @@ -423,21 +442,29 @@ | |
| 442 | |
| 443 | all: $(OX) $(APPNAME) |
| 444 | |
| 445 | zlib: |
| 446 | @echo Building zlib from "$(ZLIBDIR)"... |
| 447 | !ifdef FOSSIL_ENABLE_WINXP |
| 448 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd |
| 449 | !else |
| 450 | @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd |
| 451 | !endif |
| 452 | |
| 453 | !ifdef FOSSIL_ENABLE_SSL |
| 454 | openssl: |
| 455 | @echo Building OpenSSL from "$(SSLDIR)"... |
| 456 | !if "$(PERLDIR)" != "" |
| 457 | @set PATH=$(PERLDIR);$(PATH) |
| 458 | !endif |
| 459 | @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd |
| 460 | @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd |
| 461 | !ifdef FOSSIL_ENABLE_WINXP |
| 462 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd |
| 463 | !else |
| 464 | @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd |
| 465 | !endif |
| 466 | !endif |
| 467 | |
| 468 | !ifndef FOSSIL_ENABLE_MINIZ |
| 469 | APPTARGETS = $(APPTARGETS) zlib |
| 470 | !endif |
| @@ -446,12 +473,13 @@ | |
| 473 | !ifdef FOSSIL_BUILD_SSL |
| 474 | APPTARGETS = $(APPTARGETS) openssl |
| 475 | !endif |
| 476 | !endif |
| 477 | |
| 478 | $(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts |
| 479 | cd $(OX) |
| 480 | codecheck1$E $(SRC) |
| 481 | link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts |
| 482 | |
| 483 | $(OX)\linkopts: $B\win\Makefile.msc |
| 484 | echo $(OX)\add.obj > $@ |
| 485 | echo $(OX)\allrepo.obj >> $@ |
| @@ -459,10 +487,11 @@ | |
| 487 | echo $(OX)\bag.obj >> $@ |
| 488 | echo $(OX)\bisect.obj >> $@ |
| 489 | echo $(OX)\blob.obj >> $@ |
| 490 | echo $(OX)\branch.obj >> $@ |
| 491 | echo $(OX)\browse.obj >> $@ |
| 492 | echo $(OX)\builtin.obj >> $@ |
| 493 | echo $(OX)\cache.obj >> $@ |
| 494 | echo $(OX)\captcha.obj >> $@ |
| 495 | echo $(OX)\cgi.obj >> $@ |
| 496 | echo $(OX)\checkin.obj >> $@ |
| 497 | echo $(OX)\checkout.obj >> $@ |
| @@ -585,11 +614,17 @@ | |
| 614 | $(BCC) $** |
| 615 | |
| 616 | mkindex$E: $(SRCDIR)\mkindex.c |
| 617 | $(BCC) $** |
| 618 | |
| 619 | mkbuiltin$E: $(SRCDIR)\mkbuiltin.c |
| 620 | $(BCC) $** |
| 621 | |
| 622 | mkversion$E: $(SRCDIR)\mkversion.c |
| 623 | $(BCC) $** |
| 624 | |
| 625 | codecheck1$E: $(SRCDIR)\codecheck1.c |
| 626 | $(BCC) $** |
| 627 | |
| 628 | $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc |
| 629 | $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c |
| 630 | |
| @@ -614,10 +649,13 @@ | |
| 649 | $(TCC) /Fo$@ /c $** |
| 650 | |
| 651 | page_index.h: mkindex$E $(SRC) |
| 652 | $** > $@ |
| 653 | |
| 654 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 655 | $** > $@ |
| 656 | |
| 657 | clean: |
| 658 | -del $(OX)\*.obj |
| 659 | -del *.obj |
| 660 | -del *_.c |
| 661 | -del *.h |
| @@ -637,10 +675,14 @@ | |
| 675 | -del mkindex$P |
| 676 | -del makeheaders$E |
| 677 | -del makeheaders$P |
| 678 | -del mkversion$E |
| 679 | -del mkversion$P |
| 680 | -del codecheck1$E |
| 681 | -del codecheck1$P |
| 682 | -del mkbuiltin$E |
| 683 | -del mkbuiltin$P |
| 684 | |
| 685 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 686 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 687 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 688 | $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h |
| @@ -701,10 +743,16 @@ | |
| 743 | $(OX)\browse$O : browse_.c browse.h |
| 744 | $(TCC) /Fo$@ -c browse_.c |
| 745 | |
| 746 | browse_.c : $(SRCDIR)\browse.c |
| 747 | translate$E $** > $@ |
| 748 | |
| 749 | $(OX)\builtin$O : builtin_.c builtin.h |
| 750 | $(TCC) /Fo$@ -c builtin_.c |
| 751 | |
| 752 | builtin_.c : $(SRCDIR)\builtin.c |
| 753 | translate$E $** > $@ |
| 754 | |
| 755 | $(OX)\cache$O : cache_.c cache.h |
| 756 | $(TCC) /Fo$@ -c cache_.c |
| 757 | |
| 758 | cache_.c : $(SRCDIR)\cache.c |
| @@ -1323,19 +1371,20 @@ | |
| 1371 | translate$E $** > $@ |
| 1372 | |
| 1373 | fossil.res : $B\win\fossil.rc |
| 1374 | $(RCC) /fo $@ $** |
| 1375 | |
| 1376 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 1377 | makeheaders$E add_.c:add.h \ |
| 1378 | allrepo_.c:allrepo.h \ |
| 1379 | attach_.c:attach.h \ |
| 1380 | bag_.c:bag.h \ |
| 1381 | bisect_.c:bisect.h \ |
| 1382 | blob_.c:blob.h \ |
| 1383 | branch_.c:branch.h \ |
| 1384 | browse_.c:browse.h \ |
| 1385 | builtin_.c:builtin.h \ |
| 1386 | cache_.c:cache.h \ |
| 1387 | captcha_.c:captcha.h \ |
| 1388 | cgi_.c:cgi.h \ |
| 1389 | checkin_.c:checkin.h \ |
| 1390 | checkout_.c:checkout.h \ |
| 1391 |
+41
-1
| --- win/buildmsvc.bat | ||
| +++ win/buildmsvc.bat | ||
| @@ -192,15 +192,30 @@ | ||
| 192 | 192 | IF ERRORLEVEL 1 ( |
| 193 | 193 | ECHO Could not change to directory "%ROOT%\msvcbld". |
| 194 | 194 | GOTO errors |
| 195 | 195 | ) |
| 196 | 196 | |
| 197 | +REM | |
| 198 | +REM NOTE: If requested, setup the build environment to refer to the Windows | |
| 199 | +REM SDK v7.1A, which is required if the binaries are being built with | |
| 200 | +REM Visual Studio 201x and need to work on Windows XP. | |
| 201 | +REM | |
| 202 | +IF DEFINED USE_V110SDK71A ( | |
| 203 | + %_AECHO% Forcing use of the Windows SDK v7.1A... | |
| 204 | + CALL :fn_UseV110Sdk71A | |
| 205 | +) | |
| 206 | + | |
| 207 | +%_VECHO% Path = '%PATH%' | |
| 208 | +%_VECHO% Include = '%INCLUDE%' | |
| 209 | +%_VECHO% Lib = '%LIB%' | |
| 210 | +%_VECHO% NmakeArgs = '%NMAKE_ARGS%' | |
| 211 | + | |
| 197 | 212 | REM |
| 198 | 213 | REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing |
| 199 | 214 | REM anything extra from our command line along (e.g. extra options). |
| 200 | 215 | REM |
| 201 | -%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %* | |
| 216 | +%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %* | |
| 202 | 217 | |
| 203 | 218 | IF ERRORLEVEL 1 ( |
| 204 | 219 | GOTO errors |
| 205 | 220 | ) |
| 206 | 221 | |
| @@ -213,10 +228,35 @@ | ||
| 213 | 228 | ECHO Could not restore directory. |
| 214 | 229 | GOTO errors |
| 215 | 230 | ) |
| 216 | 231 | |
| 217 | 232 | GOTO no_errors |
| 233 | + | |
| 234 | +:fn_UseV110Sdk71A | |
| 235 | + IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86 | |
| 236 | + SET PFILES_SDK71A=%ProgramFiles(x86)% | |
| 237 | + GOTO set_v110Sdk71A_done | |
| 238 | + :set_v110Sdk71A_x86 | |
| 239 | + SET PFILES_SDK71A=%ProgramFiles% | |
| 240 | + :set_v110Sdk71A_done | |
| 241 | + SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH% | |
| 242 | + SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE% | |
| 243 | + IF "%PLATFORM%" == "x64" ( | |
| 244 | + SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB% | |
| 245 | + ) ELSE ( | |
| 246 | + SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB% | |
| 247 | + ) | |
| 248 | + CALL :fn_UnsetVariable PFILES_SDK71A | |
| 249 | + SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1 | |
| 250 | + GOTO :EOF | |
| 251 | + | |
| 252 | +:fn_UnsetVariable | |
| 253 | + IF NOT "%1" == "" ( | |
| 254 | + SET %1= | |
| 255 | + CALL :fn_ResetErrorLevel | |
| 256 | + ) | |
| 257 | + GOTO :EOF | |
| 218 | 258 | |
| 219 | 259 | :fn_ResetErrorLevel |
| 220 | 260 | VERIFY > NUL |
| 221 | 261 | GOTO :EOF |
| 222 | 262 | |
| 223 | 263 |
| --- win/buildmsvc.bat | |
| +++ win/buildmsvc.bat | |
| @@ -192,15 +192,30 @@ | |
| 192 | IF ERRORLEVEL 1 ( |
| 193 | ECHO Could not change to directory "%ROOT%\msvcbld". |
| 194 | GOTO errors |
| 195 | ) |
| 196 | |
| 197 | REM |
| 198 | REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing |
| 199 | REM anything extra from our command line along (e.g. extra options). |
| 200 | REM |
| 201 | %__ECHO% nmake /f "%TOOLS%\Makefile.msc" %* |
| 202 | |
| 203 | IF ERRORLEVEL 1 ( |
| 204 | GOTO errors |
| 205 | ) |
| 206 | |
| @@ -213,10 +228,35 @@ | |
| 213 | ECHO Could not restore directory. |
| 214 | GOTO errors |
| 215 | ) |
| 216 | |
| 217 | GOTO no_errors |
| 218 | |
| 219 | :fn_ResetErrorLevel |
| 220 | VERIFY > NUL |
| 221 | GOTO :EOF |
| 222 | |
| 223 |
| --- win/buildmsvc.bat | |
| +++ win/buildmsvc.bat | |
| @@ -192,15 +192,30 @@ | |
| 192 | IF ERRORLEVEL 1 ( |
| 193 | ECHO Could not change to directory "%ROOT%\msvcbld". |
| 194 | GOTO errors |
| 195 | ) |
| 196 | |
| 197 | REM |
| 198 | REM NOTE: If requested, setup the build environment to refer to the Windows |
| 199 | REM SDK v7.1A, which is required if the binaries are being built with |
| 200 | REM Visual Studio 201x and need to work on Windows XP. |
| 201 | REM |
| 202 | IF DEFINED USE_V110SDK71A ( |
| 203 | %_AECHO% Forcing use of the Windows SDK v7.1A... |
| 204 | CALL :fn_UseV110Sdk71A |
| 205 | ) |
| 206 | |
| 207 | %_VECHO% Path = '%PATH%' |
| 208 | %_VECHO% Include = '%INCLUDE%' |
| 209 | %_VECHO% Lib = '%LIB%' |
| 210 | %_VECHO% NmakeArgs = '%NMAKE_ARGS%' |
| 211 | |
| 212 | REM |
| 213 | REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing |
| 214 | REM anything extra from our command line along (e.g. extra options). |
| 215 | REM |
| 216 | %__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %* |
| 217 | |
| 218 | IF ERRORLEVEL 1 ( |
| 219 | GOTO errors |
| 220 | ) |
| 221 | |
| @@ -213,10 +228,35 @@ | |
| 228 | ECHO Could not restore directory. |
| 229 | GOTO errors |
| 230 | ) |
| 231 | |
| 232 | GOTO no_errors |
| 233 | |
| 234 | :fn_UseV110Sdk71A |
| 235 | IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86 |
| 236 | SET PFILES_SDK71A=%ProgramFiles(x86)% |
| 237 | GOTO set_v110Sdk71A_done |
| 238 | :set_v110Sdk71A_x86 |
| 239 | SET PFILES_SDK71A=%ProgramFiles% |
| 240 | :set_v110Sdk71A_done |
| 241 | SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH% |
| 242 | SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE% |
| 243 | IF "%PLATFORM%" == "x64" ( |
| 244 | SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB% |
| 245 | ) ELSE ( |
| 246 | SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB% |
| 247 | ) |
| 248 | CALL :fn_UnsetVariable PFILES_SDK71A |
| 249 | SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1 |
| 250 | GOTO :EOF |
| 251 | |
| 252 | :fn_UnsetVariable |
| 253 | IF NOT "%1" == "" ( |
| 254 | SET %1= |
| 255 | CALL :fn_ResetErrorLevel |
| 256 | ) |
| 257 | GOTO :EOF |
| 258 | |
| 259 | :fn_ResetErrorLevel |
| 260 | VERIFY > NUL |
| 261 | GOTO :EOF |
| 262 | |
| 263 |
| --- win/fossil.exe.manifest | ||
| +++ win/fossil.exe.manifest | ||
| @@ -13,10 +13,12 @@ | ||
| 13 | 13 | </requestedPrivileges> |
| 14 | 14 | </security> |
| 15 | 15 | </trustInfo> |
| 16 | 16 | <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> |
| 17 | 17 | <application> |
| 18 | + <!-- Windows 10 --> | |
| 19 | + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> | |
| 18 | 20 | <!-- Windows 8.1 --> |
| 19 | 21 | <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> |
| 20 | 22 | <!-- Windows 8 --> |
| 21 | 23 | <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> |
| 22 | 24 | <!-- Windows 7 --> |
| 23 | 25 |
| --- win/fossil.exe.manifest | |
| +++ win/fossil.exe.manifest | |
| @@ -13,10 +13,12 @@ | |
| 13 | </requestedPrivileges> |
| 14 | </security> |
| 15 | </trustInfo> |
| 16 | <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> |
| 17 | <application> |
| 18 | <!-- Windows 8.1 --> |
| 19 | <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> |
| 20 | <!-- Windows 8 --> |
| 21 | <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> |
| 22 | <!-- Windows 7 --> |
| 23 |
| --- win/fossil.exe.manifest | |
| +++ win/fossil.exe.manifest | |
| @@ -13,10 +13,12 @@ | |
| 13 | </requestedPrivileges> |
| 14 | </security> |
| 15 | </trustInfo> |
| 16 | <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> |
| 17 | <application> |
| 18 | <!-- Windows 10 --> |
| 19 | <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> |
| 20 | <!-- Windows 8.1 --> |
| 21 | <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> |
| 22 | <!-- Windows 8 --> |
| 23 | <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> |
| 24 | <!-- Windows 7 --> |
| 25 |
+1
-1
| --- www/build.wiki | ||
| +++ www/build.wiki | ||
| @@ -122,11 +122,11 @@ | ||
| 122 | 122 | the optional <a href="https://www.openssl.org/">OpenSSL</a> support, |
| 123 | 123 | first <a href="https://www.openssl.org/source/">download the official |
| 124 | 124 | source code for OpenSSL</a> and extract it to an appropriately named |
| 125 | 125 | "<b>openssl-X.Y.ZA</b>" subdirectory within the local |
| 126 | 126 | [/tree?ci=trunk&name=compat | compat] directory (e.g. |
| 127 | -"<b>compat/openssl-1.0.1i</b>"), then make sure that some recent | |
| 127 | +"<b>compat/openssl-1.0.1j</b>"), then make sure that some recent | |
| 128 | 128 | <a href="http://www.perl.org/">Perl</a> binaries are installed locally, |
| 129 | 129 | and finally run one of the following commands: |
| 130 | 130 | <blockquote><pre> |
| 131 | 131 | nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin |
| 132 | 132 | </pre></blockquote> |
| 133 | 133 |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -122,11 +122,11 @@ | |
| 122 | the optional <a href="https://www.openssl.org/">OpenSSL</a> support, |
| 123 | first <a href="https://www.openssl.org/source/">download the official |
| 124 | source code for OpenSSL</a> and extract it to an appropriately named |
| 125 | "<b>openssl-X.Y.ZA</b>" subdirectory within the local |
| 126 | [/tree?ci=trunk&name=compat | compat] directory (e.g. |
| 127 | "<b>compat/openssl-1.0.1i</b>"), then make sure that some recent |
| 128 | <a href="http://www.perl.org/">Perl</a> binaries are installed locally, |
| 129 | and finally run one of the following commands: |
| 130 | <blockquote><pre> |
| 131 | nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin |
| 132 | </pre></blockquote> |
| 133 |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -122,11 +122,11 @@ | |
| 122 | the optional <a href="https://www.openssl.org/">OpenSSL</a> support, |
| 123 | first <a href="https://www.openssl.org/source/">download the official |
| 124 | source code for OpenSSL</a> and extract it to an appropriately named |
| 125 | "<b>openssl-X.Y.ZA</b>" subdirectory within the local |
| 126 | [/tree?ci=trunk&name=compat | compat] directory (e.g. |
| 127 | "<b>compat/openssl-1.0.1j</b>"), then make sure that some recent |
| 128 | <a href="http://www.perl.org/">Perl</a> binaries are installed locally, |
| 129 | and finally run one of the following commands: |
| 130 | <blockquote><pre> |
| 131 | nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin |
| 132 | </pre></blockquote> |
| 133 |