Fossil SCM
Add ability to append to ticket fields from the fossil ticket command
Commit
35d6029a135669d062af6ccc9d0076f1ccf99a2b
Parent
acfbfe0dd36a5fc…
68 files changed
+2
-1
+6
-6
+4
-4
+11
-11
+8
-10
+4
-4
+1
-1
+48
-26
+26
-21
+6
-6
+2
-2
+6
-6
+6
-6
+7
+5
-5
+5
-5
+17
-20
+7
-13
+1
-1
+6
-5
+6
-6
+41
-11
+4
-4
+176
-28
+3
-3
+4
-4
+2
-2
+9
+5
-5
+9
-9
+36
-26
+9
-5
+43
-48
+2
-2
+2
-2
+21
-19
+8
-12
+28
-20
+10
-9
+48
-1
+31
-23
+11
-11
+7
-7
+2
-2
+19
-11
+5
-5
+428
-282
+5
-3
+14
-14
+16
-5
+13
-9
+3
-3
+2
-2
+15
-15
+38
-20
+38
-20
+15
-14
+34
-28
+17
-17
+6
-6
+16
-9
+7
-7
+6
-5
+8
-8
+6
-6
+3
-3
~
Makefile
~
src/add.c
~
src/allrepo.c
~
src/bisect.c
~
src/blob.c
~
src/branch.c
~
src/captcha.c
~
src/cgi.c
~
src/checkin.c
~
src/checkout.c
~
src/clearsign.c
~
src/clone.c
~
src/comformat.c
~
src/config.h
~
src/configure.c
~
src/content.c
~
src/db.c
~
src/deltacmd.c
~
src/descendants.c
~
src/diff.c
~
src/diffcmd.c
~
src/doc.c
~
src/encode.c
~
src/file.c
~
src/finfo.c
~
src/glob.c
~
src/http.c
~
src/http_ssl.c
~
src/http_transport.c
~
src/import.c
~
src/info.c
~
src/login.c
~
src/main.c
~
src/manifest.c
~
src/md5.c
~
src/merge.c
~
src/merge3.c
~
src/name.c
~
src/path.c
~
src/printf.c
~
src/rebuild.c
~
src/report.c
~
src/setup.c
~
src/sha1.c
~
src/shell.c
~
src/skins.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/stash.c
~
src/sync.c
~
src/tag.c
~
src/tar.c
~
src/th_main.c
~
src/timeline.c
~
src/tkt.c
~
src/tkt.c
~
src/undo.c
~
src/update.c
~
src/url.c
~
src/user.c
~
src/vfile.c
~
src/wiki.c
~
src/wikiformat.c
~
src/winhttp.c
~
src/xfer.c
~
src/zip.c
~
www/build-icons/mac.gif
~
www/fossil_logo_small.gif
M
Makefile
+2
-1
| --- Makefile | ||
| +++ Makefile | ||
| @@ -58,11 +58,12 @@ | ||
| 58 | 58 | |
| 59 | 59 | # You should not need to change anything below this line |
| 60 | 60 | ############################################################################### |
| 61 | 61 | # |
| 62 | 62 | # Automatic platform-specific options. |
| 63 | -HOST_OS!= uname -s | |
| 63 | +HOST_OS_CMD = uname -s | |
| 64 | +HOST_OS = $(HOST_OS_CMD:sh) | |
| 64 | 65 | |
| 65 | 66 | LIB.SunOS= -lsocket -lnsl |
| 66 | 67 | LIB += $(LIB.$(HOST_OS)) |
| 67 | 68 | |
| 68 | 69 | TCC.DragonFly += -DUSE_PREAD |
| 69 | 70 |
| --- Makefile | |
| +++ Makefile | |
| @@ -58,11 +58,12 @@ | |
| 58 | |
| 59 | # You should not need to change anything below this line |
| 60 | ############################################################################### |
| 61 | # |
| 62 | # Automatic platform-specific options. |
| 63 | HOST_OS!= uname -s |
| 64 | |
| 65 | LIB.SunOS= -lsocket -lnsl |
| 66 | LIB += $(LIB.$(HOST_OS)) |
| 67 | |
| 68 | TCC.DragonFly += -DUSE_PREAD |
| 69 |
| --- Makefile | |
| +++ Makefile | |
| @@ -58,11 +58,12 @@ | |
| 58 | |
| 59 | # You should not need to change anything below this line |
| 60 | ############################################################################### |
| 61 | # |
| 62 | # Automatic platform-specific options. |
| 63 | HOST_OS_CMD = uname -s |
| 64 | HOST_OS = $(HOST_OS_CMD:sh) |
| 65 | |
| 66 | LIB.SunOS= -lsocket -lnsl |
| 67 | LIB += $(LIB.$(HOST_OS)) |
| 68 | |
| 69 | TCC.DragonFly += -DUSE_PREAD |
| 70 |
+6
-6
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -116,11 +116,11 @@ | ||
| 116 | 116 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | 117 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | 118 | vid, zPath, file_isexe(zFullname)); |
| 119 | 119 | fossil_free(zFullname); |
| 120 | 120 | } |
| 121 | - printf("ADDED %s\n", zPath); | |
| 121 | + fossil_print("ADDED %s\n", zPath); | |
| 122 | 122 | return 1; |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | /* |
| 126 | 126 | ** Add all files in the sfile temp table. |
| @@ -215,11 +215,11 @@ | ||
| 215 | 215 | isDir = file_isdir(zName); |
| 216 | 216 | if( isDir==1 ){ |
| 217 | 217 | vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore); |
| 218 | 218 | }else if( isDir==0 ){ |
| 219 | 219 | fossil_fatal("not found: %s", zName); |
| 220 | - }else if( access(zName, R_OK) ){ | |
| 220 | + }else if( file_access(zName, R_OK) ){ | |
| 221 | 221 | fossil_fatal("cannot open %s", zName); |
| 222 | 222 | }else{ |
| 223 | 223 | char *zTreeName = &zName[nRoot]; |
| 224 | 224 | db_multi_exec( |
| 225 | 225 | "INSERT OR IGNORE INTO sfile(x)" |
| @@ -280,11 +280,11 @@ | ||
| 280 | 280 | blob_reset(&treeName); |
| 281 | 281 | } |
| 282 | 282 | |
| 283 | 283 | db_prepare(&loop, "SELECT x FROM sfile"); |
| 284 | 284 | while( db_step(&loop)==SQLITE_ROW ){ |
| 285 | - printf("DELETED %s\n", db_column_text(&loop, 0)); | |
| 285 | + fossil_print("DELETED %s\n", db_column_text(&loop, 0)); | |
| 286 | 286 | } |
| 287 | 287 | db_finalize(&loop); |
| 288 | 288 | db_multi_exec( |
| 289 | 289 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | 290 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| @@ -377,17 +377,17 @@ | ||
| 377 | 377 | zPath = db_column_text(&q, 1); |
| 378 | 378 | if( !file_isfile(zPath) ){ |
| 379 | 379 | if( !isTest ){ |
| 380 | 380 | db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile); |
| 381 | 381 | } |
| 382 | - printf("DELETED %s\n", zFile); | |
| 382 | + fossil_print("DELETED %s\n", zFile); | |
| 383 | 383 | nDelete++; |
| 384 | 384 | } |
| 385 | 385 | } |
| 386 | 386 | db_finalize(&q); |
| 387 | 387 | /* show cmmand summary */ |
| 388 | - printf("added %d files, deleted %d files\n", nAdd, nDelete); | |
| 388 | + fossil_print("added %d files, deleted %d files\n", nAdd, nDelete); | |
| 389 | 389 | |
| 390 | 390 | db_end_transaction(isTest); |
| 391 | 391 | } |
| 392 | 392 | |
| 393 | 393 | |
| @@ -395,11 +395,11 @@ | ||
| 395 | 395 | ** Rename a single file. |
| 396 | 396 | ** |
| 397 | 397 | ** The original name of the file is zOrig. The new filename is zNew. |
| 398 | 398 | */ |
| 399 | 399 | static void mv_one_file(int vid, const char *zOrig, const char *zNew){ |
| 400 | - printf("RENAME %s %s\n", zOrig, zNew); | |
| 400 | + fossil_print("RENAME %s %s\n", zOrig, zNew); | |
| 401 | 401 | db_multi_exec( |
| 402 | 402 | "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d", |
| 403 | 403 | zNew, zOrig, vid |
| 404 | 404 | ); |
| 405 | 405 | } |
| 406 | 406 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -116,11 +116,11 @@ | |
| 116 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | vid, zPath, file_isexe(zFullname)); |
| 119 | fossil_free(zFullname); |
| 120 | } |
| 121 | printf("ADDED %s\n", zPath); |
| 122 | return 1; |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Add all files in the sfile temp table. |
| @@ -215,11 +215,11 @@ | |
| 215 | isDir = file_isdir(zName); |
| 216 | if( isDir==1 ){ |
| 217 | vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore); |
| 218 | }else if( isDir==0 ){ |
| 219 | fossil_fatal("not found: %s", zName); |
| 220 | }else if( access(zName, R_OK) ){ |
| 221 | fossil_fatal("cannot open %s", zName); |
| 222 | }else{ |
| 223 | char *zTreeName = &zName[nRoot]; |
| 224 | db_multi_exec( |
| 225 | "INSERT OR IGNORE INTO sfile(x)" |
| @@ -280,11 +280,11 @@ | |
| 280 | blob_reset(&treeName); |
| 281 | } |
| 282 | |
| 283 | db_prepare(&loop, "SELECT x FROM sfile"); |
| 284 | while( db_step(&loop)==SQLITE_ROW ){ |
| 285 | printf("DELETED %s\n", db_column_text(&loop, 0)); |
| 286 | } |
| 287 | db_finalize(&loop); |
| 288 | db_multi_exec( |
| 289 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| @@ -377,17 +377,17 @@ | |
| 377 | zPath = db_column_text(&q, 1); |
| 378 | if( !file_isfile(zPath) ){ |
| 379 | if( !isTest ){ |
| 380 | db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile); |
| 381 | } |
| 382 | printf("DELETED %s\n", zFile); |
| 383 | nDelete++; |
| 384 | } |
| 385 | } |
| 386 | db_finalize(&q); |
| 387 | /* show cmmand summary */ |
| 388 | printf("added %d files, deleted %d files\n", nAdd, nDelete); |
| 389 | |
| 390 | db_end_transaction(isTest); |
| 391 | } |
| 392 | |
| 393 | |
| @@ -395,11 +395,11 @@ | |
| 395 | ** Rename a single file. |
| 396 | ** |
| 397 | ** The original name of the file is zOrig. The new filename is zNew. |
| 398 | */ |
| 399 | static void mv_one_file(int vid, const char *zOrig, const char *zNew){ |
| 400 | printf("RENAME %s %s\n", zOrig, zNew); |
| 401 | db_multi_exec( |
| 402 | "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d", |
| 403 | zNew, zOrig, vid |
| 404 | ); |
| 405 | } |
| 406 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -116,11 +116,11 @@ | |
| 116 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | vid, zPath, file_isexe(zFullname)); |
| 119 | fossil_free(zFullname); |
| 120 | } |
| 121 | fossil_print("ADDED %s\n", zPath); |
| 122 | return 1; |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Add all files in the sfile temp table. |
| @@ -215,11 +215,11 @@ | |
| 215 | isDir = file_isdir(zName); |
| 216 | if( isDir==1 ){ |
| 217 | vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore); |
| 218 | }else if( isDir==0 ){ |
| 219 | fossil_fatal("not found: %s", zName); |
| 220 | }else if( file_access(zName, R_OK) ){ |
| 221 | fossil_fatal("cannot open %s", zName); |
| 222 | }else{ |
| 223 | char *zTreeName = &zName[nRoot]; |
| 224 | db_multi_exec( |
| 225 | "INSERT OR IGNORE INTO sfile(x)" |
| @@ -280,11 +280,11 @@ | |
| 280 | blob_reset(&treeName); |
| 281 | } |
| 282 | |
| 283 | db_prepare(&loop, "SELECT x FROM sfile"); |
| 284 | while( db_step(&loop)==SQLITE_ROW ){ |
| 285 | fossil_print("DELETED %s\n", db_column_text(&loop, 0)); |
| 286 | } |
| 287 | db_finalize(&loop); |
| 288 | db_multi_exec( |
| 289 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| @@ -377,17 +377,17 @@ | |
| 377 | zPath = db_column_text(&q, 1); |
| 378 | if( !file_isfile(zPath) ){ |
| 379 | if( !isTest ){ |
| 380 | db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile); |
| 381 | } |
| 382 | fossil_print("DELETED %s\n", zFile); |
| 383 | nDelete++; |
| 384 | } |
| 385 | } |
| 386 | db_finalize(&q); |
| 387 | /* show cmmand summary */ |
| 388 | fossil_print("added %d files, deleted %d files\n", nAdd, nDelete); |
| 389 | |
| 390 | db_end_transaction(isTest); |
| 391 | } |
| 392 | |
| 393 | |
| @@ -395,11 +395,11 @@ | |
| 395 | ** Rename a single file. |
| 396 | ** |
| 397 | ** The original name of the file is zOrig. The new filename is zNew. |
| 398 | */ |
| 399 | static void mv_one_file(int vid, const char *zOrig, const char *zNew){ |
| 400 | fossil_print("RENAME %s %s\n", zOrig, zNew); |
| 401 | db_multi_exec( |
| 402 | "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d", |
| 403 | zNew, zOrig, vid |
| 404 | ); |
| 405 | } |
| 406 |
+4
-4
| --- src/allrepo.c | ||
| +++ src/allrepo.c | ||
| @@ -129,22 +129,22 @@ | ||
| 129 | 129 | " FROM global_config" |
| 130 | 130 | " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1" |
| 131 | 131 | ); |
| 132 | 132 | while( db_step(&q)==SQLITE_ROW ){ |
| 133 | 133 | const char *zFilename = db_column_text(&q, 0); |
| 134 | - if( access(zFilename, 0) ){ | |
| 134 | + if( file_access(zFilename, 0) ){ | |
| 135 | 135 | nMissing++; |
| 136 | 136 | continue; |
| 137 | 137 | } |
| 138 | 138 | if( !file_is_canonical(zFilename) ) nMissing++; |
| 139 | 139 | if( zCmd[0]=='l' ){ |
| 140 | - printf("%s\n", zFilename); | |
| 140 | + fossil_print("%s\n", zFilename); | |
| 141 | 141 | continue; |
| 142 | 142 | } |
| 143 | 143 | zQFilename = quoteFilename(zFilename); |
| 144 | 144 | zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename); |
| 145 | - printf("%s\n", zSyscmd); | |
| 145 | + fossil_print("%s\n", zSyscmd); | |
| 146 | 146 | fflush(stdout); |
| 147 | 147 | rc = fossil_system(zSyscmd); |
| 148 | 148 | free(zSyscmd); |
| 149 | 149 | free(zQFilename); |
| 150 | 150 | if( stopOnError && rc ){ |
| @@ -159,11 +159,11 @@ | ||
| 159 | 159 | if( nMissing ){ |
| 160 | 160 | db_begin_transaction(); |
| 161 | 161 | db_reset(&q); |
| 162 | 162 | while( db_step(&q)==SQLITE_ROW ){ |
| 163 | 163 | const char *zFilename = db_column_text(&q, 0); |
| 164 | - if( access(zFilename, 0) ){ | |
| 164 | + if( file_access(zFilename, 0) ){ | |
| 165 | 165 | char *zRepo = mprintf("repo:%s", zFilename); |
| 166 | 166 | db_unset(zRepo, 1); |
| 167 | 167 | free(zRepo); |
| 168 | 168 | }else if( !file_is_canonical(zFilename) ){ |
| 169 | 169 | Blob cname; |
| 170 | 170 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -129,22 +129,22 @@ | |
| 129 | " FROM global_config" |
| 130 | " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1" |
| 131 | ); |
| 132 | while( db_step(&q)==SQLITE_ROW ){ |
| 133 | const char *zFilename = db_column_text(&q, 0); |
| 134 | if( access(zFilename, 0) ){ |
| 135 | nMissing++; |
| 136 | continue; |
| 137 | } |
| 138 | if( !file_is_canonical(zFilename) ) nMissing++; |
| 139 | if( zCmd[0]=='l' ){ |
| 140 | printf("%s\n", zFilename); |
| 141 | continue; |
| 142 | } |
| 143 | zQFilename = quoteFilename(zFilename); |
| 144 | zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename); |
| 145 | printf("%s\n", zSyscmd); |
| 146 | fflush(stdout); |
| 147 | rc = fossil_system(zSyscmd); |
| 148 | free(zSyscmd); |
| 149 | free(zQFilename); |
| 150 | if( stopOnError && rc ){ |
| @@ -159,11 +159,11 @@ | |
| 159 | if( nMissing ){ |
| 160 | db_begin_transaction(); |
| 161 | db_reset(&q); |
| 162 | while( db_step(&q)==SQLITE_ROW ){ |
| 163 | const char *zFilename = db_column_text(&q, 0); |
| 164 | if( access(zFilename, 0) ){ |
| 165 | char *zRepo = mprintf("repo:%s", zFilename); |
| 166 | db_unset(zRepo, 1); |
| 167 | free(zRepo); |
| 168 | }else if( !file_is_canonical(zFilename) ){ |
| 169 | Blob cname; |
| 170 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -129,22 +129,22 @@ | |
| 129 | " FROM global_config" |
| 130 | " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1" |
| 131 | ); |
| 132 | while( db_step(&q)==SQLITE_ROW ){ |
| 133 | const char *zFilename = db_column_text(&q, 0); |
| 134 | if( file_access(zFilename, 0) ){ |
| 135 | nMissing++; |
| 136 | continue; |
| 137 | } |
| 138 | if( !file_is_canonical(zFilename) ) nMissing++; |
| 139 | if( zCmd[0]=='l' ){ |
| 140 | fossil_print("%s\n", zFilename); |
| 141 | continue; |
| 142 | } |
| 143 | zQFilename = quoteFilename(zFilename); |
| 144 | zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename); |
| 145 | fossil_print("%s\n", zSyscmd); |
| 146 | fflush(stdout); |
| 147 | rc = fossil_system(zSyscmd); |
| 148 | free(zSyscmd); |
| 149 | free(zQFilename); |
| 150 | if( stopOnError && rc ){ |
| @@ -159,11 +159,11 @@ | |
| 159 | if( nMissing ){ |
| 160 | db_begin_transaction(); |
| 161 | db_reset(&q); |
| 162 | while( db_step(&q)==SQLITE_ROW ){ |
| 163 | const char *zFilename = db_column_text(&q, 0); |
| 164 | if( file_access(zFilename, 0) ){ |
| 165 | char *zRepo = mprintf("repo:%s", zFilename); |
| 166 | db_unset(zRepo, 1); |
| 167 | free(zRepo); |
| 168 | }else if( !file_is_canonical(zFilename) ){ |
| 169 | Blob cname; |
| 170 |
+11
-11
| --- src/bisect.c | ||
| +++ src/bisect.c | ||
| @@ -72,11 +72,11 @@ | ||
| 72 | 72 | */ |
| 73 | 73 | int bisect_option(const char *zName){ |
| 74 | 74 | unsigned int i; |
| 75 | 75 | int r = -1; |
| 76 | 76 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 77 | - if( strcmp(zName, aBisectOption[i].zName)==0 ){ | |
| 77 | + if( fossil_strcmp(zName, aBisectOption[i].zName)==0 ){ | |
| 78 | 78 | char *zLabel = mprintf("bisect-%s", zName); |
| 79 | 79 | char *z = db_lget(zLabel, (char*)aBisectOption[i].zDefault); |
| 80 | 80 | if( is_truth(z) ) r = 1; |
| 81 | 81 | if( is_false(z) ) r = 0; |
| 82 | 82 | if( r<0 ) r = is_truth(aBisectOption[i].zDefault); |
| @@ -137,11 +137,11 @@ | ||
| 137 | 137 | if( memcmp(zCmd, "bad", n)==0 ){ |
| 138 | 138 | int ridBad; |
| 139 | 139 | if( g.argc==3 ){ |
| 140 | 140 | ridBad = db_lget_int("checkout",0); |
| 141 | 141 | }else{ |
| 142 | - ridBad = name_to_rid(g.argv[3]); | |
| 142 | + ridBad = name_to_typed_rid(g.argv[3], "ci"); | |
| 143 | 143 | } |
| 144 | 144 | db_lset_int("bisect-bad", ridBad); |
| 145 | 145 | if( ridBad>0 |
| 146 | 146 | && bisect_option("auto-next") |
| 147 | 147 | && db_lget_int("bisect-good",0)>0 |
| @@ -154,11 +154,11 @@ | ||
| 154 | 154 | }else if( memcmp(zCmd, "good", n)==0 ){ |
| 155 | 155 | int ridGood; |
| 156 | 156 | if( g.argc==3 ){ |
| 157 | 157 | ridGood = db_lget_int("checkout",0); |
| 158 | 158 | }else{ |
| 159 | - ridGood = name_to_rid(g.argv[3]); | |
| 159 | + ridGood = name_to_typed_rid(g.argv[3], "ci"); | |
| 160 | 160 | } |
| 161 | 161 | db_lset_int("bisect-good", ridGood); |
| 162 | 162 | if( ridGood>0 |
| 163 | 163 | && bisect_option("auto-next") |
| 164 | 164 | && db_lget_int("bisect-bad",0)>0 |
| @@ -184,11 +184,11 @@ | ||
| 184 | 184 | }else if( memcmp(zCmd, "options", n)==0 ){ |
| 185 | 185 | if( g.argc==3 ){ |
| 186 | 186 | unsigned int i; |
| 187 | 187 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 188 | 188 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 189 | - printf(" %-15s %-6s ", aBisectOption[i].zName, | |
| 189 | + fossil_print(" %-15s %-6s ", aBisectOption[i].zName, | |
| 190 | 190 | db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 191 | 191 | fossil_free(z); |
| 192 | 192 | comment_print(aBisectOption[i].zDesc, 27, 79); |
| 193 | 193 | } |
| 194 | 194 | }else if( g.argc==4 || g.argc==5 ){ |
| @@ -198,11 +198,11 @@ | ||
| 198 | 198 | if( memcmp(g.argv[3], aBisectOption[i].zName, n)==0 ){ |
| 199 | 199 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 200 | 200 | if( g.argc==5 ){ |
| 201 | 201 | db_lset(z, g.argv[4]); |
| 202 | 202 | } |
| 203 | - printf("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault)); | |
| 203 | + fossil_print("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault)); | |
| 204 | 204 | fossil_free(z); |
| 205 | 205 | break; |
| 206 | 206 | } |
| 207 | 207 | } |
| 208 | 208 | if( i>=sizeof(aBisectOption)/sizeof(aBisectOption[0]) ){ |
| @@ -230,19 +230,19 @@ | ||
| 230 | 230 | for(p=path_last(), n=0; p; p=p->pFrom, n++){ |
| 231 | 231 | const char *z; |
| 232 | 232 | db_bind_int(&s, ":rid", p->rid); |
| 233 | 233 | if( db_step(&s)==SQLITE_ROW ){ |
| 234 | 234 | z = db_column_text(&s, 0); |
| 235 | - printf("%s", z); | |
| 236 | - if( p->rid==bisect.good ) printf(" GOOD"); | |
| 237 | - if( p->rid==bisect.bad ) printf(" BAD"); | |
| 238 | - if( p->rid==vid ) printf(" CURRENT"); | |
| 239 | - if( nStep>1 && n==nStep/2 ) printf(" NEXT"); | |
| 240 | - printf("\n"); | |
| 235 | + fossil_print("%s", z); | |
| 236 | + if( p->rid==bisect.good ) fossil_print(" GOOD"); | |
| 237 | + if( p->rid==bisect.bad ) fossil_print(" BAD"); | |
| 238 | + if( p->rid==vid ) fossil_print(" CURRENT"); | |
| 239 | + if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); | |
| 240 | + fossil_print("\n"); | |
| 241 | 241 | } |
| 242 | 242 | db_reset(&s); |
| 243 | 243 | } |
| 244 | 244 | db_finalize(&s); |
| 245 | 245 | }else{ |
| 246 | 246 | usage("bad|good|next|reset|vlist ..."); |
| 247 | 247 | } |
| 248 | 248 | } |
| 249 | 249 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -72,11 +72,11 @@ | |
| 72 | */ |
| 73 | int bisect_option(const char *zName){ |
| 74 | unsigned int i; |
| 75 | int r = -1; |
| 76 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 77 | if( strcmp(zName, aBisectOption[i].zName)==0 ){ |
| 78 | char *zLabel = mprintf("bisect-%s", zName); |
| 79 | char *z = db_lget(zLabel, (char*)aBisectOption[i].zDefault); |
| 80 | if( is_truth(z) ) r = 1; |
| 81 | if( is_false(z) ) r = 0; |
| 82 | if( r<0 ) r = is_truth(aBisectOption[i].zDefault); |
| @@ -137,11 +137,11 @@ | |
| 137 | if( memcmp(zCmd, "bad", n)==0 ){ |
| 138 | int ridBad; |
| 139 | if( g.argc==3 ){ |
| 140 | ridBad = db_lget_int("checkout",0); |
| 141 | }else{ |
| 142 | ridBad = name_to_rid(g.argv[3]); |
| 143 | } |
| 144 | db_lset_int("bisect-bad", ridBad); |
| 145 | if( ridBad>0 |
| 146 | && bisect_option("auto-next") |
| 147 | && db_lget_int("bisect-good",0)>0 |
| @@ -154,11 +154,11 @@ | |
| 154 | }else if( memcmp(zCmd, "good", n)==0 ){ |
| 155 | int ridGood; |
| 156 | if( g.argc==3 ){ |
| 157 | ridGood = db_lget_int("checkout",0); |
| 158 | }else{ |
| 159 | ridGood = name_to_rid(g.argv[3]); |
| 160 | } |
| 161 | db_lset_int("bisect-good", ridGood); |
| 162 | if( ridGood>0 |
| 163 | && bisect_option("auto-next") |
| 164 | && db_lget_int("bisect-bad",0)>0 |
| @@ -184,11 +184,11 @@ | |
| 184 | }else if( memcmp(zCmd, "options", n)==0 ){ |
| 185 | if( g.argc==3 ){ |
| 186 | unsigned int i; |
| 187 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 188 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 189 | printf(" %-15s %-6s ", aBisectOption[i].zName, |
| 190 | db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 191 | fossil_free(z); |
| 192 | comment_print(aBisectOption[i].zDesc, 27, 79); |
| 193 | } |
| 194 | }else if( g.argc==4 || g.argc==5 ){ |
| @@ -198,11 +198,11 @@ | |
| 198 | if( memcmp(g.argv[3], aBisectOption[i].zName, n)==0 ){ |
| 199 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 200 | if( g.argc==5 ){ |
| 201 | db_lset(z, g.argv[4]); |
| 202 | } |
| 203 | printf("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 204 | fossil_free(z); |
| 205 | break; |
| 206 | } |
| 207 | } |
| 208 | if( i>=sizeof(aBisectOption)/sizeof(aBisectOption[0]) ){ |
| @@ -230,19 +230,19 @@ | |
| 230 | for(p=path_last(), n=0; p; p=p->pFrom, n++){ |
| 231 | const char *z; |
| 232 | db_bind_int(&s, ":rid", p->rid); |
| 233 | if( db_step(&s)==SQLITE_ROW ){ |
| 234 | z = db_column_text(&s, 0); |
| 235 | printf("%s", z); |
| 236 | if( p->rid==bisect.good ) printf(" GOOD"); |
| 237 | if( p->rid==bisect.bad ) printf(" BAD"); |
| 238 | if( p->rid==vid ) printf(" CURRENT"); |
| 239 | if( nStep>1 && n==nStep/2 ) printf(" NEXT"); |
| 240 | printf("\n"); |
| 241 | } |
| 242 | db_reset(&s); |
| 243 | } |
| 244 | db_finalize(&s); |
| 245 | }else{ |
| 246 | usage("bad|good|next|reset|vlist ..."); |
| 247 | } |
| 248 | } |
| 249 |
| --- src/bisect.c | |
| +++ src/bisect.c | |
| @@ -72,11 +72,11 @@ | |
| 72 | */ |
| 73 | int bisect_option(const char *zName){ |
| 74 | unsigned int i; |
| 75 | int r = -1; |
| 76 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 77 | if( fossil_strcmp(zName, aBisectOption[i].zName)==0 ){ |
| 78 | char *zLabel = mprintf("bisect-%s", zName); |
| 79 | char *z = db_lget(zLabel, (char*)aBisectOption[i].zDefault); |
| 80 | if( is_truth(z) ) r = 1; |
| 81 | if( is_false(z) ) r = 0; |
| 82 | if( r<0 ) r = is_truth(aBisectOption[i].zDefault); |
| @@ -137,11 +137,11 @@ | |
| 137 | if( memcmp(zCmd, "bad", n)==0 ){ |
| 138 | int ridBad; |
| 139 | if( g.argc==3 ){ |
| 140 | ridBad = db_lget_int("checkout",0); |
| 141 | }else{ |
| 142 | ridBad = name_to_typed_rid(g.argv[3], "ci"); |
| 143 | } |
| 144 | db_lset_int("bisect-bad", ridBad); |
| 145 | if( ridBad>0 |
| 146 | && bisect_option("auto-next") |
| 147 | && db_lget_int("bisect-good",0)>0 |
| @@ -154,11 +154,11 @@ | |
| 154 | }else if( memcmp(zCmd, "good", n)==0 ){ |
| 155 | int ridGood; |
| 156 | if( g.argc==3 ){ |
| 157 | ridGood = db_lget_int("checkout",0); |
| 158 | }else{ |
| 159 | ridGood = name_to_typed_rid(g.argv[3], "ci"); |
| 160 | } |
| 161 | db_lset_int("bisect-good", ridGood); |
| 162 | if( ridGood>0 |
| 163 | && bisect_option("auto-next") |
| 164 | && db_lget_int("bisect-bad",0)>0 |
| @@ -184,11 +184,11 @@ | |
| 184 | }else if( memcmp(zCmd, "options", n)==0 ){ |
| 185 | if( g.argc==3 ){ |
| 186 | unsigned int i; |
| 187 | for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ |
| 188 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 189 | fossil_print(" %-15s %-6s ", aBisectOption[i].zName, |
| 190 | db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 191 | fossil_free(z); |
| 192 | comment_print(aBisectOption[i].zDesc, 27, 79); |
| 193 | } |
| 194 | }else if( g.argc==4 || g.argc==5 ){ |
| @@ -198,11 +198,11 @@ | |
| 198 | if( memcmp(g.argv[3], aBisectOption[i].zName, n)==0 ){ |
| 199 | char *z = mprintf("bisect-%s", aBisectOption[i].zName); |
| 200 | if( g.argc==5 ){ |
| 201 | db_lset(z, g.argv[4]); |
| 202 | } |
| 203 | fossil_print("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault)); |
| 204 | fossil_free(z); |
| 205 | break; |
| 206 | } |
| 207 | } |
| 208 | if( i>=sizeof(aBisectOption)/sizeof(aBisectOption[0]) ){ |
| @@ -230,19 +230,19 @@ | |
| 230 | for(p=path_last(), n=0; p; p=p->pFrom, n++){ |
| 231 | const char *z; |
| 232 | db_bind_int(&s, ":rid", p->rid); |
| 233 | if( db_step(&s)==SQLITE_ROW ){ |
| 234 | z = db_column_text(&s, 0); |
| 235 | fossil_print("%s", z); |
| 236 | if( p->rid==bisect.good ) fossil_print(" GOOD"); |
| 237 | if( p->rid==bisect.bad ) fossil_print(" BAD"); |
| 238 | if( p->rid==vid ) fossil_print(" CURRENT"); |
| 239 | if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); |
| 240 | fossil_print("\n"); |
| 241 | } |
| 242 | db_reset(&s); |
| 243 | } |
| 244 | db_finalize(&s); |
| 245 | }else{ |
| 246 | usage("bad|good|next|reset|vlist ..."); |
| 247 | } |
| 248 | } |
| 249 |
+8
-10
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -111,11 +111,11 @@ | ||
| 111 | 111 | assert( fossil_isspace((char)i) ); |
| 112 | 112 | }else{ |
| 113 | 113 | assert( !fossil_isspace((char)i) ); |
| 114 | 114 | } |
| 115 | 115 | } |
| 116 | - printf("All 256 characters OK\n"); | |
| 116 | + fossil_print("All 256 characters OK\n"); | |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | /* |
| 120 | 120 | ** This routine is called if a blob operation fails because we |
| 121 | 121 | ** have run out of memory. |
| @@ -690,11 +690,11 @@ | ||
| 690 | 690 | } |
| 691 | 691 | if( size==0 ){ |
| 692 | 692 | return 0; |
| 693 | 693 | } |
| 694 | 694 | blob_resize(pBlob, size); |
| 695 | - in = fopen(zFilename, "rb"); | |
| 695 | + in = fossil_fopen(zFilename, "rb"); | |
| 696 | 696 | if( in==0 ){ |
| 697 | 697 | fossil_panic("cannot open %s for reading", zFilename); |
| 698 | 698 | } |
| 699 | 699 | got = fread(blob_buffer(pBlob), 1, size, in); |
| 700 | 700 | fclose(in); |
| @@ -711,16 +711,15 @@ | ||
| 711 | 711 | ** |
| 712 | 712 | ** Return the number of bytes written. |
| 713 | 713 | */ |
| 714 | 714 | int blob_write_to_file(Blob *pBlob, const char *zFilename){ |
| 715 | 715 | FILE *out; |
| 716 | - int needToClose; | |
| 717 | 716 | int wrote; |
| 718 | 717 | |
| 719 | 718 | if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){ |
| 720 | - out = stdout; | |
| 721 | - needToClose = 0; | |
| 719 | + fossil_puts(blob_str(pBlob), 0); | |
| 720 | + return blob_size(pBlob); | |
| 722 | 721 | }else{ |
| 723 | 722 | int i, nName; |
| 724 | 723 | char *zName, zBuf[1000]; |
| 725 | 724 | |
| 726 | 725 | nName = strlen(zFilename); |
| @@ -750,22 +749,21 @@ | ||
| 750 | 749 | } |
| 751 | 750 | #endif |
| 752 | 751 | zName[i] = '/'; |
| 753 | 752 | } |
| 754 | 753 | } |
| 755 | - out = fopen(zName, "wb"); | |
| 754 | + out = fossil_fopen(zName, "wb"); | |
| 756 | 755 | if( out==0 ){ |
| 757 | 756 | fossil_fatal_recursive("unable to open file \"%s\" for writing", zName); |
| 758 | 757 | return 0; |
| 759 | 758 | } |
| 760 | - needToClose = 1; | |
| 761 | 759 | if( zName!=zBuf ) free(zName); |
| 762 | 760 | } |
| 763 | 761 | blob_is_init(pBlob); |
| 764 | 762 | wrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); |
| 765 | - if( needToClose ) fclose(out); | |
| 766 | - if( wrote!=blob_size(pBlob) ){ | |
| 763 | + fclose(out); | |
| 764 | + if( wrote!=blob_size(pBlob) && out!=stdout ){ | |
| 767 | 765 | fossil_fatal_recursive("short write: %d of %d bytes to %s", wrote, |
| 768 | 766 | blob_size(pBlob), zFilename); |
| 769 | 767 | } |
| 770 | 768 | return wrote; |
| 771 | 769 | } |
| @@ -925,11 +923,11 @@ | ||
| 925 | 923 | } |
| 926 | 924 | blob_reset(&b1); |
| 927 | 925 | blob_reset(&b2); |
| 928 | 926 | blob_reset(&b3); |
| 929 | 927 | } |
| 930 | - printf("ok\n"); | |
| 928 | + fossil_print("ok\n"); | |
| 931 | 929 | } |
| 932 | 930 | |
| 933 | 931 | #if defined(_WIN32) |
| 934 | 932 | /* |
| 935 | 933 | ** Convert every \n character in the given blob into \r\n. |
| 936 | 934 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -111,11 +111,11 @@ | |
| 111 | assert( fossil_isspace((char)i) ); |
| 112 | }else{ |
| 113 | assert( !fossil_isspace((char)i) ); |
| 114 | } |
| 115 | } |
| 116 | printf("All 256 characters OK\n"); |
| 117 | } |
| 118 | |
| 119 | /* |
| 120 | ** This routine is called if a blob operation fails because we |
| 121 | ** have run out of memory. |
| @@ -690,11 +690,11 @@ | |
| 690 | } |
| 691 | if( size==0 ){ |
| 692 | return 0; |
| 693 | } |
| 694 | blob_resize(pBlob, size); |
| 695 | in = fopen(zFilename, "rb"); |
| 696 | if( in==0 ){ |
| 697 | fossil_panic("cannot open %s for reading", zFilename); |
| 698 | } |
| 699 | got = fread(blob_buffer(pBlob), 1, size, in); |
| 700 | fclose(in); |
| @@ -711,16 +711,15 @@ | |
| 711 | ** |
| 712 | ** Return the number of bytes written. |
| 713 | */ |
| 714 | int blob_write_to_file(Blob *pBlob, const char *zFilename){ |
| 715 | FILE *out; |
| 716 | int needToClose; |
| 717 | int wrote; |
| 718 | |
| 719 | if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){ |
| 720 | out = stdout; |
| 721 | needToClose = 0; |
| 722 | }else{ |
| 723 | int i, nName; |
| 724 | char *zName, zBuf[1000]; |
| 725 | |
| 726 | nName = strlen(zFilename); |
| @@ -750,22 +749,21 @@ | |
| 750 | } |
| 751 | #endif |
| 752 | zName[i] = '/'; |
| 753 | } |
| 754 | } |
| 755 | out = fopen(zName, "wb"); |
| 756 | if( out==0 ){ |
| 757 | fossil_fatal_recursive("unable to open file \"%s\" for writing", zName); |
| 758 | return 0; |
| 759 | } |
| 760 | needToClose = 1; |
| 761 | if( zName!=zBuf ) free(zName); |
| 762 | } |
| 763 | blob_is_init(pBlob); |
| 764 | wrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); |
| 765 | if( needToClose ) fclose(out); |
| 766 | if( wrote!=blob_size(pBlob) ){ |
| 767 | fossil_fatal_recursive("short write: %d of %d bytes to %s", wrote, |
| 768 | blob_size(pBlob), zFilename); |
| 769 | } |
| 770 | return wrote; |
| 771 | } |
| @@ -925,11 +923,11 @@ | |
| 925 | } |
| 926 | blob_reset(&b1); |
| 927 | blob_reset(&b2); |
| 928 | blob_reset(&b3); |
| 929 | } |
| 930 | printf("ok\n"); |
| 931 | } |
| 932 | |
| 933 | #if defined(_WIN32) |
| 934 | /* |
| 935 | ** Convert every \n character in the given blob into \r\n. |
| 936 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -111,11 +111,11 @@ | |
| 111 | assert( fossil_isspace((char)i) ); |
| 112 | }else{ |
| 113 | assert( !fossil_isspace((char)i) ); |
| 114 | } |
| 115 | } |
| 116 | fossil_print("All 256 characters OK\n"); |
| 117 | } |
| 118 | |
| 119 | /* |
| 120 | ** This routine is called if a blob operation fails because we |
| 121 | ** have run out of memory. |
| @@ -690,11 +690,11 @@ | |
| 690 | } |
| 691 | if( size==0 ){ |
| 692 | return 0; |
| 693 | } |
| 694 | blob_resize(pBlob, size); |
| 695 | in = fossil_fopen(zFilename, "rb"); |
| 696 | if( in==0 ){ |
| 697 | fossil_panic("cannot open %s for reading", zFilename); |
| 698 | } |
| 699 | got = fread(blob_buffer(pBlob), 1, size, in); |
| 700 | fclose(in); |
| @@ -711,16 +711,15 @@ | |
| 711 | ** |
| 712 | ** Return the number of bytes written. |
| 713 | */ |
| 714 | int blob_write_to_file(Blob *pBlob, const char *zFilename){ |
| 715 | FILE *out; |
| 716 | int wrote; |
| 717 | |
| 718 | if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){ |
| 719 | fossil_puts(blob_str(pBlob), 0); |
| 720 | return blob_size(pBlob); |
| 721 | }else{ |
| 722 | int i, nName; |
| 723 | char *zName, zBuf[1000]; |
| 724 | |
| 725 | nName = strlen(zFilename); |
| @@ -750,22 +749,21 @@ | |
| 749 | } |
| 750 | #endif |
| 751 | zName[i] = '/'; |
| 752 | } |
| 753 | } |
| 754 | out = fossil_fopen(zName, "wb"); |
| 755 | if( out==0 ){ |
| 756 | fossil_fatal_recursive("unable to open file \"%s\" for writing", zName); |
| 757 | return 0; |
| 758 | } |
| 759 | if( zName!=zBuf ) free(zName); |
| 760 | } |
| 761 | blob_is_init(pBlob); |
| 762 | wrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); |
| 763 | fclose(out); |
| 764 | if( wrote!=blob_size(pBlob) && out!=stdout ){ |
| 765 | fossil_fatal_recursive("short write: %d of %d bytes to %s", wrote, |
| 766 | blob_size(pBlob), zFilename); |
| 767 | } |
| 768 | return wrote; |
| 769 | } |
| @@ -925,11 +923,11 @@ | |
| 923 | } |
| 924 | blob_reset(&b1); |
| 925 | blob_reset(&b2); |
| 926 | blob_reset(&b3); |
| 927 | } |
| 928 | fossil_print("ok\n"); |
| 929 | } |
| 930 | |
| 931 | #if defined(_WIN32) |
| 932 | /* |
| 933 | ** Convert every \n character in the given blob into \r\n. |
| 934 |
+4
-4
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -68,11 +68,11 @@ | ||
| 68 | 68 | fossil_fatal("branch \"%s\" already exists", zBranch); |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | user_select(); |
| 72 | 72 | db_begin_transaction(); |
| 73 | - rootid = name_to_rid(g.argv[4]); | |
| 73 | + rootid = name_to_typed_rid(g.argv[4], "ci"); | |
| 74 | 74 | if( rootid==0 ){ |
| 75 | 75 | fossil_fatal("unable to locate check-in off of which to branch"); |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | pParent = manifest_get(rootid, CFTYPE_MANIFEST); |
| @@ -157,13 +157,13 @@ | ||
| 157 | 157 | fossil_panic("unable to install new manifest"); |
| 158 | 158 | } |
| 159 | 159 | assert( blob_is_reset(&branch) ); |
| 160 | 160 | content_deltify(rootid, brid, 0); |
| 161 | 161 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); |
| 162 | - printf("New branch: %s\n", zUuid); | |
| 162 | + fossil_print("New branch: %s\n", zUuid); | |
| 163 | 163 | if( g.argc==3 ){ |
| 164 | - printf( | |
| 164 | + fossil_print( | |
| 165 | 165 | "\n" |
| 166 | 166 | "Note: the local check-out has not been updated to the new\n" |
| 167 | 167 | " branch. To begin working on the new branch, do this:\n" |
| 168 | 168 | "\n" |
| 169 | 169 | " %s update %s\n", |
| @@ -229,11 +229,11 @@ | ||
| 229 | 229 | TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 230 | 230 | ); |
| 231 | 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | 232 | const char *zBr = db_column_text(&q, 0); |
| 233 | 233 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 234 | - printf("%s%s\n", (isCur ? "* " : " "), zBr); | |
| 234 | + fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); | |
| 235 | 235 | } |
| 236 | 236 | db_finalize(&q); |
| 237 | 237 | }else{ |
| 238 | 238 | fossil_panic("branch subcommand should be one of: " |
| 239 | 239 | "new list ls"); |
| 240 | 240 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -68,11 +68,11 @@ | |
| 68 | fossil_fatal("branch \"%s\" already exists", zBranch); |
| 69 | } |
| 70 | |
| 71 | user_select(); |
| 72 | db_begin_transaction(); |
| 73 | rootid = name_to_rid(g.argv[4]); |
| 74 | if( rootid==0 ){ |
| 75 | fossil_fatal("unable to locate check-in off of which to branch"); |
| 76 | } |
| 77 | |
| 78 | pParent = manifest_get(rootid, CFTYPE_MANIFEST); |
| @@ -157,13 +157,13 @@ | |
| 157 | fossil_panic("unable to install new manifest"); |
| 158 | } |
| 159 | assert( blob_is_reset(&branch) ); |
| 160 | content_deltify(rootid, brid, 0); |
| 161 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); |
| 162 | printf("New branch: %s\n", zUuid); |
| 163 | if( g.argc==3 ){ |
| 164 | printf( |
| 165 | "\n" |
| 166 | "Note: the local check-out has not been updated to the new\n" |
| 167 | " branch. To begin working on the new branch, do this:\n" |
| 168 | "\n" |
| 169 | " %s update %s\n", |
| @@ -229,11 +229,11 @@ | |
| 229 | TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 230 | ); |
| 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | const char *zBr = db_column_text(&q, 0); |
| 233 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 234 | printf("%s%s\n", (isCur ? "* " : " "), zBr); |
| 235 | } |
| 236 | db_finalize(&q); |
| 237 | }else{ |
| 238 | fossil_panic("branch subcommand should be one of: " |
| 239 | "new list ls"); |
| 240 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -68,11 +68,11 @@ | |
| 68 | fossil_fatal("branch \"%s\" already exists", zBranch); |
| 69 | } |
| 70 | |
| 71 | user_select(); |
| 72 | db_begin_transaction(); |
| 73 | rootid = name_to_typed_rid(g.argv[4], "ci"); |
| 74 | if( rootid==0 ){ |
| 75 | fossil_fatal("unable to locate check-in off of which to branch"); |
| 76 | } |
| 77 | |
| 78 | pParent = manifest_get(rootid, CFTYPE_MANIFEST); |
| @@ -157,13 +157,13 @@ | |
| 157 | fossil_panic("unable to install new manifest"); |
| 158 | } |
| 159 | assert( blob_is_reset(&branch) ); |
| 160 | content_deltify(rootid, brid, 0); |
| 161 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); |
| 162 | fossil_print("New branch: %s\n", zUuid); |
| 163 | if( g.argc==3 ){ |
| 164 | fossil_print( |
| 165 | "\n" |
| 166 | "Note: the local check-out has not been updated to the new\n" |
| 167 | " branch. To begin working on the new branch, do this:\n" |
| 168 | "\n" |
| 169 | " %s update %s\n", |
| @@ -229,11 +229,11 @@ | |
| 229 | TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 230 | ); |
| 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | const char *zBr = db_column_text(&q, 0); |
| 233 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 234 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 235 | } |
| 236 | db_finalize(&q); |
| 237 | }else{ |
| 238 | fossil_panic("branch subcommand should be one of: " |
| 239 | "new list ls"); |
| 240 |
+1
-1
| --- src/captcha.c | ||
| +++ src/captcha.c | ||
| @@ -392,11 +392,11 @@ | ||
| 392 | 392 | for(i=2; i<g.argc; i++){ |
| 393 | 393 | char zHex[30]; |
| 394 | 394 | v = (unsigned int)atoi(g.argv[i]); |
| 395 | 395 | sqlite3_snprintf(sizeof(zHex), zHex, "%x", v); |
| 396 | 396 | z = captcha_render(zHex); |
| 397 | - printf("%s:\n%s", zHex, z); | |
| 397 | + fossil_print("%s:\n%s", zHex, z); | |
| 398 | 398 | free(z); |
| 399 | 399 | } |
| 400 | 400 | } |
| 401 | 401 | |
| 402 | 402 | /* |
| 403 | 403 |
| --- src/captcha.c | |
| +++ src/captcha.c | |
| @@ -392,11 +392,11 @@ | |
| 392 | for(i=2; i<g.argc; i++){ |
| 393 | char zHex[30]; |
| 394 | v = (unsigned int)atoi(g.argv[i]); |
| 395 | sqlite3_snprintf(sizeof(zHex), zHex, "%x", v); |
| 396 | z = captcha_render(zHex); |
| 397 | printf("%s:\n%s", zHex, z); |
| 398 | free(z); |
| 399 | } |
| 400 | } |
| 401 | |
| 402 | /* |
| 403 |
| --- src/captcha.c | |
| +++ src/captcha.c | |
| @@ -392,11 +392,11 @@ | |
| 392 | for(i=2; i<g.argc; i++){ |
| 393 | char zHex[30]; |
| 394 | v = (unsigned int)atoi(g.argv[i]); |
| 395 | sqlite3_snprintf(sizeof(zHex), zHex, "%x", v); |
| 396 | z = captcha_render(zHex); |
| 397 | fossil_print("%s:\n%s", zHex, z); |
| 398 | free(z); |
| 399 | } |
| 400 | } |
| 401 | |
| 402 | /* |
| 403 |
+48
-26
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -2,11 +2,11 @@ | ||
| 2 | 2 | ** Copyright (c) 2006 D. Richard Hipp |
| 3 | 3 | ** |
| 4 | 4 | ** This program is free software; you can redistribute it and/or |
| 5 | 5 | ** modify it under the terms of the Simplified BSD License (also |
| 6 | 6 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 7 | - | |
| 7 | +** | |
| 8 | 8 | ** This program is distributed in the hope that it will be useful, |
| 9 | 9 | ** but without any warranty; without even the implied warranty of |
| 10 | 10 | ** merchantability or fitness for a particular purpose. |
| 11 | 11 | ** |
| 12 | 12 | ** Author contact information: |
| @@ -191,20 +191,24 @@ | ||
| 191 | 191 | const char *zName, /* Name of the cookie */ |
| 192 | 192 | const char *zValue, /* Value of the cookie. Automatically escaped */ |
| 193 | 193 | const char *zPath, /* Path cookie applies to. NULL means "/" */ |
| 194 | 194 | int lifetime /* Expiration of the cookie in seconds from now */ |
| 195 | 195 | ){ |
| 196 | + char *zSecure = ""; | |
| 196 | 197 | if( zPath==0 ) zPath = g.zTop; |
| 198 | + if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){ | |
| 199 | + zSecure = " secure;"; | |
| 200 | + } | |
| 197 | 201 | if( lifetime>0 ){ |
| 198 | 202 | lifetime += (int)time(0); |
| 199 | 203 | blob_appendf(&extraHeader, |
| 200 | - "Set-Cookie: %s=%t; Path=%s; expires=%z; Version=1\r\n", | |
| 201 | - zName, zValue, zPath, cgi_rfc822_datestamp(lifetime)); | |
| 204 | + "Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n", | |
| 205 | + zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure); | |
| 202 | 206 | }else{ |
| 203 | 207 | blob_appendf(&extraHeader, |
| 204 | - "Set-Cookie: %s=%t; Path=%s; Version=1\r\n", | |
| 205 | - zName, zValue, zPath); | |
| 208 | + "Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n", | |
| 209 | + zName, zValue, zPath, zSecure); | |
| 206 | 210 | } |
| 207 | 211 | } |
| 208 | 212 | |
| 209 | 213 | #if 0 |
| 210 | 214 | /* |
| @@ -289,10 +293,28 @@ | ||
| 289 | 293 | } |
| 290 | 294 | |
| 291 | 295 | if( blob_size(&extraHeader)>0 ){ |
| 292 | 296 | fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); |
| 293 | 297 | } |
| 298 | + | |
| 299 | + /* Add headers to turn on useful security options in browsers. */ | |
| 300 | + fprintf(g.httpOut, "X-Frame-Options: DENY\r\n"); | |
| 301 | + /* This stops fossil pages appearing in frames or iframes, preventing | |
| 302 | + ** click-jacking attacks on supporting browsers. | |
| 303 | + ** | |
| 304 | + ** Other good headers would be | |
| 305 | + ** Strict-Transport-Security: max-age=62208000 | |
| 306 | + ** if we're using https. However, this would break sites which serve different | |
| 307 | + ** content on http and https protocols. Also, | |
| 308 | + ** X-Content-Security-Policy: allow 'self' | |
| 309 | + ** would help mitigate some XSS and data injection attacks, but will break | |
| 310 | + ** deliberate inclusion of external resources, such as JavaScript syntax | |
| 311 | + ** highlighter scripts. | |
| 312 | + ** | |
| 313 | + ** These headers are probably best added by the web server hosting fossil as | |
| 314 | + ** a CGI script. | |
| 315 | + */ | |
| 294 | 316 | |
| 295 | 317 | if( g.isConst ){ |
| 296 | 318 | /* constant means that the input URL will _never_ generate anything |
| 297 | 319 | ** else. In the case of attachments, the contents won't change because |
| 298 | 320 | ** an attempt to change them generates a new attachment number. In the |
| @@ -310,11 +332,11 @@ | ||
| 310 | 332 | |
| 311 | 333 | /* Content intended for logged in users should only be cached in |
| 312 | 334 | ** the browser, not some shared location. |
| 313 | 335 | */ |
| 314 | 336 | fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType); |
| 315 | - if( strcmp(zContentType,"application/x-fossil")==0 ){ | |
| 337 | + if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){ | |
| 316 | 338 | cgi_combine_header_and_body(); |
| 317 | 339 | blob_compress(&cgiContent[0], &cgiContent[0]); |
| 318 | 340 | } |
| 319 | 341 | |
| 320 | 342 | if( iReplyStatus != 304 ) { |
| @@ -419,11 +441,11 @@ | ||
| 419 | 441 | ** Replace a parameter with a new value. |
| 420 | 442 | */ |
| 421 | 443 | void cgi_replace_parameter(const char *zName, const char *zValue){ |
| 422 | 444 | int i; |
| 423 | 445 | for(i=0; i<nUsedQP; i++){ |
| 424 | - if( strcmp(aParamQP[i].zName,zName)==0 ){ | |
| 446 | + if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){ | |
| 425 | 447 | aParamQP[i].zValue = zValue; |
| 426 | 448 | return; |
| 427 | 449 | } |
| 428 | 450 | } |
| 429 | 451 | cgi_set_parameter_nocopy(zName, zValue); |
| @@ -681,26 +703,26 @@ | ||
| 681 | 703 | |
| 682 | 704 | len = atoi(PD("CONTENT_LENGTH", "0")); |
| 683 | 705 | g.zContentType = zType = P("CONTENT_TYPE"); |
| 684 | 706 | if( len>0 && zType ){ |
| 685 | 707 | blob_zero(&g.cgiIn); |
| 686 | - if( strcmp(zType,"application/x-www-form-urlencoded")==0 | |
| 708 | + if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0 | |
| 687 | 709 | || strncmp(zType,"multipart/form-data",19)==0 ){ |
| 688 | 710 | z = fossil_malloc( len+1 ); |
| 689 | 711 | len = fread(z, 1, len, g.httpIn); |
| 690 | 712 | z[len] = 0; |
| 691 | 713 | if( zType[0]=='a' ){ |
| 692 | 714 | add_param_list(z, '&'); |
| 693 | 715 | }else{ |
| 694 | 716 | process_multipart_form_data(z, len); |
| 695 | 717 | } |
| 696 | - }else if( strcmp(zType, "application/x-fossil")==0 ){ | |
| 718 | + }else if( fossil_strcmp(zType, "application/x-fossil")==0 ){ | |
| 697 | 719 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 698 | 720 | blob_uncompress(&g.cgiIn, &g.cgiIn); |
| 699 | - }else if( strcmp(zType, "application/x-fossil-debug")==0 ){ | |
| 721 | + }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){ | |
| 700 | 722 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 701 | - }else if( strcmp(zType, "application/x-fossil-uncompressed")==0 ){ | |
| 723 | + }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){ | |
| 702 | 724 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 703 | 725 | } |
| 704 | 726 | } |
| 705 | 727 | |
| 706 | 728 | z = (char*)P("HTTP_COOKIE"); |
| @@ -716,11 +738,11 @@ | ||
| 716 | 738 | */ |
| 717 | 739 | static int qparam_compare(const void *a, const void *b){ |
| 718 | 740 | struct QParam *pA = (struct QParam*)a; |
| 719 | 741 | struct QParam *pB = (struct QParam*)b; |
| 720 | 742 | int c; |
| 721 | - c = strcmp(pA->zName, pB->zName); | |
| 743 | + c = fossil_strcmp(pA->zName, pB->zName); | |
| 722 | 744 | if( c==0 ){ |
| 723 | 745 | c = pA->seq - pB->seq; |
| 724 | 746 | } |
| 725 | 747 | return c; |
| 726 | 748 | } |
| @@ -745,11 +767,11 @@ | ||
| 745 | 767 | /* After sorting, remove duplicate parameters. The secondary sort |
| 746 | 768 | ** key is aParamQP[].seq and we keep the first entry. That means |
| 747 | 769 | ** with duplicate calls to cgi_set_parameter() the second and |
| 748 | 770 | ** subsequent calls are effectively no-ops. */ |
| 749 | 771 | for(i=j=1; i<nUsedQP; i++){ |
| 750 | - if( strcmp(aParamQP[i].zName,aParamQP[i-1].zName)==0 ){ | |
| 772 | + if( fossil_strcmp(aParamQP[i].zName,aParamQP[i-1].zName)==0 ){ | |
| 751 | 773 | continue; |
| 752 | 774 | } |
| 753 | 775 | if( j<i ){ |
| 754 | 776 | memcpy(&aParamQP[j], &aParamQP[i], sizeof(aParamQP[j])); |
| 755 | 777 | } |
| @@ -761,11 +783,11 @@ | ||
| 761 | 783 | /* Do a binary search for a matching query parameter */ |
| 762 | 784 | lo = 0; |
| 763 | 785 | hi = nUsedQP-1; |
| 764 | 786 | while( lo<=hi ){ |
| 765 | 787 | mid = (lo+hi)/2; |
| 766 | - c = strcmp(aParamQP[mid].zName, zName); | |
| 788 | + c = fossil_strcmp(aParamQP[mid].zName, zName); | |
| 767 | 789 | if( c==0 ){ |
| 768 | 790 | CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue)); |
| 769 | 791 | return aParamQP[mid].zValue; |
| 770 | 792 | }else if( c>0 ){ |
| 771 | 793 | hi = mid-1; |
| @@ -972,12 +994,12 @@ | ||
| 972 | 994 | } |
| 973 | 995 | zToken = extract_token(zLine, &z); |
| 974 | 996 | if( zToken==0 ){ |
| 975 | 997 | malformed_request(); |
| 976 | 998 | } |
| 977 | - if( strcmp(zToken,"GET")!=0 && strcmp(zToken,"POST")!=0 | |
| 978 | - && strcmp(zToken,"HEAD")!=0 ){ | |
| 999 | + if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0 | |
| 1000 | + && fossil_strcmp(zToken,"HEAD")!=0 ){ | |
| 979 | 1001 | malformed_request(); |
| 980 | 1002 | } |
| 981 | 1003 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 982 | 1004 | cgi_setenv("REQUEST_METHOD",zToken); |
| 983 | 1005 | zToken = extract_token(z, &z); |
| @@ -1013,29 +1035,29 @@ | ||
| 1013 | 1035 | while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } |
| 1014 | 1036 | zVal[i] = 0; |
| 1015 | 1037 | for(i=0; zFieldName[i]; i++){ |
| 1016 | 1038 | zFieldName[i] = fossil_tolower(zFieldName[i]); |
| 1017 | 1039 | } |
| 1018 | - if( strcmp(zFieldName,"content-length:")==0 ){ | |
| 1040 | + if( fossil_strcmp(zFieldName,"content-length:")==0 ){ | |
| 1019 | 1041 | cgi_setenv("CONTENT_LENGTH", zVal); |
| 1020 | - }else if( strcmp(zFieldName,"content-type:")==0 ){ | |
| 1042 | + }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){ | |
| 1021 | 1043 | cgi_setenv("CONTENT_TYPE", zVal); |
| 1022 | - }else if( strcmp(zFieldName,"cookie:")==0 ){ | |
| 1044 | + }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){ | |
| 1023 | 1045 | cgi_setenv("HTTP_COOKIE", zVal); |
| 1024 | - }else if( strcmp(zFieldName,"https:")==0 ){ | |
| 1046 | + }else if( fossil_strcmp(zFieldName,"https:")==0 ){ | |
| 1025 | 1047 | cgi_setenv("HTTPS", zVal); |
| 1026 | - }else if( strcmp(zFieldName,"host:")==0 ){ | |
| 1048 | + }else if( fossil_strcmp(zFieldName,"host:")==0 ){ | |
| 1027 | 1049 | cgi_setenv("HTTP_HOST", zVal); |
| 1028 | - }else if( strcmp(zFieldName,"if-none-match:")==0 ){ | |
| 1050 | + }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){ | |
| 1029 | 1051 | cgi_setenv("HTTP_IF_NONE_MATCH", zVal); |
| 1030 | - }else if( strcmp(zFieldName,"if-modified-since:")==0 ){ | |
| 1052 | + }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){ | |
| 1031 | 1053 | cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal); |
| 1032 | 1054 | } |
| 1033 | 1055 | #if 0 |
| 1034 | - else if( strcmp(zFieldName,"referer:")==0 ){ | |
| 1056 | + else if( fossil_strcmp(zFieldName,"referer:")==0 ){ | |
| 1035 | 1057 | cgi_setenv("HTTP_REFERER", zVal); |
| 1036 | - }else if( strcmp(zFieldName,"user-agent:")==0 ){ | |
| 1058 | + }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){ | |
| 1037 | 1059 | cgi_setenv("HTTP_USER_AGENT", zVal); |
| 1038 | 1060 | } |
| 1039 | 1061 | #endif |
| 1040 | 1062 | } |
| 1041 | 1063 | |
| @@ -1116,11 +1138,11 @@ | ||
| 1116 | 1138 | } |
| 1117 | 1139 | } |
| 1118 | 1140 | if( iPort>mxPort ) return 1; |
| 1119 | 1141 | listen(listener,10); |
| 1120 | 1142 | if( iPort>mnPort ){ |
| 1121 | - printf("Listening for HTTP requests on TCP port %d\n", iPort); | |
| 1143 | + fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); | |
| 1122 | 1144 | fflush(stdout); |
| 1123 | 1145 | } |
| 1124 | 1146 | if( zBrowser ){ |
| 1125 | 1147 | zBrowser = mprintf(zBrowser, iPort); |
| 1126 | 1148 | system(zBrowser); |
| 1127 | 1149 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -2,11 +2,11 @@ | |
| 2 | ** Copyright (c) 2006 D. Richard Hipp |
| 3 | ** |
| 4 | ** This program is free software; you can redistribute it and/or |
| 5 | ** modify it under the terms of the Simplified BSD License (also |
| 6 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 7 | |
| 8 | ** This program is distributed in the hope that it will be useful, |
| 9 | ** but without any warranty; without even the implied warranty of |
| 10 | ** merchantability or fitness for a particular purpose. |
| 11 | ** |
| 12 | ** Author contact information: |
| @@ -191,20 +191,24 @@ | |
| 191 | const char *zName, /* Name of the cookie */ |
| 192 | const char *zValue, /* Value of the cookie. Automatically escaped */ |
| 193 | const char *zPath, /* Path cookie applies to. NULL means "/" */ |
| 194 | int lifetime /* Expiration of the cookie in seconds from now */ |
| 195 | ){ |
| 196 | if( zPath==0 ) zPath = g.zTop; |
| 197 | if( lifetime>0 ){ |
| 198 | lifetime += (int)time(0); |
| 199 | blob_appendf(&extraHeader, |
| 200 | "Set-Cookie: %s=%t; Path=%s; expires=%z; Version=1\r\n", |
| 201 | zName, zValue, zPath, cgi_rfc822_datestamp(lifetime)); |
| 202 | }else{ |
| 203 | blob_appendf(&extraHeader, |
| 204 | "Set-Cookie: %s=%t; Path=%s; Version=1\r\n", |
| 205 | zName, zValue, zPath); |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | #if 0 |
| 210 | /* |
| @@ -289,10 +293,28 @@ | |
| 289 | } |
| 290 | |
| 291 | if( blob_size(&extraHeader)>0 ){ |
| 292 | fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); |
| 293 | } |
| 294 | |
| 295 | if( g.isConst ){ |
| 296 | /* constant means that the input URL will _never_ generate anything |
| 297 | ** else. In the case of attachments, the contents won't change because |
| 298 | ** an attempt to change them generates a new attachment number. In the |
| @@ -310,11 +332,11 @@ | |
| 310 | |
| 311 | /* Content intended for logged in users should only be cached in |
| 312 | ** the browser, not some shared location. |
| 313 | */ |
| 314 | fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType); |
| 315 | if( strcmp(zContentType,"application/x-fossil")==0 ){ |
| 316 | cgi_combine_header_and_body(); |
| 317 | blob_compress(&cgiContent[0], &cgiContent[0]); |
| 318 | } |
| 319 | |
| 320 | if( iReplyStatus != 304 ) { |
| @@ -419,11 +441,11 @@ | |
| 419 | ** Replace a parameter with a new value. |
| 420 | */ |
| 421 | void cgi_replace_parameter(const char *zName, const char *zValue){ |
| 422 | int i; |
| 423 | for(i=0; i<nUsedQP; i++){ |
| 424 | if( strcmp(aParamQP[i].zName,zName)==0 ){ |
| 425 | aParamQP[i].zValue = zValue; |
| 426 | return; |
| 427 | } |
| 428 | } |
| 429 | cgi_set_parameter_nocopy(zName, zValue); |
| @@ -681,26 +703,26 @@ | |
| 681 | |
| 682 | len = atoi(PD("CONTENT_LENGTH", "0")); |
| 683 | g.zContentType = zType = P("CONTENT_TYPE"); |
| 684 | if( len>0 && zType ){ |
| 685 | blob_zero(&g.cgiIn); |
| 686 | if( strcmp(zType,"application/x-www-form-urlencoded")==0 |
| 687 | || strncmp(zType,"multipart/form-data",19)==0 ){ |
| 688 | z = fossil_malloc( len+1 ); |
| 689 | len = fread(z, 1, len, g.httpIn); |
| 690 | z[len] = 0; |
| 691 | if( zType[0]=='a' ){ |
| 692 | add_param_list(z, '&'); |
| 693 | }else{ |
| 694 | process_multipart_form_data(z, len); |
| 695 | } |
| 696 | }else if( strcmp(zType, "application/x-fossil")==0 ){ |
| 697 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 698 | blob_uncompress(&g.cgiIn, &g.cgiIn); |
| 699 | }else if( strcmp(zType, "application/x-fossil-debug")==0 ){ |
| 700 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 701 | }else if( strcmp(zType, "application/x-fossil-uncompressed")==0 ){ |
| 702 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 703 | } |
| 704 | } |
| 705 | |
| 706 | z = (char*)P("HTTP_COOKIE"); |
| @@ -716,11 +738,11 @@ | |
| 716 | */ |
| 717 | static int qparam_compare(const void *a, const void *b){ |
| 718 | struct QParam *pA = (struct QParam*)a; |
| 719 | struct QParam *pB = (struct QParam*)b; |
| 720 | int c; |
| 721 | c = strcmp(pA->zName, pB->zName); |
| 722 | if( c==0 ){ |
| 723 | c = pA->seq - pB->seq; |
| 724 | } |
| 725 | return c; |
| 726 | } |
| @@ -745,11 +767,11 @@ | |
| 745 | /* After sorting, remove duplicate parameters. The secondary sort |
| 746 | ** key is aParamQP[].seq and we keep the first entry. That means |
| 747 | ** with duplicate calls to cgi_set_parameter() the second and |
| 748 | ** subsequent calls are effectively no-ops. */ |
| 749 | for(i=j=1; i<nUsedQP; i++){ |
| 750 | if( strcmp(aParamQP[i].zName,aParamQP[i-1].zName)==0 ){ |
| 751 | continue; |
| 752 | } |
| 753 | if( j<i ){ |
| 754 | memcpy(&aParamQP[j], &aParamQP[i], sizeof(aParamQP[j])); |
| 755 | } |
| @@ -761,11 +783,11 @@ | |
| 761 | /* Do a binary search for a matching query parameter */ |
| 762 | lo = 0; |
| 763 | hi = nUsedQP-1; |
| 764 | while( lo<=hi ){ |
| 765 | mid = (lo+hi)/2; |
| 766 | c = strcmp(aParamQP[mid].zName, zName); |
| 767 | if( c==0 ){ |
| 768 | CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue)); |
| 769 | return aParamQP[mid].zValue; |
| 770 | }else if( c>0 ){ |
| 771 | hi = mid-1; |
| @@ -972,12 +994,12 @@ | |
| 972 | } |
| 973 | zToken = extract_token(zLine, &z); |
| 974 | if( zToken==0 ){ |
| 975 | malformed_request(); |
| 976 | } |
| 977 | if( strcmp(zToken,"GET")!=0 && strcmp(zToken,"POST")!=0 |
| 978 | && strcmp(zToken,"HEAD")!=0 ){ |
| 979 | malformed_request(); |
| 980 | } |
| 981 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 982 | cgi_setenv("REQUEST_METHOD",zToken); |
| 983 | zToken = extract_token(z, &z); |
| @@ -1013,29 +1035,29 @@ | |
| 1013 | while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } |
| 1014 | zVal[i] = 0; |
| 1015 | for(i=0; zFieldName[i]; i++){ |
| 1016 | zFieldName[i] = fossil_tolower(zFieldName[i]); |
| 1017 | } |
| 1018 | if( strcmp(zFieldName,"content-length:")==0 ){ |
| 1019 | cgi_setenv("CONTENT_LENGTH", zVal); |
| 1020 | }else if( strcmp(zFieldName,"content-type:")==0 ){ |
| 1021 | cgi_setenv("CONTENT_TYPE", zVal); |
| 1022 | }else if( strcmp(zFieldName,"cookie:")==0 ){ |
| 1023 | cgi_setenv("HTTP_COOKIE", zVal); |
| 1024 | }else if( strcmp(zFieldName,"https:")==0 ){ |
| 1025 | cgi_setenv("HTTPS", zVal); |
| 1026 | }else if( strcmp(zFieldName,"host:")==0 ){ |
| 1027 | cgi_setenv("HTTP_HOST", zVal); |
| 1028 | }else if( strcmp(zFieldName,"if-none-match:")==0 ){ |
| 1029 | cgi_setenv("HTTP_IF_NONE_MATCH", zVal); |
| 1030 | }else if( strcmp(zFieldName,"if-modified-since:")==0 ){ |
| 1031 | cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal); |
| 1032 | } |
| 1033 | #if 0 |
| 1034 | else if( strcmp(zFieldName,"referer:")==0 ){ |
| 1035 | cgi_setenv("HTTP_REFERER", zVal); |
| 1036 | }else if( strcmp(zFieldName,"user-agent:")==0 ){ |
| 1037 | cgi_setenv("HTTP_USER_AGENT", zVal); |
| 1038 | } |
| 1039 | #endif |
| 1040 | } |
| 1041 | |
| @@ -1116,11 +1138,11 @@ | |
| 1116 | } |
| 1117 | } |
| 1118 | if( iPort>mxPort ) return 1; |
| 1119 | listen(listener,10); |
| 1120 | if( iPort>mnPort ){ |
| 1121 | printf("Listening for HTTP requests on TCP port %d\n", iPort); |
| 1122 | fflush(stdout); |
| 1123 | } |
| 1124 | if( zBrowser ){ |
| 1125 | zBrowser = mprintf(zBrowser, iPort); |
| 1126 | system(zBrowser); |
| 1127 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -2,11 +2,11 @@ | |
| 2 | ** Copyright (c) 2006 D. Richard Hipp |
| 3 | ** |
| 4 | ** This program is free software; you can redistribute it and/or |
| 5 | ** modify it under the terms of the Simplified BSD License (also |
| 6 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 7 | ** |
| 8 | ** This program is distributed in the hope that it will be useful, |
| 9 | ** but without any warranty; without even the implied warranty of |
| 10 | ** merchantability or fitness for a particular purpose. |
| 11 | ** |
| 12 | ** Author contact information: |
| @@ -191,20 +191,24 @@ | |
| 191 | const char *zName, /* Name of the cookie */ |
| 192 | const char *zValue, /* Value of the cookie. Automatically escaped */ |
| 193 | const char *zPath, /* Path cookie applies to. NULL means "/" */ |
| 194 | int lifetime /* Expiration of the cookie in seconds from now */ |
| 195 | ){ |
| 196 | char *zSecure = ""; |
| 197 | if( zPath==0 ) zPath = g.zTop; |
| 198 | if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){ |
| 199 | zSecure = " secure;"; |
| 200 | } |
| 201 | if( lifetime>0 ){ |
| 202 | lifetime += (int)time(0); |
| 203 | blob_appendf(&extraHeader, |
| 204 | "Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n", |
| 205 | zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure); |
| 206 | }else{ |
| 207 | blob_appendf(&extraHeader, |
| 208 | "Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n", |
| 209 | zName, zValue, zPath, zSecure); |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | #if 0 |
| 214 | /* |
| @@ -289,10 +293,28 @@ | |
| 293 | } |
| 294 | |
| 295 | if( blob_size(&extraHeader)>0 ){ |
| 296 | fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); |
| 297 | } |
| 298 | |
| 299 | /* Add headers to turn on useful security options in browsers. */ |
| 300 | fprintf(g.httpOut, "X-Frame-Options: DENY\r\n"); |
| 301 | /* This stops fossil pages appearing in frames or iframes, preventing |
| 302 | ** click-jacking attacks on supporting browsers. |
| 303 | ** |
| 304 | ** Other good headers would be |
| 305 | ** Strict-Transport-Security: max-age=62208000 |
| 306 | ** if we're using https. However, this would break sites which serve different |
| 307 | ** content on http and https protocols. Also, |
| 308 | ** X-Content-Security-Policy: allow 'self' |
| 309 | ** would help mitigate some XSS and data injection attacks, but will break |
| 310 | ** deliberate inclusion of external resources, such as JavaScript syntax |
| 311 | ** highlighter scripts. |
| 312 | ** |
| 313 | ** These headers are probably best added by the web server hosting fossil as |
| 314 | ** a CGI script. |
| 315 | */ |
| 316 | |
| 317 | if( g.isConst ){ |
| 318 | /* constant means that the input URL will _never_ generate anything |
| 319 | ** else. In the case of attachments, the contents won't change because |
| 320 | ** an attempt to change them generates a new attachment number. In the |
| @@ -310,11 +332,11 @@ | |
| 332 | |
| 333 | /* Content intended for logged in users should only be cached in |
| 334 | ** the browser, not some shared location. |
| 335 | */ |
| 336 | fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType); |
| 337 | if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){ |
| 338 | cgi_combine_header_and_body(); |
| 339 | blob_compress(&cgiContent[0], &cgiContent[0]); |
| 340 | } |
| 341 | |
| 342 | if( iReplyStatus != 304 ) { |
| @@ -419,11 +441,11 @@ | |
| 441 | ** Replace a parameter with a new value. |
| 442 | */ |
| 443 | void cgi_replace_parameter(const char *zName, const char *zValue){ |
| 444 | int i; |
| 445 | for(i=0; i<nUsedQP; i++){ |
| 446 | if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){ |
| 447 | aParamQP[i].zValue = zValue; |
| 448 | return; |
| 449 | } |
| 450 | } |
| 451 | cgi_set_parameter_nocopy(zName, zValue); |
| @@ -681,26 +703,26 @@ | |
| 703 | |
| 704 | len = atoi(PD("CONTENT_LENGTH", "0")); |
| 705 | g.zContentType = zType = P("CONTENT_TYPE"); |
| 706 | if( len>0 && zType ){ |
| 707 | blob_zero(&g.cgiIn); |
| 708 | if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0 |
| 709 | || strncmp(zType,"multipart/form-data",19)==0 ){ |
| 710 | z = fossil_malloc( len+1 ); |
| 711 | len = fread(z, 1, len, g.httpIn); |
| 712 | z[len] = 0; |
| 713 | if( zType[0]=='a' ){ |
| 714 | add_param_list(z, '&'); |
| 715 | }else{ |
| 716 | process_multipart_form_data(z, len); |
| 717 | } |
| 718 | }else if( fossil_strcmp(zType, "application/x-fossil")==0 ){ |
| 719 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 720 | blob_uncompress(&g.cgiIn, &g.cgiIn); |
| 721 | }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){ |
| 722 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 723 | }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){ |
| 724 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 725 | } |
| 726 | } |
| 727 | |
| 728 | z = (char*)P("HTTP_COOKIE"); |
| @@ -716,11 +738,11 @@ | |
| 738 | */ |
| 739 | static int qparam_compare(const void *a, const void *b){ |
| 740 | struct QParam *pA = (struct QParam*)a; |
| 741 | struct QParam *pB = (struct QParam*)b; |
| 742 | int c; |
| 743 | c = fossil_strcmp(pA->zName, pB->zName); |
| 744 | if( c==0 ){ |
| 745 | c = pA->seq - pB->seq; |
| 746 | } |
| 747 | return c; |
| 748 | } |
| @@ -745,11 +767,11 @@ | |
| 767 | /* After sorting, remove duplicate parameters. The secondary sort |
| 768 | ** key is aParamQP[].seq and we keep the first entry. That means |
| 769 | ** with duplicate calls to cgi_set_parameter() the second and |
| 770 | ** subsequent calls are effectively no-ops. */ |
| 771 | for(i=j=1; i<nUsedQP; i++){ |
| 772 | if( fossil_strcmp(aParamQP[i].zName,aParamQP[i-1].zName)==0 ){ |
| 773 | continue; |
| 774 | } |
| 775 | if( j<i ){ |
| 776 | memcpy(&aParamQP[j], &aParamQP[i], sizeof(aParamQP[j])); |
| 777 | } |
| @@ -761,11 +783,11 @@ | |
| 783 | /* Do a binary search for a matching query parameter */ |
| 784 | lo = 0; |
| 785 | hi = nUsedQP-1; |
| 786 | while( lo<=hi ){ |
| 787 | mid = (lo+hi)/2; |
| 788 | c = fossil_strcmp(aParamQP[mid].zName, zName); |
| 789 | if( c==0 ){ |
| 790 | CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue)); |
| 791 | return aParamQP[mid].zValue; |
| 792 | }else if( c>0 ){ |
| 793 | hi = mid-1; |
| @@ -972,12 +994,12 @@ | |
| 994 | } |
| 995 | zToken = extract_token(zLine, &z); |
| 996 | if( zToken==0 ){ |
| 997 | malformed_request(); |
| 998 | } |
| 999 | if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0 |
| 1000 | && fossil_strcmp(zToken,"HEAD")!=0 ){ |
| 1001 | malformed_request(); |
| 1002 | } |
| 1003 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 1004 | cgi_setenv("REQUEST_METHOD",zToken); |
| 1005 | zToken = extract_token(z, &z); |
| @@ -1013,29 +1035,29 @@ | |
| 1035 | while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } |
| 1036 | zVal[i] = 0; |
| 1037 | for(i=0; zFieldName[i]; i++){ |
| 1038 | zFieldName[i] = fossil_tolower(zFieldName[i]); |
| 1039 | } |
| 1040 | if( fossil_strcmp(zFieldName,"content-length:")==0 ){ |
| 1041 | cgi_setenv("CONTENT_LENGTH", zVal); |
| 1042 | }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){ |
| 1043 | cgi_setenv("CONTENT_TYPE", zVal); |
| 1044 | }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){ |
| 1045 | cgi_setenv("HTTP_COOKIE", zVal); |
| 1046 | }else if( fossil_strcmp(zFieldName,"https:")==0 ){ |
| 1047 | cgi_setenv("HTTPS", zVal); |
| 1048 | }else if( fossil_strcmp(zFieldName,"host:")==0 ){ |
| 1049 | cgi_setenv("HTTP_HOST", zVal); |
| 1050 | }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){ |
| 1051 | cgi_setenv("HTTP_IF_NONE_MATCH", zVal); |
| 1052 | }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){ |
| 1053 | cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal); |
| 1054 | } |
| 1055 | #if 0 |
| 1056 | else if( fossil_strcmp(zFieldName,"referer:")==0 ){ |
| 1057 | cgi_setenv("HTTP_REFERER", zVal); |
| 1058 | }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){ |
| 1059 | cgi_setenv("HTTP_USER_AGENT", zVal); |
| 1060 | } |
| 1061 | #endif |
| 1062 | } |
| 1063 | |
| @@ -1116,11 +1138,11 @@ | |
| 1138 | } |
| 1139 | } |
| 1140 | if( iPort>mxPort ) return 1; |
| 1141 | listen(listener,10); |
| 1142 | if( iPort>mnPort ){ |
| 1143 | fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); |
| 1144 | fflush(stdout); |
| 1145 | } |
| 1146 | if( zBrowser ){ |
| 1147 | zBrowser = mprintf(zBrowser, iPort); |
| 1148 | system(zBrowser); |
| 1149 |
+26
-21
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -54,11 +54,11 @@ | ||
| 54 | 54 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 55 | 55 | blob_append(report, zPrefix, nPrefix); |
| 56 | 56 | if( isDeleted ){ |
| 57 | 57 | blob_appendf(report, "DELETED %s\n", zPathname); |
| 58 | 58 | }else if( !file_isfile(zFullName) ){ |
| 59 | - if( access(zFullName, 0)==0 ){ | |
| 59 | + if( file_access(zFullName, 0)==0 ){ | |
| 60 | 60 | blob_appendf(report, "NOT_A_FILE %s\n", zPathname); |
| 61 | 61 | if( missingIsFatal ){ |
| 62 | 62 | fossil_warning("not a file: %s", zPathname); |
| 63 | 63 | nErr++; |
| 64 | 64 | } |
| @@ -136,13 +136,13 @@ | ||
| 136 | 136 | */ |
| 137 | 137 | void status_cmd(void){ |
| 138 | 138 | int vid; |
| 139 | 139 | db_must_be_within_tree(); |
| 140 | 140 | /* 012345678901234 */ |
| 141 | - printf("repository: %s\n", db_lget("repository","")); | |
| 142 | - printf("local-root: %s\n", g.zLocalRoot); | |
| 143 | - printf("server-code: %s\n", db_get("server-code", "")); | |
| 141 | + fossil_print("repository: %s\n", db_lget("repository","")); | |
| 142 | + fossil_print("local-root: %s\n", g.zLocalRoot); | |
| 143 | + fossil_print("server-code: %s\n", db_get("server-code", "")); | |
| 144 | 144 | vid = db_lget_int("checkout", 0); |
| 145 | 145 | if( vid ){ |
| 146 | 146 | show_common_info(vid, "checkout:", 1, 1); |
| 147 | 147 | } |
| 148 | 148 | changes_cmd(); |
| @@ -176,27 +176,27 @@ | ||
| 176 | 176 | int isNew = db_column_int(&q,2)==0; |
| 177 | 177 | int chnged = db_column_int(&q,3); |
| 178 | 178 | int renamed = db_column_int(&q,4); |
| 179 | 179 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 180 | 180 | if( isBrief ){ |
| 181 | - printf("%s\n", zPathname); | |
| 181 | + fossil_print("%s\n", zPathname); | |
| 182 | 182 | }else if( isNew ){ |
| 183 | - printf("ADDED %s\n", zPathname); | |
| 183 | + fossil_print("ADDED %s\n", zPathname); | |
| 184 | 184 | }else if( isDeleted ){ |
| 185 | - printf("DELETED %s\n", zPathname); | |
| 185 | + fossil_print("DELETED %s\n", zPathname); | |
| 186 | 186 | }else if( !file_isfile(zFullName) ){ |
| 187 | - if( access(zFullName, 0)==0 ){ | |
| 188 | - printf("NOT_A_FILE %s\n", zPathname); | |
| 187 | + if( file_access(zFullName, 0)==0 ){ | |
| 188 | + fossil_print("NOT_A_FILE %s\n", zPathname); | |
| 189 | 189 | }else{ |
| 190 | - printf("MISSING %s\n", zPathname); | |
| 190 | + fossil_print("MISSING %s\n", zPathname); | |
| 191 | 191 | } |
| 192 | 192 | }else if( chnged ){ |
| 193 | - printf("EDITED %s\n", zPathname); | |
| 193 | + fossil_print("EDITED %s\n", zPathname); | |
| 194 | 194 | }else if( renamed ){ |
| 195 | - printf("RENAMED %s\n", zPathname); | |
| 195 | + fossil_print("RENAMED %s\n", zPathname); | |
| 196 | 196 | }else{ |
| 197 | - printf("UNCHANGED %s\n", zPathname); | |
| 197 | + fossil_print("UNCHANGED %s\n", zPathname); | |
| 198 | 198 | } |
| 199 | 199 | free(zFullName); |
| 200 | 200 | } |
| 201 | 201 | db_finalize(&q); |
| 202 | 202 | } |
| @@ -244,11 +244,11 @@ | ||
| 244 | 244 | ); |
| 245 | 245 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 246 | 246 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 247 | 247 | } |
| 248 | 248 | while( db_step(&q)==SQLITE_ROW ){ |
| 249 | - printf("%s\n", db_column_text(&q, 0)); | |
| 249 | + fossil_print("%s\n", db_column_text(&q, 0)); | |
| 250 | 250 | } |
| 251 | 251 | db_finalize(&q); |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | 254 | /* |
| @@ -302,19 +302,19 @@ | ||
| 302 | 302 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 303 | 303 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 304 | 304 | } |
| 305 | 305 | while( db_step(&q)==SQLITE_ROW ){ |
| 306 | 306 | if( allFlag ){ |
| 307 | - unlink(db_column_text(&q, 0)); | |
| 307 | + file_delete(db_column_text(&q, 0)); | |
| 308 | 308 | }else{ |
| 309 | 309 | Blob ans; |
| 310 | 310 | char *prompt = mprintf("remove unmanaged file \"%s\" (y/N)? ", |
| 311 | 311 | db_column_text(&q, 0)); |
| 312 | 312 | blob_zero(&ans); |
| 313 | 313 | prompt_user(prompt, &ans); |
| 314 | 314 | if( blob_str(&ans)[0]=='y' ){ |
| 315 | - unlink(db_column_text(&q, 0)); | |
| 315 | + file_delete(db_column_text(&q, 0)); | |
| 316 | 316 | } |
| 317 | 317 | } |
| 318 | 318 | } |
| 319 | 319 | db_finalize(&q); |
| 320 | 320 | } |
| @@ -395,26 +395,31 @@ | ||
| 395 | 395 | blob_add_cr(&text); |
| 396 | 396 | #endif |
| 397 | 397 | blob_write_to_file(&text, zFile); |
| 398 | 398 | if( zEditor ){ |
| 399 | 399 | zCmd = mprintf("%s \"%s\"", zEditor, zFile); |
| 400 | - printf("%s\n", zCmd); | |
| 400 | + fossil_print("%s\n", zCmd); | |
| 401 | 401 | if( fossil_system(zCmd) ){ |
| 402 | 402 | fossil_panic("editor aborted"); |
| 403 | 403 | } |
| 404 | 404 | blob_reset(&text); |
| 405 | 405 | blob_read_from_file(&text, zFile); |
| 406 | 406 | }else{ |
| 407 | 407 | char zIn[300]; |
| 408 | 408 | blob_reset(&text); |
| 409 | 409 | while( fgets(zIn, sizeof(zIn), stdin)!=0 ){ |
| 410 | - if( zIn[0]=='.' && (zIn[1]==0 || zIn[1]=='\r' || zIn[1]=='\n') ) break; | |
| 410 | + char *zUtf8 = fossil_mbcs_to_utf8(zIn); | |
| 411 | + if( zUtf8[0]=='.' && (zUtf8[1]==0 || zUtf8[1]=='\r' || zUtf8[1]=='\n') ){ | |
| 412 | + fossil_mbcs_free(zUtf8); | |
| 413 | + break; | |
| 414 | + } | |
| 411 | 415 | blob_append(&text, zIn, -1); |
| 416 | + fossil_mbcs_free(zUtf8); | |
| 412 | 417 | } |
| 413 | 418 | } |
| 414 | 419 | blob_remove_cr(&text); |
| 415 | - unlink(zFile); | |
| 420 | + file_delete(zFile); | |
| 416 | 421 | free(zFile); |
| 417 | 422 | blob_zero(pComment); |
| 418 | 423 | while( blob_line(&text, &line) ){ |
| 419 | 424 | int i, n; |
| 420 | 425 | char *z; |
| @@ -1084,11 +1089,11 @@ | ||
| 1084 | 1089 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); |
| 1085 | 1090 | manifest_crosslink(nvid, &manifest); |
| 1086 | 1091 | assert( blob_is_reset(&manifest) ); |
| 1087 | 1092 | content_deltify(vid, nvid, 0); |
| 1088 | 1093 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); |
| 1089 | - printf("New_Version: %s\n", zUuid); | |
| 1094 | + fossil_print("New_Version: %s\n", zUuid); | |
| 1090 | 1095 | if( outputManifest ){ |
| 1091 | 1096 | zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot); |
| 1092 | 1097 | blob_zero(&muuid); |
| 1093 | 1098 | blob_appendf(&muuid, "%s\n", zUuid); |
| 1094 | 1099 | blob_write_to_file(&muuid, zManifestFile); |
| @@ -1153,8 +1158,8 @@ | ||
| 1153 | 1158 | |
| 1154 | 1159 | if( !g.markPrivate ){ |
| 1155 | 1160 | autosync(AUTOSYNC_PUSH); |
| 1156 | 1161 | } |
| 1157 | 1162 | if( count_nonbranch_children(vid)>1 ){ |
| 1158 | - printf("**** warning: a fork has occurred *****\n"); | |
| 1163 | + fossil_print("**** warning: a fork has occurred *****\n"); | |
| 1159 | 1164 | } |
| 1160 | 1165 | } |
| 1161 | 1166 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -54,11 +54,11 @@ | |
| 54 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 55 | blob_append(report, zPrefix, nPrefix); |
| 56 | if( isDeleted ){ |
| 57 | blob_appendf(report, "DELETED %s\n", zPathname); |
| 58 | }else if( !file_isfile(zFullName) ){ |
| 59 | if( access(zFullName, 0)==0 ){ |
| 60 | blob_appendf(report, "NOT_A_FILE %s\n", zPathname); |
| 61 | if( missingIsFatal ){ |
| 62 | fossil_warning("not a file: %s", zPathname); |
| 63 | nErr++; |
| 64 | } |
| @@ -136,13 +136,13 @@ | |
| 136 | */ |
| 137 | void status_cmd(void){ |
| 138 | int vid; |
| 139 | db_must_be_within_tree(); |
| 140 | /* 012345678901234 */ |
| 141 | printf("repository: %s\n", db_lget("repository","")); |
| 142 | printf("local-root: %s\n", g.zLocalRoot); |
| 143 | printf("server-code: %s\n", db_get("server-code", "")); |
| 144 | vid = db_lget_int("checkout", 0); |
| 145 | if( vid ){ |
| 146 | show_common_info(vid, "checkout:", 1, 1); |
| 147 | } |
| 148 | changes_cmd(); |
| @@ -176,27 +176,27 @@ | |
| 176 | int isNew = db_column_int(&q,2)==0; |
| 177 | int chnged = db_column_int(&q,3); |
| 178 | int renamed = db_column_int(&q,4); |
| 179 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 180 | if( isBrief ){ |
| 181 | printf("%s\n", zPathname); |
| 182 | }else if( isNew ){ |
| 183 | printf("ADDED %s\n", zPathname); |
| 184 | }else if( isDeleted ){ |
| 185 | printf("DELETED %s\n", zPathname); |
| 186 | }else if( !file_isfile(zFullName) ){ |
| 187 | if( access(zFullName, 0)==0 ){ |
| 188 | printf("NOT_A_FILE %s\n", zPathname); |
| 189 | }else{ |
| 190 | printf("MISSING %s\n", zPathname); |
| 191 | } |
| 192 | }else if( chnged ){ |
| 193 | printf("EDITED %s\n", zPathname); |
| 194 | }else if( renamed ){ |
| 195 | printf("RENAMED %s\n", zPathname); |
| 196 | }else{ |
| 197 | printf("UNCHANGED %s\n", zPathname); |
| 198 | } |
| 199 | free(zFullName); |
| 200 | } |
| 201 | db_finalize(&q); |
| 202 | } |
| @@ -244,11 +244,11 @@ | |
| 244 | ); |
| 245 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 246 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 247 | } |
| 248 | while( db_step(&q)==SQLITE_ROW ){ |
| 249 | printf("%s\n", db_column_text(&q, 0)); |
| 250 | } |
| 251 | db_finalize(&q); |
| 252 | } |
| 253 | |
| 254 | /* |
| @@ -302,19 +302,19 @@ | |
| 302 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 303 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 304 | } |
| 305 | while( db_step(&q)==SQLITE_ROW ){ |
| 306 | if( allFlag ){ |
| 307 | unlink(db_column_text(&q, 0)); |
| 308 | }else{ |
| 309 | Blob ans; |
| 310 | char *prompt = mprintf("remove unmanaged file \"%s\" (y/N)? ", |
| 311 | db_column_text(&q, 0)); |
| 312 | blob_zero(&ans); |
| 313 | prompt_user(prompt, &ans); |
| 314 | if( blob_str(&ans)[0]=='y' ){ |
| 315 | unlink(db_column_text(&q, 0)); |
| 316 | } |
| 317 | } |
| 318 | } |
| 319 | db_finalize(&q); |
| 320 | } |
| @@ -395,26 +395,31 @@ | |
| 395 | blob_add_cr(&text); |
| 396 | #endif |
| 397 | blob_write_to_file(&text, zFile); |
| 398 | if( zEditor ){ |
| 399 | zCmd = mprintf("%s \"%s\"", zEditor, zFile); |
| 400 | printf("%s\n", zCmd); |
| 401 | if( fossil_system(zCmd) ){ |
| 402 | fossil_panic("editor aborted"); |
| 403 | } |
| 404 | blob_reset(&text); |
| 405 | blob_read_from_file(&text, zFile); |
| 406 | }else{ |
| 407 | char zIn[300]; |
| 408 | blob_reset(&text); |
| 409 | while( fgets(zIn, sizeof(zIn), stdin)!=0 ){ |
| 410 | if( zIn[0]=='.' && (zIn[1]==0 || zIn[1]=='\r' || zIn[1]=='\n') ) break; |
| 411 | blob_append(&text, zIn, -1); |
| 412 | } |
| 413 | } |
| 414 | blob_remove_cr(&text); |
| 415 | unlink(zFile); |
| 416 | free(zFile); |
| 417 | blob_zero(pComment); |
| 418 | while( blob_line(&text, &line) ){ |
| 419 | int i, n; |
| 420 | char *z; |
| @@ -1084,11 +1089,11 @@ | |
| 1084 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); |
| 1085 | manifest_crosslink(nvid, &manifest); |
| 1086 | assert( blob_is_reset(&manifest) ); |
| 1087 | content_deltify(vid, nvid, 0); |
| 1088 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); |
| 1089 | printf("New_Version: %s\n", zUuid); |
| 1090 | if( outputManifest ){ |
| 1091 | zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot); |
| 1092 | blob_zero(&muuid); |
| 1093 | blob_appendf(&muuid, "%s\n", zUuid); |
| 1094 | blob_write_to_file(&muuid, zManifestFile); |
| @@ -1153,8 +1158,8 @@ | |
| 1153 | |
| 1154 | if( !g.markPrivate ){ |
| 1155 | autosync(AUTOSYNC_PUSH); |
| 1156 | } |
| 1157 | if( count_nonbranch_children(vid)>1 ){ |
| 1158 | printf("**** warning: a fork has occurred *****\n"); |
| 1159 | } |
| 1160 | } |
| 1161 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -54,11 +54,11 @@ | |
| 54 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 55 | blob_append(report, zPrefix, nPrefix); |
| 56 | if( isDeleted ){ |
| 57 | blob_appendf(report, "DELETED %s\n", zPathname); |
| 58 | }else if( !file_isfile(zFullName) ){ |
| 59 | if( file_access(zFullName, 0)==0 ){ |
| 60 | blob_appendf(report, "NOT_A_FILE %s\n", zPathname); |
| 61 | if( missingIsFatal ){ |
| 62 | fossil_warning("not a file: %s", zPathname); |
| 63 | nErr++; |
| 64 | } |
| @@ -136,13 +136,13 @@ | |
| 136 | */ |
| 137 | void status_cmd(void){ |
| 138 | int vid; |
| 139 | db_must_be_within_tree(); |
| 140 | /* 012345678901234 */ |
| 141 | fossil_print("repository: %s\n", db_lget("repository","")); |
| 142 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| 143 | fossil_print("server-code: %s\n", db_get("server-code", "")); |
| 144 | vid = db_lget_int("checkout", 0); |
| 145 | if( vid ){ |
| 146 | show_common_info(vid, "checkout:", 1, 1); |
| 147 | } |
| 148 | changes_cmd(); |
| @@ -176,27 +176,27 @@ | |
| 176 | int isNew = db_column_int(&q,2)==0; |
| 177 | int chnged = db_column_int(&q,3); |
| 178 | int renamed = db_column_int(&q,4); |
| 179 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 180 | if( isBrief ){ |
| 181 | fossil_print("%s\n", zPathname); |
| 182 | }else if( isNew ){ |
| 183 | fossil_print("ADDED %s\n", zPathname); |
| 184 | }else if( isDeleted ){ |
| 185 | fossil_print("DELETED %s\n", zPathname); |
| 186 | }else if( !file_isfile(zFullName) ){ |
| 187 | if( file_access(zFullName, 0)==0 ){ |
| 188 | fossil_print("NOT_A_FILE %s\n", zPathname); |
| 189 | }else{ |
| 190 | fossil_print("MISSING %s\n", zPathname); |
| 191 | } |
| 192 | }else if( chnged ){ |
| 193 | fossil_print("EDITED %s\n", zPathname); |
| 194 | }else if( renamed ){ |
| 195 | fossil_print("RENAMED %s\n", zPathname); |
| 196 | }else{ |
| 197 | fossil_print("UNCHANGED %s\n", zPathname); |
| 198 | } |
| 199 | free(zFullName); |
| 200 | } |
| 201 | db_finalize(&q); |
| 202 | } |
| @@ -244,11 +244,11 @@ | |
| 244 | ); |
| 245 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 246 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 247 | } |
| 248 | while( db_step(&q)==SQLITE_ROW ){ |
| 249 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 250 | } |
| 251 | db_finalize(&q); |
| 252 | } |
| 253 | |
| 254 | /* |
| @@ -302,19 +302,19 @@ | |
| 302 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 303 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 304 | } |
| 305 | while( db_step(&q)==SQLITE_ROW ){ |
| 306 | if( allFlag ){ |
| 307 | file_delete(db_column_text(&q, 0)); |
| 308 | }else{ |
| 309 | Blob ans; |
| 310 | char *prompt = mprintf("remove unmanaged file \"%s\" (y/N)? ", |
| 311 | db_column_text(&q, 0)); |
| 312 | blob_zero(&ans); |
| 313 | prompt_user(prompt, &ans); |
| 314 | if( blob_str(&ans)[0]=='y' ){ |
| 315 | file_delete(db_column_text(&q, 0)); |
| 316 | } |
| 317 | } |
| 318 | } |
| 319 | db_finalize(&q); |
| 320 | } |
| @@ -395,26 +395,31 @@ | |
| 395 | blob_add_cr(&text); |
| 396 | #endif |
| 397 | blob_write_to_file(&text, zFile); |
| 398 | if( zEditor ){ |
| 399 | zCmd = mprintf("%s \"%s\"", zEditor, zFile); |
| 400 | fossil_print("%s\n", zCmd); |
| 401 | if( fossil_system(zCmd) ){ |
| 402 | fossil_panic("editor aborted"); |
| 403 | } |
| 404 | blob_reset(&text); |
| 405 | blob_read_from_file(&text, zFile); |
| 406 | }else{ |
| 407 | char zIn[300]; |
| 408 | blob_reset(&text); |
| 409 | while( fgets(zIn, sizeof(zIn), stdin)!=0 ){ |
| 410 | char *zUtf8 = fossil_mbcs_to_utf8(zIn); |
| 411 | if( zUtf8[0]=='.' && (zUtf8[1]==0 || zUtf8[1]=='\r' || zUtf8[1]=='\n') ){ |
| 412 | fossil_mbcs_free(zUtf8); |
| 413 | break; |
| 414 | } |
| 415 | blob_append(&text, zIn, -1); |
| 416 | fossil_mbcs_free(zUtf8); |
| 417 | } |
| 418 | } |
| 419 | blob_remove_cr(&text); |
| 420 | file_delete(zFile); |
| 421 | free(zFile); |
| 422 | blob_zero(pComment); |
| 423 | while( blob_line(&text, &line) ){ |
| 424 | int i, n; |
| 425 | char *z; |
| @@ -1084,11 +1089,11 @@ | |
| 1089 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); |
| 1090 | manifest_crosslink(nvid, &manifest); |
| 1091 | assert( blob_is_reset(&manifest) ); |
| 1092 | content_deltify(vid, nvid, 0); |
| 1093 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); |
| 1094 | fossil_print("New_Version: %s\n", zUuid); |
| 1095 | if( outputManifest ){ |
| 1096 | zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot); |
| 1097 | blob_zero(&muuid); |
| 1098 | blob_appendf(&muuid, "%s\n", zUuid); |
| 1099 | blob_write_to_file(&muuid, zManifestFile); |
| @@ -1153,8 +1158,8 @@ | |
| 1158 | |
| 1159 | if( !g.markPrivate ){ |
| 1160 | autosync(AUTOSYNC_PUSH); |
| 1161 | } |
| 1162 | if( count_nonbranch_children(vid)>1 ){ |
| 1163 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1164 | } |
| 1165 | } |
| 1166 |
+6
-6
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -60,11 +60,11 @@ | ||
| 60 | 60 | int load_vfile(const char *zName){ |
| 61 | 61 | Blob uuid; |
| 62 | 62 | int vid; |
| 63 | 63 | |
| 64 | 64 | blob_init(&uuid, zName, -1); |
| 65 | - if( name_to_uuid(&uuid, 1) ){ | |
| 65 | + if( name_to_uuid(&uuid, 1, "ci") ){ | |
| 66 | 66 | fossil_panic(g.zErrMsg); |
| 67 | 67 | } |
| 68 | 68 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 69 | 69 | if( vid==0 ){ |
| 70 | 70 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| @@ -157,16 +157,16 @@ | ||
| 157 | 157 | free(zManFile); |
| 158 | 158 | blob_reset(&hash); |
| 159 | 159 | }else{ |
| 160 | 160 | if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){ |
| 161 | 161 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 162 | - unlink(zManFile); | |
| 162 | + file_delete(zManFile); | |
| 163 | 163 | free(zManFile); |
| 164 | 164 | } |
| 165 | 165 | if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){ |
| 166 | 166 | zManFile = mprintf("%smanifest.uuid", g.zLocalRoot); |
| 167 | - unlink(zManFile); | |
| 167 | + file_delete(zManFile); | |
| 168 | 168 | free(zManFile); |
| 169 | 169 | } |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | } |
| @@ -249,14 +249,14 @@ | ||
| 249 | 249 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | 250 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | 251 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 | 252 | vfile_aggregate_checksum_disk(vid, &cksum2); |
| 253 | 253 | if( blob_compare(&cksum1, &cksum2) ){ |
| 254 | - printf("WARNING: manifest checksum does not agree with disk\n"); | |
| 254 | + fossil_print("WARNING: manifest checksum does not agree with disk\n"); | |
| 255 | 255 | } |
| 256 | 256 | if( blob_size(&cksum1b) && blob_compare(&cksum1, &cksum1b) ){ |
| 257 | - printf("WARNING: manifest checksum does not agree with manifest\n"); | |
| 257 | + fossil_print("WARNING: manifest checksum does not agree with manifest\n"); | |
| 258 | 258 | } |
| 259 | 259 | } |
| 260 | 260 | db_end_transaction(0); |
| 261 | 261 | } |
| 262 | 262 | |
| @@ -268,11 +268,11 @@ | ||
| 268 | 268 | int i; |
| 269 | 269 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 270 | 270 | if( manifestOnly==0 || zReserved[0]=='m' ){ |
| 271 | 271 | char *z; |
| 272 | 272 | z = mprintf("%s%s", g.zLocalRoot, zReserved); |
| 273 | - unlink(z); | |
| 273 | + file_delete(z); | |
| 274 | 274 | free(z); |
| 275 | 275 | } |
| 276 | 276 | } |
| 277 | 277 | } |
| 278 | 278 | |
| 279 | 279 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | int load_vfile(const char *zName){ |
| 61 | Blob uuid; |
| 62 | int vid; |
| 63 | |
| 64 | blob_init(&uuid, zName, -1); |
| 65 | if( name_to_uuid(&uuid, 1) ){ |
| 66 | fossil_panic(g.zErrMsg); |
| 67 | } |
| 68 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 69 | if( vid==0 ){ |
| 70 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| @@ -157,16 +157,16 @@ | |
| 157 | free(zManFile); |
| 158 | blob_reset(&hash); |
| 159 | }else{ |
| 160 | if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){ |
| 161 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 162 | unlink(zManFile); |
| 163 | free(zManFile); |
| 164 | } |
| 165 | if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){ |
| 166 | zManFile = mprintf("%smanifest.uuid", g.zLocalRoot); |
| 167 | unlink(zManFile); |
| 168 | free(zManFile); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | } |
| @@ -249,14 +249,14 @@ | |
| 249 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 | vfile_aggregate_checksum_disk(vid, &cksum2); |
| 253 | if( blob_compare(&cksum1, &cksum2) ){ |
| 254 | printf("WARNING: manifest checksum does not agree with disk\n"); |
| 255 | } |
| 256 | if( blob_size(&cksum1b) && blob_compare(&cksum1, &cksum1b) ){ |
| 257 | printf("WARNING: manifest checksum does not agree with manifest\n"); |
| 258 | } |
| 259 | } |
| 260 | db_end_transaction(0); |
| 261 | } |
| 262 | |
| @@ -268,11 +268,11 @@ | |
| 268 | int i; |
| 269 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 270 | if( manifestOnly==0 || zReserved[0]=='m' ){ |
| 271 | char *z; |
| 272 | z = mprintf("%s%s", g.zLocalRoot, zReserved); |
| 273 | unlink(z); |
| 274 | free(z); |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | |
| 279 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | int load_vfile(const char *zName){ |
| 61 | Blob uuid; |
| 62 | int vid; |
| 63 | |
| 64 | blob_init(&uuid, zName, -1); |
| 65 | if( name_to_uuid(&uuid, 1, "ci") ){ |
| 66 | fossil_panic(g.zErrMsg); |
| 67 | } |
| 68 | vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 69 | if( vid==0 ){ |
| 70 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| @@ -157,16 +157,16 @@ | |
| 157 | free(zManFile); |
| 158 | blob_reset(&hash); |
| 159 | }else{ |
| 160 | if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){ |
| 161 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 162 | file_delete(zManFile); |
| 163 | free(zManFile); |
| 164 | } |
| 165 | if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){ |
| 166 | zManFile = mprintf("%smanifest.uuid", g.zLocalRoot); |
| 167 | file_delete(zManFile); |
| 168 | free(zManFile); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | } |
| @@ -249,14 +249,14 @@ | |
| 249 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 | vfile_aggregate_checksum_disk(vid, &cksum2); |
| 253 | if( blob_compare(&cksum1, &cksum2) ){ |
| 254 | fossil_print("WARNING: manifest checksum does not agree with disk\n"); |
| 255 | } |
| 256 | if( blob_size(&cksum1b) && blob_compare(&cksum1, &cksum1b) ){ |
| 257 | fossil_print("WARNING: manifest checksum does not agree with manifest\n"); |
| 258 | } |
| 259 | } |
| 260 | db_end_transaction(0); |
| 261 | } |
| 262 | |
| @@ -268,11 +268,11 @@ | |
| 268 | int i; |
| 269 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 270 | if( manifestOnly==0 || zReserved[0]=='m' ){ |
| 271 | char *z; |
| 272 | z = mprintf("%s%s", g.zLocalRoot, zReserved); |
| 273 | file_delete(z); |
| 274 | free(z); |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | |
| 279 |
+2
-2
| --- src/clearsign.c | ||
| +++ src/clearsign.c | ||
| @@ -52,11 +52,11 @@ | ||
| 52 | 52 | }else{ |
| 53 | 53 | if( pOut!=pIn ){ |
| 54 | 54 | blob_copy(pOut, pIn); |
| 55 | 55 | } |
| 56 | 56 | } |
| 57 | - unlink(zOut); | |
| 58 | - unlink(zIn); | |
| 57 | + file_delete(zOut); | |
| 58 | + file_delete(zIn); | |
| 59 | 59 | free(zOut); |
| 60 | 60 | free(zIn); |
| 61 | 61 | return rc; |
| 62 | 62 | } |
| 63 | 63 |
| --- src/clearsign.c | |
| +++ src/clearsign.c | |
| @@ -52,11 +52,11 @@ | |
| 52 | }else{ |
| 53 | if( pOut!=pIn ){ |
| 54 | blob_copy(pOut, pIn); |
| 55 | } |
| 56 | } |
| 57 | unlink(zOut); |
| 58 | unlink(zIn); |
| 59 | free(zOut); |
| 60 | free(zIn); |
| 61 | return rc; |
| 62 | } |
| 63 |
| --- src/clearsign.c | |
| +++ src/clearsign.c | |
| @@ -52,11 +52,11 @@ | |
| 52 | }else{ |
| 53 | if( pOut!=pIn ){ |
| 54 | blob_copy(pOut, pIn); |
| 55 | } |
| 56 | } |
| 57 | file_delete(zOut); |
| 58 | file_delete(zIn); |
| 59 | free(zOut); |
| 60 | free(zIn); |
| 61 | return rc; |
| 62 | } |
| 63 |
+6
-6
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -80,11 +80,11 @@ | ||
| 80 | 80 | shun_artifacts(); |
| 81 | 81 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 82 | 82 | if( g.zLogin==0 ){ |
| 83 | 83 | db_create_default_users(1,zDefaultUser); |
| 84 | 84 | } |
| 85 | - printf("Repository cloned into %s\n", g.argv[3]); | |
| 85 | + fossil_print("Repository cloned into %s\n", g.argv[3]); | |
| 86 | 86 | }else{ |
| 87 | 87 | db_create_repository(g.argv[3]); |
| 88 | 88 | db_open_repository(g.argv[3]); |
| 89 | 89 | db_begin_transaction(); |
| 90 | 90 | db_record_repository_filename(g.argv[3]); |
| @@ -104,19 +104,19 @@ | ||
| 104 | 104 | g.xlinkClusterOnly = 0; |
| 105 | 105 | verify_cancel(); |
| 106 | 106 | db_end_transaction(0); |
| 107 | 107 | db_close(1); |
| 108 | 108 | if( nErr ){ |
| 109 | - unlink(g.argv[3]); | |
| 109 | + file_delete(g.argv[3]); | |
| 110 | 110 | fossil_fatal("server returned an error - clone aborted"); |
| 111 | 111 | } |
| 112 | 112 | db_open_repository(g.argv[3]); |
| 113 | 113 | } |
| 114 | 114 | db_begin_transaction(); |
| 115 | - printf("Rebuilding repository meta-data...\n"); | |
| 115 | + fossil_print("Rebuilding repository meta-data...\n"); | |
| 116 | 116 | rebuild_db(0, 1, 0); |
| 117 | - printf("project-id: %s\n", db_get("project-code", 0)); | |
| 118 | - printf("server-id: %s\n", db_get("server-code", 0)); | |
| 117 | + fossil_print("project-id: %s\n", db_get("project-code", 0)); | |
| 118 | + fossil_print("server-id: %s\n", db_get("server-code", 0)); | |
| 119 | 119 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 120 | - printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); | |
| 120 | + fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); | |
| 121 | 121 | db_end_transaction(0); |
| 122 | 122 | } |
| 123 | 123 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -80,11 +80,11 @@ | |
| 80 | shun_artifacts(); |
| 81 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 82 | if( g.zLogin==0 ){ |
| 83 | db_create_default_users(1,zDefaultUser); |
| 84 | } |
| 85 | printf("Repository cloned into %s\n", g.argv[3]); |
| 86 | }else{ |
| 87 | db_create_repository(g.argv[3]); |
| 88 | db_open_repository(g.argv[3]); |
| 89 | db_begin_transaction(); |
| 90 | db_record_repository_filename(g.argv[3]); |
| @@ -104,19 +104,19 @@ | |
| 104 | g.xlinkClusterOnly = 0; |
| 105 | verify_cancel(); |
| 106 | db_end_transaction(0); |
| 107 | db_close(1); |
| 108 | if( nErr ){ |
| 109 | unlink(g.argv[3]); |
| 110 | fossil_fatal("server returned an error - clone aborted"); |
| 111 | } |
| 112 | db_open_repository(g.argv[3]); |
| 113 | } |
| 114 | db_begin_transaction(); |
| 115 | printf("Rebuilding repository meta-data...\n"); |
| 116 | rebuild_db(0, 1, 0); |
| 117 | printf("project-id: %s\n", db_get("project-code", 0)); |
| 118 | printf("server-id: %s\n", db_get("server-code", 0)); |
| 119 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 120 | printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 121 | db_end_transaction(0); |
| 122 | } |
| 123 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -80,11 +80,11 @@ | |
| 80 | shun_artifacts(); |
| 81 | g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); |
| 82 | if( g.zLogin==0 ){ |
| 83 | db_create_default_users(1,zDefaultUser); |
| 84 | } |
| 85 | fossil_print("Repository cloned into %s\n", g.argv[3]); |
| 86 | }else{ |
| 87 | db_create_repository(g.argv[3]); |
| 88 | db_open_repository(g.argv[3]); |
| 89 | db_begin_transaction(); |
| 90 | db_record_repository_filename(g.argv[3]); |
| @@ -104,19 +104,19 @@ | |
| 104 | g.xlinkClusterOnly = 0; |
| 105 | verify_cancel(); |
| 106 | db_end_transaction(0); |
| 107 | db_close(1); |
| 108 | if( nErr ){ |
| 109 | file_delete(g.argv[3]); |
| 110 | fossil_fatal("server returned an error - clone aborted"); |
| 111 | } |
| 112 | db_open_repository(g.argv[3]); |
| 113 | } |
| 114 | db_begin_transaction(); |
| 115 | fossil_print("Rebuilding repository meta-data...\n"); |
| 116 | rebuild_db(0, 1, 0); |
| 117 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 118 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 119 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 120 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 121 | db_end_transaction(0); |
| 122 | } |
| 123 |
+6
-6
| --- src/comformat.c | ||
| +++ src/comformat.c | ||
| @@ -41,11 +41,11 @@ | ||
| 41 | 41 | |
| 42 | 42 | for(;;){ |
| 43 | 43 | while( fossil_isspace(zText[0]) ){ zText++; } |
| 44 | 44 | if( zText[0]==0 ){ |
| 45 | 45 | if( doIndent==0 ){ |
| 46 | - printf("\n"); | |
| 46 | + fossil_print("\n"); | |
| 47 | 47 | lineCnt = 1; |
| 48 | 48 | } |
| 49 | 49 | return lineCnt; |
| 50 | 50 | } |
| 51 | 51 | for(sk=si=i=k=0; zText[i] && k<tlen; i++){ |
| @@ -64,23 +64,23 @@ | ||
| 64 | 64 | } |
| 65 | 65 | k++; |
| 66 | 66 | } |
| 67 | 67 | } |
| 68 | 68 | if( doIndent ){ |
| 69 | - printf("%*s", indent, ""); | |
| 69 | + fossil_print("%*s", indent, ""); | |
| 70 | 70 | } |
| 71 | 71 | doIndent = 1; |
| 72 | 72 | if( sk>0 && zText[i] ){ |
| 73 | 73 | zText += si; |
| 74 | 74 | zBuf[sk++] = '\n'; |
| 75 | 75 | zBuf[sk] = 0; |
| 76 | - printf("%s", zBuf); | |
| 76 | + fossil_print("%s", zBuf); | |
| 77 | 77 | }else{ |
| 78 | 78 | zText += i; |
| 79 | 79 | zBuf[k++] = '\n'; |
| 80 | 80 | zBuf[k] = 0; |
| 81 | - printf("%s", zBuf); | |
| 81 | + fossil_print("%s", zBuf); | |
| 82 | 82 | } |
| 83 | 83 | lineCnt++; |
| 84 | 84 | } |
| 85 | 85 | } |
| 86 | 86 | |
| @@ -93,8 +93,8 @@ | ||
| 93 | 93 | int indent; |
| 94 | 94 | if( g.argc!=4 ){ |
| 95 | 95 | usage("PREFIX TEXT"); |
| 96 | 96 | } |
| 97 | 97 | indent = strlen(g.argv[2]) + 1; |
| 98 | - printf("%s ", g.argv[2]); | |
| 99 | - printf("(%d lines output)\n", comment_print(g.argv[3], indent, 79)); | |
| 98 | + fossil_print("%s ", g.argv[2]); | |
| 99 | + fossil_print("(%d lines output)\n", comment_print(g.argv[3], indent, 79)); | |
| 100 | 100 | } |
| 101 | 101 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -41,11 +41,11 @@ | |
| 41 | |
| 42 | for(;;){ |
| 43 | while( fossil_isspace(zText[0]) ){ zText++; } |
| 44 | if( zText[0]==0 ){ |
| 45 | if( doIndent==0 ){ |
| 46 | printf("\n"); |
| 47 | lineCnt = 1; |
| 48 | } |
| 49 | return lineCnt; |
| 50 | } |
| 51 | for(sk=si=i=k=0; zText[i] && k<tlen; i++){ |
| @@ -64,23 +64,23 @@ | |
| 64 | } |
| 65 | k++; |
| 66 | } |
| 67 | } |
| 68 | if( doIndent ){ |
| 69 | printf("%*s", indent, ""); |
| 70 | } |
| 71 | doIndent = 1; |
| 72 | if( sk>0 && zText[i] ){ |
| 73 | zText += si; |
| 74 | zBuf[sk++] = '\n'; |
| 75 | zBuf[sk] = 0; |
| 76 | printf("%s", zBuf); |
| 77 | }else{ |
| 78 | zText += i; |
| 79 | zBuf[k++] = '\n'; |
| 80 | zBuf[k] = 0; |
| 81 | printf("%s", zBuf); |
| 82 | } |
| 83 | lineCnt++; |
| 84 | } |
| 85 | } |
| 86 | |
| @@ -93,8 +93,8 @@ | |
| 93 | int indent; |
| 94 | if( g.argc!=4 ){ |
| 95 | usage("PREFIX TEXT"); |
| 96 | } |
| 97 | indent = strlen(g.argv[2]) + 1; |
| 98 | printf("%s ", g.argv[2]); |
| 99 | printf("(%d lines output)\n", comment_print(g.argv[3], indent, 79)); |
| 100 | } |
| 101 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -41,11 +41,11 @@ | |
| 41 | |
| 42 | for(;;){ |
| 43 | while( fossil_isspace(zText[0]) ){ zText++; } |
| 44 | if( zText[0]==0 ){ |
| 45 | if( doIndent==0 ){ |
| 46 | fossil_print("\n"); |
| 47 | lineCnt = 1; |
| 48 | } |
| 49 | return lineCnt; |
| 50 | } |
| 51 | for(sk=si=i=k=0; zText[i] && k<tlen; i++){ |
| @@ -64,23 +64,23 @@ | |
| 64 | } |
| 65 | k++; |
| 66 | } |
| 67 | } |
| 68 | if( doIndent ){ |
| 69 | fossil_print("%*s", indent, ""); |
| 70 | } |
| 71 | doIndent = 1; |
| 72 | if( sk>0 && zText[i] ){ |
| 73 | zText += si; |
| 74 | zBuf[sk++] = '\n'; |
| 75 | zBuf[sk] = 0; |
| 76 | fossil_print("%s", zBuf); |
| 77 | }else{ |
| 78 | zText += i; |
| 79 | zBuf[k++] = '\n'; |
| 80 | zBuf[k] = 0; |
| 81 | fossil_print("%s", zBuf); |
| 82 | } |
| 83 | lineCnt++; |
| 84 | } |
| 85 | } |
| 86 | |
| @@ -93,8 +93,8 @@ | |
| 93 | int indent; |
| 94 | if( g.argc!=4 ){ |
| 95 | usage("PREFIX TEXT"); |
| 96 | } |
| 97 | indent = strlen(g.argv[2]) + 1; |
| 98 | fossil_print("%s ", g.argv[2]); |
| 99 | fossil_print("(%d lines output)\n", comment_print(g.argv[3], indent, 79)); |
| 100 | } |
| 101 |
+7
| --- src/config.h | ||
| +++ src/config.h | ||
| @@ -82,10 +82,17 @@ | ||
| 82 | 82 | |
| 83 | 83 | #ifndef _RC_COMPILE_ |
| 84 | 84 | |
| 85 | 85 | #include "sqlite3.h" |
| 86 | 86 | |
| 87 | +/* | |
| 88 | +** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. | |
| 89 | +*/ | |
| 90 | +#if defined(__sun__) || defined(sun) | |
| 91 | + #define getpass getpassphrase | |
| 92 | +#endif | |
| 93 | + | |
| 87 | 94 | /* |
| 88 | 95 | ** Typedef for a 64-bit integer |
| 89 | 96 | */ |
| 90 | 97 | typedef sqlite3_int64 i64; |
| 91 | 98 | typedef sqlite3_uint64 u64; |
| 92 | 99 |
| --- src/config.h | |
| +++ src/config.h | |
| @@ -82,10 +82,17 @@ | |
| 82 | |
| 83 | #ifndef _RC_COMPILE_ |
| 84 | |
| 85 | #include "sqlite3.h" |
| 86 | |
| 87 | /* |
| 88 | ** Typedef for a 64-bit integer |
| 89 | */ |
| 90 | typedef sqlite3_int64 i64; |
| 91 | typedef sqlite3_uint64 u64; |
| 92 |
| --- src/config.h | |
| +++ src/config.h | |
| @@ -82,10 +82,17 @@ | |
| 82 | |
| 83 | #ifndef _RC_COMPILE_ |
| 84 | |
| 85 | #include "sqlite3.h" |
| 86 | |
| 87 | /* |
| 88 | ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. |
| 89 | */ |
| 90 | #if defined(__sun__) || defined(sun) |
| 91 | #define getpass getpassphrase |
| 92 | #endif |
| 93 | |
| 94 | /* |
| 95 | ** Typedef for a 64-bit integer |
| 96 | */ |
| 97 | typedef sqlite3_int64 i64; |
| 98 | typedef sqlite3_uint64 u64; |
| 99 |
+5
-5
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -506,11 +506,11 @@ | ||
| 506 | 506 | } |
| 507 | 507 | blob_reset(&sql); |
| 508 | 508 | }else{ |
| 509 | 509 | /* Otherwise, the old format */ |
| 510 | 510 | if( (configure_is_exportable(zName) & groupMask)==0 ) return; |
| 511 | - if( strcmp(zName, "logo-image")==0 ){ | |
| 511 | + if( fossil_strcmp(zName, "logo-image")==0 ){ | |
| 512 | 512 | Stmt ins; |
| 513 | 513 | db_prepare(&ins, |
| 514 | 514 | "REPLACE INTO config(name, value, mtime) VALUES(:name, :value, now())" |
| 515 | 515 | ); |
| 516 | 516 | db_bind_text(&ins, ":name", zName); |
| @@ -688,13 +688,13 @@ | ||
| 688 | 688 | if( strncmp(z, &aGroupName[i].zName[1], n)==0 ){ |
| 689 | 689 | return aGroupName[i].groupMask; |
| 690 | 690 | } |
| 691 | 691 | } |
| 692 | 692 | if( notFoundIsFatal ){ |
| 693 | - printf("Available configuration areas:\n"); | |
| 693 | + fossil_print("Available configuration areas:\n"); | |
| 694 | 694 | for(i=0; i<count(aGroupName); i++){ |
| 695 | - printf(" %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp); | |
| 695 | + fossil_print(" %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp); | |
| 696 | 696 | } |
| 697 | 697 | fossil_fatal("no such configuration area: \"%s\"", z); |
| 698 | 698 | } |
| 699 | 699 | return 0; |
| 700 | 700 | } |
| @@ -883,14 +883,14 @@ | ||
| 883 | 883 | }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ |
| 884 | 884 | db_multi_exec("DELETE FROM reportfmt"); |
| 885 | 885 | } |
| 886 | 886 | } |
| 887 | 887 | db_end_transaction(0); |
| 888 | - printf("Configuration reset to factory defaults.\n"); | |
| 889 | - printf("To recover, use: %s %s import %s\n", | |
| 888 | + fossil_print("Configuration reset to factory defaults.\n"); | |
| 889 | + fossil_print("To recover, use: %s %s import %s\n", | |
| 890 | 890 | fossil_nameofexe(), g.argv[1], zBackup); |
| 891 | 891 | }else |
| 892 | 892 | { |
| 893 | 893 | fossil_fatal("METHOD should be one of:" |
| 894 | 894 | " export import merge pull push reset"); |
| 895 | 895 | } |
| 896 | 896 | } |
| 897 | 897 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -506,11 +506,11 @@ | |
| 506 | } |
| 507 | blob_reset(&sql); |
| 508 | }else{ |
| 509 | /* Otherwise, the old format */ |
| 510 | if( (configure_is_exportable(zName) & groupMask)==0 ) return; |
| 511 | if( strcmp(zName, "logo-image")==0 ){ |
| 512 | Stmt ins; |
| 513 | db_prepare(&ins, |
| 514 | "REPLACE INTO config(name, value, mtime) VALUES(:name, :value, now())" |
| 515 | ); |
| 516 | db_bind_text(&ins, ":name", zName); |
| @@ -688,13 +688,13 @@ | |
| 688 | if( strncmp(z, &aGroupName[i].zName[1], n)==0 ){ |
| 689 | return aGroupName[i].groupMask; |
| 690 | } |
| 691 | } |
| 692 | if( notFoundIsFatal ){ |
| 693 | printf("Available configuration areas:\n"); |
| 694 | for(i=0; i<count(aGroupName); i++){ |
| 695 | printf(" %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp); |
| 696 | } |
| 697 | fossil_fatal("no such configuration area: \"%s\"", z); |
| 698 | } |
| 699 | return 0; |
| 700 | } |
| @@ -883,14 +883,14 @@ | |
| 883 | }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ |
| 884 | db_multi_exec("DELETE FROM reportfmt"); |
| 885 | } |
| 886 | } |
| 887 | db_end_transaction(0); |
| 888 | printf("Configuration reset to factory defaults.\n"); |
| 889 | printf("To recover, use: %s %s import %s\n", |
| 890 | fossil_nameofexe(), g.argv[1], zBackup); |
| 891 | }else |
| 892 | { |
| 893 | fossil_fatal("METHOD should be one of:" |
| 894 | " export import merge pull push reset"); |
| 895 | } |
| 896 | } |
| 897 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -506,11 +506,11 @@ | |
| 506 | } |
| 507 | blob_reset(&sql); |
| 508 | }else{ |
| 509 | /* Otherwise, the old format */ |
| 510 | if( (configure_is_exportable(zName) & groupMask)==0 ) return; |
| 511 | if( fossil_strcmp(zName, "logo-image")==0 ){ |
| 512 | Stmt ins; |
| 513 | db_prepare(&ins, |
| 514 | "REPLACE INTO config(name, value, mtime) VALUES(:name, :value, now())" |
| 515 | ); |
| 516 | db_bind_text(&ins, ":name", zName); |
| @@ -688,13 +688,13 @@ | |
| 688 | if( strncmp(z, &aGroupName[i].zName[1], n)==0 ){ |
| 689 | return aGroupName[i].groupMask; |
| 690 | } |
| 691 | } |
| 692 | if( notFoundIsFatal ){ |
| 693 | fossil_print("Available configuration areas:\n"); |
| 694 | for(i=0; i<count(aGroupName); i++){ |
| 695 | fossil_print(" %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp); |
| 696 | } |
| 697 | fossil_fatal("no such configuration area: \"%s\"", z); |
| 698 | } |
| 699 | return 0; |
| 700 | } |
| @@ -883,14 +883,14 @@ | |
| 883 | }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ |
| 884 | db_multi_exec("DELETE FROM reportfmt"); |
| 885 | } |
| 886 | } |
| 887 | db_end_transaction(0); |
| 888 | fossil_print("Configuration reset to factory defaults.\n"); |
| 889 | fossil_print("To recover, use: %s %s import %s\n", |
| 890 | fossil_nameofexe(), g.argv[1], zBackup); |
| 891 | }else |
| 892 | { |
| 893 | fossil_fatal("METHOD should be one of:" |
| 894 | " export import merge pull push reset"); |
| 895 | } |
| 896 | } |
| 897 |
+5
-5
| --- src/content.c | ||
| +++ src/content.c | ||
| @@ -670,11 +670,11 @@ | ||
| 670 | 670 | if( g.argc!=3 ) usage("FILENAME"); |
| 671 | 671 | db_must_be_within_tree(); |
| 672 | 672 | user_select(); |
| 673 | 673 | blob_read_from_file(&content, g.argv[2]); |
| 674 | 674 | rid = content_put(&content); |
| 675 | - printf("inserted as record %d\n", rid); | |
| 675 | + fossil_print("inserted as record %d\n", rid); | |
| 676 | 676 | } |
| 677 | 677 | |
| 678 | 678 | /* |
| 679 | 679 | ** Make sure the content at rid is the original content and is not a |
| 680 | 680 | ** delta. |
| @@ -838,28 +838,28 @@ | ||
| 838 | 838 | while( db_step(&q)==SQLITE_ROW ){ |
| 839 | 839 | int rid = db_column_int(&q, 0); |
| 840 | 840 | const char *zUuid = db_column_text(&q, 1); |
| 841 | 841 | int size = db_column_int(&q, 2); |
| 842 | 842 | n1++; |
| 843 | - printf(" %d/%d\r", n1, total); | |
| 843 | + fossil_print(" %d/%d\r", n1, total); | |
| 844 | 844 | fflush(stdout); |
| 845 | 845 | if( size<0 ){ |
| 846 | - printf("skip phantom %d %s\n", rid, zUuid); | |
| 846 | + fossil_print("skip phantom %d %s\n", rid, zUuid); | |
| 847 | 847 | continue; /* Ignore phantoms */ |
| 848 | 848 | } |
| 849 | 849 | content_get(rid, &content); |
| 850 | 850 | if( blob_size(&content)!=size ){ |
| 851 | 851 | fossil_warning("size mismatch on blob rid=%d: %d vs %d", |
| 852 | 852 | rid, blob_size(&content), size); |
| 853 | 853 | } |
| 854 | 854 | sha1sum_blob(&content, &cksum); |
| 855 | - if( strcmp(blob_str(&cksum), zUuid)!=0 ){ | |
| 855 | + if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){ | |
| 856 | 856 | fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s", |
| 857 | 857 | rid, blob_str(&cksum), zUuid); |
| 858 | 858 | } |
| 859 | 859 | blob_reset(&cksum); |
| 860 | 860 | blob_reset(&content); |
| 861 | 861 | n2++; |
| 862 | 862 | } |
| 863 | 863 | db_finalize(&q); |
| 864 | - printf("%d non-phantom blobs (out of %d total) verified\n", n2, n1); | |
| 864 | + fossil_print("%d non-phantom blobs (out of %d total) verified\n", n2, n1); | |
| 865 | 865 | } |
| 866 | 866 |
| --- src/content.c | |
| +++ src/content.c | |
| @@ -670,11 +670,11 @@ | |
| 670 | if( g.argc!=3 ) usage("FILENAME"); |
| 671 | db_must_be_within_tree(); |
| 672 | user_select(); |
| 673 | blob_read_from_file(&content, g.argv[2]); |
| 674 | rid = content_put(&content); |
| 675 | printf("inserted as record %d\n", rid); |
| 676 | } |
| 677 | |
| 678 | /* |
| 679 | ** Make sure the content at rid is the original content and is not a |
| 680 | ** delta. |
| @@ -838,28 +838,28 @@ | |
| 838 | while( db_step(&q)==SQLITE_ROW ){ |
| 839 | int rid = db_column_int(&q, 0); |
| 840 | const char *zUuid = db_column_text(&q, 1); |
| 841 | int size = db_column_int(&q, 2); |
| 842 | n1++; |
| 843 | printf(" %d/%d\r", n1, total); |
| 844 | fflush(stdout); |
| 845 | if( size<0 ){ |
| 846 | printf("skip phantom %d %s\n", rid, zUuid); |
| 847 | continue; /* Ignore phantoms */ |
| 848 | } |
| 849 | content_get(rid, &content); |
| 850 | if( blob_size(&content)!=size ){ |
| 851 | fossil_warning("size mismatch on blob rid=%d: %d vs %d", |
| 852 | rid, blob_size(&content), size); |
| 853 | } |
| 854 | sha1sum_blob(&content, &cksum); |
| 855 | if( strcmp(blob_str(&cksum), zUuid)!=0 ){ |
| 856 | fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s", |
| 857 | rid, blob_str(&cksum), zUuid); |
| 858 | } |
| 859 | blob_reset(&cksum); |
| 860 | blob_reset(&content); |
| 861 | n2++; |
| 862 | } |
| 863 | db_finalize(&q); |
| 864 | printf("%d non-phantom blobs (out of %d total) verified\n", n2, n1); |
| 865 | } |
| 866 |
| --- src/content.c | |
| +++ src/content.c | |
| @@ -670,11 +670,11 @@ | |
| 670 | if( g.argc!=3 ) usage("FILENAME"); |
| 671 | db_must_be_within_tree(); |
| 672 | user_select(); |
| 673 | blob_read_from_file(&content, g.argv[2]); |
| 674 | rid = content_put(&content); |
| 675 | fossil_print("inserted as record %d\n", rid); |
| 676 | } |
| 677 | |
| 678 | /* |
| 679 | ** Make sure the content at rid is the original content and is not a |
| 680 | ** delta. |
| @@ -838,28 +838,28 @@ | |
| 838 | while( db_step(&q)==SQLITE_ROW ){ |
| 839 | int rid = db_column_int(&q, 0); |
| 840 | const char *zUuid = db_column_text(&q, 1); |
| 841 | int size = db_column_int(&q, 2); |
| 842 | n1++; |
| 843 | fossil_print(" %d/%d\r", n1, total); |
| 844 | fflush(stdout); |
| 845 | if( size<0 ){ |
| 846 | fossil_print("skip phantom %d %s\n", rid, zUuid); |
| 847 | continue; /* Ignore phantoms */ |
| 848 | } |
| 849 | content_get(rid, &content); |
| 850 | if( blob_size(&content)!=size ){ |
| 851 | fossil_warning("size mismatch on blob rid=%d: %d vs %d", |
| 852 | rid, blob_size(&content), size); |
| 853 | } |
| 854 | sha1sum_blob(&content, &cksum); |
| 855 | if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){ |
| 856 | fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s", |
| 857 | rid, blob_str(&cksum), zUuid); |
| 858 | } |
| 859 | blob_reset(&cksum); |
| 860 | blob_reset(&content); |
| 861 | n2++; |
| 862 | } |
| 863 | db_finalize(&q); |
| 864 | fossil_print("%d non-phantom blobs (out of %d total) verified\n", n2, n1); |
| 865 | } |
| 866 |
M
src/db.c
+17
-20
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -166,11 +166,11 @@ | ||
| 166 | 166 | nBegin = 0; |
| 167 | 167 | } |
| 168 | 168 | busy = 0; |
| 169 | 169 | db_close(0); |
| 170 | 170 | for(i=0; i<nDeleteOnFail; i++){ |
| 171 | - unlink(azDeleteOnFail[i]); | |
| 171 | + file_delete(azDeleteOnFail[i]); | |
| 172 | 172 | } |
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | /* |
| 176 | 176 | ** Install a commit hook. Hooks are installed in sequence order. |
| @@ -615,11 +615,11 @@ | ||
| 615 | 615 | |
| 616 | 616 | /* |
| 617 | 617 | ** Function to return the number of seconds since 1970. This is |
| 618 | 618 | ** the same as strftime('%s','now') but is more compact. |
| 619 | 619 | */ |
| 620 | -static void db_now_function( | |
| 620 | +void db_now_function( | |
| 621 | 621 | sqlite3_context *context, |
| 622 | 622 | int argc, |
| 623 | 623 | sqlite3_value **argv |
| 624 | 624 | ){ |
| 625 | 625 | sqlite3_result_int64(context, time(0)); |
| @@ -695,10 +695,11 @@ | ||
| 695 | 695 | if( zHome==0 ){ |
| 696 | 696 | fossil_fatal("cannot locate home directory - " |
| 697 | 697 | "please set the LOCALAPPDATA or APPDATA or HOMEPATH " |
| 698 | 698 | "environment variables"); |
| 699 | 699 | } |
| 700 | + zHome = fossil_mbcs_to_utf8(zHome); | |
| 700 | 701 | #else |
| 701 | 702 | zHome = getenv("HOME"); |
| 702 | 703 | if( zHome==0 ){ |
| 703 | 704 | fossil_fatal("cannot locate home directory - " |
| 704 | 705 | "please set the HOME environment variable"); |
| @@ -740,11 +741,11 @@ | ||
| 740 | 741 | static int isValidLocalDb(const char *zDbName){ |
| 741 | 742 | i64 lsize; |
| 742 | 743 | int rc; |
| 743 | 744 | sqlite3_stmt *pStmt; |
| 744 | 745 | |
| 745 | - if( access(zDbName, F_OK) ) return 0; | |
| 746 | + if( file_access(zDbName, F_OK) ) return 0; | |
| 746 | 747 | lsize = file_size(zDbName); |
| 747 | 748 | if( lsize%1024!=0 || lsize<4096 ) return 0; |
| 748 | 749 | db_open_or_attach(zDbName, "localdb"); |
| 749 | 750 | g.localOpen = 1; |
| 750 | 751 | db_open_config(0); |
| @@ -803,23 +804,17 @@ | ||
| 803 | 804 | ** is found, it is attached to the open database connection too. |
| 804 | 805 | */ |
| 805 | 806 | int db_open_local(void){ |
| 806 | 807 | int i, n; |
| 807 | 808 | char zPwd[2000]; |
| 808 | - char *zPwdConv; | |
| 809 | 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | 810 | |
| 811 | 811 | if( g.localOpen) return 1; |
| 812 | - if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ | |
| 813 | - db_err("pwd too big: max %d", sizeof(zPwd)-20); | |
| 814 | - } | |
| 812 | + file_getcwd(zPwd, sizeof(zPwd)-20); | |
| 815 | 813 | n = strlen(zPwd); |
| 816 | - zPwdConv = mprintf("%/", zPwd); | |
| 817 | - strncpy(zPwd, zPwdConv, 2000-20); | |
| 818 | - free(zPwdConv); | |
| 819 | 814 | while( n>0 ){ |
| 820 | - if( access(zPwd, W_OK) ) break; | |
| 815 | + if( file_access(zPwd, W_OK) ) break; | |
| 821 | 816 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 822 | 817 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 823 | 818 | if( isValidLocalDb(zPwd) ){ |
| 824 | 819 | /* Found a valid checkout database file */ |
| 825 | 820 | zPwd[n] = 0; |
| @@ -853,15 +848,15 @@ | ||
| 853 | 848 | } |
| 854 | 849 | if( zDbName==0 ){ |
| 855 | 850 | db_err("unable to find the name of a repository database"); |
| 856 | 851 | } |
| 857 | 852 | } |
| 858 | - if( access(zDbName, R_OK) || file_size(zDbName)<1024 ){ | |
| 859 | - if( access(zDbName, 0) ){ | |
| 853 | + if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ | |
| 854 | + if( file_access(zDbName, 0) ){ | |
| 860 | 855 | fossil_panic("repository does not exist or" |
| 861 | 856 | " is in an unreadable directory: %s", zDbName); |
| 862 | - }else if( access(zDbName, R_OK) ){ | |
| 857 | + }else if( file_access(zDbName, R_OK) ){ | |
| 863 | 858 | fossil_panic("read permission denied for repository %s", zDbName); |
| 864 | 859 | }else{ |
| 865 | 860 | fossil_panic("not a valid repository: %s", zDbName); |
| 866 | 861 | } |
| 867 | 862 | } |
| @@ -912,14 +907,14 @@ | ||
| 912 | 907 | |
| 913 | 908 | /* |
| 914 | 909 | ** Return the name of the database "localdb", "configdb", or "repository". |
| 915 | 910 | */ |
| 916 | 911 | const char *db_name(const char *zDb){ |
| 917 | - assert( strcmp(zDb,"localdb")==0 | |
| 918 | - || strcmp(zDb,"configdb")==0 | |
| 919 | - || strcmp(zDb,"repository")==0 ); | |
| 920 | - if( strcmp(zDb, g.zMainDbType)==0 ) zDb = "main"; | |
| 912 | + assert( fossil_strcmp(zDb,"localdb")==0 | |
| 913 | + || fossil_strcmp(zDb,"configdb")==0 | |
| 914 | + || fossil_strcmp(zDb,"repository")==0 ); | |
| 915 | + if( fossil_strcmp(zDb, g.zMainDbType)==0 ) zDb = "main"; | |
| 921 | 916 | return zDb; |
| 922 | 917 | } |
| 923 | 918 | |
| 924 | 919 | /* |
| 925 | 920 | ** Return TRUE if the schema is out-of-date |
| @@ -964,11 +959,11 @@ | ||
| 964 | 959 | fossil_fatal("not in a local checkout"); |
| 965 | 960 | return; |
| 966 | 961 | } |
| 967 | 962 | file_canonical_name(g.argv[2], &repo); |
| 968 | 963 | zRepo = blob_str(&repo); |
| 969 | - if( access(zRepo, 0) ){ | |
| 964 | + if( file_access(zRepo, 0) ){ | |
| 970 | 965 | fossil_fatal("no such file: %s", zRepo); |
| 971 | 966 | } |
| 972 | 967 | db_open_or_attach(zRepo, "test_repo"); |
| 973 | 968 | db_lset("repository", blob_str(&repo)); |
| 974 | 969 | db_close(1); |
| @@ -1217,11 +1212,13 @@ | ||
| 1217 | 1212 | } |
| 1218 | 1213 | } |
| 1219 | 1214 | } |
| 1220 | 1215 | static void db_sql_trace(void *notUsed, const char *zSql){ |
| 1221 | 1216 | int n = strlen(zSql); |
| 1222 | - fprintf(stderr, "%s%s\n", zSql, (n>0 && zSql[n-1]==';') ? "" : ";"); | |
| 1217 | + char *zMsg = mprintf("%s%s\n", zSql, (n>0 && zSql[n-1]==';') ? "" : ";"); | |
| 1218 | + fossil_puts(zMsg, 1); | |
| 1219 | + fossil_free(zMsg); | |
| 1223 | 1220 | } |
| 1224 | 1221 | |
| 1225 | 1222 | /* |
| 1226 | 1223 | ** Implement the user() SQL function. user() takes no arguments and |
| 1227 | 1224 | ** returns the user ID of the current user. |
| 1228 | 1225 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -166,11 +166,11 @@ | |
| 166 | nBegin = 0; |
| 167 | } |
| 168 | busy = 0; |
| 169 | db_close(0); |
| 170 | for(i=0; i<nDeleteOnFail; i++){ |
| 171 | unlink(azDeleteOnFail[i]); |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | /* |
| 176 | ** Install a commit hook. Hooks are installed in sequence order. |
| @@ -615,11 +615,11 @@ | |
| 615 | |
| 616 | /* |
| 617 | ** Function to return the number of seconds since 1970. This is |
| 618 | ** the same as strftime('%s','now') but is more compact. |
| 619 | */ |
| 620 | static void db_now_function( |
| 621 | sqlite3_context *context, |
| 622 | int argc, |
| 623 | sqlite3_value **argv |
| 624 | ){ |
| 625 | sqlite3_result_int64(context, time(0)); |
| @@ -695,10 +695,11 @@ | |
| 695 | if( zHome==0 ){ |
| 696 | fossil_fatal("cannot locate home directory - " |
| 697 | "please set the LOCALAPPDATA or APPDATA or HOMEPATH " |
| 698 | "environment variables"); |
| 699 | } |
| 700 | #else |
| 701 | zHome = getenv("HOME"); |
| 702 | if( zHome==0 ){ |
| 703 | fossil_fatal("cannot locate home directory - " |
| 704 | "please set the HOME environment variable"); |
| @@ -740,11 +741,11 @@ | |
| 740 | static int isValidLocalDb(const char *zDbName){ |
| 741 | i64 lsize; |
| 742 | int rc; |
| 743 | sqlite3_stmt *pStmt; |
| 744 | |
| 745 | if( access(zDbName, F_OK) ) return 0; |
| 746 | lsize = file_size(zDbName); |
| 747 | if( lsize%1024!=0 || lsize<4096 ) return 0; |
| 748 | db_open_or_attach(zDbName, "localdb"); |
| 749 | g.localOpen = 1; |
| 750 | db_open_config(0); |
| @@ -803,23 +804,17 @@ | |
| 803 | ** is found, it is attached to the open database connection too. |
| 804 | */ |
| 805 | int db_open_local(void){ |
| 806 | int i, n; |
| 807 | char zPwd[2000]; |
| 808 | char *zPwdConv; |
| 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | |
| 811 | if( g.localOpen) return 1; |
| 812 | if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ |
| 813 | db_err("pwd too big: max %d", sizeof(zPwd)-20); |
| 814 | } |
| 815 | n = strlen(zPwd); |
| 816 | zPwdConv = mprintf("%/", zPwd); |
| 817 | strncpy(zPwd, zPwdConv, 2000-20); |
| 818 | free(zPwdConv); |
| 819 | while( n>0 ){ |
| 820 | if( access(zPwd, W_OK) ) break; |
| 821 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 822 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 823 | if( isValidLocalDb(zPwd) ){ |
| 824 | /* Found a valid checkout database file */ |
| 825 | zPwd[n] = 0; |
| @@ -853,15 +848,15 @@ | |
| 853 | } |
| 854 | if( zDbName==0 ){ |
| 855 | db_err("unable to find the name of a repository database"); |
| 856 | } |
| 857 | } |
| 858 | if( access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 859 | if( access(zDbName, 0) ){ |
| 860 | fossil_panic("repository does not exist or" |
| 861 | " is in an unreadable directory: %s", zDbName); |
| 862 | }else if( access(zDbName, R_OK) ){ |
| 863 | fossil_panic("read permission denied for repository %s", zDbName); |
| 864 | }else{ |
| 865 | fossil_panic("not a valid repository: %s", zDbName); |
| 866 | } |
| 867 | } |
| @@ -912,14 +907,14 @@ | |
| 912 | |
| 913 | /* |
| 914 | ** Return the name of the database "localdb", "configdb", or "repository". |
| 915 | */ |
| 916 | const char *db_name(const char *zDb){ |
| 917 | assert( strcmp(zDb,"localdb")==0 |
| 918 | || strcmp(zDb,"configdb")==0 |
| 919 | || strcmp(zDb,"repository")==0 ); |
| 920 | if( strcmp(zDb, g.zMainDbType)==0 ) zDb = "main"; |
| 921 | return zDb; |
| 922 | } |
| 923 | |
| 924 | /* |
| 925 | ** Return TRUE if the schema is out-of-date |
| @@ -964,11 +959,11 @@ | |
| 964 | fossil_fatal("not in a local checkout"); |
| 965 | return; |
| 966 | } |
| 967 | file_canonical_name(g.argv[2], &repo); |
| 968 | zRepo = blob_str(&repo); |
| 969 | if( access(zRepo, 0) ){ |
| 970 | fossil_fatal("no such file: %s", zRepo); |
| 971 | } |
| 972 | db_open_or_attach(zRepo, "test_repo"); |
| 973 | db_lset("repository", blob_str(&repo)); |
| 974 | db_close(1); |
| @@ -1217,11 +1212,13 @@ | |
| 1217 | } |
| 1218 | } |
| 1219 | } |
| 1220 | static void db_sql_trace(void *notUsed, const char *zSql){ |
| 1221 | int n = strlen(zSql); |
| 1222 | fprintf(stderr, "%s%s\n", zSql, (n>0 && zSql[n-1]==';') ? "" : ";"); |
| 1223 | } |
| 1224 | |
| 1225 | /* |
| 1226 | ** Implement the user() SQL function. user() takes no arguments and |
| 1227 | ** returns the user ID of the current user. |
| 1228 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -166,11 +166,11 @@ | |
| 166 | nBegin = 0; |
| 167 | } |
| 168 | busy = 0; |
| 169 | db_close(0); |
| 170 | for(i=0; i<nDeleteOnFail; i++){ |
| 171 | file_delete(azDeleteOnFail[i]); |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | /* |
| 176 | ** Install a commit hook. Hooks are installed in sequence order. |
| @@ -615,11 +615,11 @@ | |
| 615 | |
| 616 | /* |
| 617 | ** Function to return the number of seconds since 1970. This is |
| 618 | ** the same as strftime('%s','now') but is more compact. |
| 619 | */ |
| 620 | void db_now_function( |
| 621 | sqlite3_context *context, |
| 622 | int argc, |
| 623 | sqlite3_value **argv |
| 624 | ){ |
| 625 | sqlite3_result_int64(context, time(0)); |
| @@ -695,10 +695,11 @@ | |
| 695 | if( zHome==0 ){ |
| 696 | fossil_fatal("cannot locate home directory - " |
| 697 | "please set the LOCALAPPDATA or APPDATA or HOMEPATH " |
| 698 | "environment variables"); |
| 699 | } |
| 700 | zHome = fossil_mbcs_to_utf8(zHome); |
| 701 | #else |
| 702 | zHome = getenv("HOME"); |
| 703 | if( zHome==0 ){ |
| 704 | fossil_fatal("cannot locate home directory - " |
| 705 | "please set the HOME environment variable"); |
| @@ -740,11 +741,11 @@ | |
| 741 | static int isValidLocalDb(const char *zDbName){ |
| 742 | i64 lsize; |
| 743 | int rc; |
| 744 | sqlite3_stmt *pStmt; |
| 745 | |
| 746 | if( file_access(zDbName, F_OK) ) return 0; |
| 747 | lsize = file_size(zDbName); |
| 748 | if( lsize%1024!=0 || lsize<4096 ) return 0; |
| 749 | db_open_or_attach(zDbName, "localdb"); |
| 750 | g.localOpen = 1; |
| 751 | db_open_config(0); |
| @@ -803,23 +804,17 @@ | |
| 804 | ** is found, it is attached to the open database connection too. |
| 805 | */ |
| 806 | int db_open_local(void){ |
| 807 | int i, n; |
| 808 | char zPwd[2000]; |
| 809 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 810 | |
| 811 | if( g.localOpen) return 1; |
| 812 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 813 | n = strlen(zPwd); |
| 814 | while( n>0 ){ |
| 815 | if( file_access(zPwd, W_OK) ) break; |
| 816 | for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ |
| 817 | sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); |
| 818 | if( isValidLocalDb(zPwd) ){ |
| 819 | /* Found a valid checkout database file */ |
| 820 | zPwd[n] = 0; |
| @@ -853,15 +848,15 @@ | |
| 848 | } |
| 849 | if( zDbName==0 ){ |
| 850 | db_err("unable to find the name of a repository database"); |
| 851 | } |
| 852 | } |
| 853 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 854 | if( file_access(zDbName, 0) ){ |
| 855 | fossil_panic("repository does not exist or" |
| 856 | " is in an unreadable directory: %s", zDbName); |
| 857 | }else if( file_access(zDbName, R_OK) ){ |
| 858 | fossil_panic("read permission denied for repository %s", zDbName); |
| 859 | }else{ |
| 860 | fossil_panic("not a valid repository: %s", zDbName); |
| 861 | } |
| 862 | } |
| @@ -912,14 +907,14 @@ | |
| 907 | |
| 908 | /* |
| 909 | ** Return the name of the database "localdb", "configdb", or "repository". |
| 910 | */ |
| 911 | const char *db_name(const char *zDb){ |
| 912 | assert( fossil_strcmp(zDb,"localdb")==0 |
| 913 | || fossil_strcmp(zDb,"configdb")==0 |
| 914 | || fossil_strcmp(zDb,"repository")==0 ); |
| 915 | if( fossil_strcmp(zDb, g.zMainDbType)==0 ) zDb = "main"; |
| 916 | return zDb; |
| 917 | } |
| 918 | |
| 919 | /* |
| 920 | ** Return TRUE if the schema is out-of-date |
| @@ -964,11 +959,11 @@ | |
| 959 | fossil_fatal("not in a local checkout"); |
| 960 | return; |
| 961 | } |
| 962 | file_canonical_name(g.argv[2], &repo); |
| 963 | zRepo = blob_str(&repo); |
| 964 | if( file_access(zRepo, 0) ){ |
| 965 | fossil_fatal("no such file: %s", zRepo); |
| 966 | } |
| 967 | db_open_or_attach(zRepo, "test_repo"); |
| 968 | db_lset("repository", blob_str(&repo)); |
| 969 | db_close(1); |
| @@ -1217,11 +1212,13 @@ | |
| 1212 | } |
| 1213 | } |
| 1214 | } |
| 1215 | static void db_sql_trace(void *notUsed, const char *zSql){ |
| 1216 | int n = strlen(zSql); |
| 1217 | char *zMsg = mprintf("%s%s\n", zSql, (n>0 && zSql[n-1]==';') ? "" : ";"); |
| 1218 | fossil_puts(zMsg, 1); |
| 1219 | fossil_free(zMsg); |
| 1220 | } |
| 1221 | |
| 1222 | /* |
| 1223 | ** Implement the user() SQL function. user() takes no arguments and |
| 1224 | ** returns the user ID of the current user. |
| 1225 |
+7
-13
| --- src/deltacmd.c | ||
| +++ src/deltacmd.c | ||
| @@ -52,21 +52,18 @@ | ||
| 52 | 52 | Blob orig, target, delta; |
| 53 | 53 | if( g.argc!=5 ){ |
| 54 | 54 | usage("ORIGIN TARGET DELTA"); |
| 55 | 55 | } |
| 56 | 56 | if( blob_read_from_file(&orig, g.argv[2])<0 ){ |
| 57 | - fprintf(stderr,"cannot read %s\n", g.argv[2]); | |
| 58 | - fossil_exit(1); | |
| 57 | + fossil_fatal("cannot read %s\n", g.argv[2]); | |
| 59 | 58 | } |
| 60 | 59 | if( blob_read_from_file(&target, g.argv[3])<0 ){ |
| 61 | - fprintf(stderr,"cannot read %s\n", g.argv[3]); | |
| 62 | - fossil_exit(1); | |
| 60 | + fossil_fatal("cannot read %s\n", g.argv[3]); | |
| 63 | 61 | } |
| 64 | 62 | blob_delta_create(&orig, &target, &delta); |
| 65 | 63 | if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){ |
| 66 | - fprintf(stderr,"cannot write %s\n", g.argv[4]); | |
| 67 | - fossil_exit(1); | |
| 64 | + fossil_fatal("cannot write %s\n", g.argv[4]); | |
| 68 | 65 | } |
| 69 | 66 | blob_reset(&orig); |
| 70 | 67 | blob_reset(&target); |
| 71 | 68 | blob_reset(&delta); |
| 72 | 69 | } |
| @@ -114,21 +111,18 @@ | ||
| 114 | 111 | Blob orig, target, delta; |
| 115 | 112 | if( g.argc!=5 ){ |
| 116 | 113 | usage("ORIGIN DELTA TARGET"); |
| 117 | 114 | } |
| 118 | 115 | if( blob_read_from_file(&orig, g.argv[2])<0 ){ |
| 119 | - fprintf(stderr,"cannot read %s\n", g.argv[2]); | |
| 120 | - fossil_exit(1); | |
| 116 | + fossil_fatal("cannot read %s\n", g.argv[2]); | |
| 121 | 117 | } |
| 122 | 118 | if( blob_read_from_file(&delta, g.argv[3])<0 ){ |
| 123 | - fprintf(stderr,"cannot read %s\n", g.argv[3]); | |
| 124 | - fossil_exit(1); | |
| 119 | + fossil_fatal("cannot read %s\n", g.argv[3]); | |
| 125 | 120 | } |
| 126 | 121 | blob_delta_apply(&orig, &delta, &target); |
| 127 | 122 | if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){ |
| 128 | - fprintf(stderr,"cannot write %s\n", g.argv[4]); | |
| 129 | - fossil_exit(1); | |
| 123 | + fossil_fatal("cannot write %s\n", g.argv[4]); | |
| 130 | 124 | } |
| 131 | 125 | blob_reset(&orig); |
| 132 | 126 | blob_reset(&target); |
| 133 | 127 | blob_reset(&delta); |
| 134 | 128 | } |
| @@ -152,7 +146,7 @@ | ||
| 152 | 146 | blob_delta_apply(&f1, &d12, &a2); |
| 153 | 147 | blob_delta_apply(&f2, &d21, &a1); |
| 154 | 148 | if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){ |
| 155 | 149 | fossil_panic("delta test failed"); |
| 156 | 150 | } |
| 157 | - printf("ok\n"); | |
| 151 | + fossil_print("ok\n"); | |
| 158 | 152 | } |
| 159 | 153 |
| --- src/deltacmd.c | |
| +++ src/deltacmd.c | |
| @@ -52,21 +52,18 @@ | |
| 52 | Blob orig, target, delta; |
| 53 | if( g.argc!=5 ){ |
| 54 | usage("ORIGIN TARGET DELTA"); |
| 55 | } |
| 56 | if( blob_read_from_file(&orig, g.argv[2])<0 ){ |
| 57 | fprintf(stderr,"cannot read %s\n", g.argv[2]); |
| 58 | fossil_exit(1); |
| 59 | } |
| 60 | if( blob_read_from_file(&target, g.argv[3])<0 ){ |
| 61 | fprintf(stderr,"cannot read %s\n", g.argv[3]); |
| 62 | fossil_exit(1); |
| 63 | } |
| 64 | blob_delta_create(&orig, &target, &delta); |
| 65 | if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){ |
| 66 | fprintf(stderr,"cannot write %s\n", g.argv[4]); |
| 67 | fossil_exit(1); |
| 68 | } |
| 69 | blob_reset(&orig); |
| 70 | blob_reset(&target); |
| 71 | blob_reset(&delta); |
| 72 | } |
| @@ -114,21 +111,18 @@ | |
| 114 | Blob orig, target, delta; |
| 115 | if( g.argc!=5 ){ |
| 116 | usage("ORIGIN DELTA TARGET"); |
| 117 | } |
| 118 | if( blob_read_from_file(&orig, g.argv[2])<0 ){ |
| 119 | fprintf(stderr,"cannot read %s\n", g.argv[2]); |
| 120 | fossil_exit(1); |
| 121 | } |
| 122 | if( blob_read_from_file(&delta, g.argv[3])<0 ){ |
| 123 | fprintf(stderr,"cannot read %s\n", g.argv[3]); |
| 124 | fossil_exit(1); |
| 125 | } |
| 126 | blob_delta_apply(&orig, &delta, &target); |
| 127 | if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){ |
| 128 | fprintf(stderr,"cannot write %s\n", g.argv[4]); |
| 129 | fossil_exit(1); |
| 130 | } |
| 131 | blob_reset(&orig); |
| 132 | blob_reset(&target); |
| 133 | blob_reset(&delta); |
| 134 | } |
| @@ -152,7 +146,7 @@ | |
| 152 | blob_delta_apply(&f1, &d12, &a2); |
| 153 | blob_delta_apply(&f2, &d21, &a1); |
| 154 | if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){ |
| 155 | fossil_panic("delta test failed"); |
| 156 | } |
| 157 | printf("ok\n"); |
| 158 | } |
| 159 |
| --- src/deltacmd.c | |
| +++ src/deltacmd.c | |
| @@ -52,21 +52,18 @@ | |
| 52 | Blob orig, target, delta; |
| 53 | if( g.argc!=5 ){ |
| 54 | usage("ORIGIN TARGET DELTA"); |
| 55 | } |
| 56 | if( blob_read_from_file(&orig, g.argv[2])<0 ){ |
| 57 | fossil_fatal("cannot read %s\n", g.argv[2]); |
| 58 | } |
| 59 | if( blob_read_from_file(&target, g.argv[3])<0 ){ |
| 60 | fossil_fatal("cannot read %s\n", g.argv[3]); |
| 61 | } |
| 62 | blob_delta_create(&orig, &target, &delta); |
| 63 | if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){ |
| 64 | fossil_fatal("cannot write %s\n", g.argv[4]); |
| 65 | } |
| 66 | blob_reset(&orig); |
| 67 | blob_reset(&target); |
| 68 | blob_reset(&delta); |
| 69 | } |
| @@ -114,21 +111,18 @@ | |
| 111 | Blob orig, target, delta; |
| 112 | if( g.argc!=5 ){ |
| 113 | usage("ORIGIN DELTA TARGET"); |
| 114 | } |
| 115 | if( blob_read_from_file(&orig, g.argv[2])<0 ){ |
| 116 | fossil_fatal("cannot read %s\n", g.argv[2]); |
| 117 | } |
| 118 | if( blob_read_from_file(&delta, g.argv[3])<0 ){ |
| 119 | fossil_fatal("cannot read %s\n", g.argv[3]); |
| 120 | } |
| 121 | blob_delta_apply(&orig, &delta, &target); |
| 122 | if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){ |
| 123 | fossil_fatal("cannot write %s\n", g.argv[4]); |
| 124 | } |
| 125 | blob_reset(&orig); |
| 126 | blob_reset(&target); |
| 127 | blob_reset(&delta); |
| 128 | } |
| @@ -152,7 +146,7 @@ | |
| 146 | blob_delta_apply(&f1, &d12, &a2); |
| 147 | blob_delta_apply(&f2, &d21, &a1); |
| 148 | if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){ |
| 149 | fossil_panic("delta test failed"); |
| 150 | } |
| 151 | fossil_print("ok\n"); |
| 152 | } |
| 153 |
+1
-1
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -242,11 +242,11 @@ | ||
| 242 | 242 | |
| 243 | 243 | db_must_be_within_tree(); |
| 244 | 244 | if( g.argc==2 ){ |
| 245 | 245 | base = db_lget_int("checkout", 0); |
| 246 | 246 | }else{ |
| 247 | - base = name_to_rid(g.argv[2]); | |
| 247 | + base = name_to_typed_rid(g.argv[2], "ci"); | |
| 248 | 248 | } |
| 249 | 249 | if( base==0 ) return; |
| 250 | 250 | compute_leaves(base, 0); |
| 251 | 251 | db_prepare(&q, |
| 252 | 252 | "%s" |
| 253 | 253 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -242,11 +242,11 @@ | |
| 242 | |
| 243 | db_must_be_within_tree(); |
| 244 | if( g.argc==2 ){ |
| 245 | base = db_lget_int("checkout", 0); |
| 246 | }else{ |
| 247 | base = name_to_rid(g.argv[2]); |
| 248 | } |
| 249 | if( base==0 ) return; |
| 250 | compute_leaves(base, 0); |
| 251 | db_prepare(&q, |
| 252 | "%s" |
| 253 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -242,11 +242,11 @@ | |
| 242 | |
| 243 | db_must_be_within_tree(); |
| 244 | if( g.argc==2 ){ |
| 245 | base = db_lget_int("checkout", 0); |
| 246 | }else{ |
| 247 | base = name_to_typed_rid(g.argv[2], "ci"); |
| 248 | } |
| 249 | if( base==0 ) return; |
| 250 | compute_leaves(base, 0); |
| 251 | db_prepare(&q, |
| 252 | "%s" |
| 253 |
+6
-5
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -590,15 +590,15 @@ | ||
| 590 | 590 | int i; |
| 591 | 591 | int *R; |
| 592 | 592 | if( g.argc<4 ) usage("FILE1 FILE2 ..."); |
| 593 | 593 | blob_read_from_file(&a, g.argv[2]); |
| 594 | 594 | for(i=3; i<g.argc; i++){ |
| 595 | - if( i>3 ) printf("-------------------------------\n"); | |
| 595 | + if( i>3 ) fossil_print("-------------------------------\n"); | |
| 596 | 596 | blob_read_from_file(&b, g.argv[i]); |
| 597 | 597 | R = text_diff(&a, &b, 0, 0, 0); |
| 598 | 598 | for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){ |
| 599 | - printf(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]); | |
| 599 | + fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]); | |
| 600 | 600 | } |
| 601 | 601 | /* free(R); */ |
| 602 | 602 | blob_reset(&b); |
| 603 | 603 | } |
| 604 | 604 | } |
| @@ -743,11 +743,11 @@ | ||
| 743 | 743 | } |
| 744 | 744 | } |
| 745 | 745 | for(i=0; i<x.nOrig; i++){ |
| 746 | 746 | const char *zSrc = x.aOrig[i].zSrc; |
| 747 | 747 | if( zSrc==0 ) zSrc = g.argv[g.argc-1]; |
| 748 | - printf("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); | |
| 748 | + fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); | |
| 749 | 749 | } |
| 750 | 750 | } |
| 751 | 751 | |
| 752 | 752 | /* Annotation flags */ |
| 753 | 753 | #define ANN_FILE_VERS 0x001 /* Show file version rather than commit version */ |
| @@ -837,11 +837,11 @@ | ||
| 837 | 837 | int annFlags = 0; |
| 838 | 838 | Annotator ann; |
| 839 | 839 | |
| 840 | 840 | login_check_credentials(); |
| 841 | 841 | if( !g.okRead ){ login_needed(); return; } |
| 842 | - mid = name_to_rid(PD("checkin","0")); | |
| 842 | + mid = name_to_typed_rid(PD("checkin","0"),"ci"); | |
| 843 | 843 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename")); |
| 844 | 844 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 845 | 845 | iLimit = atoi(PD("limit","-1")); |
| 846 | 846 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 847 | 847 | fossil_redirect_home(); |
| @@ -926,8 +926,9 @@ | ||
| 926 | 926 | printf("version %3d: %s\n", i+1, ann.azVers[i]); |
| 927 | 927 | } |
| 928 | 928 | printf("---------------------------------------------------\n"); |
| 929 | 929 | } |
| 930 | 930 | for(i=0; i<ann.nOrig; i++){ |
| 931 | - printf("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z); | |
| 931 | + fossil_print("%s: %.*s\n", | |
| 932 | + ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z); | |
| 932 | 933 | } |
| 933 | 934 | } |
| 934 | 935 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -590,15 +590,15 @@ | |
| 590 | int i; |
| 591 | int *R; |
| 592 | if( g.argc<4 ) usage("FILE1 FILE2 ..."); |
| 593 | blob_read_from_file(&a, g.argv[2]); |
| 594 | for(i=3; i<g.argc; i++){ |
| 595 | if( i>3 ) printf("-------------------------------\n"); |
| 596 | blob_read_from_file(&b, g.argv[i]); |
| 597 | R = text_diff(&a, &b, 0, 0, 0); |
| 598 | for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){ |
| 599 | printf(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]); |
| 600 | } |
| 601 | /* free(R); */ |
| 602 | blob_reset(&b); |
| 603 | } |
| 604 | } |
| @@ -743,11 +743,11 @@ | |
| 743 | } |
| 744 | } |
| 745 | for(i=0; i<x.nOrig; i++){ |
| 746 | const char *zSrc = x.aOrig[i].zSrc; |
| 747 | if( zSrc==0 ) zSrc = g.argv[g.argc-1]; |
| 748 | printf("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); |
| 749 | } |
| 750 | } |
| 751 | |
| 752 | /* Annotation flags */ |
| 753 | #define ANN_FILE_VERS 0x001 /* Show file version rather than commit version */ |
| @@ -837,11 +837,11 @@ | |
| 837 | int annFlags = 0; |
| 838 | Annotator ann; |
| 839 | |
| 840 | login_check_credentials(); |
| 841 | if( !g.okRead ){ login_needed(); return; } |
| 842 | mid = name_to_rid(PD("checkin","0")); |
| 843 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename")); |
| 844 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 845 | iLimit = atoi(PD("limit","-1")); |
| 846 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 847 | fossil_redirect_home(); |
| @@ -926,8 +926,9 @@ | |
| 926 | printf("version %3d: %s\n", i+1, ann.azVers[i]); |
| 927 | } |
| 928 | printf("---------------------------------------------------\n"); |
| 929 | } |
| 930 | for(i=0; i<ann.nOrig; i++){ |
| 931 | printf("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z); |
| 932 | } |
| 933 | } |
| 934 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -590,15 +590,15 @@ | |
| 590 | int i; |
| 591 | int *R; |
| 592 | if( g.argc<4 ) usage("FILE1 FILE2 ..."); |
| 593 | blob_read_from_file(&a, g.argv[2]); |
| 594 | for(i=3; i<g.argc; i++){ |
| 595 | if( i>3 ) fossil_print("-------------------------------\n"); |
| 596 | blob_read_from_file(&b, g.argv[i]); |
| 597 | R = text_diff(&a, &b, 0, 0, 0); |
| 598 | for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){ |
| 599 | fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]); |
| 600 | } |
| 601 | /* free(R); */ |
| 602 | blob_reset(&b); |
| 603 | } |
| 604 | } |
| @@ -743,11 +743,11 @@ | |
| 743 | } |
| 744 | } |
| 745 | for(i=0; i<x.nOrig; i++){ |
| 746 | const char *zSrc = x.aOrig[i].zSrc; |
| 747 | if( zSrc==0 ) zSrc = g.argv[g.argc-1]; |
| 748 | fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); |
| 749 | } |
| 750 | } |
| 751 | |
| 752 | /* Annotation flags */ |
| 753 | #define ANN_FILE_VERS 0x001 /* Show file version rather than commit version */ |
| @@ -837,11 +837,11 @@ | |
| 837 | int annFlags = 0; |
| 838 | Annotator ann; |
| 839 | |
| 840 | login_check_credentials(); |
| 841 | if( !g.okRead ){ login_needed(); return; } |
| 842 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 843 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename")); |
| 844 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 845 | iLimit = atoi(PD("limit","-1")); |
| 846 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 847 | fossil_redirect_home(); |
| @@ -926,8 +926,9 @@ | |
| 926 | printf("version %3d: %s\n", i+1, ann.azVers[i]); |
| 927 | } |
| 928 | printf("---------------------------------------------------\n"); |
| 929 | } |
| 930 | for(i=0; i<ann.nOrig; i++){ |
| 931 | fossil_print("%s: %.*s\n", |
| 932 | ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z); |
| 933 | } |
| 934 | } |
| 935 |
+6
-6
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -100,11 +100,11 @@ | ||
| 100 | 100 | ** zFile2 */ |
| 101 | 101 | blob_zero(&nameFile1); |
| 102 | 102 | do{ |
| 103 | 103 | blob_reset(&nameFile1); |
| 104 | 104 | blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); |
| 105 | - }while( access(blob_str(&nameFile1),0)==0 ); | |
| 105 | + }while( file_access(blob_str(&nameFile1),0)==0 ); | |
| 106 | 106 | blob_write_to_file(pFile1, blob_str(&nameFile1)); |
| 107 | 107 | |
| 108 | 108 | /* Construct the external diff command */ |
| 109 | 109 | blob_zero(&cmd); |
| 110 | 110 | blob_appendf(&cmd, "%s ", zDiffCmd); |
| @@ -114,11 +114,11 @@ | ||
| 114 | 114 | |
| 115 | 115 | /* Run the external diff command */ |
| 116 | 116 | fossil_system(blob_str(&cmd)); |
| 117 | 117 | |
| 118 | 118 | /* Delete the temporary file and clean up memory used */ |
| 119 | - unlink(blob_str(&nameFile1)); | |
| 119 | + file_delete(blob_str(&nameFile1)); | |
| 120 | 120 | blob_reset(&nameFile1); |
| 121 | 121 | blob_reset(&cmd); |
| 122 | 122 | } |
| 123 | 123 | } |
| 124 | 124 | |
| @@ -168,12 +168,12 @@ | ||
| 168 | 168 | |
| 169 | 169 | /* Run the external diff command */ |
| 170 | 170 | fossil_system(blob_str(&cmd)); |
| 171 | 171 | |
| 172 | 172 | /* Delete the temporary file and clean up memory used */ |
| 173 | - unlink(zTemp1); | |
| 174 | - unlink(zTemp2); | |
| 173 | + file_delete(zTemp1); | |
| 174 | + file_delete(zTemp2); | |
| 175 | 175 | blob_reset(&cmd); |
| 176 | 176 | } |
| 177 | 177 | } |
| 178 | 178 | |
| 179 | 179 | /* |
| @@ -215,11 +215,11 @@ | ||
| 215 | 215 | vid = db_lget_int("checkout", 0); |
| 216 | 216 | vfile_check_signature(vid, 1, 0); |
| 217 | 217 | blob_zero(&sql); |
| 218 | 218 | db_begin_transaction(); |
| 219 | 219 | if( zFrom ){ |
| 220 | - int rid = name_to_rid(zFrom); | |
| 220 | + int rid = name_to_typed_rid(zFrom, "ci"); | |
| 221 | 221 | if( !is_a_version(rid) ){ |
| 222 | 222 | fossil_fatal("no such check-in: %s", zFrom); |
| 223 | 223 | } |
| 224 | 224 | load_vfile_from_rid(rid); |
| 225 | 225 | blob_appendf(&sql, |
| @@ -263,11 +263,11 @@ | ||
| 263 | 263 | char *zToFree = zFullName; |
| 264 | 264 | int showDiff = 1; |
| 265 | 265 | if( isDeleted ){ |
| 266 | 266 | diff_printf("DELETED %s\n", zPathname); |
| 267 | 267 | if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } |
| 268 | - }else if( access(zFullName, 0) ){ | |
| 268 | + }else if( file_access(zFullName, 0) ){ | |
| 269 | 269 | diff_printf("MISSING %s\n", zPathname); |
| 270 | 270 | if( !asNewFile ){ showDiff = 0; } |
| 271 | 271 | }else if( isNew ){ |
| 272 | 272 | diff_printf("ADDED %s\n", zPathname); |
| 273 | 273 | srcid = 0; |
| 274 | 274 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -100,11 +100,11 @@ | |
| 100 | ** zFile2 */ |
| 101 | blob_zero(&nameFile1); |
| 102 | do{ |
| 103 | blob_reset(&nameFile1); |
| 104 | blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); |
| 105 | }while( access(blob_str(&nameFile1),0)==0 ); |
| 106 | blob_write_to_file(pFile1, blob_str(&nameFile1)); |
| 107 | |
| 108 | /* Construct the external diff command */ |
| 109 | blob_zero(&cmd); |
| 110 | blob_appendf(&cmd, "%s ", zDiffCmd); |
| @@ -114,11 +114,11 @@ | |
| 114 | |
| 115 | /* Run the external diff command */ |
| 116 | fossil_system(blob_str(&cmd)); |
| 117 | |
| 118 | /* Delete the temporary file and clean up memory used */ |
| 119 | unlink(blob_str(&nameFile1)); |
| 120 | blob_reset(&nameFile1); |
| 121 | blob_reset(&cmd); |
| 122 | } |
| 123 | } |
| 124 | |
| @@ -168,12 +168,12 @@ | |
| 168 | |
| 169 | /* Run the external diff command */ |
| 170 | fossil_system(blob_str(&cmd)); |
| 171 | |
| 172 | /* Delete the temporary file and clean up memory used */ |
| 173 | unlink(zTemp1); |
| 174 | unlink(zTemp2); |
| 175 | blob_reset(&cmd); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | /* |
| @@ -215,11 +215,11 @@ | |
| 215 | vid = db_lget_int("checkout", 0); |
| 216 | vfile_check_signature(vid, 1, 0); |
| 217 | blob_zero(&sql); |
| 218 | db_begin_transaction(); |
| 219 | if( zFrom ){ |
| 220 | int rid = name_to_rid(zFrom); |
| 221 | if( !is_a_version(rid) ){ |
| 222 | fossil_fatal("no such check-in: %s", zFrom); |
| 223 | } |
| 224 | load_vfile_from_rid(rid); |
| 225 | blob_appendf(&sql, |
| @@ -263,11 +263,11 @@ | |
| 263 | char *zToFree = zFullName; |
| 264 | int showDiff = 1; |
| 265 | if( isDeleted ){ |
| 266 | diff_printf("DELETED %s\n", zPathname); |
| 267 | if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } |
| 268 | }else if( access(zFullName, 0) ){ |
| 269 | diff_printf("MISSING %s\n", zPathname); |
| 270 | if( !asNewFile ){ showDiff = 0; } |
| 271 | }else if( isNew ){ |
| 272 | diff_printf("ADDED %s\n", zPathname); |
| 273 | srcid = 0; |
| 274 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -100,11 +100,11 @@ | |
| 100 | ** zFile2 */ |
| 101 | blob_zero(&nameFile1); |
| 102 | do{ |
| 103 | blob_reset(&nameFile1); |
| 104 | blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); |
| 105 | }while( file_access(blob_str(&nameFile1),0)==0 ); |
| 106 | blob_write_to_file(pFile1, blob_str(&nameFile1)); |
| 107 | |
| 108 | /* Construct the external diff command */ |
| 109 | blob_zero(&cmd); |
| 110 | blob_appendf(&cmd, "%s ", zDiffCmd); |
| @@ -114,11 +114,11 @@ | |
| 114 | |
| 115 | /* Run the external diff command */ |
| 116 | fossil_system(blob_str(&cmd)); |
| 117 | |
| 118 | /* Delete the temporary file and clean up memory used */ |
| 119 | file_delete(blob_str(&nameFile1)); |
| 120 | blob_reset(&nameFile1); |
| 121 | blob_reset(&cmd); |
| 122 | } |
| 123 | } |
| 124 | |
| @@ -168,12 +168,12 @@ | |
| 168 | |
| 169 | /* Run the external diff command */ |
| 170 | fossil_system(blob_str(&cmd)); |
| 171 | |
| 172 | /* Delete the temporary file and clean up memory used */ |
| 173 | file_delete(zTemp1); |
| 174 | file_delete(zTemp2); |
| 175 | blob_reset(&cmd); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | /* |
| @@ -215,11 +215,11 @@ | |
| 215 | vid = db_lget_int("checkout", 0); |
| 216 | vfile_check_signature(vid, 1, 0); |
| 217 | blob_zero(&sql); |
| 218 | db_begin_transaction(); |
| 219 | if( zFrom ){ |
| 220 | int rid = name_to_typed_rid(zFrom, "ci"); |
| 221 | if( !is_a_version(rid) ){ |
| 222 | fossil_fatal("no such check-in: %s", zFrom); |
| 223 | } |
| 224 | load_vfile_from_rid(rid); |
| 225 | blob_appendf(&sql, |
| @@ -263,11 +263,11 @@ | |
| 263 | char *zToFree = zFullName; |
| 264 | int showDiff = 1; |
| 265 | if( isDeleted ){ |
| 266 | diff_printf("DELETED %s\n", zPathname); |
| 267 | if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } |
| 268 | }else if( file_access(zFullName, 0) ){ |
| 269 | diff_printf("MISSING %s\n", zPathname); |
| 270 | if( !asNewFile ){ showDiff = 0; } |
| 271 | }else if( isNew ){ |
| 272 | diff_printf("ADDED %s\n", zPathname); |
| 273 | srcid = 0; |
| 274 |
+41
-11
| --- src/doc.c | ||
| +++ src/doc.c | ||
| @@ -139,14 +139,14 @@ | ||
| 139 | 139 | { "flv", 3, "video/flv" }, |
| 140 | 140 | { "gif", 3, "image/gif" }, |
| 141 | 141 | { "gl", 2, "video/gl" }, |
| 142 | 142 | { "gtar", 4, "application/x-gtar" }, |
| 143 | 143 | { "gz", 2, "application/x-gzip" }, |
| 144 | + { "h", 1, "text/plain" }, | |
| 144 | 145 | { "hdf", 3, "application/x-hdf" }, |
| 145 | 146 | { "hh", 2, "text/plain" }, |
| 146 | 147 | { "hqx", 3, "application/mac-binhex40" }, |
| 147 | - { "h", 1, "text/plain" }, | |
| 148 | 148 | { "htm", 3, "text/html" }, |
| 149 | 149 | { "html", 4, "text/html" }, |
| 150 | 150 | { "ice", 3, "x-conference/x-cooltalk" }, |
| 151 | 151 | { "ief", 3, "image/ief" }, |
| 152 | 152 | { "iges", 4, "model/iges" }, |
| @@ -153,12 +153,12 @@ | ||
| 153 | 153 | { "igs", 3, "model/iges" }, |
| 154 | 154 | { "ips", 3, "application/x-ipscript" }, |
| 155 | 155 | { "ipx", 3, "application/x-ipix" }, |
| 156 | 156 | { "jad", 3, "text/vnd.sun.j2me.app-descriptor" }, |
| 157 | 157 | { "jar", 3, "application/java-archive" }, |
| 158 | - { "jpeg", 4, "image/jpeg" }, | |
| 159 | 158 | { "jpe", 3, "image/jpeg" }, |
| 159 | + { "jpeg", 4, "image/jpeg" }, | |
| 160 | 160 | { "jpg", 3, "image/jpeg" }, |
| 161 | 161 | { "js", 2, "application/x-javascript" }, |
| 162 | 162 | { "kar", 3, "audio/midi" }, |
| 163 | 163 | { "latex", 5, "application/x-latex" }, |
| 164 | 164 | { "lha", 3, "application/octet-stream" }, |
| @@ -171,19 +171,18 @@ | ||
| 171 | 171 | { "mesh", 4, "model/mesh" }, |
| 172 | 172 | { "mid", 3, "audio/midi" }, |
| 173 | 173 | { "midi", 4, "audio/midi" }, |
| 174 | 174 | { "mif", 3, "application/x-mif" }, |
| 175 | 175 | { "mime", 4, "www/mime" }, |
| 176 | - { "movie", 5, "video/x-sgi-movie" }, | |
| 177 | 176 | { "mov", 3, "video/quicktime" }, |
| 177 | + { "movie", 5, "video/x-sgi-movie" }, | |
| 178 | 178 | { "mp2", 3, "audio/mpeg" }, |
| 179 | - { "mp2", 3, "video/mpeg" }, | |
| 180 | 179 | { "mp3", 3, "audio/mpeg" }, |
| 181 | - { "mpeg", 4, "video/mpeg" }, | |
| 182 | 180 | { "mpe", 3, "video/mpeg" }, |
| 183 | - { "mpga", 4, "audio/mpeg" }, | |
| 181 | + { "mpeg", 4, "video/mpeg" }, | |
| 184 | 182 | { "mpg", 3, "video/mpeg" }, |
| 183 | + { "mpga", 4, "audio/mpeg" }, | |
| 185 | 184 | { "ms", 2, "application/x-troff-ms" }, |
| 186 | 185 | { "msh", 3, "model/mesh" }, |
| 187 | 186 | { "nc", 2, "application/x-netcdf" }, |
| 188 | 187 | { "oda", 3, "application/oda" }, |
| 189 | 188 | { "ogg", 3, "application/ogg" }, |
| @@ -209,22 +208,20 @@ | ||
| 209 | 208 | { "qt", 2, "video/quicktime" }, |
| 210 | 209 | { "ra", 2, "audio/x-realaudio" }, |
| 211 | 210 | { "ram", 3, "audio/x-pn-realaudio" }, |
| 212 | 211 | { "rar", 3, "application/x-rar-compressed" }, |
| 213 | 212 | { "ras", 3, "image/cmu-raster" }, |
| 214 | - { "ras", 3, "image/x-cmu-raster" }, | |
| 215 | 213 | { "rgb", 3, "image/x-rgb" }, |
| 216 | 214 | { "rm", 2, "audio/x-pn-realaudio" }, |
| 217 | 215 | { "roff", 4, "application/x-troff" }, |
| 218 | 216 | { "rpm", 3, "audio/x-pn-realaudio-plugin" }, |
| 219 | - { "rtf", 3, "application/rtf" }, | |
| 220 | 217 | { "rtf", 3, "text/rtf" }, |
| 221 | 218 | { "rtx", 3, "text/richtext" }, |
| 222 | 219 | { "scm", 3, "application/x-lotusscreencam" }, |
| 223 | 220 | { "set", 3, "application/set" }, |
| 224 | - { "sgml", 4, "text/sgml" }, | |
| 225 | 221 | { "sgm", 3, "text/sgml" }, |
| 222 | + { "sgml", 4, "text/sgml" }, | |
| 226 | 223 | { "sh", 2, "application/x-sh" }, |
| 227 | 224 | { "shar", 4, "application/x-shar" }, |
| 228 | 225 | { "silo", 4, "model/mesh" }, |
| 229 | 226 | { "sit", 3, "application/x-stuffit" }, |
| 230 | 227 | { "skd", 3, "application/x-koan" }, |
| @@ -249,12 +246,12 @@ | ||
| 249 | 246 | { "tcl", 3, "application/x-tcl" }, |
| 250 | 247 | { "tex", 3, "application/x-tex" }, |
| 251 | 248 | { "texi", 4, "application/x-texinfo" }, |
| 252 | 249 | { "texinfo", 7, "application/x-texinfo" }, |
| 253 | 250 | { "tgz", 3, "application/x-tar-gz" }, |
| 254 | - { "tiff", 4, "image/tiff" }, | |
| 255 | 251 | { "tif", 3, "image/tiff" }, |
| 252 | + { "tiff", 4, "image/tiff" }, | |
| 256 | 253 | { "tr", 2, "application/x-troff" }, |
| 257 | 254 | { "tsi", 3, "audio/TSP-audio" }, |
| 258 | 255 | { "tsp", 3, "application/dsptype" }, |
| 259 | 256 | { "tsv", 3, "text/tab-separated-values" }, |
| 260 | 257 | { "txt", 3, "text/plain" }, |
| @@ -283,10 +280,25 @@ | ||
| 283 | 280 | { "xpm", 3, "image/x-xpixmap" }, |
| 284 | 281 | { "xwd", 3, "image/x-xwindowdump" }, |
| 285 | 282 | { "xyz", 3, "chemical/x-pdb" }, |
| 286 | 283 | { "zip", 3, "application/zip" }, |
| 287 | 284 | }; |
| 285 | + | |
| 286 | +#ifdef FOSSIL_DEBUG | |
| 287 | + /* This is test code to make sure the table above is in the correct | |
| 288 | + ** order | |
| 289 | + */ | |
| 290 | + if( fossil_strcmp(zName, "mimetype-test")==0 ){ | |
| 291 | + for(i=1; i<sizeof(aMime)/sizeof(aMime[0]); i++){ | |
| 292 | + if( fossil_strcmp(aMime[i-1].zSuffix,aMime[i].zSuffix)>=0 ){ | |
| 293 | + fossil_fatal("mimetypes out of sequence: %s before %s", | |
| 294 | + aMime[i-1].zSuffix, aMime[i].zSuffix); | |
| 295 | + } | |
| 296 | + } | |
| 297 | + return "ok"; | |
| 298 | + } | |
| 299 | +#endif | |
| 288 | 300 | |
| 289 | 301 | z = zName; |
| 290 | 302 | for(i=0; zName[i]; i++){ |
| 291 | 303 | if( zName[i]=='.' ) z = &zName[i+1]; |
| 292 | 304 | } |
| @@ -308,10 +320,28 @@ | ||
| 308 | 320 | } |
| 309 | 321 | } |
| 310 | 322 | } |
| 311 | 323 | return "application/x-fossil-artifact"; |
| 312 | 324 | } |
| 325 | + | |
| 326 | +/* | |
| 327 | +** COMMAND: test-mimetype | |
| 328 | +** | |
| 329 | +** Usage: %fossil test-mimetype FILENAME... | |
| 330 | +** | |
| 331 | +** Return the deduced mimetype for each file listed. | |
| 332 | +** | |
| 333 | +** If Fossil is compiled with -DFOSSIL_DEBUG then the "mimetype-test" | |
| 334 | +** filename is special and verifies the integrity of the mimetype table. | |
| 335 | +** It should return "ok". | |
| 336 | +*/ | |
| 337 | +void mimetype_test_cmd(void){ | |
| 338 | + int i; | |
| 339 | + for(i=2; i<g.argc; i++){ | |
| 340 | + fossil_print("%-20s -> %s\n", g.argv[i], mimetype_from_name(g.argv[i])); | |
| 341 | + } | |
| 342 | +} | |
| 313 | 343 | |
| 314 | 344 | /* |
| 315 | 345 | ** WEBPAGE: doc |
| 316 | 346 | ** URL: /doc?name=BASELINE/PATH |
| 317 | 347 | ** URL: /doc/BASELINE/PATH |
| @@ -366,11 +396,11 @@ | ||
| 366 | 396 | db_begin_transaction(); |
| 367 | 397 | if( fossil_strcmp(zBaseline,"tip")==0 ){ |
| 368 | 398 | vid = db_int(0, "SELECT objid FROM event WHERE type='ci'" |
| 369 | 399 | " ORDER BY mtime DESC LIMIT 1"); |
| 370 | 400 | }else{ |
| 371 | - vid = name_to_rid(zBaseline); | |
| 401 | + vid = name_to_typed_rid(zBaseline, "ci"); | |
| 372 | 402 | } |
| 373 | 403 | |
| 374 | 404 | /* Create the baseline cache if it does not already exist */ |
| 375 | 405 | db_multi_exec( |
| 376 | 406 | "CREATE TABLE IF NOT EXISTS vcache(\n" |
| 377 | 407 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -139,14 +139,14 @@ | |
| 139 | { "flv", 3, "video/flv" }, |
| 140 | { "gif", 3, "image/gif" }, |
| 141 | { "gl", 2, "video/gl" }, |
| 142 | { "gtar", 4, "application/x-gtar" }, |
| 143 | { "gz", 2, "application/x-gzip" }, |
| 144 | { "hdf", 3, "application/x-hdf" }, |
| 145 | { "hh", 2, "text/plain" }, |
| 146 | { "hqx", 3, "application/mac-binhex40" }, |
| 147 | { "h", 1, "text/plain" }, |
| 148 | { "htm", 3, "text/html" }, |
| 149 | { "html", 4, "text/html" }, |
| 150 | { "ice", 3, "x-conference/x-cooltalk" }, |
| 151 | { "ief", 3, "image/ief" }, |
| 152 | { "iges", 4, "model/iges" }, |
| @@ -153,12 +153,12 @@ | |
| 153 | { "igs", 3, "model/iges" }, |
| 154 | { "ips", 3, "application/x-ipscript" }, |
| 155 | { "ipx", 3, "application/x-ipix" }, |
| 156 | { "jad", 3, "text/vnd.sun.j2me.app-descriptor" }, |
| 157 | { "jar", 3, "application/java-archive" }, |
| 158 | { "jpeg", 4, "image/jpeg" }, |
| 159 | { "jpe", 3, "image/jpeg" }, |
| 160 | { "jpg", 3, "image/jpeg" }, |
| 161 | { "js", 2, "application/x-javascript" }, |
| 162 | { "kar", 3, "audio/midi" }, |
| 163 | { "latex", 5, "application/x-latex" }, |
| 164 | { "lha", 3, "application/octet-stream" }, |
| @@ -171,19 +171,18 @@ | |
| 171 | { "mesh", 4, "model/mesh" }, |
| 172 | { "mid", 3, "audio/midi" }, |
| 173 | { "midi", 4, "audio/midi" }, |
| 174 | { "mif", 3, "application/x-mif" }, |
| 175 | { "mime", 4, "www/mime" }, |
| 176 | { "movie", 5, "video/x-sgi-movie" }, |
| 177 | { "mov", 3, "video/quicktime" }, |
| 178 | { "mp2", 3, "audio/mpeg" }, |
| 179 | { "mp2", 3, "video/mpeg" }, |
| 180 | { "mp3", 3, "audio/mpeg" }, |
| 181 | { "mpeg", 4, "video/mpeg" }, |
| 182 | { "mpe", 3, "video/mpeg" }, |
| 183 | { "mpga", 4, "audio/mpeg" }, |
| 184 | { "mpg", 3, "video/mpeg" }, |
| 185 | { "ms", 2, "application/x-troff-ms" }, |
| 186 | { "msh", 3, "model/mesh" }, |
| 187 | { "nc", 2, "application/x-netcdf" }, |
| 188 | { "oda", 3, "application/oda" }, |
| 189 | { "ogg", 3, "application/ogg" }, |
| @@ -209,22 +208,20 @@ | |
| 209 | { "qt", 2, "video/quicktime" }, |
| 210 | { "ra", 2, "audio/x-realaudio" }, |
| 211 | { "ram", 3, "audio/x-pn-realaudio" }, |
| 212 | { "rar", 3, "application/x-rar-compressed" }, |
| 213 | { "ras", 3, "image/cmu-raster" }, |
| 214 | { "ras", 3, "image/x-cmu-raster" }, |
| 215 | { "rgb", 3, "image/x-rgb" }, |
| 216 | { "rm", 2, "audio/x-pn-realaudio" }, |
| 217 | { "roff", 4, "application/x-troff" }, |
| 218 | { "rpm", 3, "audio/x-pn-realaudio-plugin" }, |
| 219 | { "rtf", 3, "application/rtf" }, |
| 220 | { "rtf", 3, "text/rtf" }, |
| 221 | { "rtx", 3, "text/richtext" }, |
| 222 | { "scm", 3, "application/x-lotusscreencam" }, |
| 223 | { "set", 3, "application/set" }, |
| 224 | { "sgml", 4, "text/sgml" }, |
| 225 | { "sgm", 3, "text/sgml" }, |
| 226 | { "sh", 2, "application/x-sh" }, |
| 227 | { "shar", 4, "application/x-shar" }, |
| 228 | { "silo", 4, "model/mesh" }, |
| 229 | { "sit", 3, "application/x-stuffit" }, |
| 230 | { "skd", 3, "application/x-koan" }, |
| @@ -249,12 +246,12 @@ | |
| 249 | { "tcl", 3, "application/x-tcl" }, |
| 250 | { "tex", 3, "application/x-tex" }, |
| 251 | { "texi", 4, "application/x-texinfo" }, |
| 252 | { "texinfo", 7, "application/x-texinfo" }, |
| 253 | { "tgz", 3, "application/x-tar-gz" }, |
| 254 | { "tiff", 4, "image/tiff" }, |
| 255 | { "tif", 3, "image/tiff" }, |
| 256 | { "tr", 2, "application/x-troff" }, |
| 257 | { "tsi", 3, "audio/TSP-audio" }, |
| 258 | { "tsp", 3, "application/dsptype" }, |
| 259 | { "tsv", 3, "text/tab-separated-values" }, |
| 260 | { "txt", 3, "text/plain" }, |
| @@ -283,10 +280,25 @@ | |
| 283 | { "xpm", 3, "image/x-xpixmap" }, |
| 284 | { "xwd", 3, "image/x-xwindowdump" }, |
| 285 | { "xyz", 3, "chemical/x-pdb" }, |
| 286 | { "zip", 3, "application/zip" }, |
| 287 | }; |
| 288 | |
| 289 | z = zName; |
| 290 | for(i=0; zName[i]; i++){ |
| 291 | if( zName[i]=='.' ) z = &zName[i+1]; |
| 292 | } |
| @@ -308,10 +320,28 @@ | |
| 308 | } |
| 309 | } |
| 310 | } |
| 311 | return "application/x-fossil-artifact"; |
| 312 | } |
| 313 | |
| 314 | /* |
| 315 | ** WEBPAGE: doc |
| 316 | ** URL: /doc?name=BASELINE/PATH |
| 317 | ** URL: /doc/BASELINE/PATH |
| @@ -366,11 +396,11 @@ | |
| 366 | db_begin_transaction(); |
| 367 | if( fossil_strcmp(zBaseline,"tip")==0 ){ |
| 368 | vid = db_int(0, "SELECT objid FROM event WHERE type='ci'" |
| 369 | " ORDER BY mtime DESC LIMIT 1"); |
| 370 | }else{ |
| 371 | vid = name_to_rid(zBaseline); |
| 372 | } |
| 373 | |
| 374 | /* Create the baseline cache if it does not already exist */ |
| 375 | db_multi_exec( |
| 376 | "CREATE TABLE IF NOT EXISTS vcache(\n" |
| 377 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -139,14 +139,14 @@ | |
| 139 | { "flv", 3, "video/flv" }, |
| 140 | { "gif", 3, "image/gif" }, |
| 141 | { "gl", 2, "video/gl" }, |
| 142 | { "gtar", 4, "application/x-gtar" }, |
| 143 | { "gz", 2, "application/x-gzip" }, |
| 144 | { "h", 1, "text/plain" }, |
| 145 | { "hdf", 3, "application/x-hdf" }, |
| 146 | { "hh", 2, "text/plain" }, |
| 147 | { "hqx", 3, "application/mac-binhex40" }, |
| 148 | { "htm", 3, "text/html" }, |
| 149 | { "html", 4, "text/html" }, |
| 150 | { "ice", 3, "x-conference/x-cooltalk" }, |
| 151 | { "ief", 3, "image/ief" }, |
| 152 | { "iges", 4, "model/iges" }, |
| @@ -153,12 +153,12 @@ | |
| 153 | { "igs", 3, "model/iges" }, |
| 154 | { "ips", 3, "application/x-ipscript" }, |
| 155 | { "ipx", 3, "application/x-ipix" }, |
| 156 | { "jad", 3, "text/vnd.sun.j2me.app-descriptor" }, |
| 157 | { "jar", 3, "application/java-archive" }, |
| 158 | { "jpe", 3, "image/jpeg" }, |
| 159 | { "jpeg", 4, "image/jpeg" }, |
| 160 | { "jpg", 3, "image/jpeg" }, |
| 161 | { "js", 2, "application/x-javascript" }, |
| 162 | { "kar", 3, "audio/midi" }, |
| 163 | { "latex", 5, "application/x-latex" }, |
| 164 | { "lha", 3, "application/octet-stream" }, |
| @@ -171,19 +171,18 @@ | |
| 171 | { "mesh", 4, "model/mesh" }, |
| 172 | { "mid", 3, "audio/midi" }, |
| 173 | { "midi", 4, "audio/midi" }, |
| 174 | { "mif", 3, "application/x-mif" }, |
| 175 | { "mime", 4, "www/mime" }, |
| 176 | { "mov", 3, "video/quicktime" }, |
| 177 | { "movie", 5, "video/x-sgi-movie" }, |
| 178 | { "mp2", 3, "audio/mpeg" }, |
| 179 | { "mp3", 3, "audio/mpeg" }, |
| 180 | { "mpe", 3, "video/mpeg" }, |
| 181 | { "mpeg", 4, "video/mpeg" }, |
| 182 | { "mpg", 3, "video/mpeg" }, |
| 183 | { "mpga", 4, "audio/mpeg" }, |
| 184 | { "ms", 2, "application/x-troff-ms" }, |
| 185 | { "msh", 3, "model/mesh" }, |
| 186 | { "nc", 2, "application/x-netcdf" }, |
| 187 | { "oda", 3, "application/oda" }, |
| 188 | { "ogg", 3, "application/ogg" }, |
| @@ -209,22 +208,20 @@ | |
| 208 | { "qt", 2, "video/quicktime" }, |
| 209 | { "ra", 2, "audio/x-realaudio" }, |
| 210 | { "ram", 3, "audio/x-pn-realaudio" }, |
| 211 | { "rar", 3, "application/x-rar-compressed" }, |
| 212 | { "ras", 3, "image/cmu-raster" }, |
| 213 | { "rgb", 3, "image/x-rgb" }, |
| 214 | { "rm", 2, "audio/x-pn-realaudio" }, |
| 215 | { "roff", 4, "application/x-troff" }, |
| 216 | { "rpm", 3, "audio/x-pn-realaudio-plugin" }, |
| 217 | { "rtf", 3, "text/rtf" }, |
| 218 | { "rtx", 3, "text/richtext" }, |
| 219 | { "scm", 3, "application/x-lotusscreencam" }, |
| 220 | { "set", 3, "application/set" }, |
| 221 | { "sgm", 3, "text/sgml" }, |
| 222 | { "sgml", 4, "text/sgml" }, |
| 223 | { "sh", 2, "application/x-sh" }, |
| 224 | { "shar", 4, "application/x-shar" }, |
| 225 | { "silo", 4, "model/mesh" }, |
| 226 | { "sit", 3, "application/x-stuffit" }, |
| 227 | { "skd", 3, "application/x-koan" }, |
| @@ -249,12 +246,12 @@ | |
| 246 | { "tcl", 3, "application/x-tcl" }, |
| 247 | { "tex", 3, "application/x-tex" }, |
| 248 | { "texi", 4, "application/x-texinfo" }, |
| 249 | { "texinfo", 7, "application/x-texinfo" }, |
| 250 | { "tgz", 3, "application/x-tar-gz" }, |
| 251 | { "tif", 3, "image/tiff" }, |
| 252 | { "tiff", 4, "image/tiff" }, |
| 253 | { "tr", 2, "application/x-troff" }, |
| 254 | { "tsi", 3, "audio/TSP-audio" }, |
| 255 | { "tsp", 3, "application/dsptype" }, |
| 256 | { "tsv", 3, "text/tab-separated-values" }, |
| 257 | { "txt", 3, "text/plain" }, |
| @@ -283,10 +280,25 @@ | |
| 280 | { "xpm", 3, "image/x-xpixmap" }, |
| 281 | { "xwd", 3, "image/x-xwindowdump" }, |
| 282 | { "xyz", 3, "chemical/x-pdb" }, |
| 283 | { "zip", 3, "application/zip" }, |
| 284 | }; |
| 285 | |
| 286 | #ifdef FOSSIL_DEBUG |
| 287 | /* This is test code to make sure the table above is in the correct |
| 288 | ** order |
| 289 | */ |
| 290 | if( fossil_strcmp(zName, "mimetype-test")==0 ){ |
| 291 | for(i=1; i<sizeof(aMime)/sizeof(aMime[0]); i++){ |
| 292 | if( fossil_strcmp(aMime[i-1].zSuffix,aMime[i].zSuffix)>=0 ){ |
| 293 | fossil_fatal("mimetypes out of sequence: %s before %s", |
| 294 | aMime[i-1].zSuffix, aMime[i].zSuffix); |
| 295 | } |
| 296 | } |
| 297 | return "ok"; |
| 298 | } |
| 299 | #endif |
| 300 | |
| 301 | z = zName; |
| 302 | for(i=0; zName[i]; i++){ |
| 303 | if( zName[i]=='.' ) z = &zName[i+1]; |
| 304 | } |
| @@ -308,10 +320,28 @@ | |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | return "application/x-fossil-artifact"; |
| 324 | } |
| 325 | |
| 326 | /* |
| 327 | ** COMMAND: test-mimetype |
| 328 | ** |
| 329 | ** Usage: %fossil test-mimetype FILENAME... |
| 330 | ** |
| 331 | ** Return the deduced mimetype for each file listed. |
| 332 | ** |
| 333 | ** If Fossil is compiled with -DFOSSIL_DEBUG then the "mimetype-test" |
| 334 | ** filename is special and verifies the integrity of the mimetype table. |
| 335 | ** It should return "ok". |
| 336 | */ |
| 337 | void mimetype_test_cmd(void){ |
| 338 | int i; |
| 339 | for(i=2; i<g.argc; i++){ |
| 340 | fossil_print("%-20s -> %s\n", g.argv[i], mimetype_from_name(g.argv[i])); |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | /* |
| 345 | ** WEBPAGE: doc |
| 346 | ** URL: /doc?name=BASELINE/PATH |
| 347 | ** URL: /doc/BASELINE/PATH |
| @@ -366,11 +396,11 @@ | |
| 396 | db_begin_transaction(); |
| 397 | if( fossil_strcmp(zBaseline,"tip")==0 ){ |
| 398 | vid = db_int(0, "SELECT objid FROM event WHERE type='ci'" |
| 399 | " ORDER BY mtime DESC LIMIT 1"); |
| 400 | }else{ |
| 401 | vid = name_to_typed_rid(zBaseline, "ci"); |
| 402 | } |
| 403 | |
| 404 | /* Create the baseline cache if it does not already exist */ |
| 405 | db_multi_exec( |
| 406 | "CREATE TABLE IF NOT EXISTS vcache(\n" |
| 407 |
+4
-4
| --- src/encode.c | ||
| +++ src/encode.c | ||
| @@ -340,11 +340,11 @@ | ||
| 340 | 340 | void test_encode64_cmd(void){ |
| 341 | 341 | char *z; |
| 342 | 342 | int i; |
| 343 | 343 | for(i=2; i<g.argc; i++){ |
| 344 | 344 | z = encode64(g.argv[i], -1); |
| 345 | - printf("%s\n", z); | |
| 345 | + fossil_print("%s\n", z); | |
| 346 | 346 | free(z); |
| 347 | 347 | } |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | 350 | |
| @@ -405,11 +405,11 @@ | ||
| 405 | 405 | void test_decode64_cmd(void){ |
| 406 | 406 | char *z; |
| 407 | 407 | int i, n; |
| 408 | 408 | for(i=2; i<g.argc; i++){ |
| 409 | 409 | z = decode64(g.argv[i], &n); |
| 410 | - printf("%d: %s\n", n, z); | |
| 410 | + fossil_print("%d: %s\n", n, z); | |
| 411 | 411 | free(z); |
| 412 | 412 | } |
| 413 | 413 | } |
| 414 | 414 | |
| 415 | 415 | /* |
| @@ -579,13 +579,13 @@ | ||
| 579 | 579 | int i; |
| 580 | 580 | char *z, *z2; |
| 581 | 581 | for(i=2; i<g.argc; i++){ |
| 582 | 582 | z = obscure(g.argv[i]); |
| 583 | 583 | z2 = unobscure(z); |
| 584 | - printf("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2); | |
| 584 | + fossil_print("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2); | |
| 585 | 585 | free(z); |
| 586 | 586 | free(z2); |
| 587 | 587 | z = unobscure(g.argv[i]); |
| 588 | - printf("UNOBSCURE: %s -> %s\n", g.argv[i], z); | |
| 588 | + fossil_print("UNOBSCURE: %s -> %s\n", g.argv[i], z); | |
| 589 | 589 | free(z); |
| 590 | 590 | } |
| 591 | 591 | } |
| 592 | 592 |
| --- src/encode.c | |
| +++ src/encode.c | |
| @@ -340,11 +340,11 @@ | |
| 340 | void test_encode64_cmd(void){ |
| 341 | char *z; |
| 342 | int i; |
| 343 | for(i=2; i<g.argc; i++){ |
| 344 | z = encode64(g.argv[i], -1); |
| 345 | printf("%s\n", z); |
| 346 | free(z); |
| 347 | } |
| 348 | } |
| 349 | |
| 350 | |
| @@ -405,11 +405,11 @@ | |
| 405 | void test_decode64_cmd(void){ |
| 406 | char *z; |
| 407 | int i, n; |
| 408 | for(i=2; i<g.argc; i++){ |
| 409 | z = decode64(g.argv[i], &n); |
| 410 | printf("%d: %s\n", n, z); |
| 411 | free(z); |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | /* |
| @@ -579,13 +579,13 @@ | |
| 579 | int i; |
| 580 | char *z, *z2; |
| 581 | for(i=2; i<g.argc; i++){ |
| 582 | z = obscure(g.argv[i]); |
| 583 | z2 = unobscure(z); |
| 584 | printf("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2); |
| 585 | free(z); |
| 586 | free(z2); |
| 587 | z = unobscure(g.argv[i]); |
| 588 | printf("UNOBSCURE: %s -> %s\n", g.argv[i], z); |
| 589 | free(z); |
| 590 | } |
| 591 | } |
| 592 |
| --- src/encode.c | |
| +++ src/encode.c | |
| @@ -340,11 +340,11 @@ | |
| 340 | void test_encode64_cmd(void){ |
| 341 | char *z; |
| 342 | int i; |
| 343 | for(i=2; i<g.argc; i++){ |
| 344 | z = encode64(g.argv[i], -1); |
| 345 | fossil_print("%s\n", z); |
| 346 | free(z); |
| 347 | } |
| 348 | } |
| 349 | |
| 350 | |
| @@ -405,11 +405,11 @@ | |
| 405 | void test_decode64_cmd(void){ |
| 406 | char *z; |
| 407 | int i, n; |
| 408 | for(i=2; i<g.argc; i++){ |
| 409 | z = decode64(g.argv[i], &n); |
| 410 | fossil_print("%d: %s\n", n, z); |
| 411 | free(z); |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | /* |
| @@ -579,13 +579,13 @@ | |
| 579 | int i; |
| 580 | char *z, *z2; |
| 581 | for(i=2; i<g.argc; i++){ |
| 582 | z = obscure(g.argv[i]); |
| 583 | z2 = unobscure(z); |
| 584 | fossil_print("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2); |
| 585 | free(z); |
| 586 | free(z2); |
| 587 | z = unobscure(g.argv[i]); |
| 588 | fossil_print("UNOBSCURE: %s -> %s\n", g.argv[i], z); |
| 589 | free(z); |
| 590 | } |
| 591 | } |
| 592 |
+176
-28
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -47,17 +47,19 @@ | ||
| 47 | 47 | static int getStat(const char *zFilename){ |
| 48 | 48 | int rc = 0; |
| 49 | 49 | if( zFilename==0 ){ |
| 50 | 50 | if( fileStatValid==0 ) rc = 1; |
| 51 | 51 | }else{ |
| 52 | - if( stat(zFilename, &fileStat)!=0 ){ | |
| 52 | + char *zMbcs = fossil_utf8_to_mbcs(zFilename); | |
| 53 | + if( stat(zMbcs, &fileStat)!=0 ){ | |
| 53 | 54 | fileStatValid = 0; |
| 54 | 55 | rc = 1; |
| 55 | 56 | }else{ |
| 56 | 57 | fileStatValid = 1; |
| 57 | 58 | rc = 0; |
| 58 | 59 | } |
| 60 | + fossil_mbcs_free(zMbcs); | |
| 59 | 61 | } |
| 60 | 62 | return rc; |
| 61 | 63 | } |
| 62 | 64 | |
| 63 | 65 | |
| @@ -120,10 +122,20 @@ | ||
| 120 | 122 | }else{ |
| 121 | 123 | rc = getStat(0); |
| 122 | 124 | } |
| 123 | 125 | return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); |
| 124 | 126 | } |
| 127 | + | |
| 128 | +/* | |
| 129 | +** Wrapper around the access() system call. | |
| 130 | +*/ | |
| 131 | +int file_access(const char *zFilename, int flags){ | |
| 132 | + char *zMbcs = fossil_utf8_to_mbcs(zFilename); | |
| 133 | + int rc = access(zMbcs, flags); | |
| 134 | + fossil_mbcs_free(zMbcs); | |
| 135 | + return rc; | |
| 136 | +} | |
| 125 | 137 | |
| 126 | 138 | /* |
| 127 | 139 | ** Find an unused filename similar to zBase with zSuffix appended. |
| 128 | 140 | ** |
| 129 | 141 | ** Make the name relative to the working directory if relFlag is true. |
| @@ -166,13 +178,13 @@ | ||
| 166 | 178 | */ |
| 167 | 179 | void file_copy(const char *zFrom, const char *zTo){ |
| 168 | 180 | FILE *in, *out; |
| 169 | 181 | int got; |
| 170 | 182 | char zBuf[8192]; |
| 171 | - in = fopen(zFrom, "rb"); | |
| 183 | + in = fossil_fopen(zFrom, "rb"); | |
| 172 | 184 | if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); |
| 173 | - out = fopen(zTo, "wb"); | |
| 185 | + out = fossil_fopen(zTo, "wb"); | |
| 174 | 186 | if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); |
| 175 | 187 | while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 176 | 188 | fwrite(zBuf, 1, got, out); |
| 177 | 189 | } |
| 178 | 190 | fclose(in); |
| @@ -200,10 +212,19 @@ | ||
| 200 | 212 | } |
| 201 | 213 | } |
| 202 | 214 | #endif /* _WIN32 */ |
| 203 | 215 | return rc; |
| 204 | 216 | } |
| 217 | + | |
| 218 | +/* | |
| 219 | +** Delete a file. | |
| 220 | +*/ | |
| 221 | +void file_delete(const char *zFilename){ | |
| 222 | + char *z = fossil_utf8_to_mbcs(zFilename); | |
| 223 | + unlink(z); | |
| 224 | + fossil_mbcs_free(z); | |
| 225 | +} | |
| 205 | 226 | |
| 206 | 227 | /* |
| 207 | 228 | ** Create the directory named in the argument, if it does not already |
| 208 | 229 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| 209 | 230 | ** with the same name. |
| @@ -212,15 +233,19 @@ | ||
| 212 | 233 | */ |
| 213 | 234 | int file_mkdir(const char *zName, int forceFlag){ |
| 214 | 235 | int rc = file_isdir(zName); |
| 215 | 236 | if( rc==2 ){ |
| 216 | 237 | if( !forceFlag ) return 1; |
| 217 | - unlink(zName); | |
| 238 | + file_delete(zName); | |
| 218 | 239 | } |
| 219 | 240 | if( rc!=1 ){ |
| 220 | 241 | #if defined(_WIN32) |
| 221 | - return mkdir(zName); | |
| 242 | + int rc; | |
| 243 | + char *zMbcs = fossil_utf8_to_mbcs(zName); | |
| 244 | + rc = mkdir(zMbcs); | |
| 245 | + fossil_mbcs_free(zMbcs); | |
| 246 | + return rc; | |
| 222 | 247 | #else |
| 223 | 248 | return mkdir(zName, 0755); |
| 224 | 249 | #endif |
| 225 | 250 | } |
| 226 | 251 | return 0; |
| @@ -350,16 +375,47 @@ | ||
| 350 | 375 | void cmd_test_simplify_name(void){ |
| 351 | 376 | int i; |
| 352 | 377 | char *z; |
| 353 | 378 | for(i=2; i<g.argc; i++){ |
| 354 | 379 | z = mprintf("%s", g.argv[i]); |
| 355 | - printf("[%s] -> ", z); | |
| 380 | + fossil_print("[%s] -> ", z); | |
| 356 | 381 | file_simplify_name(z, -1); |
| 357 | - printf("[%s]\n", z); | |
| 382 | + fossil_print("[%s]\n", z); | |
| 358 | 383 | fossil_free(z); |
| 359 | 384 | } |
| 360 | 385 | } |
| 386 | + | |
| 387 | +/* | |
| 388 | +** Get the current working directory. | |
| 389 | +** | |
| 390 | +** On windows, the name is converted from MBCS to UTF8 and all '\\' | |
| 391 | +** characters are converted to '/'. No conversions are needed on | |
| 392 | +** unix. | |
| 393 | +*/ | |
| 394 | +void file_getcwd(char *zBuf, int nBuf){ | |
| 395 | +#ifdef _WIN32 | |
| 396 | + char *zPwdUtf8; | |
| 397 | + int nPwd; | |
| 398 | + int i; | |
| 399 | + char zPwd[2000]; | |
| 400 | + if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){ | |
| 401 | + fossil_fatal("pwd too big: max %d\n", (int)sizeof(zPwd)-1); | |
| 402 | + } | |
| 403 | + zPwdUtf8 = fossil_mbcs_to_utf8(zPwd); | |
| 404 | + nPwd = strlen(zPwdUtf8); | |
| 405 | + if( nPwd > nBuf-1 ){ | |
| 406 | + fossil_fatal("pwd too big: max %d\n", nBuf-1); | |
| 407 | + } | |
| 408 | + for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/'; | |
| 409 | + memcpy(zBuf, zPwdUtf8, nPwd+1); | |
| 410 | + fossil_mbcs_free(zPwdUtf8); | |
| 411 | +#else | |
| 412 | + if( getcwd(zBuf, nBuf-1)==0 ){ | |
| 413 | + fossil_fatal("pwd too big: max %d\n", nBuf-1); | |
| 414 | + } | |
| 415 | +#endif | |
| 416 | +} | |
| 361 | 417 | |
| 362 | 418 | /* |
| 363 | 419 | ** Compute a canonical pathname for a file or directory. |
| 364 | 420 | ** Make the name absolute if it is relative. |
| 365 | 421 | ** Remove redundant / characters |
| @@ -376,14 +432,11 @@ | ||
| 376 | 432 | ){ |
| 377 | 433 | blob_set(pOut, zOrigName); |
| 378 | 434 | blob_materialize(pOut); |
| 379 | 435 | }else{ |
| 380 | 436 | char zPwd[2000]; |
| 381 | - if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ | |
| 382 | - fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); | |
| 383 | - fossil_exit(1); | |
| 384 | - } | |
| 437 | + file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName)); | |
| 385 | 438 | blob_zero(pOut); |
| 386 | 439 | blob_appendf(pOut, "%//%/", zPwd, zOrigName); |
| 387 | 440 | } |
| 388 | 441 | blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); |
| 389 | 442 | } |
| @@ -401,19 +454,19 @@ | ||
| 401 | 454 | blob_zero(&x); |
| 402 | 455 | for(i=2; i<g.argc; i++){ |
| 403 | 456 | char zBuf[100]; |
| 404 | 457 | const char *zName = g.argv[i]; |
| 405 | 458 | file_canonical_name(zName, &x); |
| 406 | - printf("[%s] -> [%s]\n", zName, blob_buffer(&x)); | |
| 459 | + fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x)); | |
| 407 | 460 | blob_reset(&x); |
| 408 | 461 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zName)); |
| 409 | - printf(" file_size = %s\n", zBuf); | |
| 462 | + fossil_print(" file_size = %s\n", zBuf); | |
| 410 | 463 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_mtime(zName)); |
| 411 | - printf(" file_mtime = %s\n", zBuf); | |
| 412 | - printf(" file_isfile = %d\n", file_isfile(zName)); | |
| 413 | - printf(" file_isexe = %d\n", file_isexe(zName)); | |
| 414 | - printf(" file_isdir = %d\n", file_isdir(zName)); | |
| 464 | + fossil_print(" file_mtime = %s\n", zBuf); | |
| 465 | + fossil_print(" file_isfile = %d\n", file_isfile(zName)); | |
| 466 | + fossil_print(" file_isexe = %d\n", file_isexe(zName)); | |
| 467 | + fossil_print(" file_isdir = %d\n", file_isdir(zName)); | |
| 415 | 468 | } |
| 416 | 469 | } |
| 417 | 470 | |
| 418 | 471 | /* |
| 419 | 472 | ** Return TRUE if the given filename is canonical. |
| @@ -452,14 +505,11 @@ | ||
| 452 | 505 | zPath = blob_buffer(pOut); |
| 453 | 506 | if( zPath[0]=='/' ){ |
| 454 | 507 | int i, j; |
| 455 | 508 | Blob tmp; |
| 456 | 509 | char zPwd[2000]; |
| 457 | - if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ | |
| 458 | - fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); | |
| 459 | - fossil_exit(1); | |
| 460 | - } | |
| 510 | + file_getcwd(zPwd, sizeof(zPwd)-20); | |
| 461 | 511 | for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){} |
| 462 | 512 | if( zPath[i]==0 ){ |
| 463 | 513 | blob_reset(pOut); |
| 464 | 514 | if( zPwd[i]==0 ){ |
| 465 | 515 | blob_append(pOut, ".", 1); |
| @@ -502,11 +552,11 @@ | ||
| 502 | 552 | int i; |
| 503 | 553 | Blob x; |
| 504 | 554 | blob_zero(&x); |
| 505 | 555 | for(i=2; i<g.argc; i++){ |
| 506 | 556 | file_relative_name(g.argv[i], &x); |
| 507 | - printf("%s\n", blob_buffer(&x)); | |
| 557 | + fossil_print("%s\n", blob_buffer(&x)); | |
| 508 | 558 | blob_reset(&x); |
| 509 | 559 | } |
| 510 | 560 | } |
| 511 | 561 | |
| 512 | 562 | /* |
| @@ -557,11 +607,11 @@ | ||
| 557 | 607 | int i; |
| 558 | 608 | Blob x; |
| 559 | 609 | blob_zero(&x); |
| 560 | 610 | for(i=2; i<g.argc; i++){ |
| 561 | 611 | if( file_tree_name(g.argv[i], &x, 1) ){ |
| 562 | - printf("%s\n", blob_buffer(&x)); | |
| 612 | + fossil_print("%s\n", blob_buffer(&x)); | |
| 563 | 613 | blob_reset(&x); |
| 564 | 614 | } |
| 565 | 615 | } |
| 566 | 616 | } |
| 567 | 617 | |
| @@ -620,17 +670,14 @@ | ||
| 620 | 670 | static const unsigned char zChars[] = |
| 621 | 671 | "abcdefghijklmnopqrstuvwxyz" |
| 622 | 672 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 623 | 673 | "0123456789"; |
| 624 | 674 | unsigned int i, j; |
| 625 | - struct stat buf; | |
| 626 | 675 | const char *zDir = "."; |
| 627 | 676 | |
| 628 | 677 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ |
| 629 | - if( stat(azDirs[i], &buf) ) continue; | |
| 630 | - if( !S_ISDIR(buf.st_mode) ) continue; | |
| 631 | - if( access(azDirs[i], 07) ) continue; | |
| 678 | + if( !file_isdir(azDirs[i]) ) continue; | |
| 632 | 679 | zDir = azDirs[i]; |
| 633 | 680 | break; |
| 634 | 681 | } |
| 635 | 682 | |
| 636 | 683 | /* Check that the output buffer is large enough for the temporary file |
| @@ -646,11 +693,11 @@ | ||
| 646 | 693 | sqlite3_randomness(15, &zBuf[j]); |
| 647 | 694 | for(i=0; i<15; i++, j++){ |
| 648 | 695 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 649 | 696 | } |
| 650 | 697 | zBuf[j] = 0; |
| 651 | - }while( access(zBuf,0)==0 ); | |
| 698 | + }while( file_size(zBuf)<0 ); | |
| 652 | 699 | } |
| 653 | 700 | |
| 654 | 701 | |
| 655 | 702 | /* |
| 656 | 703 | ** Return true if a file named zName exists and has identical content |
| @@ -668,5 +715,106 @@ | ||
| 668 | 715 | blob_read_from_file(&onDisk, zName); |
| 669 | 716 | rc = blob_compare(&onDisk, pContent); |
| 670 | 717 | blob_reset(&onDisk); |
| 671 | 718 | return rc==0; |
| 672 | 719 | } |
| 720 | + | |
| 721 | + | |
| 722 | +/************************************************************************** | |
| 723 | +** The following routines translate between MBCS and UTF8 on windows. | |
| 724 | +** Since everything is always UTF8 on unix, these routines are no-ops | |
| 725 | +** there. | |
| 726 | +*/ | |
| 727 | +#ifdef _WIN32 | |
| 728 | +# include <windows.h> | |
| 729 | +#endif | |
| 730 | + | |
| 731 | +/* | |
| 732 | +** Translate MBCS to UTF8. Return a pointer to the translated text. | |
| 733 | +** Call fossil_mbcs_free() to deallocate any memory used to store the | |
| 734 | +** returned pointer when done. | |
| 735 | +*/ | |
| 736 | +char *fossil_mbcs_to_utf8(const char *zMbcs){ | |
| 737 | +#ifdef _WIN32 | |
| 738 | + extern char *sqlite3_win32_mbcs_to_utf8(const char*); | |
| 739 | + return sqlite3_win32_mbcs_to_utf8(zMbcs); | |
| 740 | +#else | |
| 741 | + return (char*)zMbcs; /* No-op on unix */ | |
| 742 | +#endif | |
| 743 | +} | |
| 744 | + | |
| 745 | +/* | |
| 746 | +** Translate UTF8 to MBCS for use in system calls. Return a pointer to the | |
| 747 | +** translated text.. Call fossil_mbcs_free() to deallocate any memory | |
| 748 | +** used to store the returned pointer when done. | |
| 749 | +*/ | |
| 750 | +char *fossil_utf8_to_mbcs(const char *zUtf8){ | |
| 751 | +#ifdef _WIN32 | |
| 752 | + extern char *sqlite3_win32_utf8_to_mbcs(const char*); | |
| 753 | + return sqlite3_win32_utf8_to_mbcs(zUtf8); | |
| 754 | +#else | |
| 755 | + return (char*)zUtf8; /* No-op on unix */ | |
| 756 | +#endif | |
| 757 | +} | |
| 758 | + | |
| 759 | +/* | |
| 760 | +** Translate UTF8 to MBCS for display on the console. Return a pointer to the | |
| 761 | +** translated text.. Call fossil_mbcs_free() to deallocate any memory | |
| 762 | +** used to store the returned pointer when done. | |
| 763 | +*/ | |
| 764 | +char *fossil_utf8_to_console(const char *zUtf8){ | |
| 765 | +#ifdef _WIN32 | |
| 766 | + int nChar, nByte; | |
| 767 | + WCHAR *zUnicode; /* Unicode version of zUtf8 */ | |
| 768 | + char *zConsole; /* Console version of zUtf8 */ | |
| 769 | + int codepage; /* Console code page */ | |
| 770 | + | |
| 771 | + nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); | |
| 772 | + zUnicode = malloc( nChar*sizeof(zUnicode[0]) ); | |
| 773 | + if( zUnicode==0 ){ | |
| 774 | + return 0; | |
| 775 | + } | |
| 776 | + nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); | |
| 777 | + if( nChar==0 ){ | |
| 778 | + free(zUnicode); | |
| 779 | + return 0; | |
| 780 | + } | |
| 781 | + codepage = GetConsoleCP(); | |
| 782 | + nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0); | |
| 783 | + zConsole = malloc( nByte ); | |
| 784 | + if( zConsole==0 ){ | |
| 785 | + free(zUnicode); | |
| 786 | + return 0; | |
| 787 | + } | |
| 788 | + nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0); | |
| 789 | + free(zUnicode); | |
| 790 | + if( nByte == 0 ){ | |
| 791 | + free(zConsole); | |
| 792 | + zConsole = 0; | |
| 793 | + } | |
| 794 | + return zConsole; | |
| 795 | +#else | |
| 796 | + return (char*)zUtf8; /* No-op on unix */ | |
| 797 | +#endif | |
| 798 | +} | |
| 799 | + | |
| 800 | +/* | |
| 801 | +** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() | |
| 802 | +** to deallocate any memory used to store the returned pointer when done. | |
| 803 | +*/ | |
| 804 | +void fossil_mbcs_free(char *zOld){ | |
| 805 | +#ifdef _WIN32 | |
| 806 | + free(zOld); | |
| 807 | +#else | |
| 808 | + /* No-op on unix */ | |
| 809 | +#endif | |
| 810 | +} | |
| 811 | + | |
| 812 | +/* | |
| 813 | +** Like fopen() but always takes a UTF8 argument. | |
| 814 | +*/ | |
| 815 | +FILE *fossil_fopen(const char *zName, const char *zMode){ | |
| 816 | + char *zMbcs = fossil_utf8_to_mbcs(zName); | |
| 817 | + FILE *f = fopen(zMbcs, zMode); | |
| 818 | + fossil_mbcs_free(zMbcs); | |
| 819 | + return f; | |
| 820 | +} | |
| 673 | 821 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -47,17 +47,19 @@ | |
| 47 | static int getStat(const char *zFilename){ |
| 48 | int rc = 0; |
| 49 | if( zFilename==0 ){ |
| 50 | if( fileStatValid==0 ) rc = 1; |
| 51 | }else{ |
| 52 | if( stat(zFilename, &fileStat)!=0 ){ |
| 53 | fileStatValid = 0; |
| 54 | rc = 1; |
| 55 | }else{ |
| 56 | fileStatValid = 1; |
| 57 | rc = 0; |
| 58 | } |
| 59 | } |
| 60 | return rc; |
| 61 | } |
| 62 | |
| 63 | |
| @@ -120,10 +122,20 @@ | |
| 120 | }else{ |
| 121 | rc = getStat(0); |
| 122 | } |
| 123 | return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); |
| 124 | } |
| 125 | |
| 126 | /* |
| 127 | ** Find an unused filename similar to zBase with zSuffix appended. |
| 128 | ** |
| 129 | ** Make the name relative to the working directory if relFlag is true. |
| @@ -166,13 +178,13 @@ | |
| 166 | */ |
| 167 | void file_copy(const char *zFrom, const char *zTo){ |
| 168 | FILE *in, *out; |
| 169 | int got; |
| 170 | char zBuf[8192]; |
| 171 | in = fopen(zFrom, "rb"); |
| 172 | if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); |
| 173 | out = fopen(zTo, "wb"); |
| 174 | if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); |
| 175 | while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 176 | fwrite(zBuf, 1, got, out); |
| 177 | } |
| 178 | fclose(in); |
| @@ -200,10 +212,19 @@ | |
| 200 | } |
| 201 | } |
| 202 | #endif /* _WIN32 */ |
| 203 | return rc; |
| 204 | } |
| 205 | |
| 206 | /* |
| 207 | ** Create the directory named in the argument, if it does not already |
| 208 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| 209 | ** with the same name. |
| @@ -212,15 +233,19 @@ | |
| 212 | */ |
| 213 | int file_mkdir(const char *zName, int forceFlag){ |
| 214 | int rc = file_isdir(zName); |
| 215 | if( rc==2 ){ |
| 216 | if( !forceFlag ) return 1; |
| 217 | unlink(zName); |
| 218 | } |
| 219 | if( rc!=1 ){ |
| 220 | #if defined(_WIN32) |
| 221 | return mkdir(zName); |
| 222 | #else |
| 223 | return mkdir(zName, 0755); |
| 224 | #endif |
| 225 | } |
| 226 | return 0; |
| @@ -350,16 +375,47 @@ | |
| 350 | void cmd_test_simplify_name(void){ |
| 351 | int i; |
| 352 | char *z; |
| 353 | for(i=2; i<g.argc; i++){ |
| 354 | z = mprintf("%s", g.argv[i]); |
| 355 | printf("[%s] -> ", z); |
| 356 | file_simplify_name(z, -1); |
| 357 | printf("[%s]\n", z); |
| 358 | fossil_free(z); |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | /* |
| 363 | ** Compute a canonical pathname for a file or directory. |
| 364 | ** Make the name absolute if it is relative. |
| 365 | ** Remove redundant / characters |
| @@ -376,14 +432,11 @@ | |
| 376 | ){ |
| 377 | blob_set(pOut, zOrigName); |
| 378 | blob_materialize(pOut); |
| 379 | }else{ |
| 380 | char zPwd[2000]; |
| 381 | if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ |
| 382 | fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); |
| 383 | fossil_exit(1); |
| 384 | } |
| 385 | blob_zero(pOut); |
| 386 | blob_appendf(pOut, "%//%/", zPwd, zOrigName); |
| 387 | } |
| 388 | blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); |
| 389 | } |
| @@ -401,19 +454,19 @@ | |
| 401 | blob_zero(&x); |
| 402 | for(i=2; i<g.argc; i++){ |
| 403 | char zBuf[100]; |
| 404 | const char *zName = g.argv[i]; |
| 405 | file_canonical_name(zName, &x); |
| 406 | printf("[%s] -> [%s]\n", zName, blob_buffer(&x)); |
| 407 | blob_reset(&x); |
| 408 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zName)); |
| 409 | printf(" file_size = %s\n", zBuf); |
| 410 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_mtime(zName)); |
| 411 | printf(" file_mtime = %s\n", zBuf); |
| 412 | printf(" file_isfile = %d\n", file_isfile(zName)); |
| 413 | printf(" file_isexe = %d\n", file_isexe(zName)); |
| 414 | printf(" file_isdir = %d\n", file_isdir(zName)); |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | /* |
| 419 | ** Return TRUE if the given filename is canonical. |
| @@ -452,14 +505,11 @@ | |
| 452 | zPath = blob_buffer(pOut); |
| 453 | if( zPath[0]=='/' ){ |
| 454 | int i, j; |
| 455 | Blob tmp; |
| 456 | char zPwd[2000]; |
| 457 | if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ |
| 458 | fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); |
| 459 | fossil_exit(1); |
| 460 | } |
| 461 | for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){} |
| 462 | if( zPath[i]==0 ){ |
| 463 | blob_reset(pOut); |
| 464 | if( zPwd[i]==0 ){ |
| 465 | blob_append(pOut, ".", 1); |
| @@ -502,11 +552,11 @@ | |
| 502 | int i; |
| 503 | Blob x; |
| 504 | blob_zero(&x); |
| 505 | for(i=2; i<g.argc; i++){ |
| 506 | file_relative_name(g.argv[i], &x); |
| 507 | printf("%s\n", blob_buffer(&x)); |
| 508 | blob_reset(&x); |
| 509 | } |
| 510 | } |
| 511 | |
| 512 | /* |
| @@ -557,11 +607,11 @@ | |
| 557 | int i; |
| 558 | Blob x; |
| 559 | blob_zero(&x); |
| 560 | for(i=2; i<g.argc; i++){ |
| 561 | if( file_tree_name(g.argv[i], &x, 1) ){ |
| 562 | printf("%s\n", blob_buffer(&x)); |
| 563 | blob_reset(&x); |
| 564 | } |
| 565 | } |
| 566 | } |
| 567 | |
| @@ -620,17 +670,14 @@ | |
| 620 | static const unsigned char zChars[] = |
| 621 | "abcdefghijklmnopqrstuvwxyz" |
| 622 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 623 | "0123456789"; |
| 624 | unsigned int i, j; |
| 625 | struct stat buf; |
| 626 | const char *zDir = "."; |
| 627 | |
| 628 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ |
| 629 | if( stat(azDirs[i], &buf) ) continue; |
| 630 | if( !S_ISDIR(buf.st_mode) ) continue; |
| 631 | if( access(azDirs[i], 07) ) continue; |
| 632 | zDir = azDirs[i]; |
| 633 | break; |
| 634 | } |
| 635 | |
| 636 | /* Check that the output buffer is large enough for the temporary file |
| @@ -646,11 +693,11 @@ | |
| 646 | sqlite3_randomness(15, &zBuf[j]); |
| 647 | for(i=0; i<15; i++, j++){ |
| 648 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 649 | } |
| 650 | zBuf[j] = 0; |
| 651 | }while( access(zBuf,0)==0 ); |
| 652 | } |
| 653 | |
| 654 | |
| 655 | /* |
| 656 | ** Return true if a file named zName exists and has identical content |
| @@ -668,5 +715,106 @@ | |
| 668 | blob_read_from_file(&onDisk, zName); |
| 669 | rc = blob_compare(&onDisk, pContent); |
| 670 | blob_reset(&onDisk); |
| 671 | return rc==0; |
| 672 | } |
| 673 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -47,17 +47,19 @@ | |
| 47 | static int getStat(const char *zFilename){ |
| 48 | int rc = 0; |
| 49 | if( zFilename==0 ){ |
| 50 | if( fileStatValid==0 ) rc = 1; |
| 51 | }else{ |
| 52 | char *zMbcs = fossil_utf8_to_mbcs(zFilename); |
| 53 | if( stat(zMbcs, &fileStat)!=0 ){ |
| 54 | fileStatValid = 0; |
| 55 | rc = 1; |
| 56 | }else{ |
| 57 | fileStatValid = 1; |
| 58 | rc = 0; |
| 59 | } |
| 60 | fossil_mbcs_free(zMbcs); |
| 61 | } |
| 62 | return rc; |
| 63 | } |
| 64 | |
| 65 | |
| @@ -120,10 +122,20 @@ | |
| 122 | }else{ |
| 123 | rc = getStat(0); |
| 124 | } |
| 125 | return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); |
| 126 | } |
| 127 | |
| 128 | /* |
| 129 | ** Wrapper around the access() system call. |
| 130 | */ |
| 131 | int file_access(const char *zFilename, int flags){ |
| 132 | char *zMbcs = fossil_utf8_to_mbcs(zFilename); |
| 133 | int rc = access(zMbcs, flags); |
| 134 | fossil_mbcs_free(zMbcs); |
| 135 | return rc; |
| 136 | } |
| 137 | |
| 138 | /* |
| 139 | ** Find an unused filename similar to zBase with zSuffix appended. |
| 140 | ** |
| 141 | ** Make the name relative to the working directory if relFlag is true. |
| @@ -166,13 +178,13 @@ | |
| 178 | */ |
| 179 | void file_copy(const char *zFrom, const char *zTo){ |
| 180 | FILE *in, *out; |
| 181 | int got; |
| 182 | char zBuf[8192]; |
| 183 | in = fossil_fopen(zFrom, "rb"); |
| 184 | if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); |
| 185 | out = fossil_fopen(zTo, "wb"); |
| 186 | if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); |
| 187 | while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 188 | fwrite(zBuf, 1, got, out); |
| 189 | } |
| 190 | fclose(in); |
| @@ -200,10 +212,19 @@ | |
| 212 | } |
| 213 | } |
| 214 | #endif /* _WIN32 */ |
| 215 | return rc; |
| 216 | } |
| 217 | |
| 218 | /* |
| 219 | ** Delete a file. |
| 220 | */ |
| 221 | void file_delete(const char *zFilename){ |
| 222 | char *z = fossil_utf8_to_mbcs(zFilename); |
| 223 | unlink(z); |
| 224 | fossil_mbcs_free(z); |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | ** Create the directory named in the argument, if it does not already |
| 229 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| 230 | ** with the same name. |
| @@ -212,15 +233,19 @@ | |
| 233 | */ |
| 234 | int file_mkdir(const char *zName, int forceFlag){ |
| 235 | int rc = file_isdir(zName); |
| 236 | if( rc==2 ){ |
| 237 | if( !forceFlag ) return 1; |
| 238 | file_delete(zName); |
| 239 | } |
| 240 | if( rc!=1 ){ |
| 241 | #if defined(_WIN32) |
| 242 | int rc; |
| 243 | char *zMbcs = fossil_utf8_to_mbcs(zName); |
| 244 | rc = mkdir(zMbcs); |
| 245 | fossil_mbcs_free(zMbcs); |
| 246 | return rc; |
| 247 | #else |
| 248 | return mkdir(zName, 0755); |
| 249 | #endif |
| 250 | } |
| 251 | return 0; |
| @@ -350,16 +375,47 @@ | |
| 375 | void cmd_test_simplify_name(void){ |
| 376 | int i; |
| 377 | char *z; |
| 378 | for(i=2; i<g.argc; i++){ |
| 379 | z = mprintf("%s", g.argv[i]); |
| 380 | fossil_print("[%s] -> ", z); |
| 381 | file_simplify_name(z, -1); |
| 382 | fossil_print("[%s]\n", z); |
| 383 | fossil_free(z); |
| 384 | } |
| 385 | } |
| 386 | |
| 387 | /* |
| 388 | ** Get the current working directory. |
| 389 | ** |
| 390 | ** On windows, the name is converted from MBCS to UTF8 and all '\\' |
| 391 | ** characters are converted to '/'. No conversions are needed on |
| 392 | ** unix. |
| 393 | */ |
| 394 | void file_getcwd(char *zBuf, int nBuf){ |
| 395 | #ifdef _WIN32 |
| 396 | char *zPwdUtf8; |
| 397 | int nPwd; |
| 398 | int i; |
| 399 | char zPwd[2000]; |
| 400 | if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){ |
| 401 | fossil_fatal("pwd too big: max %d\n", (int)sizeof(zPwd)-1); |
| 402 | } |
| 403 | zPwdUtf8 = fossil_mbcs_to_utf8(zPwd); |
| 404 | nPwd = strlen(zPwdUtf8); |
| 405 | if( nPwd > nBuf-1 ){ |
| 406 | fossil_fatal("pwd too big: max %d\n", nBuf-1); |
| 407 | } |
| 408 | for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/'; |
| 409 | memcpy(zBuf, zPwdUtf8, nPwd+1); |
| 410 | fossil_mbcs_free(zPwdUtf8); |
| 411 | #else |
| 412 | if( getcwd(zBuf, nBuf-1)==0 ){ |
| 413 | fossil_fatal("pwd too big: max %d\n", nBuf-1); |
| 414 | } |
| 415 | #endif |
| 416 | } |
| 417 | |
| 418 | /* |
| 419 | ** Compute a canonical pathname for a file or directory. |
| 420 | ** Make the name absolute if it is relative. |
| 421 | ** Remove redundant / characters |
| @@ -376,14 +432,11 @@ | |
| 432 | ){ |
| 433 | blob_set(pOut, zOrigName); |
| 434 | blob_materialize(pOut); |
| 435 | }else{ |
| 436 | char zPwd[2000]; |
| 437 | file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName)); |
| 438 | blob_zero(pOut); |
| 439 | blob_appendf(pOut, "%//%/", zPwd, zOrigName); |
| 440 | } |
| 441 | blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); |
| 442 | } |
| @@ -401,19 +454,19 @@ | |
| 454 | blob_zero(&x); |
| 455 | for(i=2; i<g.argc; i++){ |
| 456 | char zBuf[100]; |
| 457 | const char *zName = g.argv[i]; |
| 458 | file_canonical_name(zName, &x); |
| 459 | fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x)); |
| 460 | blob_reset(&x); |
| 461 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zName)); |
| 462 | fossil_print(" file_size = %s\n", zBuf); |
| 463 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_mtime(zName)); |
| 464 | fossil_print(" file_mtime = %s\n", zBuf); |
| 465 | fossil_print(" file_isfile = %d\n", file_isfile(zName)); |
| 466 | fossil_print(" file_isexe = %d\n", file_isexe(zName)); |
| 467 | fossil_print(" file_isdir = %d\n", file_isdir(zName)); |
| 468 | } |
| 469 | } |
| 470 | |
| 471 | /* |
| 472 | ** Return TRUE if the given filename is canonical. |
| @@ -452,14 +505,11 @@ | |
| 505 | zPath = blob_buffer(pOut); |
| 506 | if( zPath[0]=='/' ){ |
| 507 | int i, j; |
| 508 | Blob tmp; |
| 509 | char zPwd[2000]; |
| 510 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 511 | for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){} |
| 512 | if( zPath[i]==0 ){ |
| 513 | blob_reset(pOut); |
| 514 | if( zPwd[i]==0 ){ |
| 515 | blob_append(pOut, ".", 1); |
| @@ -502,11 +552,11 @@ | |
| 552 | int i; |
| 553 | Blob x; |
| 554 | blob_zero(&x); |
| 555 | for(i=2; i<g.argc; i++){ |
| 556 | file_relative_name(g.argv[i], &x); |
| 557 | fossil_print("%s\n", blob_buffer(&x)); |
| 558 | blob_reset(&x); |
| 559 | } |
| 560 | } |
| 561 | |
| 562 | /* |
| @@ -557,11 +607,11 @@ | |
| 607 | int i; |
| 608 | Blob x; |
| 609 | blob_zero(&x); |
| 610 | for(i=2; i<g.argc; i++){ |
| 611 | if( file_tree_name(g.argv[i], &x, 1) ){ |
| 612 | fossil_print("%s\n", blob_buffer(&x)); |
| 613 | blob_reset(&x); |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | |
| @@ -620,17 +670,14 @@ | |
| 670 | static const unsigned char zChars[] = |
| 671 | "abcdefghijklmnopqrstuvwxyz" |
| 672 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 673 | "0123456789"; |
| 674 | unsigned int i, j; |
| 675 | const char *zDir = "."; |
| 676 | |
| 677 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ |
| 678 | if( !file_isdir(azDirs[i]) ) continue; |
| 679 | zDir = azDirs[i]; |
| 680 | break; |
| 681 | } |
| 682 | |
| 683 | /* Check that the output buffer is large enough for the temporary file |
| @@ -646,11 +693,11 @@ | |
| 693 | sqlite3_randomness(15, &zBuf[j]); |
| 694 | for(i=0; i<15; i++, j++){ |
| 695 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 696 | } |
| 697 | zBuf[j] = 0; |
| 698 | }while( file_size(zBuf)<0 ); |
| 699 | } |
| 700 | |
| 701 | |
| 702 | /* |
| 703 | ** Return true if a file named zName exists and has identical content |
| @@ -668,5 +715,106 @@ | |
| 715 | blob_read_from_file(&onDisk, zName); |
| 716 | rc = blob_compare(&onDisk, pContent); |
| 717 | blob_reset(&onDisk); |
| 718 | return rc==0; |
| 719 | } |
| 720 | |
| 721 | |
| 722 | /************************************************************************** |
| 723 | ** The following routines translate between MBCS and UTF8 on windows. |
| 724 | ** Since everything is always UTF8 on unix, these routines are no-ops |
| 725 | ** there. |
| 726 | */ |
| 727 | #ifdef _WIN32 |
| 728 | # include <windows.h> |
| 729 | #endif |
| 730 | |
| 731 | /* |
| 732 | ** Translate MBCS to UTF8. Return a pointer to the translated text. |
| 733 | ** Call fossil_mbcs_free() to deallocate any memory used to store the |
| 734 | ** returned pointer when done. |
| 735 | */ |
| 736 | char *fossil_mbcs_to_utf8(const char *zMbcs){ |
| 737 | #ifdef _WIN32 |
| 738 | extern char *sqlite3_win32_mbcs_to_utf8(const char*); |
| 739 | return sqlite3_win32_mbcs_to_utf8(zMbcs); |
| 740 | #else |
| 741 | return (char*)zMbcs; /* No-op on unix */ |
| 742 | #endif |
| 743 | } |
| 744 | |
| 745 | /* |
| 746 | ** Translate UTF8 to MBCS for use in system calls. Return a pointer to the |
| 747 | ** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 748 | ** used to store the returned pointer when done. |
| 749 | */ |
| 750 | char *fossil_utf8_to_mbcs(const char *zUtf8){ |
| 751 | #ifdef _WIN32 |
| 752 | extern char *sqlite3_win32_utf8_to_mbcs(const char*); |
| 753 | return sqlite3_win32_utf8_to_mbcs(zUtf8); |
| 754 | #else |
| 755 | return (char*)zUtf8; /* No-op on unix */ |
| 756 | #endif |
| 757 | } |
| 758 | |
| 759 | /* |
| 760 | ** Translate UTF8 to MBCS for display on the console. Return a pointer to the |
| 761 | ** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 762 | ** used to store the returned pointer when done. |
| 763 | */ |
| 764 | char *fossil_utf8_to_console(const char *zUtf8){ |
| 765 | #ifdef _WIN32 |
| 766 | int nChar, nByte; |
| 767 | WCHAR *zUnicode; /* Unicode version of zUtf8 */ |
| 768 | char *zConsole; /* Console version of zUtf8 */ |
| 769 | int codepage; /* Console code page */ |
| 770 | |
| 771 | nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); |
| 772 | zUnicode = malloc( nChar*sizeof(zUnicode[0]) ); |
| 773 | if( zUnicode==0 ){ |
| 774 | return 0; |
| 775 | } |
| 776 | nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); |
| 777 | if( nChar==0 ){ |
| 778 | free(zUnicode); |
| 779 | return 0; |
| 780 | } |
| 781 | codepage = GetConsoleCP(); |
| 782 | nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0); |
| 783 | zConsole = malloc( nByte ); |
| 784 | if( zConsole==0 ){ |
| 785 | free(zUnicode); |
| 786 | return 0; |
| 787 | } |
| 788 | nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0); |
| 789 | free(zUnicode); |
| 790 | if( nByte == 0 ){ |
| 791 | free(zConsole); |
| 792 | zConsole = 0; |
| 793 | } |
| 794 | return zConsole; |
| 795 | #else |
| 796 | return (char*)zUtf8; /* No-op on unix */ |
| 797 | #endif |
| 798 | } |
| 799 | |
| 800 | /* |
| 801 | ** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() |
| 802 | ** to deallocate any memory used to store the returned pointer when done. |
| 803 | */ |
| 804 | void fossil_mbcs_free(char *zOld){ |
| 805 | #ifdef _WIN32 |
| 806 | free(zOld); |
| 807 | #else |
| 808 | /* No-op on unix */ |
| 809 | #endif |
| 810 | } |
| 811 | |
| 812 | /* |
| 813 | ** Like fopen() but always takes a UTF8 argument. |
| 814 | */ |
| 815 | FILE *fossil_fopen(const char *zName, const char *zMode){ |
| 816 | char *zMbcs = fossil_utf8_to_mbcs(zName); |
| 817 | FILE *f = fopen(zMbcs, zMode); |
| 818 | fossil_mbcs_free(zMbcs); |
| 819 | return f; |
| 820 | } |
| 821 |
+3
-3
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -89,11 +89,11 @@ | ||
| 89 | 89 | blob_reset(&uuid); |
| 90 | 90 | }else{ |
| 91 | 91 | blob_appendf(&line, "unknown 0000000000"); |
| 92 | 92 | } |
| 93 | 93 | db_finalize(&q); |
| 94 | - printf("%s\n", blob_str(&line)); | |
| 94 | + fossil_print("%s\n", blob_str(&line)); | |
| 95 | 95 | blob_reset(&fname); |
| 96 | 96 | blob_reset(&line); |
| 97 | 97 | }else if( find_option("print","p",0) ){ |
| 98 | 98 | Blob record; |
| 99 | 99 | Blob fname; |
| @@ -152,21 +152,21 @@ | ||
| 152 | 152 | " ORDER BY event.mtime DESC LIMIT %d OFFSET %d", |
| 153 | 153 | zFilename, iLimit, iOffset |
| 154 | 154 | ); |
| 155 | 155 | blob_zero(&line); |
| 156 | 156 | if( iBrief ){ |
| 157 | - printf("History of %s\n", blob_str(&fname)); | |
| 157 | + fossil_print("History of %s\n", blob_str(&fname)); | |
| 158 | 158 | } |
| 159 | 159 | while( db_step(&q)==SQLITE_ROW ){ |
| 160 | 160 | const char *zFileUuid = db_column_text(&q, 0); |
| 161 | 161 | const char *zCiUuid = db_column_text(&q,1); |
| 162 | 162 | const char *zDate = db_column_text(&q, 2); |
| 163 | 163 | const char *zCom = db_column_text(&q, 3); |
| 164 | 164 | const char *zUser = db_column_text(&q, 4); |
| 165 | 165 | char *zOut; |
| 166 | 166 | if( iBrief ){ |
| 167 | - printf("%s ", zDate); | |
| 167 | + fossil_print("%s ", zDate); | |
| 168 | 168 | zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])", |
| 169 | 169 | zCiUuid, zCom, zUser, zFileUuid); |
| 170 | 170 | comment_print(zOut, 11, 79); |
| 171 | 171 | sqlite3_free(zOut); |
| 172 | 172 | }else{ |
| 173 | 173 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -89,11 +89,11 @@ | |
| 89 | blob_reset(&uuid); |
| 90 | }else{ |
| 91 | blob_appendf(&line, "unknown 0000000000"); |
| 92 | } |
| 93 | db_finalize(&q); |
| 94 | printf("%s\n", blob_str(&line)); |
| 95 | blob_reset(&fname); |
| 96 | blob_reset(&line); |
| 97 | }else if( find_option("print","p",0) ){ |
| 98 | Blob record; |
| 99 | Blob fname; |
| @@ -152,21 +152,21 @@ | |
| 152 | " ORDER BY event.mtime DESC LIMIT %d OFFSET %d", |
| 153 | zFilename, iLimit, iOffset |
| 154 | ); |
| 155 | blob_zero(&line); |
| 156 | if( iBrief ){ |
| 157 | printf("History of %s\n", blob_str(&fname)); |
| 158 | } |
| 159 | while( db_step(&q)==SQLITE_ROW ){ |
| 160 | const char *zFileUuid = db_column_text(&q, 0); |
| 161 | const char *zCiUuid = db_column_text(&q,1); |
| 162 | const char *zDate = db_column_text(&q, 2); |
| 163 | const char *zCom = db_column_text(&q, 3); |
| 164 | const char *zUser = db_column_text(&q, 4); |
| 165 | char *zOut; |
| 166 | if( iBrief ){ |
| 167 | printf("%s ", zDate); |
| 168 | zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])", |
| 169 | zCiUuid, zCom, zUser, zFileUuid); |
| 170 | comment_print(zOut, 11, 79); |
| 171 | sqlite3_free(zOut); |
| 172 | }else{ |
| 173 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -89,11 +89,11 @@ | |
| 89 | blob_reset(&uuid); |
| 90 | }else{ |
| 91 | blob_appendf(&line, "unknown 0000000000"); |
| 92 | } |
| 93 | db_finalize(&q); |
| 94 | fossil_print("%s\n", blob_str(&line)); |
| 95 | blob_reset(&fname); |
| 96 | blob_reset(&line); |
| 97 | }else if( find_option("print","p",0) ){ |
| 98 | Blob record; |
| 99 | Blob fname; |
| @@ -152,21 +152,21 @@ | |
| 152 | " ORDER BY event.mtime DESC LIMIT %d OFFSET %d", |
| 153 | zFilename, iLimit, iOffset |
| 154 | ); |
| 155 | blob_zero(&line); |
| 156 | if( iBrief ){ |
| 157 | fossil_print("History of %s\n", blob_str(&fname)); |
| 158 | } |
| 159 | while( db_step(&q)==SQLITE_ROW ){ |
| 160 | const char *zFileUuid = db_column_text(&q, 0); |
| 161 | const char *zCiUuid = db_column_text(&q,1); |
| 162 | const char *zDate = db_column_text(&q, 2); |
| 163 | const char *zCom = db_column_text(&q, 3); |
| 164 | const char *zUser = db_column_text(&q, 4); |
| 165 | char *zOut; |
| 166 | if( iBrief ){ |
| 167 | fossil_print("%s ", zDate); |
| 168 | zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])", |
| 169 | zCiUuid, zCom, zUser, zFileUuid); |
| 170 | comment_print(zOut, 11, 79); |
| 171 | sqlite3_free(zOut); |
| 172 | }else{ |
| 173 |
+4
-4
| --- src/glob.c | ||
| +++ src/glob.c | ||
| @@ -58,11 +58,11 @@ | ||
| 58 | 58 | } |
| 59 | 59 | for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){} |
| 60 | 60 | if( cTerm==',' ){ |
| 61 | 61 | while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; } |
| 62 | 62 | } |
| 63 | - blob_appendf(&expr, "%s%s GLOB '%.*q'", zSep, zVal, i, zGlobList); | |
| 63 | + blob_appendf(&expr, "%s%s GLOB '%#q'", zSep, zVal, i, zGlobList); | |
| 64 | 64 | zSep = " OR "; |
| 65 | 65 | if( cTerm!=',' && zGlobList[i] ) i++; |
| 66 | 66 | zGlobList += i; |
| 67 | 67 | if( zGlobList[0] ) zGlobList++; |
| 68 | 68 | nTerm++; |
| @@ -250,15 +250,15 @@ | ||
| 250 | 250 | */ |
| 251 | 251 | void glob_test_cmd(void){ |
| 252 | 252 | Glob *pGlob; |
| 253 | 253 | int i; |
| 254 | 254 | if( g.argc<4 ) usage("PATTERN STRING ..."); |
| 255 | - printf("SQL expression: %s\n", glob_expr("x", g.argv[2])); | |
| 255 | + fossil_print("SQL expression: %s\n", glob_expr("x", g.argv[2])); | |
| 256 | 256 | pGlob = glob_create(g.argv[2]); |
| 257 | 257 | for(i=0; i<pGlob->nPattern; i++){ |
| 258 | - printf("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]); | |
| 258 | + fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]); | |
| 259 | 259 | } |
| 260 | 260 | for(i=3; i<g.argc; i++){ |
| 261 | - printf("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]); | |
| 261 | + fossil_print("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]); | |
| 262 | 262 | } |
| 263 | 263 | glob_free(pGlob); |
| 264 | 264 | } |
| 265 | 265 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -58,11 +58,11 @@ | |
| 58 | } |
| 59 | for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){} |
| 60 | if( cTerm==',' ){ |
| 61 | while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; } |
| 62 | } |
| 63 | blob_appendf(&expr, "%s%s GLOB '%.*q'", zSep, zVal, i, zGlobList); |
| 64 | zSep = " OR "; |
| 65 | if( cTerm!=',' && zGlobList[i] ) i++; |
| 66 | zGlobList += i; |
| 67 | if( zGlobList[0] ) zGlobList++; |
| 68 | nTerm++; |
| @@ -250,15 +250,15 @@ | |
| 250 | */ |
| 251 | void glob_test_cmd(void){ |
| 252 | Glob *pGlob; |
| 253 | int i; |
| 254 | if( g.argc<4 ) usage("PATTERN STRING ..."); |
| 255 | printf("SQL expression: %s\n", glob_expr("x", g.argv[2])); |
| 256 | pGlob = glob_create(g.argv[2]); |
| 257 | for(i=0; i<pGlob->nPattern; i++){ |
| 258 | printf("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]); |
| 259 | } |
| 260 | for(i=3; i<g.argc; i++){ |
| 261 | printf("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]); |
| 262 | } |
| 263 | glob_free(pGlob); |
| 264 | } |
| 265 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -58,11 +58,11 @@ | |
| 58 | } |
| 59 | for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){} |
| 60 | if( cTerm==',' ){ |
| 61 | while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; } |
| 62 | } |
| 63 | blob_appendf(&expr, "%s%s GLOB '%#q'", zSep, zVal, i, zGlobList); |
| 64 | zSep = " OR "; |
| 65 | if( cTerm!=',' && zGlobList[i] ) i++; |
| 66 | zGlobList += i; |
| 67 | if( zGlobList[0] ) zGlobList++; |
| 68 | nTerm++; |
| @@ -250,15 +250,15 @@ | |
| 250 | */ |
| 251 | void glob_test_cmd(void){ |
| 252 | Glob *pGlob; |
| 253 | int i; |
| 254 | if( g.argc<4 ) usage("PATTERN STRING ..."); |
| 255 | fossil_print("SQL expression: %s\n", glob_expr("x", g.argv[2])); |
| 256 | pGlob = glob_create(g.argv[2]); |
| 257 | for(i=0; i<pGlob->nPattern; i++){ |
| 258 | fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]); |
| 259 | } |
| 260 | for(i=3; i<g.argc; i++){ |
| 261 | fossil_print("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]); |
| 262 | } |
| 263 | glob_free(pGlob); |
| 264 | } |
| 265 |
+2
-2
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -39,11 +39,11 @@ | ||
| 39 | 39 | const char *zPw; /* The user password */ |
| 40 | 40 | Blob pw; /* The nonce with user password appended */ |
| 41 | 41 | Blob sig; /* The signature field */ |
| 42 | 42 | |
| 43 | 43 | blob_zero(pLogin); |
| 44 | - if( g.urlUser==0 || strcmp(g.urlUser, "anonymous")==0 ){ | |
| 44 | + if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ | |
| 45 | 45 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 46 | 46 | } |
| 47 | 47 | if( g.urlIsSsh ){ |
| 48 | 48 | return; /* If no login card for SSH: */ |
| 49 | 49 | } |
| @@ -233,11 +233,11 @@ | ||
| 233 | 233 | }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){ |
| 234 | 234 | int i, j; |
| 235 | 235 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 236 | 236 | if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); |
| 237 | 237 | j = strlen(zLine) - 1; |
| 238 | - while( j>4 && strcmp(&zLine[j-4],"/xfer")==0 ){ | |
| 238 | + while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){ | |
| 239 | 239 | j -= 4; |
| 240 | 240 | zLine[j] = 0; |
| 241 | 241 | } |
| 242 | 242 | fossil_print("redirect to %s\n", &zLine[i]); |
| 243 | 243 | url_parse(&zLine[i]); |
| 244 | 244 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -39,11 +39,11 @@ | |
| 39 | const char *zPw; /* The user password */ |
| 40 | Blob pw; /* The nonce with user password appended */ |
| 41 | Blob sig; /* The signature field */ |
| 42 | |
| 43 | blob_zero(pLogin); |
| 44 | if( g.urlUser==0 || strcmp(g.urlUser, "anonymous")==0 ){ |
| 45 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 46 | } |
| 47 | if( g.urlIsSsh ){ |
| 48 | return; /* If no login card for SSH: */ |
| 49 | } |
| @@ -233,11 +233,11 @@ | |
| 233 | }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){ |
| 234 | int i, j; |
| 235 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 236 | if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); |
| 237 | j = strlen(zLine) - 1; |
| 238 | while( j>4 && strcmp(&zLine[j-4],"/xfer")==0 ){ |
| 239 | j -= 4; |
| 240 | zLine[j] = 0; |
| 241 | } |
| 242 | fossil_print("redirect to %s\n", &zLine[i]); |
| 243 | url_parse(&zLine[i]); |
| 244 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -39,11 +39,11 @@ | |
| 39 | const char *zPw; /* The user password */ |
| 40 | Blob pw; /* The nonce with user password appended */ |
| 41 | Blob sig; /* The signature field */ |
| 42 | |
| 43 | blob_zero(pLogin); |
| 44 | if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ |
| 45 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 46 | } |
| 47 | if( g.urlIsSsh ){ |
| 48 | return; /* If no login card for SSH: */ |
| 49 | } |
| @@ -233,11 +233,11 @@ | |
| 233 | }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){ |
| 234 | int i, j; |
| 235 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 236 | if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); |
| 237 | j = strlen(zLine) - 1; |
| 238 | while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){ |
| 239 | j -= 4; |
| 240 | zLine[j] = 0; |
| 241 | } |
| 242 | fossil_print("redirect to %s\n", &zLine[i]); |
| 243 | url_parse(&zLine[i]); |
| 244 |
+9
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -182,15 +182,24 @@ | ||
| 182 | 182 | if( SSL_get_verify_result(ssl) != X509_V_OK ){ |
| 183 | 183 | char *desc, *prompt; |
| 184 | 184 | char *warning = ""; |
| 185 | 185 | Blob ans; |
| 186 | 186 | BIO *mem; |
| 187 | + unsigned char md[32]; | |
| 188 | + unsigned int mdLength = 31; | |
| 187 | 189 | |
| 188 | 190 | mem = BIO_new(BIO_s_mem()); |
| 189 | 191 | X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE); |
| 190 | 192 | BIO_puts(mem, "\n\nIssued By:\n\n"); |
| 191 | 193 | X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE); |
| 194 | + BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n "); | |
| 195 | + if(X509_digest(cert, EVP_sha1(), md, &mdLength)){ | |
| 196 | + int j; | |
| 197 | + for( j = 0; j < mdLength; ++j ) { | |
| 198 | + BIO_printf(mem, " %02x", md[j]); | |
| 199 | + } | |
| 200 | + } | |
| 192 | 201 | BIO_write(mem, "", 1); // null-terminate mem buffer |
| 193 | 202 | BIO_get_mem_data(mem, &desc); |
| 194 | 203 | |
| 195 | 204 | if( hasSavedCertificate ){ |
| 196 | 205 | warning = "WARNING: Certificate doesn't match the " |
| 197 | 206 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -182,15 +182,24 @@ | |
| 182 | if( SSL_get_verify_result(ssl) != X509_V_OK ){ |
| 183 | char *desc, *prompt; |
| 184 | char *warning = ""; |
| 185 | Blob ans; |
| 186 | BIO *mem; |
| 187 | |
| 188 | mem = BIO_new(BIO_s_mem()); |
| 189 | X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE); |
| 190 | BIO_puts(mem, "\n\nIssued By:\n\n"); |
| 191 | X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE); |
| 192 | BIO_write(mem, "", 1); // null-terminate mem buffer |
| 193 | BIO_get_mem_data(mem, &desc); |
| 194 | |
| 195 | if( hasSavedCertificate ){ |
| 196 | warning = "WARNING: Certificate doesn't match the " |
| 197 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -182,15 +182,24 @@ | |
| 182 | if( SSL_get_verify_result(ssl) != X509_V_OK ){ |
| 183 | char *desc, *prompt; |
| 184 | char *warning = ""; |
| 185 | Blob ans; |
| 186 | BIO *mem; |
| 187 | unsigned char md[32]; |
| 188 | unsigned int mdLength = 31; |
| 189 | |
| 190 | mem = BIO_new(BIO_s_mem()); |
| 191 | X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE); |
| 192 | BIO_puts(mem, "\n\nIssued By:\n\n"); |
| 193 | X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE); |
| 194 | BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n "); |
| 195 | if(X509_digest(cert, EVP_sha1(), md, &mdLength)){ |
| 196 | int j; |
| 197 | for( j = 0; j < mdLength; ++j ) { |
| 198 | BIO_printf(mem, " %02x", md[j]); |
| 199 | } |
| 200 | } |
| 201 | BIO_write(mem, "", 1); // null-terminate mem buffer |
| 202 | BIO_get_mem_data(mem, &desc); |
| 203 | |
| 204 | if( hasSavedCertificate ){ |
| 205 | warning = "WARNING: Certificate doesn't match the " |
| 206 |
+5
-5
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -120,11 +120,11 @@ | ||
| 120 | 120 | blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 121 | 121 | #else |
| 122 | 122 | blob_appendf(&zCmd, " -p %d", g.urlPort); |
| 123 | 123 | #endif |
| 124 | 124 | } |
| 125 | - printf("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ | |
| 125 | + fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ | |
| 126 | 126 | if( g.urlUser && g.urlUser[0] ){ |
| 127 | 127 | zHost = mprintf("%s@%s", g.urlUser, g.urlName); |
| 128 | 128 | #ifdef __MINGW32__ |
| 129 | 129 | /* Only win32 (and specifically PLINK.EXE) support the -pw option */ |
| 130 | 130 | if( g.urlPasswd && g.urlPasswd[0] ){ |
| @@ -139,19 +139,19 @@ | ||
| 139 | 139 | blob_init(&pw, g.urlPasswd, -1); |
| 140 | 140 | } |
| 141 | 141 | blob_append(&zCmd, " -pw ", -1); |
| 142 | 142 | shell_escape(&zCmd, blob_str(&pw)); |
| 143 | 143 | blob_reset(&pw); |
| 144 | - printf(" -pw ********"); /* Do not show the password text */ | |
| 144 | + fossil_print(" -pw ********"); /* Do not show the password text */ | |
| 145 | 145 | } |
| 146 | 146 | #endif |
| 147 | 147 | }else{ |
| 148 | 148 | zHost = mprintf("%s", g.urlName); |
| 149 | 149 | } |
| 150 | 150 | blob_append(&zCmd, " ", 1); |
| 151 | 151 | shell_escape(&zCmd, zHost); |
| 152 | - printf(" %s\n", zHost); /* Show the conclusion of the SSH command */ | |
| 152 | + fossil_print(" %s\n", zHost); /* Show the conclusion of the SSH command */ | |
| 153 | 153 | free(zHost); |
| 154 | 154 | popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); |
| 155 | 155 | if( sshPid==0 ){ |
| 156 | 156 | fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 157 | 157 | } |
| @@ -246,12 +246,12 @@ | ||
| 246 | 246 | }else if( g.urlIsFile ){ |
| 247 | 247 | if( transport.pFile ){ |
| 248 | 248 | fclose(transport.pFile); |
| 249 | 249 | transport.pFile = 0; |
| 250 | 250 | } |
| 251 | - unlink(transport.zInFile); | |
| 252 | - unlink(transport.zOutFile); | |
| 251 | + file_delete(transport.zInFile); | |
| 252 | + file_delete(transport.zOutFile); | |
| 253 | 253 | free(transport.zInFile); |
| 254 | 254 | free(transport.zOutFile); |
| 255 | 255 | }else{ |
| 256 | 256 | socket_close(); |
| 257 | 257 | } |
| 258 | 258 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -120,11 +120,11 @@ | |
| 120 | blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 121 | #else |
| 122 | blob_appendf(&zCmd, " -p %d", g.urlPort); |
| 123 | #endif |
| 124 | } |
| 125 | printf("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ |
| 126 | if( g.urlUser && g.urlUser[0] ){ |
| 127 | zHost = mprintf("%s@%s", g.urlUser, g.urlName); |
| 128 | #ifdef __MINGW32__ |
| 129 | /* Only win32 (and specifically PLINK.EXE) support the -pw option */ |
| 130 | if( g.urlPasswd && g.urlPasswd[0] ){ |
| @@ -139,19 +139,19 @@ | |
| 139 | blob_init(&pw, g.urlPasswd, -1); |
| 140 | } |
| 141 | blob_append(&zCmd, " -pw ", -1); |
| 142 | shell_escape(&zCmd, blob_str(&pw)); |
| 143 | blob_reset(&pw); |
| 144 | printf(" -pw ********"); /* Do not show the password text */ |
| 145 | } |
| 146 | #endif |
| 147 | }else{ |
| 148 | zHost = mprintf("%s", g.urlName); |
| 149 | } |
| 150 | blob_append(&zCmd, " ", 1); |
| 151 | shell_escape(&zCmd, zHost); |
| 152 | printf(" %s\n", zHost); /* Show the conclusion of the SSH command */ |
| 153 | free(zHost); |
| 154 | popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); |
| 155 | if( sshPid==0 ){ |
| 156 | fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 157 | } |
| @@ -246,12 +246,12 @@ | |
| 246 | }else if( g.urlIsFile ){ |
| 247 | if( transport.pFile ){ |
| 248 | fclose(transport.pFile); |
| 249 | transport.pFile = 0; |
| 250 | } |
| 251 | unlink(transport.zInFile); |
| 252 | unlink(transport.zOutFile); |
| 253 | free(transport.zInFile); |
| 254 | free(transport.zOutFile); |
| 255 | }else{ |
| 256 | socket_close(); |
| 257 | } |
| 258 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -120,11 +120,11 @@ | |
| 120 | blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 121 | #else |
| 122 | blob_appendf(&zCmd, " -p %d", g.urlPort); |
| 123 | #endif |
| 124 | } |
| 125 | fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ |
| 126 | if( g.urlUser && g.urlUser[0] ){ |
| 127 | zHost = mprintf("%s@%s", g.urlUser, g.urlName); |
| 128 | #ifdef __MINGW32__ |
| 129 | /* Only win32 (and specifically PLINK.EXE) support the -pw option */ |
| 130 | if( g.urlPasswd && g.urlPasswd[0] ){ |
| @@ -139,19 +139,19 @@ | |
| 139 | blob_init(&pw, g.urlPasswd, -1); |
| 140 | } |
| 141 | blob_append(&zCmd, " -pw ", -1); |
| 142 | shell_escape(&zCmd, blob_str(&pw)); |
| 143 | blob_reset(&pw); |
| 144 | fossil_print(" -pw ********"); /* Do not show the password text */ |
| 145 | } |
| 146 | #endif |
| 147 | }else{ |
| 148 | zHost = mprintf("%s", g.urlName); |
| 149 | } |
| 150 | blob_append(&zCmd, " ", 1); |
| 151 | shell_escape(&zCmd, zHost); |
| 152 | fossil_print(" %s\n", zHost); /* Show the conclusion of the SSH command */ |
| 153 | free(zHost); |
| 154 | popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); |
| 155 | if( sshPid==0 ){ |
| 156 | fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 157 | } |
| @@ -246,12 +246,12 @@ | |
| 246 | }else if( g.urlIsFile ){ |
| 247 | if( transport.pFile ){ |
| 248 | fclose(transport.pFile); |
| 249 | transport.pFile = 0; |
| 250 | } |
| 251 | file_delete(transport.zInFile); |
| 252 | file_delete(transport.zOutFile); |
| 253 | free(transport.zInFile); |
| 254 | free(transport.zOutFile); |
| 255 | }else{ |
| 256 | socket_close(); |
| 257 | } |
| 258 |
+9
-9
| --- src/import.c | ||
| +++ src/import.c | ||
| @@ -205,11 +205,11 @@ | ||
| 205 | 205 | ** Compare two ImportFile objects for sorting |
| 206 | 206 | */ |
| 207 | 207 | static int mfile_cmp(const void *pLeft, const void *pRight){ |
| 208 | 208 | const ImportFile *pA = (const ImportFile*)pLeft; |
| 209 | 209 | const ImportFile *pB = (const ImportFile*)pRight; |
| 210 | - return strcmp(pA->zName, pB->zName); | |
| 210 | + return fossil_strcmp(pA->zName, pB->zName); | |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | /* Forward reference */ |
| 214 | 214 | static void import_prior_files(void); |
| 215 | 215 | |
| @@ -497,11 +497,11 @@ | ||
| 497 | 497 | gg.xFinish(); |
| 498 | 498 | }else |
| 499 | 499 | if( memcmp(zLine, "progress ", 9)==0 ){ |
| 500 | 500 | gg.xFinish(); |
| 501 | 501 | trim_newline(&zLine[9]); |
| 502 | - printf("%s\n", &zLine[9]); | |
| 502 | + fossil_print("%s\n", &zLine[9]); | |
| 503 | 503 | fflush(stdout); |
| 504 | 504 | }else |
| 505 | 505 | if( memcmp(zLine, "data ", 5)==0 ){ |
| 506 | 506 | fossil_free(gg.aData); gg.aData = 0; |
| 507 | 507 | gg.nData = atoi(&zLine[5]); |
| @@ -697,11 +697,11 @@ | ||
| 697 | 697 | }else{ |
| 698 | 698 | pIn = stdin; |
| 699 | 699 | fossil_binary_mode(pIn); |
| 700 | 700 | } |
| 701 | 701 | if( !incrFlag ){ |
| 702 | - if( forceFlag ) unlink(g.argv[2]); | |
| 702 | + if( forceFlag ) file_delete(g.argv[2]); | |
| 703 | 703 | db_create_repository(g.argv[2]); |
| 704 | 704 | } |
| 705 | 705 | db_open_repository(g.argv[2]); |
| 706 | 706 | db_open_config(0); |
| 707 | 707 | |
| @@ -742,19 +742,19 @@ | ||
| 742 | 742 | import_reset(0); |
| 743 | 743 | } |
| 744 | 744 | db_finalize(&q); |
| 745 | 745 | db_end_transaction(0); |
| 746 | 746 | db_begin_transaction(); |
| 747 | - printf("Rebuilding repository meta-data...\n"); | |
| 747 | + fossil_print("Rebuilding repository meta-data...\n"); | |
| 748 | 748 | rebuild_db(0, 1, !incrFlag); |
| 749 | 749 | verify_cancel(); |
| 750 | 750 | db_end_transaction(0); |
| 751 | - printf("Vacuuming..."); fflush(stdout); | |
| 751 | + fossil_print("Vacuuming..."); fflush(stdout); | |
| 752 | 752 | db_multi_exec("VACUUM"); |
| 753 | - printf(" ok\n"); | |
| 753 | + fossil_print(" ok\n"); | |
| 754 | 754 | if( !incrFlag ){ |
| 755 | - printf("project-id: %s\n", db_get("project-code", 0)); | |
| 756 | - printf("server-id: %s\n", db_get("server-code", 0)); | |
| 755 | + fossil_print("project-id: %s\n", db_get("project-code", 0)); | |
| 756 | + fossil_print("server-id: %s\n", db_get("server-code", 0)); | |
| 757 | 757 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 758 | - printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); | |
| 758 | + fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); | |
| 759 | 759 | } |
| 760 | 760 | } |
| 761 | 761 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -205,11 +205,11 @@ | |
| 205 | ** Compare two ImportFile objects for sorting |
| 206 | */ |
| 207 | static int mfile_cmp(const void *pLeft, const void *pRight){ |
| 208 | const ImportFile *pA = (const ImportFile*)pLeft; |
| 209 | const ImportFile *pB = (const ImportFile*)pRight; |
| 210 | return strcmp(pA->zName, pB->zName); |
| 211 | } |
| 212 | |
| 213 | /* Forward reference */ |
| 214 | static void import_prior_files(void); |
| 215 | |
| @@ -497,11 +497,11 @@ | |
| 497 | gg.xFinish(); |
| 498 | }else |
| 499 | if( memcmp(zLine, "progress ", 9)==0 ){ |
| 500 | gg.xFinish(); |
| 501 | trim_newline(&zLine[9]); |
| 502 | printf("%s\n", &zLine[9]); |
| 503 | fflush(stdout); |
| 504 | }else |
| 505 | if( memcmp(zLine, "data ", 5)==0 ){ |
| 506 | fossil_free(gg.aData); gg.aData = 0; |
| 507 | gg.nData = atoi(&zLine[5]); |
| @@ -697,11 +697,11 @@ | |
| 697 | }else{ |
| 698 | pIn = stdin; |
| 699 | fossil_binary_mode(pIn); |
| 700 | } |
| 701 | if( !incrFlag ){ |
| 702 | if( forceFlag ) unlink(g.argv[2]); |
| 703 | db_create_repository(g.argv[2]); |
| 704 | } |
| 705 | db_open_repository(g.argv[2]); |
| 706 | db_open_config(0); |
| 707 | |
| @@ -742,19 +742,19 @@ | |
| 742 | import_reset(0); |
| 743 | } |
| 744 | db_finalize(&q); |
| 745 | db_end_transaction(0); |
| 746 | db_begin_transaction(); |
| 747 | printf("Rebuilding repository meta-data...\n"); |
| 748 | rebuild_db(0, 1, !incrFlag); |
| 749 | verify_cancel(); |
| 750 | db_end_transaction(0); |
| 751 | printf("Vacuuming..."); fflush(stdout); |
| 752 | db_multi_exec("VACUUM"); |
| 753 | printf(" ok\n"); |
| 754 | if( !incrFlag ){ |
| 755 | printf("project-id: %s\n", db_get("project-code", 0)); |
| 756 | printf("server-id: %s\n", db_get("server-code", 0)); |
| 757 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 758 | printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 759 | } |
| 760 | } |
| 761 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -205,11 +205,11 @@ | |
| 205 | ** Compare two ImportFile objects for sorting |
| 206 | */ |
| 207 | static int mfile_cmp(const void *pLeft, const void *pRight){ |
| 208 | const ImportFile *pA = (const ImportFile*)pLeft; |
| 209 | const ImportFile *pB = (const ImportFile*)pRight; |
| 210 | return fossil_strcmp(pA->zName, pB->zName); |
| 211 | } |
| 212 | |
| 213 | /* Forward reference */ |
| 214 | static void import_prior_files(void); |
| 215 | |
| @@ -497,11 +497,11 @@ | |
| 497 | gg.xFinish(); |
| 498 | }else |
| 499 | if( memcmp(zLine, "progress ", 9)==0 ){ |
| 500 | gg.xFinish(); |
| 501 | trim_newline(&zLine[9]); |
| 502 | fossil_print("%s\n", &zLine[9]); |
| 503 | fflush(stdout); |
| 504 | }else |
| 505 | if( memcmp(zLine, "data ", 5)==0 ){ |
| 506 | fossil_free(gg.aData); gg.aData = 0; |
| 507 | gg.nData = atoi(&zLine[5]); |
| @@ -697,11 +697,11 @@ | |
| 697 | }else{ |
| 698 | pIn = stdin; |
| 699 | fossil_binary_mode(pIn); |
| 700 | } |
| 701 | if( !incrFlag ){ |
| 702 | if( forceFlag ) file_delete(g.argv[2]); |
| 703 | db_create_repository(g.argv[2]); |
| 704 | } |
| 705 | db_open_repository(g.argv[2]); |
| 706 | db_open_config(0); |
| 707 | |
| @@ -742,19 +742,19 @@ | |
| 742 | import_reset(0); |
| 743 | } |
| 744 | db_finalize(&q); |
| 745 | db_end_transaction(0); |
| 746 | db_begin_transaction(); |
| 747 | fossil_print("Rebuilding repository meta-data...\n"); |
| 748 | rebuild_db(0, 1, !incrFlag); |
| 749 | verify_cancel(); |
| 750 | db_end_transaction(0); |
| 751 | fossil_print("Vacuuming..."); fflush(stdout); |
| 752 | db_multi_exec("VACUUM"); |
| 753 | fossil_print(" ok\n"); |
| 754 | if( !incrFlag ){ |
| 755 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 756 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 757 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 758 | fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); |
| 759 | } |
| 760 | } |
| 761 |
+36
-26
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -67,11 +67,11 @@ | ||
| 67 | 67 | zDate = db_text(0, |
| 68 | 68 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 69 | 69 | rid |
| 70 | 70 | ); |
| 71 | 71 | /* 01234567890123 */ |
| 72 | - printf("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); | |
| 72 | + fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); | |
| 73 | 73 | free(zUuid); |
| 74 | 74 | free(zDate); |
| 75 | 75 | } |
| 76 | 76 | if( zUuid && showComment ){ |
| 77 | 77 | zComment = db_text(0, |
| @@ -88,11 +88,11 @@ | ||
| 88 | 88 | const char *zUuid = db_column_text(&q, 0); |
| 89 | 89 | zDate = db_text("", |
| 90 | 90 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 91 | 91 | db_column_int(&q, 1) |
| 92 | 92 | ); |
| 93 | - printf("parent: %s %s\n", zUuid, zDate); | |
| 93 | + fossil_print("parent: %s %s\n", zUuid, zDate); | |
| 94 | 94 | free(zDate); |
| 95 | 95 | } |
| 96 | 96 | db_finalize(&q); |
| 97 | 97 | db_prepare(&q, "SELECT uuid, cid FROM plink JOIN blob ON cid=rid " |
| 98 | 98 | " WHERE pid=%d", rid); |
| @@ -100,22 +100,22 @@ | ||
| 100 | 100 | const char *zUuid = db_column_text(&q, 0); |
| 101 | 101 | zDate = db_text("", |
| 102 | 102 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 103 | 103 | db_column_int(&q, 1) |
| 104 | 104 | ); |
| 105 | - printf("child: %s %s\n", zUuid, zDate); | |
| 105 | + fossil_print("child: %s %s\n", zUuid, zDate); | |
| 106 | 106 | free(zDate); |
| 107 | 107 | } |
| 108 | 108 | db_finalize(&q); |
| 109 | 109 | } |
| 110 | 110 | zTags = info_tags_of_checkin(rid, 0); |
| 111 | 111 | if( zTags && zTags[0] ){ |
| 112 | - printf("tags: %s\n", zTags); | |
| 112 | + fossil_print("tags: %s\n", zTags); | |
| 113 | 113 | } |
| 114 | 114 | free(zTags); |
| 115 | 115 | if( zComment ){ |
| 116 | - printf("comment: "); | |
| 116 | + fossil_print("comment: "); | |
| 117 | 117 | comment_print(zComment, 14, 79); |
| 118 | 118 | free(zComment); |
| 119 | 119 | } |
| 120 | 120 | } |
| 121 | 121 | |
| @@ -141,33 +141,33 @@ | ||
| 141 | 141 | } |
| 142 | 142 | if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ |
| 143 | 143 | db_open_config(0); |
| 144 | 144 | db_record_repository_filename(g.argv[2]); |
| 145 | 145 | db_open_repository(g.argv[2]); |
| 146 | - printf("project-name: %s\n", db_get("project-name", "<unnamed>")); | |
| 147 | - printf("project-code: %s\n", db_get("project-code", "<none>")); | |
| 148 | - printf("server-code: %s\n", db_get("server-code", "<none>")); | |
| 146 | + fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); | |
| 147 | + fossil_print("project-code: %s\n", db_get("project-code", "<none>")); | |
| 148 | + fossil_print("server-code: %s\n", db_get("server-code", "<none>")); | |
| 149 | 149 | return; |
| 150 | 150 | } |
| 151 | 151 | db_must_be_within_tree(); |
| 152 | 152 | if( g.argc==2 ){ |
| 153 | 153 | int vid; |
| 154 | 154 | /* 012345678901234 */ |
| 155 | 155 | db_record_repository_filename(0); |
| 156 | - printf("project-name: %s\n", db_get("project-name", "<unnamed>")); | |
| 157 | - printf("repository: %s\n", db_lget("repository", "")); | |
| 158 | - printf("local-root: %s\n", g.zLocalRoot); | |
| 156 | + fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); | |
| 157 | + fossil_print("repository: %s\n", db_lget("repository", "")); | |
| 158 | + fossil_print("local-root: %s\n", g.zLocalRoot); | |
| 159 | 159 | #if defined(_WIN32) |
| 160 | 160 | if( g.zHome ){ |
| 161 | - printf("user-home: %s\n", g.zHome); | |
| 161 | + fossil_print("user-home: %s\n", g.zHome); | |
| 162 | 162 | } |
| 163 | 163 | #endif |
| 164 | - printf("project-code: %s\n", db_get("project-code", "")); | |
| 165 | - printf("server-code: %s\n", db_get("server-code", "")); | |
| 164 | + fossil_print("project-code: %s\n", db_get("project-code", "")); | |
| 165 | + fossil_print("server-code: %s\n", db_get("server-code", "")); | |
| 166 | 166 | vid = db_lget_int("checkout", 0); |
| 167 | 167 | if( vid==0 ){ |
| 168 | - printf("checkout: nil\n"); | |
| 168 | + fossil_print("checkout: nil\n"); | |
| 169 | 169 | }else{ |
| 170 | 170 | show_common_info(vid, "checkout:", 1, 1); |
| 171 | 171 | } |
| 172 | 172 | }else{ |
| 173 | 173 | int rid; |
| @@ -220,11 +220,11 @@ | ||
| 220 | 220 | hyperlink_to_uuid(zOrigUuid); |
| 221 | 221 | }else{ |
| 222 | 222 | @ propagates to descendants |
| 223 | 223 | } |
| 224 | 224 | #if 0 |
| 225 | - if( zValue && strcmp(zTagname,"branch")==0 ){ | |
| 225 | + if( zValue && fossil_strcmp(zTagname,"branch")==0 ){ | |
| 226 | 226 | @ |
| 227 | 227 | @ <a href="%s(g.zTop)/timeline?r=%T(zValue)">branch timeline</a> |
| 228 | 228 | } |
| 229 | 229 | #endif |
| 230 | 230 | } |
| @@ -280,18 +280,21 @@ | ||
| 280 | 280 | */ |
| 281 | 281 | static void append_file_change_line( |
| 282 | 282 | const char *zName, /* Name of the file that has changed */ |
| 283 | 283 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 284 | 284 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 285 | + const char *zOldName, /* Prior name. NULL if no name change. */ | |
| 285 | 286 | int showDiff, /* Show edit diffs if true */ |
| 286 | 287 | int mperm /* EXE permission for zNew */ |
| 287 | 288 | ){ |
| 288 | 289 | if( !g.okHistory ){ |
| 289 | 290 | if( zNew==0 ){ |
| 290 | 291 | @ <p>Deleted %h(zName)</p> |
| 291 | 292 | }else if( zOld==0 ){ |
| 292 | 293 | @ <p>Added %h(zName)</p> |
| 294 | + }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ | |
| 295 | + @ <p>Name change from %h(zOldName) to %h(zName) | |
| 293 | 296 | }else if( fossil_strcmp(zNew, zOld)==0 ){ |
| 294 | 297 | @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)</p> |
| 295 | 298 | }else{ |
| 296 | 299 | @ <p>Changes to %h(zName)</p> |
| 297 | 300 | } |
| @@ -304,10 +307,14 @@ | ||
| 304 | 307 | if( zOld && zNew ){ |
| 305 | 308 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 306 | 309 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 307 | 310 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 308 | 311 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 312 | + }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ | |
| 313 | + @ <p>Name change from | |
| 314 | + @ from <a href="%s(g.zTop)/finfo?name=%T(zOldName)">%h(zOldName)</a> | |
| 315 | + @ to <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>. | |
| 309 | 316 | }else{ |
| 310 | 317 | @ <p>Execute permission %s(mperm?"set":"cleared") for |
| 311 | 318 | @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 312 | 319 | } |
| 313 | 320 | }else if( zOld ){ |
| @@ -319,11 +326,11 @@ | ||
| 319 | 326 | } |
| 320 | 327 | if( showDiff ){ |
| 321 | 328 | @ <blockquote><pre> |
| 322 | 329 | append_diff(zOld, zNew); |
| 323 | 330 | @ </pre></blockquote> |
| 324 | - }else if( zOld && zNew ){ | |
| 331 | + }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ | |
| 325 | 332 | @ |
| 326 | 333 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 327 | 334 | } |
| 328 | 335 | @ </p> |
| 329 | 336 | } |
| @@ -511,13 +518,15 @@ | ||
| 511 | 518 | } |
| 512 | 519 | } |
| 513 | 520 | @ |
| 514 | 521 | @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> |
| 515 | 522 | db_prepare(&q, |
| 516 | - "SELECT name, mperm," | |
| 523 | + "SELECT name," | |
| 524 | + " mperm," | |
| 517 | 525 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 518 | - " (SELECT uuid FROM blob WHERE rid=mlink.fid)" | |
| 526 | + " (SELECT uuid FROM blob WHERE rid=mlink.fid)," | |
| 527 | + " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)" | |
| 519 | 528 | " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" |
| 520 | 529 | " WHERE mlink.mid=%d" |
| 521 | 530 | " ORDER BY name", |
| 522 | 531 | rid |
| 523 | 532 | ); |
| @@ -524,11 +533,12 @@ | ||
| 524 | 533 | while( db_step(&q)==SQLITE_ROW ){ |
| 525 | 534 | const char *zName = db_column_text(&q,0); |
| 526 | 535 | int mperm = db_column_int(&q, 1); |
| 527 | 536 | const char *zOld = db_column_text(&q,2); |
| 528 | 537 | const char *zNew = db_column_text(&q,3); |
| 529 | - append_file_change_line(zName, zOld, zNew, showDiff, mperm); | |
| 538 | + const char *zOldName = db_column_text(&q, 4); | |
| 539 | + append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm); | |
| 530 | 540 | } |
| 531 | 541 | db_finalize(&q); |
| 532 | 542 | } |
| 533 | 543 | style_footer(); |
| 534 | 544 | } |
| @@ -715,25 +725,25 @@ | ||
| 715 | 725 | }else{ |
| 716 | 726 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 717 | 727 | } |
| 718 | 728 | if( cmp<0 ){ |
| 719 | 729 | append_file_change_line(pFileFrom->zName, |
| 720 | - pFileFrom->zUuid, 0, 0, 0); | |
| 730 | + pFileFrom->zUuid, 0, 0, 0, 0); | |
| 721 | 731 | pFileFrom = manifest_file_next(pFrom, 0); |
| 722 | 732 | }else if( cmp>0 ){ |
| 723 | 733 | append_file_change_line(pFileTo->zName, |
| 724 | - 0, pFileTo->zUuid, 0, | |
| 734 | + 0, pFileTo->zUuid, 0, 0, | |
| 725 | 735 | manifest_file_mperm(pFileTo)); |
| 726 | 736 | pFileTo = manifest_file_next(pTo, 0); |
| 727 | 737 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 728 | 738 | /* No changes */ |
| 729 | 739 | pFileFrom = manifest_file_next(pFrom, 0); |
| 730 | 740 | pFileTo = manifest_file_next(pTo, 0); |
| 731 | 741 | }else{ |
| 732 | 742 | append_file_change_line(pFileFrom->zName, |
| 733 | 743 | pFileFrom->zUuid, |
| 734 | - pFileTo->zUuid, showDetail, | |
| 744 | + pFileTo->zUuid, 0, showDetail, | |
| 735 | 745 | manifest_file_mperm(pFileTo)); |
| 736 | 746 | pFileFrom = manifest_file_next(pFrom, 0); |
| 737 | 747 | pFileTo = manifest_file_next(pTo, 0); |
| 738 | 748 | } |
| 739 | 749 | } |
| @@ -1386,11 +1396,11 @@ | ||
| 1386 | 1396 | event_page(); |
| 1387 | 1397 | return; |
| 1388 | 1398 | } |
| 1389 | 1399 | } |
| 1390 | 1400 | blob_set(&uuid, zName); |
| 1391 | - rc = name_to_uuid(&uuid, -1); | |
| 1401 | + rc = name_to_uuid(&uuid, -1, "*"); | |
| 1392 | 1402 | if( rc==1 ){ |
| 1393 | 1403 | style_header("No Such Object"); |
| 1394 | 1404 | @ <p>No such object: %h(zName)</p> |
| 1395 | 1405 | style_footer(); |
| 1396 | 1406 | return; |
| @@ -1576,11 +1586,11 @@ | ||
| 1576 | 1586 | Blob comment; |
| 1577 | 1587 | Stmt q; |
| 1578 | 1588 | |
| 1579 | 1589 | login_check_credentials(); |
| 1580 | 1590 | if( !g.okWrite ){ login_needed(); return; } |
| 1581 | - rid = name_to_rid(P("r")); | |
| 1591 | + rid = name_to_typed_rid(P("r"), "ci"); | |
| 1582 | 1592 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1583 | 1593 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| 1584 | 1594 | " FROM event WHERE objid=%d", rid); |
| 1585 | 1595 | if( zComment==0 ) fossil_redirect_home(); |
| 1586 | 1596 | if( P("cancel") ){ |
| @@ -1619,11 +1629,11 @@ | ||
| 1619 | 1629 | blob_zero(&ctrl); |
| 1620 | 1630 | zNow = date_in_standard_format("now"); |
| 1621 | 1631 | blob_appendf(&ctrl, "D %s\n", zNow); |
| 1622 | 1632 | db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); |
| 1623 | 1633 | if( zNewColor[0] |
| 1624 | - && (fPropagateColor!=fNewPropagateColor || strcmp(zColor,zNewColor)!=0) | |
| 1634 | + && (fPropagateColor!=fNewPropagateColor || fossil_strcmp(zColor,zNewColor)!=0) | |
| 1625 | 1635 | ){ |
| 1626 | 1636 | char *zPrefix = "+"; |
| 1627 | 1637 | if( fNewPropagateColor ){ |
| 1628 | 1638 | zPrefix = "*"; |
| 1629 | 1639 | } |
| 1630 | 1640 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -67,11 +67,11 @@ | |
| 67 | zDate = db_text(0, |
| 68 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 69 | rid |
| 70 | ); |
| 71 | /* 01234567890123 */ |
| 72 | printf("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); |
| 73 | free(zUuid); |
| 74 | free(zDate); |
| 75 | } |
| 76 | if( zUuid && showComment ){ |
| 77 | zComment = db_text(0, |
| @@ -88,11 +88,11 @@ | |
| 88 | const char *zUuid = db_column_text(&q, 0); |
| 89 | zDate = db_text("", |
| 90 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 91 | db_column_int(&q, 1) |
| 92 | ); |
| 93 | printf("parent: %s %s\n", zUuid, zDate); |
| 94 | free(zDate); |
| 95 | } |
| 96 | db_finalize(&q); |
| 97 | db_prepare(&q, "SELECT uuid, cid FROM plink JOIN blob ON cid=rid " |
| 98 | " WHERE pid=%d", rid); |
| @@ -100,22 +100,22 @@ | |
| 100 | const char *zUuid = db_column_text(&q, 0); |
| 101 | zDate = db_text("", |
| 102 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 103 | db_column_int(&q, 1) |
| 104 | ); |
| 105 | printf("child: %s %s\n", zUuid, zDate); |
| 106 | free(zDate); |
| 107 | } |
| 108 | db_finalize(&q); |
| 109 | } |
| 110 | zTags = info_tags_of_checkin(rid, 0); |
| 111 | if( zTags && zTags[0] ){ |
| 112 | printf("tags: %s\n", zTags); |
| 113 | } |
| 114 | free(zTags); |
| 115 | if( zComment ){ |
| 116 | printf("comment: "); |
| 117 | comment_print(zComment, 14, 79); |
| 118 | free(zComment); |
| 119 | } |
| 120 | } |
| 121 | |
| @@ -141,33 +141,33 @@ | |
| 141 | } |
| 142 | if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ |
| 143 | db_open_config(0); |
| 144 | db_record_repository_filename(g.argv[2]); |
| 145 | db_open_repository(g.argv[2]); |
| 146 | printf("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| 147 | printf("project-code: %s\n", db_get("project-code", "<none>")); |
| 148 | printf("server-code: %s\n", db_get("server-code", "<none>")); |
| 149 | return; |
| 150 | } |
| 151 | db_must_be_within_tree(); |
| 152 | if( g.argc==2 ){ |
| 153 | int vid; |
| 154 | /* 012345678901234 */ |
| 155 | db_record_repository_filename(0); |
| 156 | printf("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| 157 | printf("repository: %s\n", db_lget("repository", "")); |
| 158 | printf("local-root: %s\n", g.zLocalRoot); |
| 159 | #if defined(_WIN32) |
| 160 | if( g.zHome ){ |
| 161 | printf("user-home: %s\n", g.zHome); |
| 162 | } |
| 163 | #endif |
| 164 | printf("project-code: %s\n", db_get("project-code", "")); |
| 165 | printf("server-code: %s\n", db_get("server-code", "")); |
| 166 | vid = db_lget_int("checkout", 0); |
| 167 | if( vid==0 ){ |
| 168 | printf("checkout: nil\n"); |
| 169 | }else{ |
| 170 | show_common_info(vid, "checkout:", 1, 1); |
| 171 | } |
| 172 | }else{ |
| 173 | int rid; |
| @@ -220,11 +220,11 @@ | |
| 220 | hyperlink_to_uuid(zOrigUuid); |
| 221 | }else{ |
| 222 | @ propagates to descendants |
| 223 | } |
| 224 | #if 0 |
| 225 | if( zValue && strcmp(zTagname,"branch")==0 ){ |
| 226 | @ |
| 227 | @ <a href="%s(g.zTop)/timeline?r=%T(zValue)">branch timeline</a> |
| 228 | } |
| 229 | #endif |
| 230 | } |
| @@ -280,18 +280,21 @@ | |
| 280 | */ |
| 281 | static void append_file_change_line( |
| 282 | const char *zName, /* Name of the file that has changed */ |
| 283 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 284 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 285 | int showDiff, /* Show edit diffs if true */ |
| 286 | int mperm /* EXE permission for zNew */ |
| 287 | ){ |
| 288 | if( !g.okHistory ){ |
| 289 | if( zNew==0 ){ |
| 290 | @ <p>Deleted %h(zName)</p> |
| 291 | }else if( zOld==0 ){ |
| 292 | @ <p>Added %h(zName)</p> |
| 293 | }else if( fossil_strcmp(zNew, zOld)==0 ){ |
| 294 | @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)</p> |
| 295 | }else{ |
| 296 | @ <p>Changes to %h(zName)</p> |
| 297 | } |
| @@ -304,10 +307,14 @@ | |
| 304 | if( zOld && zNew ){ |
| 305 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 306 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 307 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 308 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 309 | }else{ |
| 310 | @ <p>Execute permission %s(mperm?"set":"cleared") for |
| 311 | @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 312 | } |
| 313 | }else if( zOld ){ |
| @@ -319,11 +326,11 @@ | |
| 319 | } |
| 320 | if( showDiff ){ |
| 321 | @ <blockquote><pre> |
| 322 | append_diff(zOld, zNew); |
| 323 | @ </pre></blockquote> |
| 324 | }else if( zOld && zNew ){ |
| 325 | @ |
| 326 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 327 | } |
| 328 | @ </p> |
| 329 | } |
| @@ -511,13 +518,15 @@ | |
| 511 | } |
| 512 | } |
| 513 | @ |
| 514 | @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> |
| 515 | db_prepare(&q, |
| 516 | "SELECT name, mperm," |
| 517 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 518 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)" |
| 519 | " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" |
| 520 | " WHERE mlink.mid=%d" |
| 521 | " ORDER BY name", |
| 522 | rid |
| 523 | ); |
| @@ -524,11 +533,12 @@ | |
| 524 | while( db_step(&q)==SQLITE_ROW ){ |
| 525 | const char *zName = db_column_text(&q,0); |
| 526 | int mperm = db_column_int(&q, 1); |
| 527 | const char *zOld = db_column_text(&q,2); |
| 528 | const char *zNew = db_column_text(&q,3); |
| 529 | append_file_change_line(zName, zOld, zNew, showDiff, mperm); |
| 530 | } |
| 531 | db_finalize(&q); |
| 532 | } |
| 533 | style_footer(); |
| 534 | } |
| @@ -715,25 +725,25 @@ | |
| 715 | }else{ |
| 716 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 717 | } |
| 718 | if( cmp<0 ){ |
| 719 | append_file_change_line(pFileFrom->zName, |
| 720 | pFileFrom->zUuid, 0, 0, 0); |
| 721 | pFileFrom = manifest_file_next(pFrom, 0); |
| 722 | }else if( cmp>0 ){ |
| 723 | append_file_change_line(pFileTo->zName, |
| 724 | 0, pFileTo->zUuid, 0, |
| 725 | manifest_file_mperm(pFileTo)); |
| 726 | pFileTo = manifest_file_next(pTo, 0); |
| 727 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 728 | /* No changes */ |
| 729 | pFileFrom = manifest_file_next(pFrom, 0); |
| 730 | pFileTo = manifest_file_next(pTo, 0); |
| 731 | }else{ |
| 732 | append_file_change_line(pFileFrom->zName, |
| 733 | pFileFrom->zUuid, |
| 734 | pFileTo->zUuid, showDetail, |
| 735 | manifest_file_mperm(pFileTo)); |
| 736 | pFileFrom = manifest_file_next(pFrom, 0); |
| 737 | pFileTo = manifest_file_next(pTo, 0); |
| 738 | } |
| 739 | } |
| @@ -1386,11 +1396,11 @@ | |
| 1386 | event_page(); |
| 1387 | return; |
| 1388 | } |
| 1389 | } |
| 1390 | blob_set(&uuid, zName); |
| 1391 | rc = name_to_uuid(&uuid, -1); |
| 1392 | if( rc==1 ){ |
| 1393 | style_header("No Such Object"); |
| 1394 | @ <p>No such object: %h(zName)</p> |
| 1395 | style_footer(); |
| 1396 | return; |
| @@ -1576,11 +1586,11 @@ | |
| 1576 | Blob comment; |
| 1577 | Stmt q; |
| 1578 | |
| 1579 | login_check_credentials(); |
| 1580 | if( !g.okWrite ){ login_needed(); return; } |
| 1581 | rid = name_to_rid(P("r")); |
| 1582 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1583 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| 1584 | " FROM event WHERE objid=%d", rid); |
| 1585 | if( zComment==0 ) fossil_redirect_home(); |
| 1586 | if( P("cancel") ){ |
| @@ -1619,11 +1629,11 @@ | |
| 1619 | blob_zero(&ctrl); |
| 1620 | zNow = date_in_standard_format("now"); |
| 1621 | blob_appendf(&ctrl, "D %s\n", zNow); |
| 1622 | db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); |
| 1623 | if( zNewColor[0] |
| 1624 | && (fPropagateColor!=fNewPropagateColor || strcmp(zColor,zNewColor)!=0) |
| 1625 | ){ |
| 1626 | char *zPrefix = "+"; |
| 1627 | if( fNewPropagateColor ){ |
| 1628 | zPrefix = "*"; |
| 1629 | } |
| 1630 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -67,11 +67,11 @@ | |
| 67 | zDate = db_text(0, |
| 68 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 69 | rid |
| 70 | ); |
| 71 | /* 01234567890123 */ |
| 72 | fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); |
| 73 | free(zUuid); |
| 74 | free(zDate); |
| 75 | } |
| 76 | if( zUuid && showComment ){ |
| 77 | zComment = db_text(0, |
| @@ -88,11 +88,11 @@ | |
| 88 | const char *zUuid = db_column_text(&q, 0); |
| 89 | zDate = db_text("", |
| 90 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 91 | db_column_int(&q, 1) |
| 92 | ); |
| 93 | fossil_print("parent: %s %s\n", zUuid, zDate); |
| 94 | free(zDate); |
| 95 | } |
| 96 | db_finalize(&q); |
| 97 | db_prepare(&q, "SELECT uuid, cid FROM plink JOIN blob ON cid=rid " |
| 98 | " WHERE pid=%d", rid); |
| @@ -100,22 +100,22 @@ | |
| 100 | const char *zUuid = db_column_text(&q, 0); |
| 101 | zDate = db_text("", |
| 102 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 103 | db_column_int(&q, 1) |
| 104 | ); |
| 105 | fossil_print("child: %s %s\n", zUuid, zDate); |
| 106 | free(zDate); |
| 107 | } |
| 108 | db_finalize(&q); |
| 109 | } |
| 110 | zTags = info_tags_of_checkin(rid, 0); |
| 111 | if( zTags && zTags[0] ){ |
| 112 | fossil_print("tags: %s\n", zTags); |
| 113 | } |
| 114 | free(zTags); |
| 115 | if( zComment ){ |
| 116 | fossil_print("comment: "); |
| 117 | comment_print(zComment, 14, 79); |
| 118 | free(zComment); |
| 119 | } |
| 120 | } |
| 121 | |
| @@ -141,33 +141,33 @@ | |
| 141 | } |
| 142 | if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ |
| 143 | db_open_config(0); |
| 144 | db_record_repository_filename(g.argv[2]); |
| 145 | db_open_repository(g.argv[2]); |
| 146 | fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| 147 | fossil_print("project-code: %s\n", db_get("project-code", "<none>")); |
| 148 | fossil_print("server-code: %s\n", db_get("server-code", "<none>")); |
| 149 | return; |
| 150 | } |
| 151 | db_must_be_within_tree(); |
| 152 | if( g.argc==2 ){ |
| 153 | int vid; |
| 154 | /* 012345678901234 */ |
| 155 | db_record_repository_filename(0); |
| 156 | fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); |
| 157 | fossil_print("repository: %s\n", db_lget("repository", "")); |
| 158 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| 159 | #if defined(_WIN32) |
| 160 | if( g.zHome ){ |
| 161 | fossil_print("user-home: %s\n", g.zHome); |
| 162 | } |
| 163 | #endif |
| 164 | fossil_print("project-code: %s\n", db_get("project-code", "")); |
| 165 | fossil_print("server-code: %s\n", db_get("server-code", "")); |
| 166 | vid = db_lget_int("checkout", 0); |
| 167 | if( vid==0 ){ |
| 168 | fossil_print("checkout: nil\n"); |
| 169 | }else{ |
| 170 | show_common_info(vid, "checkout:", 1, 1); |
| 171 | } |
| 172 | }else{ |
| 173 | int rid; |
| @@ -220,11 +220,11 @@ | |
| 220 | hyperlink_to_uuid(zOrigUuid); |
| 221 | }else{ |
| 222 | @ propagates to descendants |
| 223 | } |
| 224 | #if 0 |
| 225 | if( zValue && fossil_strcmp(zTagname,"branch")==0 ){ |
| 226 | @ |
| 227 | @ <a href="%s(g.zTop)/timeline?r=%T(zValue)">branch timeline</a> |
| 228 | } |
| 229 | #endif |
| 230 | } |
| @@ -280,18 +280,21 @@ | |
| 280 | */ |
| 281 | static void append_file_change_line( |
| 282 | const char *zName, /* Name of the file that has changed */ |
| 283 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 284 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 285 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 286 | int showDiff, /* Show edit diffs if true */ |
| 287 | int mperm /* EXE permission for zNew */ |
| 288 | ){ |
| 289 | if( !g.okHistory ){ |
| 290 | if( zNew==0 ){ |
| 291 | @ <p>Deleted %h(zName)</p> |
| 292 | }else if( zOld==0 ){ |
| 293 | @ <p>Added %h(zName)</p> |
| 294 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| 295 | @ <p>Name change from %h(zOldName) to %h(zName) |
| 296 | }else if( fossil_strcmp(zNew, zOld)==0 ){ |
| 297 | @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)</p> |
| 298 | }else{ |
| 299 | @ <p>Changes to %h(zName)</p> |
| 300 | } |
| @@ -304,10 +307,14 @@ | |
| 307 | if( zOld && zNew ){ |
| 308 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 309 | @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 310 | @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> |
| 311 | @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> |
| 312 | }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ |
| 313 | @ <p>Name change from |
| 314 | @ from <a href="%s(g.zTop)/finfo?name=%T(zOldName)">%h(zOldName)</a> |
| 315 | @ to <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>. |
| 316 | }else{ |
| 317 | @ <p>Execute permission %s(mperm?"set":"cleared") for |
| 318 | @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 319 | } |
| 320 | }else if( zOld ){ |
| @@ -319,11 +326,11 @@ | |
| 326 | } |
| 327 | if( showDiff ){ |
| 328 | @ <blockquote><pre> |
| 329 | append_diff(zOld, zNew); |
| 330 | @ </pre></blockquote> |
| 331 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 332 | @ |
| 333 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 334 | } |
| 335 | @ </p> |
| 336 | } |
| @@ -511,13 +518,15 @@ | |
| 518 | } |
| 519 | } |
| 520 | @ |
| 521 | @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> |
| 522 | db_prepare(&q, |
| 523 | "SELECT name," |
| 524 | " mperm," |
| 525 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 526 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 527 | " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)" |
| 528 | " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" |
| 529 | " WHERE mlink.mid=%d" |
| 530 | " ORDER BY name", |
| 531 | rid |
| 532 | ); |
| @@ -524,11 +533,12 @@ | |
| 533 | while( db_step(&q)==SQLITE_ROW ){ |
| 534 | const char *zName = db_column_text(&q,0); |
| 535 | int mperm = db_column_int(&q, 1); |
| 536 | const char *zOld = db_column_text(&q,2); |
| 537 | const char *zNew = db_column_text(&q,3); |
| 538 | const char *zOldName = db_column_text(&q, 4); |
| 539 | append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm); |
| 540 | } |
| 541 | db_finalize(&q); |
| 542 | } |
| 543 | style_footer(); |
| 544 | } |
| @@ -715,25 +725,25 @@ | |
| 725 | }else{ |
| 726 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 727 | } |
| 728 | if( cmp<0 ){ |
| 729 | append_file_change_line(pFileFrom->zName, |
| 730 | pFileFrom->zUuid, 0, 0, 0, 0); |
| 731 | pFileFrom = manifest_file_next(pFrom, 0); |
| 732 | }else if( cmp>0 ){ |
| 733 | append_file_change_line(pFileTo->zName, |
| 734 | 0, pFileTo->zUuid, 0, 0, |
| 735 | manifest_file_mperm(pFileTo)); |
| 736 | pFileTo = manifest_file_next(pTo, 0); |
| 737 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 738 | /* No changes */ |
| 739 | pFileFrom = manifest_file_next(pFrom, 0); |
| 740 | pFileTo = manifest_file_next(pTo, 0); |
| 741 | }else{ |
| 742 | append_file_change_line(pFileFrom->zName, |
| 743 | pFileFrom->zUuid, |
| 744 | pFileTo->zUuid, 0, showDetail, |
| 745 | manifest_file_mperm(pFileTo)); |
| 746 | pFileFrom = manifest_file_next(pFrom, 0); |
| 747 | pFileTo = manifest_file_next(pTo, 0); |
| 748 | } |
| 749 | } |
| @@ -1386,11 +1396,11 @@ | |
| 1396 | event_page(); |
| 1397 | return; |
| 1398 | } |
| 1399 | } |
| 1400 | blob_set(&uuid, zName); |
| 1401 | rc = name_to_uuid(&uuid, -1, "*"); |
| 1402 | if( rc==1 ){ |
| 1403 | style_header("No Such Object"); |
| 1404 | @ <p>No such object: %h(zName)</p> |
| 1405 | style_footer(); |
| 1406 | return; |
| @@ -1576,11 +1586,11 @@ | |
| 1586 | Blob comment; |
| 1587 | Stmt q; |
| 1588 | |
| 1589 | login_check_credentials(); |
| 1590 | if( !g.okWrite ){ login_needed(); return; } |
| 1591 | rid = name_to_typed_rid(P("r"), "ci"); |
| 1592 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1593 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| 1594 | " FROM event WHERE objid=%d", rid); |
| 1595 | if( zComment==0 ) fossil_redirect_home(); |
| 1596 | if( P("cancel") ){ |
| @@ -1619,11 +1629,11 @@ | |
| 1629 | blob_zero(&ctrl); |
| 1630 | zNow = date_in_standard_format("now"); |
| 1631 | blob_appendf(&ctrl, "D %s\n", zNow); |
| 1632 | db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); |
| 1633 | if( zNewColor[0] |
| 1634 | && (fPropagateColor!=fNewPropagateColor || fossil_strcmp(zColor,zNewColor)!=0) |
| 1635 | ){ |
| 1636 | char *zPrefix = "+"; |
| 1637 | if( fNewPropagateColor ){ |
| 1638 | zPrefix = "*"; |
| 1639 | } |
| 1640 |
+9
-5
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -152,11 +152,11 @@ | ||
| 152 | 152 | const char *zPw; /* The correct password shown in the captcha */ |
| 153 | 153 | int uid; /* The user ID of anonymous */ |
| 154 | 154 | |
| 155 | 155 | if( zUsername==0 ) return 0; |
| 156 | 156 | if( zPassword==0 ) return 0; |
| 157 | - if( strcmp(zUsername,"anonymous")!=0 ) return 0; | |
| 157 | + if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; | |
| 158 | 158 | zCS = P("cs"); /* The "cs" parameter is the "captcha seed" */ |
| 159 | 159 | if( zCS==0 ) return 0; |
| 160 | 160 | zPw = captcha_decode((unsigned int)atoi(zCS)); |
| 161 | 161 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 162 | 162 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| @@ -480,10 +480,12 @@ | ||
| 480 | 480 | ); |
| 481 | 481 | if( zOtherRepo==0 ) return 0; /* No such peer repository */ |
| 482 | 482 | |
| 483 | 483 | rc = sqlite3_open(zOtherRepo, &pOther); |
| 484 | 484 | if( rc==SQLITE_OK ){ |
| 485 | + sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0); | |
| 486 | + sqlite3_busy_timeout(pOther, 5000); | |
| 485 | 487 | zSQL = mprintf( |
| 486 | 488 | "SELECT cexpire FROM user" |
| 487 | 489 | " WHERE cookie=%Q" |
| 488 | 490 | " AND ipaddr=%Q" |
| 489 | 491 | " AND login=%Q" |
| @@ -561,11 +563,11 @@ | ||
| 561 | 563 | ** |
| 562 | 564 | ** This feature allows the "fossil ui" command to give the user |
| 563 | 565 | ** full access rights without having to log in. |
| 564 | 566 | */ |
| 565 | 567 | zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil")); |
| 566 | - if( strcmp(zIpAddr, "127.0.0.1")==0 | |
| 568 | + if( fossil_strcmp(zIpAddr, "127.0.0.1")==0 | |
| 567 | 569 | && g.useLocalauth |
| 568 | 570 | && db_get_int("localauth",0)==0 |
| 569 | 571 | && P("HTTPS")==0 |
| 570 | 572 | ){ |
| 571 | 573 | uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'"); |
| @@ -594,11 +596,11 @@ | ||
| 594 | 596 | } |
| 595 | 597 | } |
| 596 | 598 | } |
| 597 | 599 | if( zUser==0 ){ |
| 598 | 600 | /* Invalid cookie */ |
| 599 | - }else if( strcmp(zUser, "anonymous")==0 ){ | |
| 601 | + }else if( fossil_strcmp(zUser, "anonymous")==0 ){ | |
| 600 | 602 | /* Cookies of the form "HASH/TIME/anonymous". The TIME must not be |
| 601 | 603 | ** too old and the sha1 hash of TIME/IPADDR/SECRET must match HASH. |
| 602 | 604 | ** SECRET is the "captcha-secret" value in the repository. |
| 603 | 605 | */ |
| 604 | 606 | double rTime = atof(zArg); |
| @@ -963,11 +965,11 @@ | ||
| 963 | 965 | @ </span></p> |
| 964 | 966 | }else if( strlen(zPasswd) < 6){ |
| 965 | 967 | @ <p><span class="loginError"> |
| 966 | 968 | @ Password too weak. |
| 967 | 969 | @ </span></p> |
| 968 | - }else if( strcmp(zPasswd,zConfirm)!=0 ){ | |
| 970 | + }else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){ | |
| 969 | 971 | @ <p><span class="loginError"> |
| 970 | 972 | @ The two copies of your new passwords do not match. |
| 971 | 973 | @ </span></p> |
| 972 | 974 | }else if( fossil_stricmp(zPw, zCap)!=0 ){ |
| 973 | 975 | @ <p><span class="loginError"> |
| @@ -1127,10 +1129,12 @@ | ||
| 1127 | 1129 | sqlite3_close(pPeer); |
| 1128 | 1130 | continue; |
| 1129 | 1131 | } |
| 1130 | 1132 | sqlite3_create_function(pPeer, "shared_secret", 3, SQLITE_UTF8, |
| 1131 | 1133 | 0, sha1_shared_secret_sql_function, 0, 0); |
| 1134 | + sqlite3_create_function(pPeer, "now", 0,SQLITE_ANY,0,db_now_function,0,0); | |
| 1135 | + sqlite3_busy_timeout(pPeer, 5000); | |
| 1132 | 1136 | zErr = 0; |
| 1133 | 1137 | rc = sqlite3_exec(pPeer, zSql, 0, 0, &zErr); |
| 1134 | 1138 | if( zErr ){ |
| 1135 | 1139 | blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, zErr, zSuffix); |
| 1136 | 1140 | sqlite3_free(zErr); |
| @@ -1192,11 +1196,11 @@ | ||
| 1192 | 1196 | if( zSelfLabel==0 ){ |
| 1193 | 1197 | zSelfLabel = zSelfProjCode; |
| 1194 | 1198 | } |
| 1195 | 1199 | |
| 1196 | 1200 | /* Make sure we are not trying to join ourselves */ |
| 1197 | - if( strcmp(zRepo, zSelfRepo)==0 ){ | |
| 1201 | + if( fossil_strcmp(zRepo, zSelfRepo)==0 ){ | |
| 1198 | 1202 | *pzErrMsg = mprintf("The \"other\" repository is the same as this one."); |
| 1199 | 1203 | return; |
| 1200 | 1204 | } |
| 1201 | 1205 | |
| 1202 | 1206 | /* Make sure the other repository is a valid Fossil database */ |
| 1203 | 1207 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -152,11 +152,11 @@ | |
| 152 | const char *zPw; /* The correct password shown in the captcha */ |
| 153 | int uid; /* The user ID of anonymous */ |
| 154 | |
| 155 | if( zUsername==0 ) return 0; |
| 156 | if( zPassword==0 ) return 0; |
| 157 | if( strcmp(zUsername,"anonymous")!=0 ) return 0; |
| 158 | zCS = P("cs"); /* The "cs" parameter is the "captcha seed" */ |
| 159 | if( zCS==0 ) return 0; |
| 160 | zPw = captcha_decode((unsigned int)atoi(zCS)); |
| 161 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 162 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| @@ -480,10 +480,12 @@ | |
| 480 | ); |
| 481 | if( zOtherRepo==0 ) return 0; /* No such peer repository */ |
| 482 | |
| 483 | rc = sqlite3_open(zOtherRepo, &pOther); |
| 484 | if( rc==SQLITE_OK ){ |
| 485 | zSQL = mprintf( |
| 486 | "SELECT cexpire FROM user" |
| 487 | " WHERE cookie=%Q" |
| 488 | " AND ipaddr=%Q" |
| 489 | " AND login=%Q" |
| @@ -561,11 +563,11 @@ | |
| 561 | ** |
| 562 | ** This feature allows the "fossil ui" command to give the user |
| 563 | ** full access rights without having to log in. |
| 564 | */ |
| 565 | zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil")); |
| 566 | if( strcmp(zIpAddr, "127.0.0.1")==0 |
| 567 | && g.useLocalauth |
| 568 | && db_get_int("localauth",0)==0 |
| 569 | && P("HTTPS")==0 |
| 570 | ){ |
| 571 | uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'"); |
| @@ -594,11 +596,11 @@ | |
| 594 | } |
| 595 | } |
| 596 | } |
| 597 | if( zUser==0 ){ |
| 598 | /* Invalid cookie */ |
| 599 | }else if( strcmp(zUser, "anonymous")==0 ){ |
| 600 | /* Cookies of the form "HASH/TIME/anonymous". The TIME must not be |
| 601 | ** too old and the sha1 hash of TIME/IPADDR/SECRET must match HASH. |
| 602 | ** SECRET is the "captcha-secret" value in the repository. |
| 603 | */ |
| 604 | double rTime = atof(zArg); |
| @@ -963,11 +965,11 @@ | |
| 963 | @ </span></p> |
| 964 | }else if( strlen(zPasswd) < 6){ |
| 965 | @ <p><span class="loginError"> |
| 966 | @ Password too weak. |
| 967 | @ </span></p> |
| 968 | }else if( strcmp(zPasswd,zConfirm)!=0 ){ |
| 969 | @ <p><span class="loginError"> |
| 970 | @ The two copies of your new passwords do not match. |
| 971 | @ </span></p> |
| 972 | }else if( fossil_stricmp(zPw, zCap)!=0 ){ |
| 973 | @ <p><span class="loginError"> |
| @@ -1127,10 +1129,12 @@ | |
| 1127 | sqlite3_close(pPeer); |
| 1128 | continue; |
| 1129 | } |
| 1130 | sqlite3_create_function(pPeer, "shared_secret", 3, SQLITE_UTF8, |
| 1131 | 0, sha1_shared_secret_sql_function, 0, 0); |
| 1132 | zErr = 0; |
| 1133 | rc = sqlite3_exec(pPeer, zSql, 0, 0, &zErr); |
| 1134 | if( zErr ){ |
| 1135 | blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, zErr, zSuffix); |
| 1136 | sqlite3_free(zErr); |
| @@ -1192,11 +1196,11 @@ | |
| 1192 | if( zSelfLabel==0 ){ |
| 1193 | zSelfLabel = zSelfProjCode; |
| 1194 | } |
| 1195 | |
| 1196 | /* Make sure we are not trying to join ourselves */ |
| 1197 | if( strcmp(zRepo, zSelfRepo)==0 ){ |
| 1198 | *pzErrMsg = mprintf("The \"other\" repository is the same as this one."); |
| 1199 | return; |
| 1200 | } |
| 1201 | |
| 1202 | /* Make sure the other repository is a valid Fossil database */ |
| 1203 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -152,11 +152,11 @@ | |
| 152 | const char *zPw; /* The correct password shown in the captcha */ |
| 153 | int uid; /* The user ID of anonymous */ |
| 154 | |
| 155 | if( zUsername==0 ) return 0; |
| 156 | if( zPassword==0 ) return 0; |
| 157 | if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; |
| 158 | zCS = P("cs"); /* The "cs" parameter is the "captcha seed" */ |
| 159 | if( zCS==0 ) return 0; |
| 160 | zPw = captcha_decode((unsigned int)atoi(zCS)); |
| 161 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 162 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| @@ -480,10 +480,12 @@ | |
| 480 | ); |
| 481 | if( zOtherRepo==0 ) return 0; /* No such peer repository */ |
| 482 | |
| 483 | rc = sqlite3_open(zOtherRepo, &pOther); |
| 484 | if( rc==SQLITE_OK ){ |
| 485 | sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0); |
| 486 | sqlite3_busy_timeout(pOther, 5000); |
| 487 | zSQL = mprintf( |
| 488 | "SELECT cexpire FROM user" |
| 489 | " WHERE cookie=%Q" |
| 490 | " AND ipaddr=%Q" |
| 491 | " AND login=%Q" |
| @@ -561,11 +563,11 @@ | |
| 563 | ** |
| 564 | ** This feature allows the "fossil ui" command to give the user |
| 565 | ** full access rights without having to log in. |
| 566 | */ |
| 567 | zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil")); |
| 568 | if( fossil_strcmp(zIpAddr, "127.0.0.1")==0 |
| 569 | && g.useLocalauth |
| 570 | && db_get_int("localauth",0)==0 |
| 571 | && P("HTTPS")==0 |
| 572 | ){ |
| 573 | uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'"); |
| @@ -594,11 +596,11 @@ | |
| 596 | } |
| 597 | } |
| 598 | } |
| 599 | if( zUser==0 ){ |
| 600 | /* Invalid cookie */ |
| 601 | }else if( fossil_strcmp(zUser, "anonymous")==0 ){ |
| 602 | /* Cookies of the form "HASH/TIME/anonymous". The TIME must not be |
| 603 | ** too old and the sha1 hash of TIME/IPADDR/SECRET must match HASH. |
| 604 | ** SECRET is the "captcha-secret" value in the repository. |
| 605 | */ |
| 606 | double rTime = atof(zArg); |
| @@ -963,11 +965,11 @@ | |
| 965 | @ </span></p> |
| 966 | }else if( strlen(zPasswd) < 6){ |
| 967 | @ <p><span class="loginError"> |
| 968 | @ Password too weak. |
| 969 | @ </span></p> |
| 970 | }else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){ |
| 971 | @ <p><span class="loginError"> |
| 972 | @ The two copies of your new passwords do not match. |
| 973 | @ </span></p> |
| 974 | }else if( fossil_stricmp(zPw, zCap)!=0 ){ |
| 975 | @ <p><span class="loginError"> |
| @@ -1127,10 +1129,12 @@ | |
| 1129 | sqlite3_close(pPeer); |
| 1130 | continue; |
| 1131 | } |
| 1132 | sqlite3_create_function(pPeer, "shared_secret", 3, SQLITE_UTF8, |
| 1133 | 0, sha1_shared_secret_sql_function, 0, 0); |
| 1134 | sqlite3_create_function(pPeer, "now", 0,SQLITE_ANY,0,db_now_function,0,0); |
| 1135 | sqlite3_busy_timeout(pPeer, 5000); |
| 1136 | zErr = 0; |
| 1137 | rc = sqlite3_exec(pPeer, zSql, 0, 0, &zErr); |
| 1138 | if( zErr ){ |
| 1139 | blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, zErr, zSuffix); |
| 1140 | sqlite3_free(zErr); |
| @@ -1192,11 +1196,11 @@ | |
| 1196 | if( zSelfLabel==0 ){ |
| 1197 | zSelfLabel = zSelfProjCode; |
| 1198 | } |
| 1199 | |
| 1200 | /* Make sure we are not trying to join ourselves */ |
| 1201 | if( fossil_strcmp(zRepo, zSelfRepo)==0 ){ |
| 1202 | *pzErrMsg = mprintf("The \"other\" repository is the same as this one."); |
| 1203 | return; |
| 1204 | } |
| 1205 | |
| 1206 | /* Make sure the other repository is a valid Fossil database */ |
| 1207 |
+43
-48
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -65,10 +65,11 @@ | ||
| 65 | 65 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 66 | 66 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 67 | 67 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 68 | 68 | int fQuiet; /* True if -quiet flag is present */ |
| 69 | 69 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 70 | + int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ | |
| 70 | 71 | int fNoSync; /* Do not do an autosync even. --nosync */ |
| 71 | 72 | char *zPath; /* Name of webpage being served */ |
| 72 | 73 | char *zExtra; /* Extra path information past the webpage name */ |
| 73 | 74 | char *zBaseURL; /* Full text of the URL being served */ |
| 74 | 75 | char *zTop; /* Parent directory of zPath */ |
| @@ -195,11 +196,11 @@ | ||
| 195 | 196 | lwr = 0; |
| 196 | 197 | upr = nMap-1; |
| 197 | 198 | while( lwr<=upr ){ |
| 198 | 199 | int mid, c; |
| 199 | 200 | mid = (upr+lwr)/2; |
| 200 | - c = strcmp(zName, aMap[mid].zName); | |
| 201 | + c = fossil_strcmp(zName, aMap[mid].zName); | |
| 201 | 202 | if( c==0 ){ |
| 202 | 203 | *pIndex = mid; |
| 203 | 204 | return 0; |
| 204 | 205 | }else if( c<0 ){ |
| 205 | 206 | upr = mid - 1; |
| @@ -227,27 +228,29 @@ | ||
| 227 | 228 | */ |
| 228 | 229 | int main(int argc, char **argv){ |
| 229 | 230 | const char *zCmdName = "unknown"; |
| 230 | 231 | int idx; |
| 231 | 232 | int rc; |
| 233 | + int i; | |
| 232 | 234 | |
| 233 | 235 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 234 | 236 | g.now = time(0); |
| 235 | 237 | g.argc = argc; |
| 236 | 238 | g.argv = argv; |
| 239 | + for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); | |
| 237 | 240 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 238 | 241 | zCmdName = "cgi"; |
| 239 | 242 | }else if( argc<2 ){ |
| 240 | - fprintf(stderr, "Usage: %s COMMAND ...\n" | |
| 241 | - "\"%s help\" for a list of available commands\n" | |
| 242 | - "\"%s help COMMAND\" for specific details\n", | |
| 243 | - argv[0], argv[0], argv[0]); | |
| 244 | - fossil_exit(1); | |
| 243 | + fossil_fatal("Usage: %s COMMAND ...\n" | |
| 244 | + "\"%s help\" for a list of available commands\n" | |
| 245 | + "\"%s help COMMAND\" for specific details\n", | |
| 246 | + argv[0], argv[0], argv[0]); | |
| 245 | 247 | }else{ |
| 246 | 248 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 247 | 249 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 248 | 250 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 251 | + g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; | |
| 249 | 252 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 250 | 253 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 251 | 254 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 252 | 255 | g.zLogin = find_option("user", "U", 1); |
| 253 | 256 | if( find_option("help",0,0)!=0 ){ |
| @@ -264,14 +267,13 @@ | ||
| 264 | 267 | } |
| 265 | 268 | zCmdName = g.argv[1]; |
| 266 | 269 | } |
| 267 | 270 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 268 | 271 | if( rc==1 ){ |
| 269 | - fprintf(stderr,"%s: unknown command: %s\n" | |
| 270 | - "%s: use \"help\" for more information\n", | |
| 272 | + fossil_fatal("%s: unknown command: %s\n" | |
| 273 | + "%s: use \"help\" for more information\n", | |
| 271 | 274 | argv[0], zCmdName, argv[0]); |
| 272 | - fossil_exit(1); | |
| 273 | 275 | }else if( rc==2 ){ |
| 274 | 276 | int i, n; |
| 275 | 277 | Blob couldbe; |
| 276 | 278 | blob_zero(&couldbe); |
| 277 | 279 | n = strlen(zCmdName); |
| @@ -278,15 +280,14 @@ | ||
| 278 | 280 | for(i=0; i<count(aCommand); i++){ |
| 279 | 281 | if( memcmp(zCmdName, aCommand[i].zName, n)==0 ){ |
| 280 | 282 | blob_appendf(&couldbe, " %s", aCommand[i].zName); |
| 281 | 283 | } |
| 282 | 284 | } |
| 283 | - fprintf(stderr,"%s: ambiguous command prefix: %s\n" | |
| 284 | - "%s: could be any of:%s\n" | |
| 285 | - "%s: use \"help\" for more information\n", | |
| 286 | - argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); | |
| 287 | - fossil_exit(1); | |
| 285 | + fossil_fatal("%s: ambiguous command prefix: %s\n" | |
| 286 | + "%s: could be any of:%s\n" | |
| 287 | + "%s: use \"help\" for more information\n", | |
| 288 | + argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); | |
| 288 | 289 | } |
| 289 | 290 | aCommand[idx].xFunc(); |
| 290 | 291 | fossil_exit(0); |
| 291 | 292 | /*NOT_REACHED*/ |
| 292 | 293 | return 0; |
| @@ -333,11 +334,12 @@ | ||
| 333 | 334 | if( g.cgiOutput && once ){ |
| 334 | 335 | once = 0; |
| 335 | 336 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 336 | 337 | cgi_reply(); |
| 337 | 338 | }else{ |
| 338 | - fprintf(stderr, "%s: %s\n", fossil_nameofexe(), z); | |
| 339 | + char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); | |
| 340 | + fossil_puts(zOut, 1); | |
| 339 | 341 | } |
| 340 | 342 | db_force_rollback(); |
| 341 | 343 | fossil_exit(1); |
| 342 | 344 | } |
| 343 | 345 | void fossil_fatal(const char *zFormat, ...){ |
| @@ -350,11 +352,12 @@ | ||
| 350 | 352 | if( g.cgiOutput ){ |
| 351 | 353 | g.cgiOutput = 0; |
| 352 | 354 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 353 | 355 | cgi_reply(); |
| 354 | 356 | }else{ |
| 355 | - fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z); | |
| 357 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 358 | + fossil_puts(zOut, 1); | |
| 356 | 359 | } |
| 357 | 360 | db_force_rollback(); |
| 358 | 361 | fossil_exit(1); |
| 359 | 362 | } |
| 360 | 363 | |
| @@ -378,11 +381,12 @@ | ||
| 378 | 381 | if( g.cgiOutput ){ |
| 379 | 382 | g.cgiOutput = 0; |
| 380 | 383 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 381 | 384 | cgi_reply(); |
| 382 | 385 | }else{ |
| 383 | - fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z); | |
| 386 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 387 | + fossil_puts(zOut, 1); | |
| 384 | 388 | } |
| 385 | 389 | db_force_rollback(); |
| 386 | 390 | fossil_exit(1); |
| 387 | 391 | } |
| 388 | 392 | |
| @@ -395,11 +399,13 @@ | ||
| 395 | 399 | z = vmprintf(zFormat, ap); |
| 396 | 400 | va_end(ap); |
| 397 | 401 | if( g.cgiOutput ){ |
| 398 | 402 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 399 | 403 | }else{ |
| 400 | - fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z); | |
| 404 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 405 | + fossil_puts(zOut, 1); | |
| 406 | + free(zOut); | |
| 401 | 407 | } |
| 402 | 408 | } |
| 403 | 409 | |
| 404 | 410 | /* |
| 405 | 411 | ** Malloc and free routines that cannot fail |
| @@ -426,35 +432,24 @@ | ||
| 426 | 432 | #if defined(_WIN32) |
| 427 | 433 | /* On windows, we have to put double-quotes around the entire command. |
| 428 | 434 | ** Who knows why - this is just the way windows works. |
| 429 | 435 | */ |
| 430 | 436 | char *zNewCmd = mprintf("\"%s\"", zOrigCmd); |
| 431 | - rc = system(zNewCmd); | |
| 437 | + char *zMbcs = fossil_utf8_to_mbcs(zNewCmd); | |
| 438 | + if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zMbcs); | |
| 439 | + rc = system(zMbcs); | |
| 440 | + fossil_mbcs_free(zMbcs); | |
| 432 | 441 | free(zNewCmd); |
| 433 | 442 | #else |
| 434 | 443 | /* On unix, evaluate the command directly. |
| 435 | 444 | */ |
| 445 | + if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd); | |
| 436 | 446 | rc = system(zOrigCmd); |
| 437 | 447 | #endif |
| 438 | 448 | return rc; |
| 439 | 449 | } |
| 440 | 450 | |
| 441 | -/* | |
| 442 | -** Like strcmp() except that it accepts NULL pointers. NULL sorts before | |
| 443 | -** all non-NULL string pointers. | |
| 444 | -*/ | |
| 445 | -int fossil_strcmp(const char *zA, const char *zB){ | |
| 446 | - if( zA==0 ){ | |
| 447 | - if( zB==0 ) return 0; | |
| 448 | - return -1; | |
| 449 | - }else if( zB==0 ){ | |
| 450 | - return +1; | |
| 451 | - }else{ | |
| 452 | - return strcmp(zA,zB); | |
| 453 | - } | |
| 454 | -} | |
| 455 | - | |
| 456 | 451 | /* |
| 457 | 452 | ** Turn off any NL to CRNL translation on the stream given as an |
| 458 | 453 | ** argument. This is a no-op on unix but is necessary on windows. |
| 459 | 454 | */ |
| 460 | 455 | void fossil_binary_mode(FILE *p){ |
| @@ -507,12 +502,11 @@ | ||
| 507 | 502 | |
| 508 | 503 | /* |
| 509 | 504 | ** Print a usage comment and quit |
| 510 | 505 | */ |
| 511 | 506 | void usage(const char *zFormat){ |
| 512 | - fprintf(stderr, "Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat); | |
| 513 | - fossil_exit(1); | |
| 507 | + fossil_fatal("Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat); | |
| 514 | 508 | } |
| 515 | 509 | |
| 516 | 510 | /* |
| 517 | 511 | ** Remove n elements from g.argv beginning with the i-th element. |
| 518 | 512 | */ |
| @@ -601,14 +595,14 @@ | ||
| 601 | 595 | if( nCol==0 ) nCol = 1; |
| 602 | 596 | nRow = (nWord + nCol - 1)/nCol; |
| 603 | 597 | for(i=0; i<nRow; i++){ |
| 604 | 598 | const char *zSpacer = ""; |
| 605 | 599 | for(j=i; j<nWord; j+=nRow){ |
| 606 | - printf("%s%-*s", zSpacer, mxLen, azWord[j]); | |
| 600 | + fossil_print("%s%-*s", zSpacer, mxLen, azWord[j]); | |
| 607 | 601 | zSpacer = " "; |
| 608 | 602 | } |
| 609 | - printf("\n"); | |
| 603 | + fossil_print("\n"); | |
| 610 | 604 | } |
| 611 | 605 | } |
| 612 | 606 | |
| 613 | 607 | /* |
| 614 | 608 | ** List of commands starting with zPrefix, or all commands if zPrefix is NULL. |
| @@ -650,11 +644,12 @@ | ||
| 650 | 644 | ** Usage: %fossil version |
| 651 | 645 | ** |
| 652 | 646 | ** Print the source code version number for the fossil executable. |
| 653 | 647 | */ |
| 654 | 648 | void version_cmd(void){ |
| 655 | - printf("This is fossil version " MANIFEST_VERSION " " MANIFEST_DATE " UTC\n"); | |
| 649 | + fossil_print("This is fossil version " | |
| 650 | + MANIFEST_VERSION " " MANIFEST_DATE " UTC\n"); | |
| 656 | 651 | } |
| 657 | 652 | |
| 658 | 653 | |
| 659 | 654 | /* |
| 660 | 655 | ** COMMAND: help |
| @@ -665,12 +660,12 @@ | ||
| 665 | 660 | */ |
| 666 | 661 | void help_cmd(void){ |
| 667 | 662 | int rc, idx; |
| 668 | 663 | const char *z; |
| 669 | 664 | if( g.argc<3 ){ |
| 670 | - printf("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", | |
| 671 | - fossil_nameofexe()); | |
| 665 | + fossil_print("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", | |
| 666 | + fossil_nameofexe()); | |
| 672 | 667 | cmd_cmd_list(0); |
| 673 | 668 | version_cmd(); |
| 674 | 669 | return; |
| 675 | 670 | } |
| 676 | 671 | rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); |
| @@ -689,11 +684,11 @@ | ||
| 689 | 684 | fossil_fatal("no help available for the %s command", |
| 690 | 685 | aCommand[idx].zName); |
| 691 | 686 | } |
| 692 | 687 | while( *z ){ |
| 693 | 688 | if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ |
| 694 | - printf("%s", fossil_nameofexe()); | |
| 689 | + fossil_print("%s", fossil_nameofexe()); | |
| 695 | 690 | z += 7; |
| 696 | 691 | }else{ |
| 697 | 692 | putchar(*z); |
| 698 | 693 | z++; |
| 699 | 694 | } |
| @@ -918,11 +913,11 @@ | ||
| 918 | 913 | } |
| 919 | 914 | if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } |
| 920 | 915 | |
| 921 | 916 | szFile = file_size(zRepo); |
| 922 | 917 | if( zPathInfo[i]=='/' && szFile<0 ){ |
| 923 | - assert( strcmp(&zRepo[j], ".fossil")==0 ); | |
| 918 | + assert( fossil_strcmp(&zRepo[j], ".fossil")==0 ); | |
| 924 | 919 | zRepo[j] = 0; |
| 925 | 920 | if( file_isdir(zRepo)==1 ){ |
| 926 | 921 | fossil_free(zToFree); |
| 927 | 922 | i++; |
| 928 | 923 | continue; |
| @@ -1177,11 +1172,11 @@ | ||
| 1177 | 1172 | zName = P("SCRIPT_NAME"); |
| 1178 | 1173 | if( zName && zName[0]=='/' ) zName++; |
| 1179 | 1174 | } |
| 1180 | 1175 | if( zName && validate16(zName, strlen(zName)) ){ |
| 1181 | 1176 | for(i=0; i<nRedirect; i++){ |
| 1182 | - if( strcmp(azRedirect[i*2],"*")==0 ){ | |
| 1177 | + if( fossil_strcmp(azRedirect[i*2],"*")==0 ){ | |
| 1183 | 1178 | zNotFound = azRedirect[i*2+1]; |
| 1184 | 1179 | continue; |
| 1185 | 1180 | } |
| 1186 | 1181 | db_open_repository(azRedirect[i*2]); |
| 1187 | 1182 | if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){ |
| @@ -1281,12 +1276,12 @@ | ||
| 1281 | 1276 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 1282 | 1277 | fossil_fatal("no repository specified"); |
| 1283 | 1278 | } |
| 1284 | 1279 | g.fullHttpReply = 1; |
| 1285 | 1280 | if( g.argc==6 ){ |
| 1286 | - g.httpIn = fopen(g.argv[3], "rb"); | |
| 1287 | - g.httpOut = fopen(g.argv[4], "wb"); | |
| 1281 | + g.httpIn = fossil_fopen(g.argv[3], "rb"); | |
| 1282 | + g.httpOut = fossil_fopen(g.argv[4], "wb"); | |
| 1288 | 1283 | zIpAddr = g.argv[5]; |
| 1289 | 1284 | }else{ |
| 1290 | 1285 | g.httpIn = stdin; |
| 1291 | 1286 | g.httpOut = stdout; |
| 1292 | 1287 | zIpAddr = 0; |
| @@ -1327,11 +1322,11 @@ | ||
| 1327 | 1322 | int bExists; |
| 1328 | 1323 | while( zPath && zPath[0] ){ |
| 1329 | 1324 | while( zPath[0]==':' ) zPath++; |
| 1330 | 1325 | for(i=0; zPath[i] && zPath[i]!=':'; i++){} |
| 1331 | 1326 | zFull = mprintf("%.*s/%s", i, zPath, zBinary); |
| 1332 | - bExists = access(zFull, X_OK); | |
| 1327 | + bExists = file_access(zFull, X_OK); | |
| 1333 | 1328 | free(zFull); |
| 1334 | 1329 | if( bExists==0 ) return 1; |
| 1335 | 1330 | zPath += i; |
| 1336 | 1331 | } |
| 1337 | 1332 | return 0; |
| @@ -1455,8 +1450,8 @@ | ||
| 1455 | 1450 | ** wildcard expansion behavior of the host shell can be investigated. |
| 1456 | 1451 | */ |
| 1457 | 1452 | void test_echo_cmd(void){ |
| 1458 | 1453 | int i; |
| 1459 | 1454 | for(i=0; i<g.argc; i++){ |
| 1460 | - printf("argv[%d] = [%s]\n", i, g.argv[i]); | |
| 1455 | + fossil_print("argv[%d] = [%s]\n", i, g.argv[i]); | |
| 1461 | 1456 | } |
| 1462 | 1457 | } |
| 1463 | 1458 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -65,10 +65,11 @@ | |
| 65 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 66 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 67 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 68 | int fQuiet; /* True if -quiet flag is present */ |
| 69 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 70 | int fNoSync; /* Do not do an autosync even. --nosync */ |
| 71 | char *zPath; /* Name of webpage being served */ |
| 72 | char *zExtra; /* Extra path information past the webpage name */ |
| 73 | char *zBaseURL; /* Full text of the URL being served */ |
| 74 | char *zTop; /* Parent directory of zPath */ |
| @@ -195,11 +196,11 @@ | |
| 195 | lwr = 0; |
| 196 | upr = nMap-1; |
| 197 | while( lwr<=upr ){ |
| 198 | int mid, c; |
| 199 | mid = (upr+lwr)/2; |
| 200 | c = strcmp(zName, aMap[mid].zName); |
| 201 | if( c==0 ){ |
| 202 | *pIndex = mid; |
| 203 | return 0; |
| 204 | }else if( c<0 ){ |
| 205 | upr = mid - 1; |
| @@ -227,27 +228,29 @@ | |
| 227 | */ |
| 228 | int main(int argc, char **argv){ |
| 229 | const char *zCmdName = "unknown"; |
| 230 | int idx; |
| 231 | int rc; |
| 232 | |
| 233 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 234 | g.now = time(0); |
| 235 | g.argc = argc; |
| 236 | g.argv = argv; |
| 237 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 238 | zCmdName = "cgi"; |
| 239 | }else if( argc<2 ){ |
| 240 | fprintf(stderr, "Usage: %s COMMAND ...\n" |
| 241 | "\"%s help\" for a list of available commands\n" |
| 242 | "\"%s help COMMAND\" for specific details\n", |
| 243 | argv[0], argv[0], argv[0]); |
| 244 | fossil_exit(1); |
| 245 | }else{ |
| 246 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 247 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 248 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 249 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 250 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 251 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 252 | g.zLogin = find_option("user", "U", 1); |
| 253 | if( find_option("help",0,0)!=0 ){ |
| @@ -264,14 +267,13 @@ | |
| 264 | } |
| 265 | zCmdName = g.argv[1]; |
| 266 | } |
| 267 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 268 | if( rc==1 ){ |
| 269 | fprintf(stderr,"%s: unknown command: %s\n" |
| 270 | "%s: use \"help\" for more information\n", |
| 271 | argv[0], zCmdName, argv[0]); |
| 272 | fossil_exit(1); |
| 273 | }else if( rc==2 ){ |
| 274 | int i, n; |
| 275 | Blob couldbe; |
| 276 | blob_zero(&couldbe); |
| 277 | n = strlen(zCmdName); |
| @@ -278,15 +280,14 @@ | |
| 278 | for(i=0; i<count(aCommand); i++){ |
| 279 | if( memcmp(zCmdName, aCommand[i].zName, n)==0 ){ |
| 280 | blob_appendf(&couldbe, " %s", aCommand[i].zName); |
| 281 | } |
| 282 | } |
| 283 | fprintf(stderr,"%s: ambiguous command prefix: %s\n" |
| 284 | "%s: could be any of:%s\n" |
| 285 | "%s: use \"help\" for more information\n", |
| 286 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 287 | fossil_exit(1); |
| 288 | } |
| 289 | aCommand[idx].xFunc(); |
| 290 | fossil_exit(0); |
| 291 | /*NOT_REACHED*/ |
| 292 | return 0; |
| @@ -333,11 +334,12 @@ | |
| 333 | if( g.cgiOutput && once ){ |
| 334 | once = 0; |
| 335 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 336 | cgi_reply(); |
| 337 | }else{ |
| 338 | fprintf(stderr, "%s: %s\n", fossil_nameofexe(), z); |
| 339 | } |
| 340 | db_force_rollback(); |
| 341 | fossil_exit(1); |
| 342 | } |
| 343 | void fossil_fatal(const char *zFormat, ...){ |
| @@ -350,11 +352,12 @@ | |
| 350 | if( g.cgiOutput ){ |
| 351 | g.cgiOutput = 0; |
| 352 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 353 | cgi_reply(); |
| 354 | }else{ |
| 355 | fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z); |
| 356 | } |
| 357 | db_force_rollback(); |
| 358 | fossil_exit(1); |
| 359 | } |
| 360 | |
| @@ -378,11 +381,12 @@ | |
| 378 | if( g.cgiOutput ){ |
| 379 | g.cgiOutput = 0; |
| 380 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 381 | cgi_reply(); |
| 382 | }else{ |
| 383 | fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z); |
| 384 | } |
| 385 | db_force_rollback(); |
| 386 | fossil_exit(1); |
| 387 | } |
| 388 | |
| @@ -395,11 +399,13 @@ | |
| 395 | z = vmprintf(zFormat, ap); |
| 396 | va_end(ap); |
| 397 | if( g.cgiOutput ){ |
| 398 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 399 | }else{ |
| 400 | fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z); |
| 401 | } |
| 402 | } |
| 403 | |
| 404 | /* |
| 405 | ** Malloc and free routines that cannot fail |
| @@ -426,35 +432,24 @@ | |
| 426 | #if defined(_WIN32) |
| 427 | /* On windows, we have to put double-quotes around the entire command. |
| 428 | ** Who knows why - this is just the way windows works. |
| 429 | */ |
| 430 | char *zNewCmd = mprintf("\"%s\"", zOrigCmd); |
| 431 | rc = system(zNewCmd); |
| 432 | free(zNewCmd); |
| 433 | #else |
| 434 | /* On unix, evaluate the command directly. |
| 435 | */ |
| 436 | rc = system(zOrigCmd); |
| 437 | #endif |
| 438 | return rc; |
| 439 | } |
| 440 | |
| 441 | /* |
| 442 | ** Like strcmp() except that it accepts NULL pointers. NULL sorts before |
| 443 | ** all non-NULL string pointers. |
| 444 | */ |
| 445 | int fossil_strcmp(const char *zA, const char *zB){ |
| 446 | if( zA==0 ){ |
| 447 | if( zB==0 ) return 0; |
| 448 | return -1; |
| 449 | }else if( zB==0 ){ |
| 450 | return +1; |
| 451 | }else{ |
| 452 | return strcmp(zA,zB); |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | /* |
| 457 | ** Turn off any NL to CRNL translation on the stream given as an |
| 458 | ** argument. This is a no-op on unix but is necessary on windows. |
| 459 | */ |
| 460 | void fossil_binary_mode(FILE *p){ |
| @@ -507,12 +502,11 @@ | |
| 507 | |
| 508 | /* |
| 509 | ** Print a usage comment and quit |
| 510 | */ |
| 511 | void usage(const char *zFormat){ |
| 512 | fprintf(stderr, "Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat); |
| 513 | fossil_exit(1); |
| 514 | } |
| 515 | |
| 516 | /* |
| 517 | ** Remove n elements from g.argv beginning with the i-th element. |
| 518 | */ |
| @@ -601,14 +595,14 @@ | |
| 601 | if( nCol==0 ) nCol = 1; |
| 602 | nRow = (nWord + nCol - 1)/nCol; |
| 603 | for(i=0; i<nRow; i++){ |
| 604 | const char *zSpacer = ""; |
| 605 | for(j=i; j<nWord; j+=nRow){ |
| 606 | printf("%s%-*s", zSpacer, mxLen, azWord[j]); |
| 607 | zSpacer = " "; |
| 608 | } |
| 609 | printf("\n"); |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | /* |
| 614 | ** List of commands starting with zPrefix, or all commands if zPrefix is NULL. |
| @@ -650,11 +644,12 @@ | |
| 650 | ** Usage: %fossil version |
| 651 | ** |
| 652 | ** Print the source code version number for the fossil executable. |
| 653 | */ |
| 654 | void version_cmd(void){ |
| 655 | printf("This is fossil version " MANIFEST_VERSION " " MANIFEST_DATE " UTC\n"); |
| 656 | } |
| 657 | |
| 658 | |
| 659 | /* |
| 660 | ** COMMAND: help |
| @@ -665,12 +660,12 @@ | |
| 665 | */ |
| 666 | void help_cmd(void){ |
| 667 | int rc, idx; |
| 668 | const char *z; |
| 669 | if( g.argc<3 ){ |
| 670 | printf("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", |
| 671 | fossil_nameofexe()); |
| 672 | cmd_cmd_list(0); |
| 673 | version_cmd(); |
| 674 | return; |
| 675 | } |
| 676 | rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); |
| @@ -689,11 +684,11 @@ | |
| 689 | fossil_fatal("no help available for the %s command", |
| 690 | aCommand[idx].zName); |
| 691 | } |
| 692 | while( *z ){ |
| 693 | if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ |
| 694 | printf("%s", fossil_nameofexe()); |
| 695 | z += 7; |
| 696 | }else{ |
| 697 | putchar(*z); |
| 698 | z++; |
| 699 | } |
| @@ -918,11 +913,11 @@ | |
| 918 | } |
| 919 | if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } |
| 920 | |
| 921 | szFile = file_size(zRepo); |
| 922 | if( zPathInfo[i]=='/' && szFile<0 ){ |
| 923 | assert( strcmp(&zRepo[j], ".fossil")==0 ); |
| 924 | zRepo[j] = 0; |
| 925 | if( file_isdir(zRepo)==1 ){ |
| 926 | fossil_free(zToFree); |
| 927 | i++; |
| 928 | continue; |
| @@ -1177,11 +1172,11 @@ | |
| 1177 | zName = P("SCRIPT_NAME"); |
| 1178 | if( zName && zName[0]=='/' ) zName++; |
| 1179 | } |
| 1180 | if( zName && validate16(zName, strlen(zName)) ){ |
| 1181 | for(i=0; i<nRedirect; i++){ |
| 1182 | if( strcmp(azRedirect[i*2],"*")==0 ){ |
| 1183 | zNotFound = azRedirect[i*2+1]; |
| 1184 | continue; |
| 1185 | } |
| 1186 | db_open_repository(azRedirect[i*2]); |
| 1187 | if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){ |
| @@ -1281,12 +1276,12 @@ | |
| 1281 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 1282 | fossil_fatal("no repository specified"); |
| 1283 | } |
| 1284 | g.fullHttpReply = 1; |
| 1285 | if( g.argc==6 ){ |
| 1286 | g.httpIn = fopen(g.argv[3], "rb"); |
| 1287 | g.httpOut = fopen(g.argv[4], "wb"); |
| 1288 | zIpAddr = g.argv[5]; |
| 1289 | }else{ |
| 1290 | g.httpIn = stdin; |
| 1291 | g.httpOut = stdout; |
| 1292 | zIpAddr = 0; |
| @@ -1327,11 +1322,11 @@ | |
| 1327 | int bExists; |
| 1328 | while( zPath && zPath[0] ){ |
| 1329 | while( zPath[0]==':' ) zPath++; |
| 1330 | for(i=0; zPath[i] && zPath[i]!=':'; i++){} |
| 1331 | zFull = mprintf("%.*s/%s", i, zPath, zBinary); |
| 1332 | bExists = access(zFull, X_OK); |
| 1333 | free(zFull); |
| 1334 | if( bExists==0 ) return 1; |
| 1335 | zPath += i; |
| 1336 | } |
| 1337 | return 0; |
| @@ -1455,8 +1450,8 @@ | |
| 1455 | ** wildcard expansion behavior of the host shell can be investigated. |
| 1456 | */ |
| 1457 | void test_echo_cmd(void){ |
| 1458 | int i; |
| 1459 | for(i=0; i<g.argc; i++){ |
| 1460 | printf("argv[%d] = [%s]\n", i, g.argv[i]); |
| 1461 | } |
| 1462 | } |
| 1463 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -65,10 +65,11 @@ | |
| 65 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 66 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 67 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 68 | int fQuiet; /* True if -quiet flag is present */ |
| 69 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 70 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 71 | int fNoSync; /* Do not do an autosync even. --nosync */ |
| 72 | char *zPath; /* Name of webpage being served */ |
| 73 | char *zExtra; /* Extra path information past the webpage name */ |
| 74 | char *zBaseURL; /* Full text of the URL being served */ |
| 75 | char *zTop; /* Parent directory of zPath */ |
| @@ -195,11 +196,11 @@ | |
| 196 | lwr = 0; |
| 197 | upr = nMap-1; |
| 198 | while( lwr<=upr ){ |
| 199 | int mid, c; |
| 200 | mid = (upr+lwr)/2; |
| 201 | c = fossil_strcmp(zName, aMap[mid].zName); |
| 202 | if( c==0 ){ |
| 203 | *pIndex = mid; |
| 204 | return 0; |
| 205 | }else if( c<0 ){ |
| 206 | upr = mid - 1; |
| @@ -227,27 +228,29 @@ | |
| 228 | */ |
| 229 | int main(int argc, char **argv){ |
| 230 | const char *zCmdName = "unknown"; |
| 231 | int idx; |
| 232 | int rc; |
| 233 | int i; |
| 234 | |
| 235 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 236 | g.now = time(0); |
| 237 | g.argc = argc; |
| 238 | g.argv = argv; |
| 239 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 240 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 241 | zCmdName = "cgi"; |
| 242 | }else if( argc<2 ){ |
| 243 | fossil_fatal("Usage: %s COMMAND ...\n" |
| 244 | "\"%s help\" for a list of available commands\n" |
| 245 | "\"%s help COMMAND\" for specific details\n", |
| 246 | argv[0], argv[0], argv[0]); |
| 247 | }else{ |
| 248 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 249 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 250 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 251 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 252 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 253 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 254 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 255 | g.zLogin = find_option("user", "U", 1); |
| 256 | if( find_option("help",0,0)!=0 ){ |
| @@ -264,14 +267,13 @@ | |
| 267 | } |
| 268 | zCmdName = g.argv[1]; |
| 269 | } |
| 270 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 271 | if( rc==1 ){ |
| 272 | fossil_fatal("%s: unknown command: %s\n" |
| 273 | "%s: use \"help\" for more information\n", |
| 274 | argv[0], zCmdName, argv[0]); |
| 275 | }else if( rc==2 ){ |
| 276 | int i, n; |
| 277 | Blob couldbe; |
| 278 | blob_zero(&couldbe); |
| 279 | n = strlen(zCmdName); |
| @@ -278,15 +280,14 @@ | |
| 280 | for(i=0; i<count(aCommand); i++){ |
| 281 | if( memcmp(zCmdName, aCommand[i].zName, n)==0 ){ |
| 282 | blob_appendf(&couldbe, " %s", aCommand[i].zName); |
| 283 | } |
| 284 | } |
| 285 | fossil_fatal("%s: ambiguous command prefix: %s\n" |
| 286 | "%s: could be any of:%s\n" |
| 287 | "%s: use \"help\" for more information\n", |
| 288 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 289 | } |
| 290 | aCommand[idx].xFunc(); |
| 291 | fossil_exit(0); |
| 292 | /*NOT_REACHED*/ |
| 293 | return 0; |
| @@ -333,11 +334,12 @@ | |
| 334 | if( g.cgiOutput && once ){ |
| 335 | once = 0; |
| 336 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 337 | cgi_reply(); |
| 338 | }else{ |
| 339 | char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); |
| 340 | fossil_puts(zOut, 1); |
| 341 | } |
| 342 | db_force_rollback(); |
| 343 | fossil_exit(1); |
| 344 | } |
| 345 | void fossil_fatal(const char *zFormat, ...){ |
| @@ -350,11 +352,12 @@ | |
| 352 | if( g.cgiOutput ){ |
| 353 | g.cgiOutput = 0; |
| 354 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 355 | cgi_reply(); |
| 356 | }else{ |
| 357 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 358 | fossil_puts(zOut, 1); |
| 359 | } |
| 360 | db_force_rollback(); |
| 361 | fossil_exit(1); |
| 362 | } |
| 363 | |
| @@ -378,11 +381,12 @@ | |
| 381 | if( g.cgiOutput ){ |
| 382 | g.cgiOutput = 0; |
| 383 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 384 | cgi_reply(); |
| 385 | }else{ |
| 386 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 387 | fossil_puts(zOut, 1); |
| 388 | } |
| 389 | db_force_rollback(); |
| 390 | fossil_exit(1); |
| 391 | } |
| 392 | |
| @@ -395,11 +399,13 @@ | |
| 399 | z = vmprintf(zFormat, ap); |
| 400 | va_end(ap); |
| 401 | if( g.cgiOutput ){ |
| 402 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 403 | }else{ |
| 404 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 405 | fossil_puts(zOut, 1); |
| 406 | free(zOut); |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | /* |
| 411 | ** Malloc and free routines that cannot fail |
| @@ -426,35 +432,24 @@ | |
| 432 | #if defined(_WIN32) |
| 433 | /* On windows, we have to put double-quotes around the entire command. |
| 434 | ** Who knows why - this is just the way windows works. |
| 435 | */ |
| 436 | char *zNewCmd = mprintf("\"%s\"", zOrigCmd); |
| 437 | char *zMbcs = fossil_utf8_to_mbcs(zNewCmd); |
| 438 | if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zMbcs); |
| 439 | rc = system(zMbcs); |
| 440 | fossil_mbcs_free(zMbcs); |
| 441 | free(zNewCmd); |
| 442 | #else |
| 443 | /* On unix, evaluate the command directly. |
| 444 | */ |
| 445 | if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd); |
| 446 | rc = system(zOrigCmd); |
| 447 | #endif |
| 448 | return rc; |
| 449 | } |
| 450 | |
| 451 | /* |
| 452 | ** Turn off any NL to CRNL translation on the stream given as an |
| 453 | ** argument. This is a no-op on unix but is necessary on windows. |
| 454 | */ |
| 455 | void fossil_binary_mode(FILE *p){ |
| @@ -507,12 +502,11 @@ | |
| 502 | |
| 503 | /* |
| 504 | ** Print a usage comment and quit |
| 505 | */ |
| 506 | void usage(const char *zFormat){ |
| 507 | fossil_fatal("Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat); |
| 508 | } |
| 509 | |
| 510 | /* |
| 511 | ** Remove n elements from g.argv beginning with the i-th element. |
| 512 | */ |
| @@ -601,14 +595,14 @@ | |
| 595 | if( nCol==0 ) nCol = 1; |
| 596 | nRow = (nWord + nCol - 1)/nCol; |
| 597 | for(i=0; i<nRow; i++){ |
| 598 | const char *zSpacer = ""; |
| 599 | for(j=i; j<nWord; j+=nRow){ |
| 600 | fossil_print("%s%-*s", zSpacer, mxLen, azWord[j]); |
| 601 | zSpacer = " "; |
| 602 | } |
| 603 | fossil_print("\n"); |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | /* |
| 608 | ** List of commands starting with zPrefix, or all commands if zPrefix is NULL. |
| @@ -650,11 +644,12 @@ | |
| 644 | ** Usage: %fossil version |
| 645 | ** |
| 646 | ** Print the source code version number for the fossil executable. |
| 647 | */ |
| 648 | void version_cmd(void){ |
| 649 | fossil_print("This is fossil version " |
| 650 | MANIFEST_VERSION " " MANIFEST_DATE " UTC\n"); |
| 651 | } |
| 652 | |
| 653 | |
| 654 | /* |
| 655 | ** COMMAND: help |
| @@ -665,12 +660,12 @@ | |
| 660 | */ |
| 661 | void help_cmd(void){ |
| 662 | int rc, idx; |
| 663 | const char *z; |
| 664 | if( g.argc<3 ){ |
| 665 | fossil_print("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", |
| 666 | fossil_nameofexe()); |
| 667 | cmd_cmd_list(0); |
| 668 | version_cmd(); |
| 669 | return; |
| 670 | } |
| 671 | rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); |
| @@ -689,11 +684,11 @@ | |
| 684 | fossil_fatal("no help available for the %s command", |
| 685 | aCommand[idx].zName); |
| 686 | } |
| 687 | while( *z ){ |
| 688 | if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ |
| 689 | fossil_print("%s", fossil_nameofexe()); |
| 690 | z += 7; |
| 691 | }else{ |
| 692 | putchar(*z); |
| 693 | z++; |
| 694 | } |
| @@ -918,11 +913,11 @@ | |
| 913 | } |
| 914 | if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } |
| 915 | |
| 916 | szFile = file_size(zRepo); |
| 917 | if( zPathInfo[i]=='/' && szFile<0 ){ |
| 918 | assert( fossil_strcmp(&zRepo[j], ".fossil")==0 ); |
| 919 | zRepo[j] = 0; |
| 920 | if( file_isdir(zRepo)==1 ){ |
| 921 | fossil_free(zToFree); |
| 922 | i++; |
| 923 | continue; |
| @@ -1177,11 +1172,11 @@ | |
| 1172 | zName = P("SCRIPT_NAME"); |
| 1173 | if( zName && zName[0]=='/' ) zName++; |
| 1174 | } |
| 1175 | if( zName && validate16(zName, strlen(zName)) ){ |
| 1176 | for(i=0; i<nRedirect; i++){ |
| 1177 | if( fossil_strcmp(azRedirect[i*2],"*")==0 ){ |
| 1178 | zNotFound = azRedirect[i*2+1]; |
| 1179 | continue; |
| 1180 | } |
| 1181 | db_open_repository(azRedirect[i*2]); |
| 1182 | if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){ |
| @@ -1281,12 +1276,12 @@ | |
| 1276 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 1277 | fossil_fatal("no repository specified"); |
| 1278 | } |
| 1279 | g.fullHttpReply = 1; |
| 1280 | if( g.argc==6 ){ |
| 1281 | g.httpIn = fossil_fopen(g.argv[3], "rb"); |
| 1282 | g.httpOut = fossil_fopen(g.argv[4], "wb"); |
| 1283 | zIpAddr = g.argv[5]; |
| 1284 | }else{ |
| 1285 | g.httpIn = stdin; |
| 1286 | g.httpOut = stdout; |
| 1287 | zIpAddr = 0; |
| @@ -1327,11 +1322,11 @@ | |
| 1322 | int bExists; |
| 1323 | while( zPath && zPath[0] ){ |
| 1324 | while( zPath[0]==':' ) zPath++; |
| 1325 | for(i=0; zPath[i] && zPath[i]!=':'; i++){} |
| 1326 | zFull = mprintf("%.*s/%s", i, zPath, zBinary); |
| 1327 | bExists = file_access(zFull, X_OK); |
| 1328 | free(zFull); |
| 1329 | if( bExists==0 ) return 1; |
| 1330 | zPath += i; |
| 1331 | } |
| 1332 | return 0; |
| @@ -1455,8 +1450,8 @@ | |
| 1450 | ** wildcard expansion behavior of the host shell can be investigated. |
| 1451 | */ |
| 1452 | void test_echo_cmd(void){ |
| 1453 | int i; |
| 1454 | for(i=0; i<g.argc; i++){ |
| 1455 | fossil_print("argv[%d] = [%s]\n", i, g.argv[i]); |
| 1456 | } |
| 1457 | } |
| 1458 |
+2
-2
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -920,11 +920,11 @@ | ||
| 920 | 920 | */ |
| 921 | 921 | Manifest *manifest_get_by_name(const char *zName, int *pRid){ |
| 922 | 922 | int rid; |
| 923 | 923 | Manifest *p; |
| 924 | 924 | |
| 925 | - rid = name_to_rid(zName); | |
| 925 | + rid = name_to_typed_rid(zName, "ci"); | |
| 926 | 926 | if( !is_a_version(rid) ){ |
| 927 | 927 | fossil_fatal("no such checkin: %s", zName); |
| 928 | 928 | } |
| 929 | 929 | if( pRid ) *pRid = rid; |
| 930 | 930 | p = manifest_get(rid, CFTYPE_MANIFEST); |
| @@ -1323,11 +1323,11 @@ | ||
| 1323 | 1323 | if( pChildFile ){ |
| 1324 | 1324 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1325 | 1325 | isPublic, manifest_file_mperm(pChildFile)); |
| 1326 | 1326 | } |
| 1327 | 1327 | } |
| 1328 | - }else if( pChild->zBaseline==0 ){ | |
| 1328 | + }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ | |
| 1329 | 1329 | /* Parent is a delta but pChild is a baseline. Look for files that are |
| 1330 | 1330 | ** present in pParent but which are missing from pChild and mark them |
| 1331 | 1331 | ** has having been deleted. */ |
| 1332 | 1332 | manifest_file_rewind(pParent); |
| 1333 | 1333 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1334 | 1334 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -920,11 +920,11 @@ | |
| 920 | */ |
| 921 | Manifest *manifest_get_by_name(const char *zName, int *pRid){ |
| 922 | int rid; |
| 923 | Manifest *p; |
| 924 | |
| 925 | rid = name_to_rid(zName); |
| 926 | if( !is_a_version(rid) ){ |
| 927 | fossil_fatal("no such checkin: %s", zName); |
| 928 | } |
| 929 | if( pRid ) *pRid = rid; |
| 930 | p = manifest_get(rid, CFTYPE_MANIFEST); |
| @@ -1323,11 +1323,11 @@ | |
| 1323 | if( pChildFile ){ |
| 1324 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1325 | isPublic, manifest_file_mperm(pChildFile)); |
| 1326 | } |
| 1327 | } |
| 1328 | }else if( pChild->zBaseline==0 ){ |
| 1329 | /* Parent is a delta but pChild is a baseline. Look for files that are |
| 1330 | ** present in pParent but which are missing from pChild and mark them |
| 1331 | ** has having been deleted. */ |
| 1332 | manifest_file_rewind(pParent); |
| 1333 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1334 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -920,11 +920,11 @@ | |
| 920 | */ |
| 921 | Manifest *manifest_get_by_name(const char *zName, int *pRid){ |
| 922 | int rid; |
| 923 | Manifest *p; |
| 924 | |
| 925 | rid = name_to_typed_rid(zName, "ci"); |
| 926 | if( !is_a_version(rid) ){ |
| 927 | fossil_fatal("no such checkin: %s", zName); |
| 928 | } |
| 929 | if( pRid ) *pRid = rid; |
| 930 | p = manifest_get(rid, CFTYPE_MANIFEST); |
| @@ -1323,11 +1323,11 @@ | |
| 1323 | if( pChildFile ){ |
| 1324 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1325 | isPublic, manifest_file_mperm(pChildFile)); |
| 1326 | } |
| 1327 | } |
| 1328 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1329 | /* Parent is a delta but pChild is a baseline. Look for files that are |
| 1330 | ** present in pParent but which are missing from pChild and mark them |
| 1331 | ** has having been deleted. */ |
| 1332 | manifest_file_rewind(pParent); |
| 1333 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1334 |
+2
-2
| --- src/md5.c | ||
| +++ src/md5.c | ||
| @@ -376,11 +376,11 @@ | ||
| 376 | 376 | FILE *in; |
| 377 | 377 | MD5Context ctx; |
| 378 | 378 | unsigned char zResult[16]; |
| 379 | 379 | char zBuf[10240]; |
| 380 | 380 | |
| 381 | - in = fopen(zFilename,"rb"); | |
| 381 | + in = fossil_fopen(zFilename,"rb"); | |
| 382 | 382 | if( in==0 ){ |
| 383 | 383 | return 1; |
| 384 | 384 | } |
| 385 | 385 | MD5Init(&ctx); |
| 386 | 386 | for(;;){ |
| @@ -438,9 +438,9 @@ | ||
| 438 | 438 | blob_read_from_channel(&in, stdin, -1); |
| 439 | 439 | md5sum_blob(&in, &cksum); |
| 440 | 440 | }else{ |
| 441 | 441 | md5sum_file(g.argv[i], &cksum); |
| 442 | 442 | } |
| 443 | - printf("%s %s\n", blob_str(&cksum), g.argv[i]); | |
| 443 | + fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); | |
| 444 | 444 | blob_reset(&cksum); |
| 445 | 445 | } |
| 446 | 446 | } |
| 447 | 447 |
| --- src/md5.c | |
| +++ src/md5.c | |
| @@ -376,11 +376,11 @@ | |
| 376 | FILE *in; |
| 377 | MD5Context ctx; |
| 378 | unsigned char zResult[16]; |
| 379 | char zBuf[10240]; |
| 380 | |
| 381 | in = fopen(zFilename,"rb"); |
| 382 | if( in==0 ){ |
| 383 | return 1; |
| 384 | } |
| 385 | MD5Init(&ctx); |
| 386 | for(;;){ |
| @@ -438,9 +438,9 @@ | |
| 438 | blob_read_from_channel(&in, stdin, -1); |
| 439 | md5sum_blob(&in, &cksum); |
| 440 | }else{ |
| 441 | md5sum_file(g.argv[i], &cksum); |
| 442 | } |
| 443 | printf("%s %s\n", blob_str(&cksum), g.argv[i]); |
| 444 | blob_reset(&cksum); |
| 445 | } |
| 446 | } |
| 447 |
| --- src/md5.c | |
| +++ src/md5.c | |
| @@ -376,11 +376,11 @@ | |
| 376 | FILE *in; |
| 377 | MD5Context ctx; |
| 378 | unsigned char zResult[16]; |
| 379 | char zBuf[10240]; |
| 380 | |
| 381 | in = fossil_fopen(zFilename,"rb"); |
| 382 | if( in==0 ){ |
| 383 | return 1; |
| 384 | } |
| 385 | MD5Init(&ctx); |
| 386 | for(;;){ |
| @@ -438,9 +438,9 @@ | |
| 438 | blob_read_from_channel(&in, stdin, -1); |
| 439 | md5sum_blob(&in, &cksum); |
| 440 | }else{ |
| 441 | md5sum_file(g.argv[i], &cksum); |
| 442 | } |
| 443 | fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); |
| 444 | blob_reset(&cksum); |
| 445 | } |
| 446 | } |
| 447 |
+21
-19
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -96,16 +96,16 @@ | ||
| 96 | 96 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 97 | 97 | vid = db_lget_int("checkout", 0); |
| 98 | 98 | if( vid==0 ){ |
| 99 | 99 | fossil_fatal("nothing is checked out"); |
| 100 | 100 | } |
| 101 | - mid = name_to_rid(g.argv[2]); | |
| 101 | + mid = name_to_typed_rid(g.argv[2], "ci"); | |
| 102 | 102 | if( mid==0 || !is_a_version(mid) ){ |
| 103 | 103 | fossil_fatal("not a version: %s", g.argv[2]); |
| 104 | 104 | } |
| 105 | 105 | if( zPivot ){ |
| 106 | - pid = name_to_rid(zPivot); | |
| 106 | + pid = name_to_typed_rid(zPivot, "ci"); | |
| 107 | 107 | if( pid==0 || !is_a_version(pid) ){ |
| 108 | 108 | fossil_fatal("not a version: %s", zPivot); |
| 109 | 109 | } |
| 110 | 110 | if( pickFlag ){ |
| 111 | 111 | fossil_fatal("incompatible options: --cherrypick & --baseline"); |
| @@ -249,20 +249,20 @@ | ||
| 249 | 249 | if( debugFlag ){ |
| 250 | 250 | db_prepare(&q, |
| 251 | 251 | "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv" |
| 252 | 252 | ); |
| 253 | 253 | while( db_step(&q)==SQLITE_ROW ){ |
| 254 | - printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n", | |
| 254 | + fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n", | |
| 255 | 255 | db_column_int(&q, 0), |
| 256 | 256 | db_column_int(&q, 5), |
| 257 | 257 | db_column_int(&q, 6), |
| 258 | 258 | db_column_int(&q, 7), |
| 259 | 259 | db_column_int(&q, 4), |
| 260 | 260 | db_column_int(&q, 8)); |
| 261 | - printf(" fn = [%s]\n", db_column_text(&q, 1)); | |
| 262 | - printf(" fnp = [%s]\n", db_column_text(&q, 2)); | |
| 263 | - printf(" fnm = [%s]\n", db_column_text(&q, 3)); | |
| 261 | + fossil_print(" fn = [%s]\n", db_column_text(&q, 1)); | |
| 262 | + fossil_print(" fnp = [%s]\n", db_column_text(&q, 2)); | |
| 263 | + fossil_print(" fnm = [%s]\n", db_column_text(&q, 3)); | |
| 264 | 264 | } |
| 265 | 265 | db_finalize(&q); |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | 268 | /* |
| @@ -274,11 +274,11 @@ | ||
| 274 | 274 | "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0" |
| 275 | 275 | ); |
| 276 | 276 | while( db_step(&q)==SQLITE_ROW ){ |
| 277 | 277 | int idm = db_column_int(&q, 0); |
| 278 | 278 | char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm); |
| 279 | - printf("WARNING - no common ancestor: %s\n", zName); | |
| 279 | + fossil_warning("WARNING - no common ancestor: %s\n", zName); | |
| 280 | 280 | free(zName); |
| 281 | 281 | db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm); |
| 282 | 282 | } |
| 283 | 283 | db_finalize(&q); |
| 284 | 284 | |
| @@ -300,11 +300,11 @@ | ||
| 300 | 300 | vid, idm |
| 301 | 301 | ); |
| 302 | 302 | idv = db_last_insert_rowid(); |
| 303 | 303 | db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); |
| 304 | 304 | zName = db_column_text(&q, 2); |
| 305 | - printf("ADDED %s\n", zName); | |
| 305 | + fossil_print("ADDED %s\n", zName); | |
| 306 | 306 | if( !nochangeFlag ){ |
| 307 | 307 | undo_save(zName); |
| 308 | 308 | vfile_to_disk(0, idm, 0, 0); |
| 309 | 309 | } |
| 310 | 310 | } |
| @@ -322,11 +322,11 @@ | ||
| 322 | 322 | while( db_step(&q)==SQLITE_ROW ){ |
| 323 | 323 | int idv = db_column_int(&q, 0); |
| 324 | 324 | int ridm = db_column_int(&q, 1); |
| 325 | 325 | const char *zName = db_column_text(&q, 2); |
| 326 | 326 | /* Copy content from idm over into idv. Overwrite idv. */ |
| 327 | - printf("UPDATE %s\n", zName); | |
| 327 | + fossil_print("UPDATE %s\n", zName); | |
| 328 | 328 | if( !nochangeFlag ){ |
| 329 | 329 | undo_save(zName); |
| 330 | 330 | db_multi_exec( |
| 331 | 331 | "UPDATE vfile SET mtime=0, mrid=%d, chnged=2 WHERE id=%d", ridm, idv |
| 332 | 332 | ); |
| @@ -355,13 +355,14 @@ | ||
| 355 | 355 | int rc; |
| 356 | 356 | char *zFullPath; |
| 357 | 357 | Blob m, p, r; |
| 358 | 358 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| 359 | 359 | if( detailFlag ){ |
| 360 | - printf("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); | |
| 360 | + fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", | |
| 361 | + zName, ridp, ridm, ridv); | |
| 361 | 362 | }else{ |
| 362 | - printf("MERGE %s\n", zName); | |
| 363 | + fossil_print("MERGE %s\n", zName); | |
| 363 | 364 | } |
| 364 | 365 | undo_save(zName); |
| 365 | 366 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 366 | 367 | content_get(ridp, &p); |
| 367 | 368 | content_get(ridm, &m); |
| @@ -376,15 +377,15 @@ | ||
| 376 | 377 | blob_write_to_file(&r, zFullPath); |
| 377 | 378 | file_setexe(zFullPath, isExe); |
| 378 | 379 | } |
| 379 | 380 | db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); |
| 380 | 381 | if( rc>0 ){ |
| 381 | - printf("***** %d merge conflicts in %s\n", rc, zName); | |
| 382 | + fossil_print("***** %d merge conflicts in %s\n", rc, zName); | |
| 382 | 383 | nConflict++; |
| 383 | 384 | } |
| 384 | 385 | }else{ |
| 385 | - printf("***** Cannot merge binary file %s\n", zName); | |
| 386 | + fossil_print("***** Cannot merge binary file %s\n", zName); | |
| 386 | 387 | nConflict++; |
| 387 | 388 | } |
| 388 | 389 | blob_reset(&p); |
| 389 | 390 | blob_reset(&m); |
| 390 | 391 | blob_reset(&r); |
| @@ -403,22 +404,22 @@ | ||
| 403 | 404 | while( db_step(&q)==SQLITE_ROW ){ |
| 404 | 405 | int idv = db_column_int(&q, 0); |
| 405 | 406 | const char *zName = db_column_text(&q, 1); |
| 406 | 407 | int chnged = db_column_int(&q, 2); |
| 407 | 408 | /* Delete the file idv */ |
| 408 | - printf("DELETE %s\n", zName); | |
| 409 | + fossil_print("DELETE %s\n", zName); | |
| 409 | 410 | if( chnged ){ |
| 410 | - printf("WARNING: local edits lost for %s\n", zName); | |
| 411 | + fossil_warning("WARNING: local edits lost for %s\n", zName); | |
| 411 | 412 | nConflict++; |
| 412 | 413 | } |
| 413 | 414 | undo_save(zName); |
| 414 | 415 | db_multi_exec( |
| 415 | 416 | "UPDATE vfile SET deleted=1 WHERE id=%d", idv |
| 416 | 417 | ); |
| 417 | 418 | if( !nochangeFlag ){ |
| 418 | 419 | char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName); |
| 419 | - unlink(zFullPath); | |
| 420 | + file_delete(zFullPath); | |
| 420 | 421 | free(zFullPath); |
| 421 | 422 | } |
| 422 | 423 | } |
| 423 | 424 | db_finalize(&q); |
| 424 | 425 | |
| @@ -433,11 +434,11 @@ | ||
| 433 | 434 | ); |
| 434 | 435 | while( db_step(&q)==SQLITE_ROW ){ |
| 435 | 436 | int idv = db_column_int(&q, 0); |
| 436 | 437 | const char *zOldName = db_column_text(&q, 1); |
| 437 | 438 | const char *zNewName = db_column_text(&q, 2); |
| 438 | - printf("RENAME %s -> %s\n", zOldName, zNewName); | |
| 439 | + fossil_print("RENAME %s -> %s\n", zOldName, zNewName); | |
| 439 | 440 | undo_save(zOldName); |
| 440 | 441 | undo_save(zNewName); |
| 441 | 442 | db_multi_exec( |
| 442 | 443 | "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)" |
| 443 | 444 | " WHERE id=%d AND vid=%d", zNewName, idv, vid |
| @@ -444,11 +445,11 @@ | ||
| 444 | 445 | ); |
| 445 | 446 | if( !nochangeFlag ){ |
| 446 | 447 | char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName); |
| 447 | 448 | char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); |
| 448 | 449 | file_copy(zFullOldPath, zFullNewPath); |
| 449 | - unlink(zFullOldPath); | |
| 450 | + file_delete(zFullOldPath); | |
| 450 | 451 | free(zFullNewPath); |
| 451 | 452 | free(zFullOldPath); |
| 452 | 453 | } |
| 453 | 454 | } |
| 454 | 455 | db_finalize(&q); |
| @@ -455,11 +456,12 @@ | ||
| 455 | 456 | |
| 456 | 457 | |
| 457 | 458 | /* Report on conflicts |
| 458 | 459 | */ |
| 459 | 460 | if( nConflict && !nochangeFlag ){ |
| 460 | - printf("WARNING: merge conflicts - see messages above for details.\n"); | |
| 461 | + fossil_warning( | |
| 462 | + "WARNING: merge conflicts - see messages above for details.\n"); | |
| 461 | 463 | } |
| 462 | 464 | |
| 463 | 465 | /* |
| 464 | 466 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 465 | 467 | */ |
| 466 | 468 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -96,16 +96,16 @@ | |
| 96 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 97 | vid = db_lget_int("checkout", 0); |
| 98 | if( vid==0 ){ |
| 99 | fossil_fatal("nothing is checked out"); |
| 100 | } |
| 101 | mid = name_to_rid(g.argv[2]); |
| 102 | if( mid==0 || !is_a_version(mid) ){ |
| 103 | fossil_fatal("not a version: %s", g.argv[2]); |
| 104 | } |
| 105 | if( zPivot ){ |
| 106 | pid = name_to_rid(zPivot); |
| 107 | if( pid==0 || !is_a_version(pid) ){ |
| 108 | fossil_fatal("not a version: %s", zPivot); |
| 109 | } |
| 110 | if( pickFlag ){ |
| 111 | fossil_fatal("incompatible options: --cherrypick & --baseline"); |
| @@ -249,20 +249,20 @@ | |
| 249 | if( debugFlag ){ |
| 250 | db_prepare(&q, |
| 251 | "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv" |
| 252 | ); |
| 253 | while( db_step(&q)==SQLITE_ROW ){ |
| 254 | printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n", |
| 255 | db_column_int(&q, 0), |
| 256 | db_column_int(&q, 5), |
| 257 | db_column_int(&q, 6), |
| 258 | db_column_int(&q, 7), |
| 259 | db_column_int(&q, 4), |
| 260 | db_column_int(&q, 8)); |
| 261 | printf(" fn = [%s]\n", db_column_text(&q, 1)); |
| 262 | printf(" fnp = [%s]\n", db_column_text(&q, 2)); |
| 263 | printf(" fnm = [%s]\n", db_column_text(&q, 3)); |
| 264 | } |
| 265 | db_finalize(&q); |
| 266 | } |
| 267 | |
| 268 | /* |
| @@ -274,11 +274,11 @@ | |
| 274 | "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0" |
| 275 | ); |
| 276 | while( db_step(&q)==SQLITE_ROW ){ |
| 277 | int idm = db_column_int(&q, 0); |
| 278 | char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm); |
| 279 | printf("WARNING - no common ancestor: %s\n", zName); |
| 280 | free(zName); |
| 281 | db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm); |
| 282 | } |
| 283 | db_finalize(&q); |
| 284 | |
| @@ -300,11 +300,11 @@ | |
| 300 | vid, idm |
| 301 | ); |
| 302 | idv = db_last_insert_rowid(); |
| 303 | db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); |
| 304 | zName = db_column_text(&q, 2); |
| 305 | printf("ADDED %s\n", zName); |
| 306 | if( !nochangeFlag ){ |
| 307 | undo_save(zName); |
| 308 | vfile_to_disk(0, idm, 0, 0); |
| 309 | } |
| 310 | } |
| @@ -322,11 +322,11 @@ | |
| 322 | while( db_step(&q)==SQLITE_ROW ){ |
| 323 | int idv = db_column_int(&q, 0); |
| 324 | int ridm = db_column_int(&q, 1); |
| 325 | const char *zName = db_column_text(&q, 2); |
| 326 | /* Copy content from idm over into idv. Overwrite idv. */ |
| 327 | printf("UPDATE %s\n", zName); |
| 328 | if( !nochangeFlag ){ |
| 329 | undo_save(zName); |
| 330 | db_multi_exec( |
| 331 | "UPDATE vfile SET mtime=0, mrid=%d, chnged=2 WHERE id=%d", ridm, idv |
| 332 | ); |
| @@ -355,13 +355,14 @@ | |
| 355 | int rc; |
| 356 | char *zFullPath; |
| 357 | Blob m, p, r; |
| 358 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| 359 | if( detailFlag ){ |
| 360 | printf("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); |
| 361 | }else{ |
| 362 | printf("MERGE %s\n", zName); |
| 363 | } |
| 364 | undo_save(zName); |
| 365 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 366 | content_get(ridp, &p); |
| 367 | content_get(ridm, &m); |
| @@ -376,15 +377,15 @@ | |
| 376 | blob_write_to_file(&r, zFullPath); |
| 377 | file_setexe(zFullPath, isExe); |
| 378 | } |
| 379 | db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); |
| 380 | if( rc>0 ){ |
| 381 | printf("***** %d merge conflicts in %s\n", rc, zName); |
| 382 | nConflict++; |
| 383 | } |
| 384 | }else{ |
| 385 | printf("***** Cannot merge binary file %s\n", zName); |
| 386 | nConflict++; |
| 387 | } |
| 388 | blob_reset(&p); |
| 389 | blob_reset(&m); |
| 390 | blob_reset(&r); |
| @@ -403,22 +404,22 @@ | |
| 403 | while( db_step(&q)==SQLITE_ROW ){ |
| 404 | int idv = db_column_int(&q, 0); |
| 405 | const char *zName = db_column_text(&q, 1); |
| 406 | int chnged = db_column_int(&q, 2); |
| 407 | /* Delete the file idv */ |
| 408 | printf("DELETE %s\n", zName); |
| 409 | if( chnged ){ |
| 410 | printf("WARNING: local edits lost for %s\n", zName); |
| 411 | nConflict++; |
| 412 | } |
| 413 | undo_save(zName); |
| 414 | db_multi_exec( |
| 415 | "UPDATE vfile SET deleted=1 WHERE id=%d", idv |
| 416 | ); |
| 417 | if( !nochangeFlag ){ |
| 418 | char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName); |
| 419 | unlink(zFullPath); |
| 420 | free(zFullPath); |
| 421 | } |
| 422 | } |
| 423 | db_finalize(&q); |
| 424 | |
| @@ -433,11 +434,11 @@ | |
| 433 | ); |
| 434 | while( db_step(&q)==SQLITE_ROW ){ |
| 435 | int idv = db_column_int(&q, 0); |
| 436 | const char *zOldName = db_column_text(&q, 1); |
| 437 | const char *zNewName = db_column_text(&q, 2); |
| 438 | printf("RENAME %s -> %s\n", zOldName, zNewName); |
| 439 | undo_save(zOldName); |
| 440 | undo_save(zNewName); |
| 441 | db_multi_exec( |
| 442 | "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)" |
| 443 | " WHERE id=%d AND vid=%d", zNewName, idv, vid |
| @@ -444,11 +445,11 @@ | |
| 444 | ); |
| 445 | if( !nochangeFlag ){ |
| 446 | char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName); |
| 447 | char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); |
| 448 | file_copy(zFullOldPath, zFullNewPath); |
| 449 | unlink(zFullOldPath); |
| 450 | free(zFullNewPath); |
| 451 | free(zFullOldPath); |
| 452 | } |
| 453 | } |
| 454 | db_finalize(&q); |
| @@ -455,11 +456,12 @@ | |
| 455 | |
| 456 | |
| 457 | /* Report on conflicts |
| 458 | */ |
| 459 | if( nConflict && !nochangeFlag ){ |
| 460 | printf("WARNING: merge conflicts - see messages above for details.\n"); |
| 461 | } |
| 462 | |
| 463 | /* |
| 464 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 465 | */ |
| 466 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -96,16 +96,16 @@ | |
| 96 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 97 | vid = db_lget_int("checkout", 0); |
| 98 | if( vid==0 ){ |
| 99 | fossil_fatal("nothing is checked out"); |
| 100 | } |
| 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 | if( mid==0 || !is_a_version(mid) ){ |
| 103 | fossil_fatal("not a version: %s", g.argv[2]); |
| 104 | } |
| 105 | if( zPivot ){ |
| 106 | pid = name_to_typed_rid(zPivot, "ci"); |
| 107 | if( pid==0 || !is_a_version(pid) ){ |
| 108 | fossil_fatal("not a version: %s", zPivot); |
| 109 | } |
| 110 | if( pickFlag ){ |
| 111 | fossil_fatal("incompatible options: --cherrypick & --baseline"); |
| @@ -249,20 +249,20 @@ | |
| 249 | if( debugFlag ){ |
| 250 | db_prepare(&q, |
| 251 | "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv" |
| 252 | ); |
| 253 | while( db_step(&q)==SQLITE_ROW ){ |
| 254 | fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n", |
| 255 | db_column_int(&q, 0), |
| 256 | db_column_int(&q, 5), |
| 257 | db_column_int(&q, 6), |
| 258 | db_column_int(&q, 7), |
| 259 | db_column_int(&q, 4), |
| 260 | db_column_int(&q, 8)); |
| 261 | fossil_print(" fn = [%s]\n", db_column_text(&q, 1)); |
| 262 | fossil_print(" fnp = [%s]\n", db_column_text(&q, 2)); |
| 263 | fossil_print(" fnm = [%s]\n", db_column_text(&q, 3)); |
| 264 | } |
| 265 | db_finalize(&q); |
| 266 | } |
| 267 | |
| 268 | /* |
| @@ -274,11 +274,11 @@ | |
| 274 | "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0" |
| 275 | ); |
| 276 | while( db_step(&q)==SQLITE_ROW ){ |
| 277 | int idm = db_column_int(&q, 0); |
| 278 | char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm); |
| 279 | fossil_warning("WARNING - no common ancestor: %s\n", zName); |
| 280 | free(zName); |
| 281 | db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm); |
| 282 | } |
| 283 | db_finalize(&q); |
| 284 | |
| @@ -300,11 +300,11 @@ | |
| 300 | vid, idm |
| 301 | ); |
| 302 | idv = db_last_insert_rowid(); |
| 303 | db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); |
| 304 | zName = db_column_text(&q, 2); |
| 305 | fossil_print("ADDED %s\n", zName); |
| 306 | if( !nochangeFlag ){ |
| 307 | undo_save(zName); |
| 308 | vfile_to_disk(0, idm, 0, 0); |
| 309 | } |
| 310 | } |
| @@ -322,11 +322,11 @@ | |
| 322 | while( db_step(&q)==SQLITE_ROW ){ |
| 323 | int idv = db_column_int(&q, 0); |
| 324 | int ridm = db_column_int(&q, 1); |
| 325 | const char *zName = db_column_text(&q, 2); |
| 326 | /* Copy content from idm over into idv. Overwrite idv. */ |
| 327 | fossil_print("UPDATE %s\n", zName); |
| 328 | if( !nochangeFlag ){ |
| 329 | undo_save(zName); |
| 330 | db_multi_exec( |
| 331 | "UPDATE vfile SET mtime=0, mrid=%d, chnged=2 WHERE id=%d", ridm, idv |
| 332 | ); |
| @@ -355,13 +355,14 @@ | |
| 355 | int rc; |
| 356 | char *zFullPath; |
| 357 | Blob m, p, r; |
| 358 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| 359 | if( detailFlag ){ |
| 360 | fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", |
| 361 | zName, ridp, ridm, ridv); |
| 362 | }else{ |
| 363 | fossil_print("MERGE %s\n", zName); |
| 364 | } |
| 365 | undo_save(zName); |
| 366 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 367 | content_get(ridp, &p); |
| 368 | content_get(ridm, &m); |
| @@ -376,15 +377,15 @@ | |
| 377 | blob_write_to_file(&r, zFullPath); |
| 378 | file_setexe(zFullPath, isExe); |
| 379 | } |
| 380 | db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); |
| 381 | if( rc>0 ){ |
| 382 | fossil_print("***** %d merge conflicts in %s\n", rc, zName); |
| 383 | nConflict++; |
| 384 | } |
| 385 | }else{ |
| 386 | fossil_print("***** Cannot merge binary file %s\n", zName); |
| 387 | nConflict++; |
| 388 | } |
| 389 | blob_reset(&p); |
| 390 | blob_reset(&m); |
| 391 | blob_reset(&r); |
| @@ -403,22 +404,22 @@ | |
| 404 | while( db_step(&q)==SQLITE_ROW ){ |
| 405 | int idv = db_column_int(&q, 0); |
| 406 | const char *zName = db_column_text(&q, 1); |
| 407 | int chnged = db_column_int(&q, 2); |
| 408 | /* Delete the file idv */ |
| 409 | fossil_print("DELETE %s\n", zName); |
| 410 | if( chnged ){ |
| 411 | fossil_warning("WARNING: local edits lost for %s\n", zName); |
| 412 | nConflict++; |
| 413 | } |
| 414 | undo_save(zName); |
| 415 | db_multi_exec( |
| 416 | "UPDATE vfile SET deleted=1 WHERE id=%d", idv |
| 417 | ); |
| 418 | if( !nochangeFlag ){ |
| 419 | char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName); |
| 420 | file_delete(zFullPath); |
| 421 | free(zFullPath); |
| 422 | } |
| 423 | } |
| 424 | db_finalize(&q); |
| 425 | |
| @@ -433,11 +434,11 @@ | |
| 434 | ); |
| 435 | while( db_step(&q)==SQLITE_ROW ){ |
| 436 | int idv = db_column_int(&q, 0); |
| 437 | const char *zOldName = db_column_text(&q, 1); |
| 438 | const char *zNewName = db_column_text(&q, 2); |
| 439 | fossil_print("RENAME %s -> %s\n", zOldName, zNewName); |
| 440 | undo_save(zOldName); |
| 441 | undo_save(zNewName); |
| 442 | db_multi_exec( |
| 443 | "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)" |
| 444 | " WHERE id=%d AND vid=%d", zNewName, idv, vid |
| @@ -444,11 +445,11 @@ | |
| 445 | ); |
| 446 | if( !nochangeFlag ){ |
| 447 | char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName); |
| 448 | char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); |
| 449 | file_copy(zFullOldPath, zFullNewPath); |
| 450 | file_delete(zFullOldPath); |
| 451 | free(zFullNewPath); |
| 452 | free(zFullOldPath); |
| 453 | } |
| 454 | } |
| 455 | db_finalize(&q); |
| @@ -455,11 +456,12 @@ | |
| 456 | |
| 457 | |
| 458 | /* Report on conflicts |
| 459 | */ |
| 460 | if( nConflict && !nochangeFlag ){ |
| 461 | fossil_warning( |
| 462 | "WARNING: merge conflicts - see messages above for details.\n"); |
| 463 | } |
| 464 | |
| 465 | /* |
| 466 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 467 | */ |
| 468 |
+8
-12
| --- src/merge3.c | ||
| +++ src/merge3.c | ||
| @@ -314,25 +314,21 @@ | ||
| 314 | 314 | Blob pivot, v1, v2, merged; |
| 315 | 315 | if( g.argc!=6 ){ |
| 316 | 316 | usage("PIVOT V1 V2 MERGED"); |
| 317 | 317 | } |
| 318 | 318 | if( blob_read_from_file(&pivot, g.argv[2])<0 ){ |
| 319 | - fprintf(stderr,"cannot read %s\n", g.argv[2]); | |
| 320 | - fossil_exit(1); | |
| 319 | + fossil_fatal("cannot read %s\n", g.argv[2]); | |
| 321 | 320 | } |
| 322 | 321 | if( blob_read_from_file(&v1, g.argv[3])<0 ){ |
| 323 | - fprintf(stderr,"cannot read %s\n", g.argv[3]); | |
| 324 | - fossil_exit(1); | |
| 322 | + fossil_fatal("cannot read %s\n", g.argv[3]); | |
| 325 | 323 | } |
| 326 | 324 | if( blob_read_from_file(&v2, g.argv[4])<0 ){ |
| 327 | - fprintf(stderr,"cannot read %s\n", g.argv[4]); | |
| 328 | - fossil_exit(1); | |
| 325 | + fossil_fatal("cannot read %s\n", g.argv[4]); | |
| 329 | 326 | } |
| 330 | 327 | blob_merge(&pivot, &v1, &v2, &merged); |
| 331 | 328 | if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){ |
| 332 | - fprintf(stderr,"cannot write %s\n", g.argv[4]); | |
| 333 | - fossil_exit(1); | |
| 329 | + fossil_fatal("cannot write %s\n", g.argv[4]); | |
| 334 | 330 | } |
| 335 | 331 | blob_reset(&pivot); |
| 336 | 332 | blob_reset(&v1); |
| 337 | 333 | blob_reset(&v2); |
| 338 | 334 | blob_reset(&merged); |
| @@ -428,14 +424,14 @@ | ||
| 428 | 424 | zCmd = string_subst(zGMerge, 8, azSubst); |
| 429 | 425 | printf("%s\n", zCmd); fflush(stdout); |
| 430 | 426 | fossil_system(zCmd); |
| 431 | 427 | if( file_size(zOut)>=0 ){ |
| 432 | 428 | blob_read_from_file(pOut, zOut); |
| 433 | - unlink(zPivot); | |
| 434 | - unlink(zOrig); | |
| 435 | - unlink(zOther); | |
| 436 | - unlink(zOut); | |
| 429 | + file_delete(zPivot); | |
| 430 | + file_delete(zOrig); | |
| 431 | + file_delete(zOther); | |
| 432 | + file_delete(zOut); | |
| 437 | 433 | } |
| 438 | 434 | fossil_free(zCmd); |
| 439 | 435 | fossil_free(zOut); |
| 440 | 436 | } |
| 441 | 437 | fossil_free(zPivot); |
| 442 | 438 |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -314,25 +314,21 @@ | |
| 314 | Blob pivot, v1, v2, merged; |
| 315 | if( g.argc!=6 ){ |
| 316 | usage("PIVOT V1 V2 MERGED"); |
| 317 | } |
| 318 | if( blob_read_from_file(&pivot, g.argv[2])<0 ){ |
| 319 | fprintf(stderr,"cannot read %s\n", g.argv[2]); |
| 320 | fossil_exit(1); |
| 321 | } |
| 322 | if( blob_read_from_file(&v1, g.argv[3])<0 ){ |
| 323 | fprintf(stderr,"cannot read %s\n", g.argv[3]); |
| 324 | fossil_exit(1); |
| 325 | } |
| 326 | if( blob_read_from_file(&v2, g.argv[4])<0 ){ |
| 327 | fprintf(stderr,"cannot read %s\n", g.argv[4]); |
| 328 | fossil_exit(1); |
| 329 | } |
| 330 | blob_merge(&pivot, &v1, &v2, &merged); |
| 331 | if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){ |
| 332 | fprintf(stderr,"cannot write %s\n", g.argv[4]); |
| 333 | fossil_exit(1); |
| 334 | } |
| 335 | blob_reset(&pivot); |
| 336 | blob_reset(&v1); |
| 337 | blob_reset(&v2); |
| 338 | blob_reset(&merged); |
| @@ -428,14 +424,14 @@ | |
| 428 | zCmd = string_subst(zGMerge, 8, azSubst); |
| 429 | printf("%s\n", zCmd); fflush(stdout); |
| 430 | fossil_system(zCmd); |
| 431 | if( file_size(zOut)>=0 ){ |
| 432 | blob_read_from_file(pOut, zOut); |
| 433 | unlink(zPivot); |
| 434 | unlink(zOrig); |
| 435 | unlink(zOther); |
| 436 | unlink(zOut); |
| 437 | } |
| 438 | fossil_free(zCmd); |
| 439 | fossil_free(zOut); |
| 440 | } |
| 441 | fossil_free(zPivot); |
| 442 |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -314,25 +314,21 @@ | |
| 314 | Blob pivot, v1, v2, merged; |
| 315 | if( g.argc!=6 ){ |
| 316 | usage("PIVOT V1 V2 MERGED"); |
| 317 | } |
| 318 | if( blob_read_from_file(&pivot, g.argv[2])<0 ){ |
| 319 | fossil_fatal("cannot read %s\n", g.argv[2]); |
| 320 | } |
| 321 | if( blob_read_from_file(&v1, g.argv[3])<0 ){ |
| 322 | fossil_fatal("cannot read %s\n", g.argv[3]); |
| 323 | } |
| 324 | if( blob_read_from_file(&v2, g.argv[4])<0 ){ |
| 325 | fossil_fatal("cannot read %s\n", g.argv[4]); |
| 326 | } |
| 327 | blob_merge(&pivot, &v1, &v2, &merged); |
| 328 | if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){ |
| 329 | fossil_fatal("cannot write %s\n", g.argv[4]); |
| 330 | } |
| 331 | blob_reset(&pivot); |
| 332 | blob_reset(&v1); |
| 333 | blob_reset(&v2); |
| 334 | blob_reset(&merged); |
| @@ -428,14 +424,14 @@ | |
| 424 | zCmd = string_subst(zGMerge, 8, azSubst); |
| 425 | printf("%s\n", zCmd); fflush(stdout); |
| 426 | fossil_system(zCmd); |
| 427 | if( file_size(zOut)>=0 ){ |
| 428 | blob_read_from_file(pOut, zOut); |
| 429 | file_delete(zPivot); |
| 430 | file_delete(zOrig); |
| 431 | file_delete(zOther); |
| 432 | file_delete(zOut); |
| 433 | } |
| 434 | fossil_free(zCmd); |
| 435 | fossil_free(zOut); |
| 436 | } |
| 437 | fossil_free(zPivot); |
| 438 |
+28
-20
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -40,24 +40,24 @@ | ||
| 40 | 40 | ** always resolve the name as a date. |
| 41 | 41 | ** |
| 42 | 42 | ** Return 0 on success. Return 1 if the name cannot be resolved. |
| 43 | 43 | ** Return 2 name is ambiguous. |
| 44 | 44 | */ |
| 45 | -int name_to_uuid(Blob *pName, int iErrPriority){ | |
| 45 | +int name_to_uuid(Blob *pName, int iErrPriority, const char *zType){ | |
| 46 | 46 | int rc; |
| 47 | 47 | int sz; |
| 48 | 48 | sz = blob_size(pName); |
| 49 | 49 | if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){ |
| 50 | 50 | char *zUuid; |
| 51 | 51 | const char *zName = blob_str(pName); |
| 52 | 52 | if( memcmp(zName, "tag:", 4)==0 ){ |
| 53 | 53 | zName += 4; |
| 54 | - zUuid = tag_to_uuid(zName); | |
| 54 | + zUuid = tag_to_uuid(zName, zType); | |
| 55 | 55 | }else{ |
| 56 | - zUuid = tag_to_uuid(zName); | |
| 56 | + zUuid = tag_to_uuid(zName, zType); | |
| 57 | 57 | if( zUuid==0 ){ |
| 58 | - zUuid = date_to_uuid(zName); | |
| 58 | + zUuid = date_to_uuid(zName, zType); | |
| 59 | 59 | } |
| 60 | 60 | } |
| 61 | 61 | if( zUuid ){ |
| 62 | 62 | blob_reset(pName); |
| 63 | 63 | blob_append(pName, zUuid, -1); |
| @@ -79,11 +79,11 @@ | ||
| 79 | 79 | Stmt q; |
| 80 | 80 | db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName); |
| 81 | 81 | if( db_step(&q)!=SQLITE_ROW ){ |
| 82 | 82 | char *zUuid; |
| 83 | 83 | db_finalize(&q); |
| 84 | - zUuid = tag_to_uuid(blob_str(pName)); | |
| 84 | + zUuid = tag_to_uuid(blob_str(pName), "*"); | |
| 85 | 85 | if( zUuid ){ |
| 86 | 86 | blob_reset(pName); |
| 87 | 87 | blob_append(pName, zUuid, -1); |
| 88 | 88 | free(zUuid); |
| 89 | 89 | return 0; |
| @@ -141,22 +141,25 @@ | ||
| 141 | 141 | ** An input of "tip" returns the most recent check-in. |
| 142 | 142 | ** |
| 143 | 143 | ** Memory to hold the returned string comes from malloc() and needs to |
| 144 | 144 | ** be freed by the caller. |
| 145 | 145 | */ |
| 146 | -char *tag_to_uuid(const char *zTag){ | |
| 146 | +char *tag_to_uuid(const char *zTag, const char *zType){ | |
| 147 | 147 | int vid; |
| 148 | - char *zUuid = | |
| 149 | - db_text(0, | |
| 148 | + char *zUuid; | |
| 149 | + | |
| 150 | + if( zType==0 || zType[0]==0 ) zType = "*"; | |
| 151 | + zUuid = db_text(0, | |
| 150 | 152 | "SELECT blob.uuid" |
| 151 | 153 | " FROM tag, tagxref, event, blob" |
| 152 | 154 | " WHERE tag.tagname='sym-%q' " |
| 153 | 155 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 154 | 156 | " AND event.objid=tagxref.rid " |
| 155 | 157 | " AND blob.rid=event.objid " |
| 158 | + " AND event.type GLOB '%q'" | |
| 156 | 159 | " ORDER BY event.mtime DESC ", |
| 157 | - zTag | |
| 160 | + zTag, zType | |
| 158 | 161 | ); |
| 159 | 162 | if( zUuid==0 ){ |
| 160 | 163 | int nTag = strlen(zTag); |
| 161 | 164 | int i; |
| 162 | 165 | for(i=0; i<nTag-10; i++){ |
| @@ -176,12 +179,13 @@ | ||
| 176 | 179 | " WHERE tag.tagname='sym-%q' " |
| 177 | 180 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 178 | 181 | " AND event.objid=tagxref.rid " |
| 179 | 182 | " AND blob.rid=event.objid " |
| 180 | 183 | " AND event.mtime<=julianday(%Q %s)" |
| 184 | + " AND event.type GLOB '%q'" | |
| 181 | 185 | " ORDER BY event.mtime DESC ", |
| 182 | - zTagBase, zDate, (useUtc ? "" : ",'utc'") | |
| 186 | + zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType | |
| 183 | 187 | ); |
| 184 | 188 | break; |
| 185 | 189 | } |
| 186 | 190 | } |
| 187 | 191 | if( zUuid==0 && fossil_strcmp(zTag, "tip")==0 ){ |
| @@ -222,11 +226,11 @@ | ||
| 222 | 226 | ** utc:DATE |
| 223 | 227 | ** |
| 224 | 228 | ** The DATE is interpreted as localtime unless the "utc:" prefix is used |
| 225 | 229 | ** or a "utc" string appears at the end of the DATE string. |
| 226 | 230 | */ |
| 227 | -char *date_to_uuid(const char *zDate){ | |
| 231 | +char *date_to_uuid(const char *zDate, const char *zType){ | |
| 228 | 232 | int useUtc = 0; |
| 229 | 233 | int n; |
| 230 | 234 | char *zCopy = 0; |
| 231 | 235 | char *zUuid; |
| 232 | 236 | |
| @@ -245,16 +249,17 @@ | ||
| 245 | 249 | zCopy[n-3] = 0; |
| 246 | 250 | zDate = zCopy; |
| 247 | 251 | n -= 3; |
| 248 | 252 | useUtc = 1; |
| 249 | 253 | } |
| 254 | + if( zType==0 || zType[0]==0 ) zType = "*"; | |
| 250 | 255 | zUuid = db_text(0, |
| 251 | 256 | "SELECT (SELECT uuid FROM blob WHERE rid=event.objid)" |
| 252 | 257 | " FROM event" |
| 253 | - " WHERE mtime<=julianday(%Q %s) AND type='ci'" | |
| 258 | + " WHERE mtime<=julianday(%Q %s) AND type GLOB '%q'" | |
| 254 | 259 | " ORDER BY mtime DESC LIMIT 1", |
| 255 | - zDate, useUtc ? "" : ",'utc'" | |
| 260 | + zDate, useUtc ? "" : ",'utc'", zType | |
| 256 | 261 | ); |
| 257 | 262 | free(zCopy); |
| 258 | 263 | return zUuid; |
| 259 | 264 | } |
| 260 | 265 | |
| @@ -267,16 +272,16 @@ | ||
| 267 | 272 | int i; |
| 268 | 273 | Blob name; |
| 269 | 274 | db_must_be_within_tree(); |
| 270 | 275 | for(i=2; i<g.argc; i++){ |
| 271 | 276 | blob_init(&name, g.argv[i], -1); |
| 272 | - printf("%s -> ", g.argv[i]); | |
| 273 | - if( name_to_uuid(&name, 1) ){ | |
| 274 | - printf("ERROR: %s\n", g.zErrMsg); | |
| 277 | + fossil_print("%s -> ", g.argv[i]); | |
| 278 | + if( name_to_uuid(&name, 1, "*") ){ | |
| 279 | + fossil_print("ERROR: %s\n", g.zErrMsg); | |
| 275 | 280 | fossil_error_reset(); |
| 276 | 281 | }else{ |
| 277 | - printf("%s\n", blob_buffer(&name)); | |
| 282 | + fossil_print("%s\n", blob_buffer(&name)); | |
| 278 | 283 | } |
| 279 | 284 | blob_reset(&name); |
| 280 | 285 | } |
| 281 | 286 | } |
| 282 | 287 | |
| @@ -287,18 +292,18 @@ | ||
| 287 | 292 | ** convert the uuid to a rid. |
| 288 | 293 | ** |
| 289 | 294 | ** This routine is used by command-line routines to resolve command-line inputs |
| 290 | 295 | ** into a rid. |
| 291 | 296 | */ |
| 292 | -int name_to_rid(const char *zName){ | |
| 297 | +int name_to_typed_rid(const char *zName, const char *zType){ | |
| 293 | 298 | int i; |
| 294 | 299 | int rid; |
| 295 | 300 | Blob name; |
| 296 | 301 | |
| 297 | 302 | if( zName==0 || zName[0]==0 ) return 0; |
| 298 | 303 | blob_init(&name, zName, -1); |
| 299 | - if( name_to_uuid(&name, -1) ){ | |
| 304 | + if( name_to_uuid(&name, -1, zType) ){ | |
| 300 | 305 | blob_reset(&name); |
| 301 | 306 | for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} |
| 302 | 307 | if( zName[i]==0 ){ |
| 303 | 308 | rid = atoi(zName); |
| 304 | 309 | if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){ |
| @@ -311,10 +316,13 @@ | ||
| 311 | 316 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); |
| 312 | 317 | blob_reset(&name); |
| 313 | 318 | } |
| 314 | 319 | return rid; |
| 315 | 320 | } |
| 321 | +int name_to_rid(const char *zName){ | |
| 322 | + return name_to_typed_rid(zName, "*"); | |
| 323 | +} | |
| 316 | 324 | |
| 317 | 325 | /* |
| 318 | 326 | ** WEBPAGE: ambiguous |
| 319 | 327 | ** URL: /ambiguous?name=UUID&src=WEBPAGE |
| 320 | 328 | ** |
| @@ -361,11 +369,11 @@ | ||
| 361 | 369 | const char *zName = P(zParamName); |
| 362 | 370 | Blob name; |
| 363 | 371 | |
| 364 | 372 | if( zName==0 || zName[0]==0 ) return 0; |
| 365 | 373 | blob_init(&name, zName, -1); |
| 366 | - rc = name_to_uuid(&name, -1); | |
| 374 | + rc = name_to_uuid(&name, -1, "*"); | |
| 367 | 375 | if( rc==1 ){ |
| 368 | 376 | blob_reset(&name); |
| 369 | 377 | for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} |
| 370 | 378 | if( zName[i]==0 ){ |
| 371 | 379 | rid = atoi(zName); |
| 372 | 380 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -40,24 +40,24 @@ | |
| 40 | ** always resolve the name as a date. |
| 41 | ** |
| 42 | ** Return 0 on success. Return 1 if the name cannot be resolved. |
| 43 | ** Return 2 name is ambiguous. |
| 44 | */ |
| 45 | int name_to_uuid(Blob *pName, int iErrPriority){ |
| 46 | int rc; |
| 47 | int sz; |
| 48 | sz = blob_size(pName); |
| 49 | if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){ |
| 50 | char *zUuid; |
| 51 | const char *zName = blob_str(pName); |
| 52 | if( memcmp(zName, "tag:", 4)==0 ){ |
| 53 | zName += 4; |
| 54 | zUuid = tag_to_uuid(zName); |
| 55 | }else{ |
| 56 | zUuid = tag_to_uuid(zName); |
| 57 | if( zUuid==0 ){ |
| 58 | zUuid = date_to_uuid(zName); |
| 59 | } |
| 60 | } |
| 61 | if( zUuid ){ |
| 62 | blob_reset(pName); |
| 63 | blob_append(pName, zUuid, -1); |
| @@ -79,11 +79,11 @@ | |
| 79 | Stmt q; |
| 80 | db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName); |
| 81 | if( db_step(&q)!=SQLITE_ROW ){ |
| 82 | char *zUuid; |
| 83 | db_finalize(&q); |
| 84 | zUuid = tag_to_uuid(blob_str(pName)); |
| 85 | if( zUuid ){ |
| 86 | blob_reset(pName); |
| 87 | blob_append(pName, zUuid, -1); |
| 88 | free(zUuid); |
| 89 | return 0; |
| @@ -141,22 +141,25 @@ | |
| 141 | ** An input of "tip" returns the most recent check-in. |
| 142 | ** |
| 143 | ** Memory to hold the returned string comes from malloc() and needs to |
| 144 | ** be freed by the caller. |
| 145 | */ |
| 146 | char *tag_to_uuid(const char *zTag){ |
| 147 | int vid; |
| 148 | char *zUuid = |
| 149 | db_text(0, |
| 150 | "SELECT blob.uuid" |
| 151 | " FROM tag, tagxref, event, blob" |
| 152 | " WHERE tag.tagname='sym-%q' " |
| 153 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 154 | " AND event.objid=tagxref.rid " |
| 155 | " AND blob.rid=event.objid " |
| 156 | " ORDER BY event.mtime DESC ", |
| 157 | zTag |
| 158 | ); |
| 159 | if( zUuid==0 ){ |
| 160 | int nTag = strlen(zTag); |
| 161 | int i; |
| 162 | for(i=0; i<nTag-10; i++){ |
| @@ -176,12 +179,13 @@ | |
| 176 | " WHERE tag.tagname='sym-%q' " |
| 177 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 178 | " AND event.objid=tagxref.rid " |
| 179 | " AND blob.rid=event.objid " |
| 180 | " AND event.mtime<=julianday(%Q %s)" |
| 181 | " ORDER BY event.mtime DESC ", |
| 182 | zTagBase, zDate, (useUtc ? "" : ",'utc'") |
| 183 | ); |
| 184 | break; |
| 185 | } |
| 186 | } |
| 187 | if( zUuid==0 && fossil_strcmp(zTag, "tip")==0 ){ |
| @@ -222,11 +226,11 @@ | |
| 222 | ** utc:DATE |
| 223 | ** |
| 224 | ** The DATE is interpreted as localtime unless the "utc:" prefix is used |
| 225 | ** or a "utc" string appears at the end of the DATE string. |
| 226 | */ |
| 227 | char *date_to_uuid(const char *zDate){ |
| 228 | int useUtc = 0; |
| 229 | int n; |
| 230 | char *zCopy = 0; |
| 231 | char *zUuid; |
| 232 | |
| @@ -245,16 +249,17 @@ | |
| 245 | zCopy[n-3] = 0; |
| 246 | zDate = zCopy; |
| 247 | n -= 3; |
| 248 | useUtc = 1; |
| 249 | } |
| 250 | zUuid = db_text(0, |
| 251 | "SELECT (SELECT uuid FROM blob WHERE rid=event.objid)" |
| 252 | " FROM event" |
| 253 | " WHERE mtime<=julianday(%Q %s) AND type='ci'" |
| 254 | " ORDER BY mtime DESC LIMIT 1", |
| 255 | zDate, useUtc ? "" : ",'utc'" |
| 256 | ); |
| 257 | free(zCopy); |
| 258 | return zUuid; |
| 259 | } |
| 260 | |
| @@ -267,16 +272,16 @@ | |
| 267 | int i; |
| 268 | Blob name; |
| 269 | db_must_be_within_tree(); |
| 270 | for(i=2; i<g.argc; i++){ |
| 271 | blob_init(&name, g.argv[i], -1); |
| 272 | printf("%s -> ", g.argv[i]); |
| 273 | if( name_to_uuid(&name, 1) ){ |
| 274 | printf("ERROR: %s\n", g.zErrMsg); |
| 275 | fossil_error_reset(); |
| 276 | }else{ |
| 277 | printf("%s\n", blob_buffer(&name)); |
| 278 | } |
| 279 | blob_reset(&name); |
| 280 | } |
| 281 | } |
| 282 | |
| @@ -287,18 +292,18 @@ | |
| 287 | ** convert the uuid to a rid. |
| 288 | ** |
| 289 | ** This routine is used by command-line routines to resolve command-line inputs |
| 290 | ** into a rid. |
| 291 | */ |
| 292 | int name_to_rid(const char *zName){ |
| 293 | int i; |
| 294 | int rid; |
| 295 | Blob name; |
| 296 | |
| 297 | if( zName==0 || zName[0]==0 ) return 0; |
| 298 | blob_init(&name, zName, -1); |
| 299 | if( name_to_uuid(&name, -1) ){ |
| 300 | blob_reset(&name); |
| 301 | for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} |
| 302 | if( zName[i]==0 ){ |
| 303 | rid = atoi(zName); |
| 304 | if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){ |
| @@ -311,10 +316,13 @@ | |
| 311 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); |
| 312 | blob_reset(&name); |
| 313 | } |
| 314 | return rid; |
| 315 | } |
| 316 | |
| 317 | /* |
| 318 | ** WEBPAGE: ambiguous |
| 319 | ** URL: /ambiguous?name=UUID&src=WEBPAGE |
| 320 | ** |
| @@ -361,11 +369,11 @@ | |
| 361 | const char *zName = P(zParamName); |
| 362 | Blob name; |
| 363 | |
| 364 | if( zName==0 || zName[0]==0 ) return 0; |
| 365 | blob_init(&name, zName, -1); |
| 366 | rc = name_to_uuid(&name, -1); |
| 367 | if( rc==1 ){ |
| 368 | blob_reset(&name); |
| 369 | for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} |
| 370 | if( zName[i]==0 ){ |
| 371 | rid = atoi(zName); |
| 372 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -40,24 +40,24 @@ | |
| 40 | ** always resolve the name as a date. |
| 41 | ** |
| 42 | ** Return 0 on success. Return 1 if the name cannot be resolved. |
| 43 | ** Return 2 name is ambiguous. |
| 44 | */ |
| 45 | int name_to_uuid(Blob *pName, int iErrPriority, const char *zType){ |
| 46 | int rc; |
| 47 | int sz; |
| 48 | sz = blob_size(pName); |
| 49 | if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){ |
| 50 | char *zUuid; |
| 51 | const char *zName = blob_str(pName); |
| 52 | if( memcmp(zName, "tag:", 4)==0 ){ |
| 53 | zName += 4; |
| 54 | zUuid = tag_to_uuid(zName, zType); |
| 55 | }else{ |
| 56 | zUuid = tag_to_uuid(zName, zType); |
| 57 | if( zUuid==0 ){ |
| 58 | zUuid = date_to_uuid(zName, zType); |
| 59 | } |
| 60 | } |
| 61 | if( zUuid ){ |
| 62 | blob_reset(pName); |
| 63 | blob_append(pName, zUuid, -1); |
| @@ -79,11 +79,11 @@ | |
| 79 | Stmt q; |
| 80 | db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName); |
| 81 | if( db_step(&q)!=SQLITE_ROW ){ |
| 82 | char *zUuid; |
| 83 | db_finalize(&q); |
| 84 | zUuid = tag_to_uuid(blob_str(pName), "*"); |
| 85 | if( zUuid ){ |
| 86 | blob_reset(pName); |
| 87 | blob_append(pName, zUuid, -1); |
| 88 | free(zUuid); |
| 89 | return 0; |
| @@ -141,22 +141,25 @@ | |
| 141 | ** An input of "tip" returns the most recent check-in. |
| 142 | ** |
| 143 | ** Memory to hold the returned string comes from malloc() and needs to |
| 144 | ** be freed by the caller. |
| 145 | */ |
| 146 | char *tag_to_uuid(const char *zTag, const char *zType){ |
| 147 | int vid; |
| 148 | char *zUuid; |
| 149 | |
| 150 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 151 | zUuid = db_text(0, |
| 152 | "SELECT blob.uuid" |
| 153 | " FROM tag, tagxref, event, blob" |
| 154 | " WHERE tag.tagname='sym-%q' " |
| 155 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 156 | " AND event.objid=tagxref.rid " |
| 157 | " AND blob.rid=event.objid " |
| 158 | " AND event.type GLOB '%q'" |
| 159 | " ORDER BY event.mtime DESC ", |
| 160 | zTag, zType |
| 161 | ); |
| 162 | if( zUuid==0 ){ |
| 163 | int nTag = strlen(zTag); |
| 164 | int i; |
| 165 | for(i=0; i<nTag-10; i++){ |
| @@ -176,12 +179,13 @@ | |
| 179 | " WHERE tag.tagname='sym-%q' " |
| 180 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 181 | " AND event.objid=tagxref.rid " |
| 182 | " AND blob.rid=event.objid " |
| 183 | " AND event.mtime<=julianday(%Q %s)" |
| 184 | " AND event.type GLOB '%q'" |
| 185 | " ORDER BY event.mtime DESC ", |
| 186 | zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType |
| 187 | ); |
| 188 | break; |
| 189 | } |
| 190 | } |
| 191 | if( zUuid==0 && fossil_strcmp(zTag, "tip")==0 ){ |
| @@ -222,11 +226,11 @@ | |
| 226 | ** utc:DATE |
| 227 | ** |
| 228 | ** The DATE is interpreted as localtime unless the "utc:" prefix is used |
| 229 | ** or a "utc" string appears at the end of the DATE string. |
| 230 | */ |
| 231 | char *date_to_uuid(const char *zDate, const char *zType){ |
| 232 | int useUtc = 0; |
| 233 | int n; |
| 234 | char *zCopy = 0; |
| 235 | char *zUuid; |
| 236 | |
| @@ -245,16 +249,17 @@ | |
| 249 | zCopy[n-3] = 0; |
| 250 | zDate = zCopy; |
| 251 | n -= 3; |
| 252 | useUtc = 1; |
| 253 | } |
| 254 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 255 | zUuid = db_text(0, |
| 256 | "SELECT (SELECT uuid FROM blob WHERE rid=event.objid)" |
| 257 | " FROM event" |
| 258 | " WHERE mtime<=julianday(%Q %s) AND type GLOB '%q'" |
| 259 | " ORDER BY mtime DESC LIMIT 1", |
| 260 | zDate, useUtc ? "" : ",'utc'", zType |
| 261 | ); |
| 262 | free(zCopy); |
| 263 | return zUuid; |
| 264 | } |
| 265 | |
| @@ -267,16 +272,16 @@ | |
| 272 | int i; |
| 273 | Blob name; |
| 274 | db_must_be_within_tree(); |
| 275 | for(i=2; i<g.argc; i++){ |
| 276 | blob_init(&name, g.argv[i], -1); |
| 277 | fossil_print("%s -> ", g.argv[i]); |
| 278 | if( name_to_uuid(&name, 1, "*") ){ |
| 279 | fossil_print("ERROR: %s\n", g.zErrMsg); |
| 280 | fossil_error_reset(); |
| 281 | }else{ |
| 282 | fossil_print("%s\n", blob_buffer(&name)); |
| 283 | } |
| 284 | blob_reset(&name); |
| 285 | } |
| 286 | } |
| 287 | |
| @@ -287,18 +292,18 @@ | |
| 292 | ** convert the uuid to a rid. |
| 293 | ** |
| 294 | ** This routine is used by command-line routines to resolve command-line inputs |
| 295 | ** into a rid. |
| 296 | */ |
| 297 | int name_to_typed_rid(const char *zName, const char *zType){ |
| 298 | int i; |
| 299 | int rid; |
| 300 | Blob name; |
| 301 | |
| 302 | if( zName==0 || zName[0]==0 ) return 0; |
| 303 | blob_init(&name, zName, -1); |
| 304 | if( name_to_uuid(&name, -1, zType) ){ |
| 305 | blob_reset(&name); |
| 306 | for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} |
| 307 | if( zName[i]==0 ){ |
| 308 | rid = atoi(zName); |
| 309 | if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){ |
| @@ -311,10 +316,13 @@ | |
| 316 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); |
| 317 | blob_reset(&name); |
| 318 | } |
| 319 | return rid; |
| 320 | } |
| 321 | int name_to_rid(const char *zName){ |
| 322 | return name_to_typed_rid(zName, "*"); |
| 323 | } |
| 324 | |
| 325 | /* |
| 326 | ** WEBPAGE: ambiguous |
| 327 | ** URL: /ambiguous?name=UUID&src=WEBPAGE |
| 328 | ** |
| @@ -361,11 +369,11 @@ | |
| 369 | const char *zName = P(zParamName); |
| 370 | Blob name; |
| 371 | |
| 372 | if( zName==0 || zName[0]==0 ) return 0; |
| 373 | blob_init(&name, zName, -1); |
| 374 | rc = name_to_uuid(&name, -1, "*"); |
| 375 | if( rc==1 ){ |
| 376 | blob_reset(&name); |
| 377 | for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} |
| 378 | if( zName[i]==0 ){ |
| 379 | rid = atoi(zName); |
| 380 |
+10
-9
| --- src/path.c | ||
| +++ src/path.c | ||
| @@ -213,16 +213,17 @@ | ||
| 213 | 213 | z = db_text(0, |
| 214 | 214 | "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" |
| 215 | 215 | " FROM blob, event" |
| 216 | 216 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 217 | 217 | p->rid, p->rid); |
| 218 | - printf("%4d: %s", n, z); | |
| 218 | + fossil_print("%4d: %s", n, z); | |
| 219 | 219 | fossil_free(z); |
| 220 | 220 | if( p->u.pTo ){ |
| 221 | - printf(" is a %s of\n", p->u.pTo->fromIsParent ? "parent" : "child"); | |
| 221 | + fossil_print(" is a %s of\n", | |
| 222 | + p->u.pTo->fromIsParent ? "parent" : "child"); | |
| 222 | 223 | }else{ |
| 223 | - printf("\n"); | |
| 224 | + fossil_print("\n"); | |
| 224 | 225 | } |
| 225 | 226 | } |
| 226 | 227 | } |
| 227 | 228 | |
| 228 | 229 | /* |
| @@ -312,16 +313,16 @@ | ||
| 312 | 313 | z = db_text(0, |
| 313 | 314 | "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" |
| 314 | 315 | " FROM blob, event" |
| 315 | 316 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 316 | 317 | p->rid, p->rid); |
| 317 | - printf("%4d: %s", n, z); | |
| 318 | + fossil_print("%4d: %s", n, z); | |
| 318 | 319 | fossil_free(z); |
| 319 | - if( p->rid==iFrom ) printf(" VERSION1"); | |
| 320 | - if( p->rid==iTo ) printf(" VERSION2"); | |
| 321 | - if( p->rid==iPivot ) printf(" PIVOT"); | |
| 322 | - printf("\n"); | |
| 320 | + if( p->rid==iFrom ) fossil_print(" VERSION1"); | |
| 321 | + if( p->rid==iTo ) fossil_print(" VERSION2"); | |
| 322 | + if( p->rid==iPivot ) fossil_print(" PIVOT"); | |
| 323 | + fossil_print("\n"); | |
| 323 | 324 | } |
| 324 | 325 | } |
| 325 | 326 | |
| 326 | 327 | |
| 327 | 328 | /* |
| @@ -445,11 +446,11 @@ | ||
| 445 | 446 | for(i=0; i<nChng; i++){ |
| 446 | 447 | char *zFrom, *zTo; |
| 447 | 448 | |
| 448 | 449 | zFrom = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]); |
| 449 | 450 | zTo = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]); |
| 450 | - printf("[%s] -> [%s]\n", zFrom, zTo); | |
| 451 | + fossil_print("[%s] -> [%s]\n", zFrom, zTo); | |
| 451 | 452 | fossil_free(zFrom); |
| 452 | 453 | fossil_free(zTo); |
| 453 | 454 | } |
| 454 | 455 | fossil_free(aChng); |
| 455 | 456 | } |
| 456 | 457 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -213,16 +213,17 @@ | |
| 213 | z = db_text(0, |
| 214 | "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" |
| 215 | " FROM blob, event" |
| 216 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 217 | p->rid, p->rid); |
| 218 | printf("%4d: %s", n, z); |
| 219 | fossil_free(z); |
| 220 | if( p->u.pTo ){ |
| 221 | printf(" is a %s of\n", p->u.pTo->fromIsParent ? "parent" : "child"); |
| 222 | }else{ |
| 223 | printf("\n"); |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | /* |
| @@ -312,16 +313,16 @@ | |
| 312 | z = db_text(0, |
| 313 | "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" |
| 314 | " FROM blob, event" |
| 315 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 316 | p->rid, p->rid); |
| 317 | printf("%4d: %s", n, z); |
| 318 | fossil_free(z); |
| 319 | if( p->rid==iFrom ) printf(" VERSION1"); |
| 320 | if( p->rid==iTo ) printf(" VERSION2"); |
| 321 | if( p->rid==iPivot ) printf(" PIVOT"); |
| 322 | printf("\n"); |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | |
| 327 | /* |
| @@ -445,11 +446,11 @@ | |
| 445 | for(i=0; i<nChng; i++){ |
| 446 | char *zFrom, *zTo; |
| 447 | |
| 448 | zFrom = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]); |
| 449 | zTo = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]); |
| 450 | printf("[%s] -> [%s]\n", zFrom, zTo); |
| 451 | fossil_free(zFrom); |
| 452 | fossil_free(zTo); |
| 453 | } |
| 454 | fossil_free(aChng); |
| 455 | } |
| 456 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -213,16 +213,17 @@ | |
| 213 | z = db_text(0, |
| 214 | "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" |
| 215 | " FROM blob, event" |
| 216 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 217 | p->rid, p->rid); |
| 218 | fossil_print("%4d: %s", n, z); |
| 219 | fossil_free(z); |
| 220 | if( p->u.pTo ){ |
| 221 | fossil_print(" is a %s of\n", |
| 222 | p->u.pTo->fromIsParent ? "parent" : "child"); |
| 223 | }else{ |
| 224 | fossil_print("\n"); |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | /* |
| @@ -312,16 +313,16 @@ | |
| 313 | z = db_text(0, |
| 314 | "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" |
| 315 | " FROM blob, event" |
| 316 | " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", |
| 317 | p->rid, p->rid); |
| 318 | fossil_print("%4d: %s", n, z); |
| 319 | fossil_free(z); |
| 320 | if( p->rid==iFrom ) fossil_print(" VERSION1"); |
| 321 | if( p->rid==iTo ) fossil_print(" VERSION2"); |
| 322 | if( p->rid==iPivot ) fossil_print(" PIVOT"); |
| 323 | fossil_print("\n"); |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | |
| 328 | /* |
| @@ -445,11 +446,11 @@ | |
| 446 | for(i=0; i<nChng; i++){ |
| 447 | char *zFrom, *zTo; |
| 448 | |
| 449 | zFrom = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]); |
| 450 | zTo = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]); |
| 451 | fossil_print("[%s] -> [%s]\n", zFrom, zTo); |
| 452 | fossil_free(zFrom); |
| 453 | fossil_free(zTo); |
| 454 | } |
| 455 | fossil_free(aChng); |
| 456 | } |
| 457 |
+48
-1
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -797,10 +797,36 @@ | ||
| 797 | 797 | void fossil_error_reset(void){ |
| 798 | 798 | free(g.zErrMsg); |
| 799 | 799 | g.zErrMsg = 0; |
| 800 | 800 | g.iErrPriority = 0; |
| 801 | 801 | } |
| 802 | + | |
| 803 | +/* | |
| 804 | +** Write to standard output or standard error. | |
| 805 | +** | |
| 806 | +** On windows, transform the output into the current terminal encoding | |
| 807 | +** if the output is going to the screen. If output is redirected into | |
| 808 | +** a file, no translation occurs. No translation ever occurs on unix. | |
| 809 | +*/ | |
| 810 | +void fossil_puts(const char *z, int toStdErr){ | |
| 811 | +#if defined(_WIN32) | |
| 812 | + static int once = 1; | |
| 813 | + static int istty[2]; | |
| 814 | + char *zToFree = 0; | |
| 815 | + if( once ){ | |
| 816 | + istty[0] = _isatty(fileno(stdout)); | |
| 817 | + istty[1] = _isatty(fileno(stderr)); | |
| 818 | + once = 0; | |
| 819 | + } | |
| 820 | + assert( toStdErr==0 || toStdErr==1 ); | |
| 821 | + if( istty[toStdErr] ) z = zToFree = fossil_utf8_to_console(z); | |
| 822 | + fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); | |
| 823 | + free(zToFree); | |
| 824 | +#else | |
| 825 | + fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); | |
| 826 | +#endif | |
| 827 | +} | |
| 802 | 828 | |
| 803 | 829 | /* |
| 804 | 830 | ** Write output for user consumption. If g.cgiOutput is enabled, then |
| 805 | 831 | ** send the output as part of the CGI reply. If g.cgiOutput is false, |
| 806 | 832 | ** then write on standard output. |
| @@ -811,14 +837,35 @@ | ||
| 811 | 837 | if( g.cgiOutput ){ |
| 812 | 838 | cgi_vprintf(zFormat, ap); |
| 813 | 839 | }else{ |
| 814 | 840 | Blob b = empty_blob; |
| 815 | 841 | vxprintf(&b, zFormat, ap); |
| 816 | - fwrite(blob_buffer(&b), 1, blob_size(&b), stdout); | |
| 842 | + fossil_puts(blob_str(&b), 0); | |
| 817 | 843 | blob_reset(&b); |
| 818 | 844 | } |
| 819 | 845 | } |
| 846 | + | |
| 847 | +/* | |
| 848 | +** Like strcmp() except that it accepts NULL pointers. NULL sorts before | |
| 849 | +** all non-NULL string pointers. Also, this strcmp() is a binary comparison | |
| 850 | +** that does not consider locale. | |
| 851 | +*/ | |
| 852 | +int fossil_strcmp(const char *zA, const char *zB){ | |
| 853 | + if( zA==0 ){ | |
| 854 | + if( zB==0 ) return 0; | |
| 855 | + return -1; | |
| 856 | + }else if( zB==0 ){ | |
| 857 | + return +1; | |
| 858 | + }else{ | |
| 859 | + int a, b; | |
| 860 | + do{ | |
| 861 | + a = *zA++; | |
| 862 | + b = *zB++; | |
| 863 | + }while( a==b && a!=0 ); | |
| 864 | + return a - b; | |
| 865 | + } | |
| 866 | +} | |
| 820 | 867 | |
| 821 | 868 | /* |
| 822 | 869 | ** Case insensitive string comparison. |
| 823 | 870 | */ |
| 824 | 871 | int fossil_strnicmp(const char *zA, const char *zB, int nByte){ |
| 825 | 872 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -797,10 +797,36 @@ | |
| 797 | void fossil_error_reset(void){ |
| 798 | free(g.zErrMsg); |
| 799 | g.zErrMsg = 0; |
| 800 | g.iErrPriority = 0; |
| 801 | } |
| 802 | |
| 803 | /* |
| 804 | ** Write output for user consumption. If g.cgiOutput is enabled, then |
| 805 | ** send the output as part of the CGI reply. If g.cgiOutput is false, |
| 806 | ** then write on standard output. |
| @@ -811,14 +837,35 @@ | |
| 811 | if( g.cgiOutput ){ |
| 812 | cgi_vprintf(zFormat, ap); |
| 813 | }else{ |
| 814 | Blob b = empty_blob; |
| 815 | vxprintf(&b, zFormat, ap); |
| 816 | fwrite(blob_buffer(&b), 1, blob_size(&b), stdout); |
| 817 | blob_reset(&b); |
| 818 | } |
| 819 | } |
| 820 | |
| 821 | /* |
| 822 | ** Case insensitive string comparison. |
| 823 | */ |
| 824 | int fossil_strnicmp(const char *zA, const char *zB, int nByte){ |
| 825 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -797,10 +797,36 @@ | |
| 797 | void fossil_error_reset(void){ |
| 798 | free(g.zErrMsg); |
| 799 | g.zErrMsg = 0; |
| 800 | g.iErrPriority = 0; |
| 801 | } |
| 802 | |
| 803 | /* |
| 804 | ** Write to standard output or standard error. |
| 805 | ** |
| 806 | ** On windows, transform the output into the current terminal encoding |
| 807 | ** if the output is going to the screen. If output is redirected into |
| 808 | ** a file, no translation occurs. No translation ever occurs on unix. |
| 809 | */ |
| 810 | void fossil_puts(const char *z, int toStdErr){ |
| 811 | #if defined(_WIN32) |
| 812 | static int once = 1; |
| 813 | static int istty[2]; |
| 814 | char *zToFree = 0; |
| 815 | if( once ){ |
| 816 | istty[0] = _isatty(fileno(stdout)); |
| 817 | istty[1] = _isatty(fileno(stderr)); |
| 818 | once = 0; |
| 819 | } |
| 820 | assert( toStdErr==0 || toStdErr==1 ); |
| 821 | if( istty[toStdErr] ) z = zToFree = fossil_utf8_to_console(z); |
| 822 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 823 | free(zToFree); |
| 824 | #else |
| 825 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 826 | #endif |
| 827 | } |
| 828 | |
| 829 | /* |
| 830 | ** Write output for user consumption. If g.cgiOutput is enabled, then |
| 831 | ** send the output as part of the CGI reply. If g.cgiOutput is false, |
| 832 | ** then write on standard output. |
| @@ -811,14 +837,35 @@ | |
| 837 | if( g.cgiOutput ){ |
| 838 | cgi_vprintf(zFormat, ap); |
| 839 | }else{ |
| 840 | Blob b = empty_blob; |
| 841 | vxprintf(&b, zFormat, ap); |
| 842 | fossil_puts(blob_str(&b), 0); |
| 843 | blob_reset(&b); |
| 844 | } |
| 845 | } |
| 846 | |
| 847 | /* |
| 848 | ** Like strcmp() except that it accepts NULL pointers. NULL sorts before |
| 849 | ** all non-NULL string pointers. Also, this strcmp() is a binary comparison |
| 850 | ** that does not consider locale. |
| 851 | */ |
| 852 | int fossil_strcmp(const char *zA, const char *zB){ |
| 853 | if( zA==0 ){ |
| 854 | if( zB==0 ) return 0; |
| 855 | return -1; |
| 856 | }else if( zB==0 ){ |
| 857 | return +1; |
| 858 | }else{ |
| 859 | int a, b; |
| 860 | do{ |
| 861 | a = *zA++; |
| 862 | b = *zB++; |
| 863 | }while( a==b && a!=0 ); |
| 864 | return a - b; |
| 865 | } |
| 866 | } |
| 867 | |
| 868 | /* |
| 869 | ** Case insensitive string comparison. |
| 870 | */ |
| 871 | int fossil_strnicmp(const char *zA, const char *zB, int nByte){ |
| 872 |
+31
-23
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -176,11 +176,11 @@ | ||
| 176 | 176 | ** The input is actually the permill complete. |
| 177 | 177 | */ |
| 178 | 178 | static void percent_complete(int permill){ |
| 179 | 179 | static int lastOutput = -1; |
| 180 | 180 | if( permill>lastOutput ){ |
| 181 | - printf(" %d.%d%% complete...\r", permill/10, permill%10); | |
| 181 | + fossil_print(" %d.%d%% complete...\r", permill/10, permill%10); | |
| 182 | 182 | fflush(stdout); |
| 183 | 183 | lastOutput = permill; |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| @@ -420,11 +420,11 @@ | ||
| 420 | 420 | if( !g.fQuiet && totalSize>0 ){ |
| 421 | 421 | processCnt += incrSize; |
| 422 | 422 | percent_complete((processCnt*1000)/totalSize); |
| 423 | 423 | } |
| 424 | 424 | if(!g.fQuiet && ttyOutput ){ |
| 425 | - printf("\n"); | |
| 425 | + fossil_print("\n"); | |
| 426 | 426 | } |
| 427 | 427 | return errCnt; |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | 430 | /* |
| @@ -549,32 +549,34 @@ | ||
| 549 | 549 | "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" |
| 550 | 550 | "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());", |
| 551 | 551 | CONTENT_SCHEMA, AUX_SCHEMA |
| 552 | 552 | ); |
| 553 | 553 | if( errCnt && !forceFlag ){ |
| 554 | - printf("%d errors. Rolling back changes. Use --force to force a commit.\n", | |
| 555 | - errCnt); | |
| 554 | + fossil_print( | |
| 555 | + "%d errors. Rolling back changes. Use --force to force a commit.\n", | |
| 556 | + errCnt | |
| 557 | + ); | |
| 556 | 558 | db_end_transaction(1); |
| 557 | 559 | }else{ |
| 558 | 560 | if( runCompress ){ |
| 559 | - printf("Extra delta compression... "); fflush(stdout); | |
| 561 | + fossil_print("Extra delta compression... "); fflush(stdout); | |
| 560 | 562 | extra_deltification(); |
| 561 | 563 | runVacuum = 1; |
| 562 | 564 | } |
| 563 | 565 | if( omitVerify ) verify_cancel(); |
| 564 | 566 | db_end_transaction(0); |
| 565 | - if( runCompress ) printf("done\n"); | |
| 567 | + if( runCompress ) fossil_print("done\n"); | |
| 566 | 568 | db_close(0); |
| 567 | 569 | db_open_repository(g.zRepositoryName); |
| 568 | 570 | if( newPagesize ){ |
| 569 | 571 | db_multi_exec("PRAGMA page_size=%d", newPagesize); |
| 570 | 572 | runVacuum = 1; |
| 571 | 573 | } |
| 572 | 574 | if( runVacuum ){ |
| 573 | - printf("Vacuuming the database... "); fflush(stdout); | |
| 575 | + fossil_print("Vacuuming the database... "); fflush(stdout); | |
| 574 | 576 | db_multi_exec("VACUUM"); |
| 575 | - printf("done\n"); | |
| 577 | + fossil_print("done\n"); | |
| 576 | 578 | } |
| 577 | 579 | if( activateWal ){ |
| 578 | 580 | db_multi_exec("PRAGMA journal_mode=WAL;"); |
| 579 | 581 | } |
| 580 | 582 | } |
| @@ -678,16 +680,16 @@ | ||
| 678 | 680 | manifest_destroy(p); |
| 679 | 681 | } |
| 680 | 682 | n = db_int(0, "SELECT count(*) FROM /*scan*/" |
| 681 | 683 | " (SELECT rid FROM blob EXCEPT SELECT x FROM xdone)"); |
| 682 | 684 | if( n==0 ){ |
| 683 | - printf("all artifacts reachable through clusters\n"); | |
| 685 | + fossil_print("all artifacts reachable through clusters\n"); | |
| 684 | 686 | }else{ |
| 685 | - printf("%d unreachable artifacts:\n", n); | |
| 687 | + fossil_print("%d unreachable artifacts:\n", n); | |
| 686 | 688 | db_prepare(&q, "SELECT rid, uuid FROM blob WHERE rid NOT IN xdone"); |
| 687 | 689 | while( db_step(&q)==SQLITE_ROW ){ |
| 688 | - printf(" %3d %s\n", db_column_int(&q,0), db_column_text(&q,1)); | |
| 690 | + fossil_print(" %3d %s\n", db_column_int(&q,0), db_column_text(&q,1)); | |
| 689 | 691 | } |
| 690 | 692 | db_finalize(&q); |
| 691 | 693 | } |
| 692 | 694 | } |
| 693 | 695 | |
| @@ -773,21 +775,26 @@ | ||
| 773 | 775 | void recon_read_dir(char *zPath){ |
| 774 | 776 | DIR *d; |
| 775 | 777 | struct dirent *pEntry; |
| 776 | 778 | Blob aContent; /* content of the just read artifact */ |
| 777 | 779 | static int nFileRead = 0; |
| 780 | + char *zMbcsPath; | |
| 781 | + char *zUtf8Name; | |
| 778 | 782 | |
| 779 | - d = opendir(zPath); | |
| 783 | + zMbcsPath = fossil_utf8_to_mbcs(zPath); | |
| 784 | + d = opendir(zMbcsPath); | |
| 780 | 785 | if( d ){ |
| 781 | 786 | while( (pEntry=readdir(d))!=0 ){ |
| 782 | 787 | Blob path; |
| 783 | 788 | char *zSubpath; |
| 784 | 789 | |
| 785 | 790 | if( pEntry->d_name[0]=='.' ){ |
| 786 | 791 | continue; |
| 787 | 792 | } |
| 788 | - zSubpath = mprintf("%s/%s",zPath,pEntry->d_name); | |
| 793 | + zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name); | |
| 794 | + zSubpath = mprintf("%s/%s", zPath, zUtf8Name); | |
| 795 | + fossil_mbcs_free(zUtf8Name); | |
| 789 | 796 | if( file_isdir(zSubpath)==1 ){ |
| 790 | 797 | recon_read_dir(zSubpath); |
| 791 | 798 | } |
| 792 | 799 | blob_init(&path, 0, 0); |
| 793 | 800 | blob_appendf(&path, "%s", zSubpath); |
| @@ -797,18 +804,19 @@ | ||
| 797 | 804 | } |
| 798 | 805 | content_put(&aContent); |
| 799 | 806 | blob_reset(&path); |
| 800 | 807 | blob_reset(&aContent); |
| 801 | 808 | free(zSubpath); |
| 802 | - printf("\r%d", ++nFileRead); | |
| 809 | + fossil_print("\r%d", ++nFileRead); | |
| 803 | 810 | fflush(stdout); |
| 804 | 811 | } |
| 805 | 812 | closedir(d); |
| 806 | 813 | }else { |
| 807 | 814 | fossil_panic("encountered error %d while trying to open \"%s\".", |
| 808 | 815 | errno, g.argv[3]); |
| 809 | 816 | } |
| 817 | + fossil_mbcs_free(zMbcsPath); | |
| 810 | 818 | } |
| 811 | 819 | |
| 812 | 820 | /* |
| 813 | 821 | ** COMMAND: reconstruct |
| 814 | 822 | ** |
| @@ -824,22 +832,22 @@ | ||
| 824 | 832 | char *zPassword; |
| 825 | 833 | if( g.argc!=4 ){ |
| 826 | 834 | usage("FILENAME DIRECTORY"); |
| 827 | 835 | } |
| 828 | 836 | if( file_isdir(g.argv[3])!=1 ){ |
| 829 | - printf("\"%s\" is not a directory\n\n", g.argv[3]); | |
| 837 | + fossil_print("\"%s\" is not a directory\n\n", g.argv[3]); | |
| 830 | 838 | usage("FILENAME DIRECTORY"); |
| 831 | 839 | } |
| 832 | 840 | db_create_repository(g.argv[2]); |
| 833 | 841 | db_open_repository(g.argv[2]); |
| 834 | 842 | db_open_config(0); |
| 835 | 843 | db_begin_transaction(); |
| 836 | 844 | db_initial_setup(0, 0, 1); |
| 837 | 845 | |
| 838 | - printf("Reading files from directory \"%s\"...\n", g.argv[3]); | |
| 846 | + fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]); | |
| 839 | 847 | recon_read_dir(g.argv[3]); |
| 840 | - printf("\nBuilding the Fossil repository...\n"); | |
| 848 | + fossil_print("\nBuilding the Fossil repository...\n"); | |
| 841 | 849 | |
| 842 | 850 | rebuild_db(0, 1, 1); |
| 843 | 851 | |
| 844 | 852 | /* Reconstruct the private table. The private table contains the rid |
| 845 | 853 | ** of every manifest that is tagged with "private" and every file that |
| @@ -861,14 +869,14 @@ | ||
| 861 | 869 | ** long time. |
| 862 | 870 | */ |
| 863 | 871 | verify_cancel(); |
| 864 | 872 | |
| 865 | 873 | db_end_transaction(0); |
| 866 | - printf("project-id: %s\n", db_get("project-code", 0)); | |
| 867 | - printf("server-id: %s\n", db_get("server-code", 0)); | |
| 874 | + fossil_print("project-id: %s\n", db_get("project-code", 0)); | |
| 875 | + fossil_print("server-id: %s\n", db_get("server-code", 0)); | |
| 868 | 876 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 869 | - printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword); | |
| 877 | + fossil_print("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword); | |
| 870 | 878 | } |
| 871 | 879 | |
| 872 | 880 | /* |
| 873 | 881 | ** COMMAND: deconstruct |
| 874 | 882 | ** |
| @@ -909,11 +917,11 @@ | ||
| 909 | 917 | }else{ |
| 910 | 918 | fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt); |
| 911 | 919 | } |
| 912 | 920 | } |
| 913 | 921 | #ifndef _WIN32 |
| 914 | - if( access(zDestDir, W_OK) ){ | |
| 922 | + if( file_access(zDestDir, W_OK) ){ | |
| 915 | 923 | fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir); |
| 916 | 924 | } |
| 917 | 925 | #else |
| 918 | 926 | /* write access on windows is not checked, errors will be |
| 919 | 927 | ** dected on blob_write_to_file |
| @@ -928,11 +936,11 @@ | ||
| 928 | 936 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 929 | 937 | bag_init(&bagDone); |
| 930 | 938 | ttyOutput = 1; |
| 931 | 939 | processCnt = 0; |
| 932 | 940 | if (!g.fQuiet) { |
| 933 | - printf("0 (0%%)...\r"); | |
| 941 | + fossil_print("0 (0%%)...\r"); | |
| 934 | 942 | fflush(stdout); |
| 935 | 943 | } |
| 936 | 944 | totalSize = db_int(0, "SELECT count(*) FROM blob"); |
| 937 | 945 | db_prepare(&s, |
| 938 | 946 | "SELECT rid, size FROM blob /*scan*/" |
| @@ -964,12 +972,12 @@ | ||
| 964 | 972 | } |
| 965 | 973 | } |
| 966 | 974 | } |
| 967 | 975 | db_finalize(&s); |
| 968 | 976 | if(!g.fQuiet && ttyOutput ){ |
| 969 | - printf("\n"); | |
| 977 | + fossil_print("\n"); | |
| 970 | 978 | } |
| 971 | 979 | |
| 972 | 980 | /* free filename format string */ |
| 973 | 981 | free(zFNameFormat); |
| 974 | 982 | zFNameFormat = 0; |
| 975 | 983 | } |
| 976 | 984 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -176,11 +176,11 @@ | |
| 176 | ** The input is actually the permill complete. |
| 177 | */ |
| 178 | static void percent_complete(int permill){ |
| 179 | static int lastOutput = -1; |
| 180 | if( permill>lastOutput ){ |
| 181 | printf(" %d.%d%% complete...\r", permill/10, permill%10); |
| 182 | fflush(stdout); |
| 183 | lastOutput = permill; |
| 184 | } |
| 185 | } |
| 186 | |
| @@ -420,11 +420,11 @@ | |
| 420 | if( !g.fQuiet && totalSize>0 ){ |
| 421 | processCnt += incrSize; |
| 422 | percent_complete((processCnt*1000)/totalSize); |
| 423 | } |
| 424 | if(!g.fQuiet && ttyOutput ){ |
| 425 | printf("\n"); |
| 426 | } |
| 427 | return errCnt; |
| 428 | } |
| 429 | |
| 430 | /* |
| @@ -549,32 +549,34 @@ | |
| 549 | "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" |
| 550 | "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());", |
| 551 | CONTENT_SCHEMA, AUX_SCHEMA |
| 552 | ); |
| 553 | if( errCnt && !forceFlag ){ |
| 554 | printf("%d errors. Rolling back changes. Use --force to force a commit.\n", |
| 555 | errCnt); |
| 556 | db_end_transaction(1); |
| 557 | }else{ |
| 558 | if( runCompress ){ |
| 559 | printf("Extra delta compression... "); fflush(stdout); |
| 560 | extra_deltification(); |
| 561 | runVacuum = 1; |
| 562 | } |
| 563 | if( omitVerify ) verify_cancel(); |
| 564 | db_end_transaction(0); |
| 565 | if( runCompress ) printf("done\n"); |
| 566 | db_close(0); |
| 567 | db_open_repository(g.zRepositoryName); |
| 568 | if( newPagesize ){ |
| 569 | db_multi_exec("PRAGMA page_size=%d", newPagesize); |
| 570 | runVacuum = 1; |
| 571 | } |
| 572 | if( runVacuum ){ |
| 573 | printf("Vacuuming the database... "); fflush(stdout); |
| 574 | db_multi_exec("VACUUM"); |
| 575 | printf("done\n"); |
| 576 | } |
| 577 | if( activateWal ){ |
| 578 | db_multi_exec("PRAGMA journal_mode=WAL;"); |
| 579 | } |
| 580 | } |
| @@ -678,16 +680,16 @@ | |
| 678 | manifest_destroy(p); |
| 679 | } |
| 680 | n = db_int(0, "SELECT count(*) FROM /*scan*/" |
| 681 | " (SELECT rid FROM blob EXCEPT SELECT x FROM xdone)"); |
| 682 | if( n==0 ){ |
| 683 | printf("all artifacts reachable through clusters\n"); |
| 684 | }else{ |
| 685 | printf("%d unreachable artifacts:\n", n); |
| 686 | db_prepare(&q, "SELECT rid, uuid FROM blob WHERE rid NOT IN xdone"); |
| 687 | while( db_step(&q)==SQLITE_ROW ){ |
| 688 | printf(" %3d %s\n", db_column_int(&q,0), db_column_text(&q,1)); |
| 689 | } |
| 690 | db_finalize(&q); |
| 691 | } |
| 692 | } |
| 693 | |
| @@ -773,21 +775,26 @@ | |
| 773 | void recon_read_dir(char *zPath){ |
| 774 | DIR *d; |
| 775 | struct dirent *pEntry; |
| 776 | Blob aContent; /* content of the just read artifact */ |
| 777 | static int nFileRead = 0; |
| 778 | |
| 779 | d = opendir(zPath); |
| 780 | if( d ){ |
| 781 | while( (pEntry=readdir(d))!=0 ){ |
| 782 | Blob path; |
| 783 | char *zSubpath; |
| 784 | |
| 785 | if( pEntry->d_name[0]=='.' ){ |
| 786 | continue; |
| 787 | } |
| 788 | zSubpath = mprintf("%s/%s",zPath,pEntry->d_name); |
| 789 | if( file_isdir(zSubpath)==1 ){ |
| 790 | recon_read_dir(zSubpath); |
| 791 | } |
| 792 | blob_init(&path, 0, 0); |
| 793 | blob_appendf(&path, "%s", zSubpath); |
| @@ -797,18 +804,19 @@ | |
| 797 | } |
| 798 | content_put(&aContent); |
| 799 | blob_reset(&path); |
| 800 | blob_reset(&aContent); |
| 801 | free(zSubpath); |
| 802 | printf("\r%d", ++nFileRead); |
| 803 | fflush(stdout); |
| 804 | } |
| 805 | closedir(d); |
| 806 | }else { |
| 807 | fossil_panic("encountered error %d while trying to open \"%s\".", |
| 808 | errno, g.argv[3]); |
| 809 | } |
| 810 | } |
| 811 | |
| 812 | /* |
| 813 | ** COMMAND: reconstruct |
| 814 | ** |
| @@ -824,22 +832,22 @@ | |
| 824 | char *zPassword; |
| 825 | if( g.argc!=4 ){ |
| 826 | usage("FILENAME DIRECTORY"); |
| 827 | } |
| 828 | if( file_isdir(g.argv[3])!=1 ){ |
| 829 | printf("\"%s\" is not a directory\n\n", g.argv[3]); |
| 830 | usage("FILENAME DIRECTORY"); |
| 831 | } |
| 832 | db_create_repository(g.argv[2]); |
| 833 | db_open_repository(g.argv[2]); |
| 834 | db_open_config(0); |
| 835 | db_begin_transaction(); |
| 836 | db_initial_setup(0, 0, 1); |
| 837 | |
| 838 | printf("Reading files from directory \"%s\"...\n", g.argv[3]); |
| 839 | recon_read_dir(g.argv[3]); |
| 840 | printf("\nBuilding the Fossil repository...\n"); |
| 841 | |
| 842 | rebuild_db(0, 1, 1); |
| 843 | |
| 844 | /* Reconstruct the private table. The private table contains the rid |
| 845 | ** of every manifest that is tagged with "private" and every file that |
| @@ -861,14 +869,14 @@ | |
| 861 | ** long time. |
| 862 | */ |
| 863 | verify_cancel(); |
| 864 | |
| 865 | db_end_transaction(0); |
| 866 | printf("project-id: %s\n", db_get("project-code", 0)); |
| 867 | printf("server-id: %s\n", db_get("server-code", 0)); |
| 868 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 869 | printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword); |
| 870 | } |
| 871 | |
| 872 | /* |
| 873 | ** COMMAND: deconstruct |
| 874 | ** |
| @@ -909,11 +917,11 @@ | |
| 909 | }else{ |
| 910 | fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt); |
| 911 | } |
| 912 | } |
| 913 | #ifndef _WIN32 |
| 914 | if( access(zDestDir, W_OK) ){ |
| 915 | fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir); |
| 916 | } |
| 917 | #else |
| 918 | /* write access on windows is not checked, errors will be |
| 919 | ** dected on blob_write_to_file |
| @@ -928,11 +936,11 @@ | |
| 928 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 929 | bag_init(&bagDone); |
| 930 | ttyOutput = 1; |
| 931 | processCnt = 0; |
| 932 | if (!g.fQuiet) { |
| 933 | printf("0 (0%%)...\r"); |
| 934 | fflush(stdout); |
| 935 | } |
| 936 | totalSize = db_int(0, "SELECT count(*) FROM blob"); |
| 937 | db_prepare(&s, |
| 938 | "SELECT rid, size FROM blob /*scan*/" |
| @@ -964,12 +972,12 @@ | |
| 964 | } |
| 965 | } |
| 966 | } |
| 967 | db_finalize(&s); |
| 968 | if(!g.fQuiet && ttyOutput ){ |
| 969 | printf("\n"); |
| 970 | } |
| 971 | |
| 972 | /* free filename format string */ |
| 973 | free(zFNameFormat); |
| 974 | zFNameFormat = 0; |
| 975 | } |
| 976 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -176,11 +176,11 @@ | |
| 176 | ** The input is actually the permill complete. |
| 177 | */ |
| 178 | static void percent_complete(int permill){ |
| 179 | static int lastOutput = -1; |
| 180 | if( permill>lastOutput ){ |
| 181 | fossil_print(" %d.%d%% complete...\r", permill/10, permill%10); |
| 182 | fflush(stdout); |
| 183 | lastOutput = permill; |
| 184 | } |
| 185 | } |
| 186 | |
| @@ -420,11 +420,11 @@ | |
| 420 | if( !g.fQuiet && totalSize>0 ){ |
| 421 | processCnt += incrSize; |
| 422 | percent_complete((processCnt*1000)/totalSize); |
| 423 | } |
| 424 | if(!g.fQuiet && ttyOutput ){ |
| 425 | fossil_print("\n"); |
| 426 | } |
| 427 | return errCnt; |
| 428 | } |
| 429 | |
| 430 | /* |
| @@ -549,32 +549,34 @@ | |
| 549 | "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" |
| 550 | "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());", |
| 551 | CONTENT_SCHEMA, AUX_SCHEMA |
| 552 | ); |
| 553 | if( errCnt && !forceFlag ){ |
| 554 | fossil_print( |
| 555 | "%d errors. Rolling back changes. Use --force to force a commit.\n", |
| 556 | errCnt |
| 557 | ); |
| 558 | db_end_transaction(1); |
| 559 | }else{ |
| 560 | if( runCompress ){ |
| 561 | fossil_print("Extra delta compression... "); fflush(stdout); |
| 562 | extra_deltification(); |
| 563 | runVacuum = 1; |
| 564 | } |
| 565 | if( omitVerify ) verify_cancel(); |
| 566 | db_end_transaction(0); |
| 567 | if( runCompress ) fossil_print("done\n"); |
| 568 | db_close(0); |
| 569 | db_open_repository(g.zRepositoryName); |
| 570 | if( newPagesize ){ |
| 571 | db_multi_exec("PRAGMA page_size=%d", newPagesize); |
| 572 | runVacuum = 1; |
| 573 | } |
| 574 | if( runVacuum ){ |
| 575 | fossil_print("Vacuuming the database... "); fflush(stdout); |
| 576 | db_multi_exec("VACUUM"); |
| 577 | fossil_print("done\n"); |
| 578 | } |
| 579 | if( activateWal ){ |
| 580 | db_multi_exec("PRAGMA journal_mode=WAL;"); |
| 581 | } |
| 582 | } |
| @@ -678,16 +680,16 @@ | |
| 680 | manifest_destroy(p); |
| 681 | } |
| 682 | n = db_int(0, "SELECT count(*) FROM /*scan*/" |
| 683 | " (SELECT rid FROM blob EXCEPT SELECT x FROM xdone)"); |
| 684 | if( n==0 ){ |
| 685 | fossil_print("all artifacts reachable through clusters\n"); |
| 686 | }else{ |
| 687 | fossil_print("%d unreachable artifacts:\n", n); |
| 688 | db_prepare(&q, "SELECT rid, uuid FROM blob WHERE rid NOT IN xdone"); |
| 689 | while( db_step(&q)==SQLITE_ROW ){ |
| 690 | fossil_print(" %3d %s\n", db_column_int(&q,0), db_column_text(&q,1)); |
| 691 | } |
| 692 | db_finalize(&q); |
| 693 | } |
| 694 | } |
| 695 | |
| @@ -773,21 +775,26 @@ | |
| 775 | void recon_read_dir(char *zPath){ |
| 776 | DIR *d; |
| 777 | struct dirent *pEntry; |
| 778 | Blob aContent; /* content of the just read artifact */ |
| 779 | static int nFileRead = 0; |
| 780 | char *zMbcsPath; |
| 781 | char *zUtf8Name; |
| 782 | |
| 783 | zMbcsPath = fossil_utf8_to_mbcs(zPath); |
| 784 | d = opendir(zMbcsPath); |
| 785 | if( d ){ |
| 786 | while( (pEntry=readdir(d))!=0 ){ |
| 787 | Blob path; |
| 788 | char *zSubpath; |
| 789 | |
| 790 | if( pEntry->d_name[0]=='.' ){ |
| 791 | continue; |
| 792 | } |
| 793 | zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name); |
| 794 | zSubpath = mprintf("%s/%s", zPath, zUtf8Name); |
| 795 | fossil_mbcs_free(zUtf8Name); |
| 796 | if( file_isdir(zSubpath)==1 ){ |
| 797 | recon_read_dir(zSubpath); |
| 798 | } |
| 799 | blob_init(&path, 0, 0); |
| 800 | blob_appendf(&path, "%s", zSubpath); |
| @@ -797,18 +804,19 @@ | |
| 804 | } |
| 805 | content_put(&aContent); |
| 806 | blob_reset(&path); |
| 807 | blob_reset(&aContent); |
| 808 | free(zSubpath); |
| 809 | fossil_print("\r%d", ++nFileRead); |
| 810 | fflush(stdout); |
| 811 | } |
| 812 | closedir(d); |
| 813 | }else { |
| 814 | fossil_panic("encountered error %d while trying to open \"%s\".", |
| 815 | errno, g.argv[3]); |
| 816 | } |
| 817 | fossil_mbcs_free(zMbcsPath); |
| 818 | } |
| 819 | |
| 820 | /* |
| 821 | ** COMMAND: reconstruct |
| 822 | ** |
| @@ -824,22 +832,22 @@ | |
| 832 | char *zPassword; |
| 833 | if( g.argc!=4 ){ |
| 834 | usage("FILENAME DIRECTORY"); |
| 835 | } |
| 836 | if( file_isdir(g.argv[3])!=1 ){ |
| 837 | fossil_print("\"%s\" is not a directory\n\n", g.argv[3]); |
| 838 | usage("FILENAME DIRECTORY"); |
| 839 | } |
| 840 | db_create_repository(g.argv[2]); |
| 841 | db_open_repository(g.argv[2]); |
| 842 | db_open_config(0); |
| 843 | db_begin_transaction(); |
| 844 | db_initial_setup(0, 0, 1); |
| 845 | |
| 846 | fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]); |
| 847 | recon_read_dir(g.argv[3]); |
| 848 | fossil_print("\nBuilding the Fossil repository...\n"); |
| 849 | |
| 850 | rebuild_db(0, 1, 1); |
| 851 | |
| 852 | /* Reconstruct the private table. The private table contains the rid |
| 853 | ** of every manifest that is tagged with "private" and every file that |
| @@ -861,14 +869,14 @@ | |
| 869 | ** long time. |
| 870 | */ |
| 871 | verify_cancel(); |
| 872 | |
| 873 | db_end_transaction(0); |
| 874 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 875 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 876 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 877 | fossil_print("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword); |
| 878 | } |
| 879 | |
| 880 | /* |
| 881 | ** COMMAND: deconstruct |
| 882 | ** |
| @@ -909,11 +917,11 @@ | |
| 917 | }else{ |
| 918 | fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt); |
| 919 | } |
| 920 | } |
| 921 | #ifndef _WIN32 |
| 922 | if( file_access(zDestDir, W_OK) ){ |
| 923 | fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir); |
| 924 | } |
| 925 | #else |
| 926 | /* write access on windows is not checked, errors will be |
| 927 | ** dected on blob_write_to_file |
| @@ -928,11 +936,11 @@ | |
| 936 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 937 | bag_init(&bagDone); |
| 938 | ttyOutput = 1; |
| 939 | processCnt = 0; |
| 940 | if (!g.fQuiet) { |
| 941 | fossil_print("0 (0%%)...\r"); |
| 942 | fflush(stdout); |
| 943 | } |
| 944 | totalSize = db_int(0, "SELECT count(*) FROM blob"); |
| 945 | db_prepare(&s, |
| 946 | "SELECT rid, size FROM blob /*scan*/" |
| @@ -964,12 +972,12 @@ | |
| 972 | } |
| 973 | } |
| 974 | } |
| 975 | db_finalize(&s); |
| 976 | if(!g.fQuiet && ttyOutput ){ |
| 977 | fossil_print("\n"); |
| 978 | } |
| 979 | |
| 980 | /* free filename format string */ |
| 981 | free(zFNameFormat); |
| 982 | zFNameFormat = 0; |
| 983 | } |
| 984 |
+11
-11
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -644,11 +644,11 @@ | ||
| 644 | 644 | pState->nCol = 0; |
| 645 | 645 | pState->isMultirow = 0; |
| 646 | 646 | pState->iNewRow = -1; |
| 647 | 647 | pState->iBg = -1; |
| 648 | 648 | for(i=0; i<nArg; i++){ |
| 649 | - if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ | |
| 649 | + if( azName[i][0]=='b' && fossil_strcmp(azName[i],"bgcolor")==0 ){ | |
| 650 | 650 | pState->iBg = i; |
| 651 | 651 | continue; |
| 652 | 652 | } |
| 653 | 653 | if( g.okWrite && azName[i][0]=='#' ){ |
| 654 | 654 | pState->nCol++; |
| @@ -947,11 +947,11 @@ | ||
| 947 | 947 | |
| 948 | 948 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 949 | 949 | style_submenu_element("Raw", "Raw", |
| 950 | 950 | "rptview?tablist=1&%h", PD("QUERY_STRING","")); |
| 951 | 951 | if( g.okAdmin |
| 952 | - || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){ | |
| 952 | + || (g.okTktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ | |
| 953 | 953 | style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); |
| 954 | 954 | } |
| 955 | 955 | if( g.okTktFmt ){ |
| 956 | 956 | style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn); |
| 957 | 957 | } |
| @@ -1000,19 +1000,19 @@ | ||
| 1000 | 1000 | */ |
| 1001 | 1001 | void rpt_list_reports(void){ |
| 1002 | 1002 | Stmt q; |
| 1003 | 1003 | char const aRptOutFrmt[] = "%s\t%s\n"; |
| 1004 | 1004 | |
| 1005 | - printf("Available reports:\n"); | |
| 1006 | - printf(aRptOutFrmt,"report number","report title"); | |
| 1007 | - printf(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle); | |
| 1005 | + fossil_print("Available reports:\n"); | |
| 1006 | + fossil_print(aRptOutFrmt,"report number","report title"); | |
| 1007 | + fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle); | |
| 1008 | 1008 | db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn"); |
| 1009 | 1009 | while( db_step(&q)==SQLITE_ROW ){ |
| 1010 | 1010 | const char *zRn = db_column_text(&q, 0); |
| 1011 | 1011 | const char *zTitle = db_column_text(&q, 1); |
| 1012 | 1012 | |
| 1013 | - printf(aRptOutFrmt,zRn,zTitle); | |
| 1013 | + fossil_print(aRptOutFrmt,zRn,zTitle); | |
| 1014 | 1014 | } |
| 1015 | 1015 | db_finalize(&q); |
| 1016 | 1016 | } |
| 1017 | 1017 | |
| 1018 | 1018 | /* |
| @@ -1037,25 +1037,25 @@ | ||
| 1037 | 1037 | case tktFossilize: |
| 1038 | 1038 | { char *zFosZ; |
| 1039 | 1039 | |
| 1040 | 1040 | if( z && *z ){ |
| 1041 | 1041 | zFosZ = fossilize(z,-1); |
| 1042 | - printf("%s",zFosZ); | |
| 1042 | + fossil_print("%s",zFosZ); | |
| 1043 | 1043 | free(zFosZ); |
| 1044 | 1044 | } |
| 1045 | 1045 | break; |
| 1046 | 1046 | } |
| 1047 | 1047 | default: |
| 1048 | 1048 | while( z && z[0] ){ |
| 1049 | 1049 | int i, j; |
| 1050 | 1050 | for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){} |
| 1051 | 1051 | if( i>0 ){ |
| 1052 | - printf("%.*s", i, z); | |
| 1052 | + fossil_print("%.*s", i, z); | |
| 1053 | 1053 | } |
| 1054 | 1054 | for(j=i; fossil_isspace(z[j]); j++){} |
| 1055 | 1055 | if( j>i ){ |
| 1056 | - printf("%*s", j-i, ""); | |
| 1056 | + fossil_print("%*s", j-i, ""); | |
| 1057 | 1057 | } |
| 1058 | 1058 | z += j; |
| 1059 | 1059 | } |
| 1060 | 1060 | break; |
| 1061 | 1061 | } |
| @@ -1074,17 +1074,17 @@ | ||
| 1074 | 1074 | int i; |
| 1075 | 1075 | |
| 1076 | 1076 | if( *pCount==0 ){ |
| 1077 | 1077 | for(i=0; i<nArg; i++){ |
| 1078 | 1078 | output_no_tabs_file(azName[i]); |
| 1079 | - printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); | |
| 1079 | + fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); | |
| 1080 | 1080 | } |
| 1081 | 1081 | } |
| 1082 | 1082 | ++*pCount; |
| 1083 | 1083 | for(i=0; i<nArg; i++){ |
| 1084 | 1084 | output_no_tabs_file(azArg[i]); |
| 1085 | - printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); | |
| 1085 | + fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); | |
| 1086 | 1086 | } |
| 1087 | 1087 | return 0; |
| 1088 | 1088 | } |
| 1089 | 1089 | |
| 1090 | 1090 | /* |
| 1091 | 1091 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -644,11 +644,11 @@ | |
| 644 | pState->nCol = 0; |
| 645 | pState->isMultirow = 0; |
| 646 | pState->iNewRow = -1; |
| 647 | pState->iBg = -1; |
| 648 | for(i=0; i<nArg; i++){ |
| 649 | if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ |
| 650 | pState->iBg = i; |
| 651 | continue; |
| 652 | } |
| 653 | if( g.okWrite && azName[i][0]=='#' ){ |
| 654 | pState->nCol++; |
| @@ -947,11 +947,11 @@ | |
| 947 | |
| 948 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 949 | style_submenu_element("Raw", "Raw", |
| 950 | "rptview?tablist=1&%h", PD("QUERY_STRING","")); |
| 951 | if( g.okAdmin |
| 952 | || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){ |
| 953 | style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); |
| 954 | } |
| 955 | if( g.okTktFmt ){ |
| 956 | style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn); |
| 957 | } |
| @@ -1000,19 +1000,19 @@ | |
| 1000 | */ |
| 1001 | void rpt_list_reports(void){ |
| 1002 | Stmt q; |
| 1003 | char const aRptOutFrmt[] = "%s\t%s\n"; |
| 1004 | |
| 1005 | printf("Available reports:\n"); |
| 1006 | printf(aRptOutFrmt,"report number","report title"); |
| 1007 | printf(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle); |
| 1008 | db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn"); |
| 1009 | while( db_step(&q)==SQLITE_ROW ){ |
| 1010 | const char *zRn = db_column_text(&q, 0); |
| 1011 | const char *zTitle = db_column_text(&q, 1); |
| 1012 | |
| 1013 | printf(aRptOutFrmt,zRn,zTitle); |
| 1014 | } |
| 1015 | db_finalize(&q); |
| 1016 | } |
| 1017 | |
| 1018 | /* |
| @@ -1037,25 +1037,25 @@ | |
| 1037 | case tktFossilize: |
| 1038 | { char *zFosZ; |
| 1039 | |
| 1040 | if( z && *z ){ |
| 1041 | zFosZ = fossilize(z,-1); |
| 1042 | printf("%s",zFosZ); |
| 1043 | free(zFosZ); |
| 1044 | } |
| 1045 | break; |
| 1046 | } |
| 1047 | default: |
| 1048 | while( z && z[0] ){ |
| 1049 | int i, j; |
| 1050 | for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){} |
| 1051 | if( i>0 ){ |
| 1052 | printf("%.*s", i, z); |
| 1053 | } |
| 1054 | for(j=i; fossil_isspace(z[j]); j++){} |
| 1055 | if( j>i ){ |
| 1056 | printf("%*s", j-i, ""); |
| 1057 | } |
| 1058 | z += j; |
| 1059 | } |
| 1060 | break; |
| 1061 | } |
| @@ -1074,17 +1074,17 @@ | |
| 1074 | int i; |
| 1075 | |
| 1076 | if( *pCount==0 ){ |
| 1077 | for(i=0; i<nArg; i++){ |
| 1078 | output_no_tabs_file(azName[i]); |
| 1079 | printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); |
| 1080 | } |
| 1081 | } |
| 1082 | ++*pCount; |
| 1083 | for(i=0; i<nArg; i++){ |
| 1084 | output_no_tabs_file(azArg[i]); |
| 1085 | printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); |
| 1086 | } |
| 1087 | return 0; |
| 1088 | } |
| 1089 | |
| 1090 | /* |
| 1091 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -644,11 +644,11 @@ | |
| 644 | pState->nCol = 0; |
| 645 | pState->isMultirow = 0; |
| 646 | pState->iNewRow = -1; |
| 647 | pState->iBg = -1; |
| 648 | for(i=0; i<nArg; i++){ |
| 649 | if( azName[i][0]=='b' && fossil_strcmp(azName[i],"bgcolor")==0 ){ |
| 650 | pState->iBg = i; |
| 651 | continue; |
| 652 | } |
| 653 | if( g.okWrite && azName[i][0]=='#' ){ |
| 654 | pState->nCol++; |
| @@ -947,11 +947,11 @@ | |
| 947 | |
| 948 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 949 | style_submenu_element("Raw", "Raw", |
| 950 | "rptview?tablist=1&%h", PD("QUERY_STRING","")); |
| 951 | if( g.okAdmin |
| 952 | || (g.okTktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ |
| 953 | style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); |
| 954 | } |
| 955 | if( g.okTktFmt ){ |
| 956 | style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn); |
| 957 | } |
| @@ -1000,19 +1000,19 @@ | |
| 1000 | */ |
| 1001 | void rpt_list_reports(void){ |
| 1002 | Stmt q; |
| 1003 | char const aRptOutFrmt[] = "%s\t%s\n"; |
| 1004 | |
| 1005 | fossil_print("Available reports:\n"); |
| 1006 | fossil_print(aRptOutFrmt,"report number","report title"); |
| 1007 | fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle); |
| 1008 | db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn"); |
| 1009 | while( db_step(&q)==SQLITE_ROW ){ |
| 1010 | const char *zRn = db_column_text(&q, 0); |
| 1011 | const char *zTitle = db_column_text(&q, 1); |
| 1012 | |
| 1013 | fossil_print(aRptOutFrmt,zRn,zTitle); |
| 1014 | } |
| 1015 | db_finalize(&q); |
| 1016 | } |
| 1017 | |
| 1018 | /* |
| @@ -1037,25 +1037,25 @@ | |
| 1037 | case tktFossilize: |
| 1038 | { char *zFosZ; |
| 1039 | |
| 1040 | if( z && *z ){ |
| 1041 | zFosZ = fossilize(z,-1); |
| 1042 | fossil_print("%s",zFosZ); |
| 1043 | free(zFosZ); |
| 1044 | } |
| 1045 | break; |
| 1046 | } |
| 1047 | default: |
| 1048 | while( z && z[0] ){ |
| 1049 | int i, j; |
| 1050 | for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){} |
| 1051 | if( i>0 ){ |
| 1052 | fossil_print("%.*s", i, z); |
| 1053 | } |
| 1054 | for(j=i; fossil_isspace(z[j]); j++){} |
| 1055 | if( j>i ){ |
| 1056 | fossil_print("%*s", j-i, ""); |
| 1057 | } |
| 1058 | z += j; |
| 1059 | } |
| 1060 | break; |
| 1061 | } |
| @@ -1074,17 +1074,17 @@ | |
| 1074 | int i; |
| 1075 | |
| 1076 | if( *pCount==0 ){ |
| 1077 | for(i=0; i<nArg; i++){ |
| 1078 | output_no_tabs_file(azName[i]); |
| 1079 | fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); |
| 1080 | } |
| 1081 | } |
| 1082 | ++*pCount; |
| 1083 | for(i=0; i<nArg; i++){ |
| 1084 | output_no_tabs_file(azArg[i]); |
| 1085 | fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); |
| 1086 | } |
| 1087 | return 0; |
| 1088 | } |
| 1089 | |
| 1090 | /* |
| 1091 |
+7
-7
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -436,38 +436,38 @@ | ||
| 436 | 436 | if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; |
| 437 | 437 | } |
| 438 | 438 | |
| 439 | 439 | /* figure out inherited permissions */ |
| 440 | 440 | memset(inherit, 0, sizeof(inherit)); |
| 441 | - if( strcmp(zLogin, "developer") ){ | |
| 441 | + if( fossil_strcmp(zLogin, "developer") ){ | |
| 442 | 442 | char *z1, *z2; |
| 443 | 443 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 444 | 444 | while( z1 && *z1 ){ |
| 445 | 445 | inherit[0x7f & *(z1++)] = |
| 446 | 446 | "<span class=\"ueditInheritDeveloper\">•</span>"; |
| 447 | 447 | } |
| 448 | 448 | free(z2); |
| 449 | 449 | } |
| 450 | - if( strcmp(zLogin, "reader") ){ | |
| 450 | + if( fossil_strcmp(zLogin, "reader") ){ | |
| 451 | 451 | char *z1, *z2; |
| 452 | 452 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 453 | 453 | while( z1 && *z1 ){ |
| 454 | 454 | inherit[0x7f & *(z1++)] = |
| 455 | 455 | "<span class=\"ueditInheritReader\">•</span>"; |
| 456 | 456 | } |
| 457 | 457 | free(z2); |
| 458 | 458 | } |
| 459 | - if( strcmp(zLogin, "anonymous") ){ | |
| 459 | + if( fossil_strcmp(zLogin, "anonymous") ){ | |
| 460 | 460 | char *z1, *z2; |
| 461 | 461 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 462 | 462 | while( z1 && *z1 ){ |
| 463 | 463 | inherit[0x7f & *(z1++)] = |
| 464 | 464 | "<span class=\"ueditInheritAnonymous\">•</span>"; |
| 465 | 465 | } |
| 466 | 466 | free(z2); |
| 467 | 467 | } |
| 468 | - if( strcmp(zLogin, "nobody") ){ | |
| 468 | + if( fossil_strcmp(zLogin, "nobody") ){ | |
| 469 | 469 | char *z1, *z2; |
| 470 | 470 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 471 | 471 | while( z1 && *z1 ){ |
| 472 | 472 | inherit[0x7f & *(z1++)] = |
| 473 | 473 | "<span class=\"ueditInheritNobody\">•</span>"; |
| @@ -741,11 +741,11 @@ | ||
| 741 | 741 | int iVal = db_get_boolean(zVar, dfltVal); |
| 742 | 742 | if( zQ==0 && P("submit") ){ |
| 743 | 743 | zQ = "off"; |
| 744 | 744 | } |
| 745 | 745 | if( zQ ){ |
| 746 | - int iQ = strcmp(zQ,"on")==0 || atoi(zQ); | |
| 746 | + int iQ = fossil_strcmp(zQ,"on")==0 || atoi(zQ); | |
| 747 | 747 | if( iQ!=iVal ){ |
| 748 | 748 | login_verify_csrf_secret(); |
| 749 | 749 | db_set(zVar, iQ ? "1" : "0", 0); |
| 750 | 750 | iVal = iQ; |
| 751 | 751 | } |
| @@ -768,11 +768,11 @@ | ||
| 768 | 768 | const char *zQParm, /* The query parameter */ |
| 769 | 769 | char *zDflt /* Default value if VAR table entry does not exist */ |
| 770 | 770 | ){ |
| 771 | 771 | const char *zVal = db_get(zVar, zDflt); |
| 772 | 772 | const char *zQ = P(zQParm); |
| 773 | - if( zQ && strcmp(zQ,zVal)!=0 ){ | |
| 773 | + if( zQ && fossil_strcmp(zQ,zVal)!=0 ){ | |
| 774 | 774 | login_verify_csrf_secret(); |
| 775 | 775 | db_set(zVar, zQ, 0); |
| 776 | 776 | zVal = zQ; |
| 777 | 777 | } |
| 778 | 778 | @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" /> |
| @@ -790,11 +790,11 @@ | ||
| 790 | 790 | const char *zQP, /* The query parameter */ |
| 791 | 791 | const char *zDflt /* Default value if VAR table entry does not exist */ |
| 792 | 792 | ){ |
| 793 | 793 | const char *z = db_get(zVar, (char*)zDflt); |
| 794 | 794 | const char *zQ = P(zQP); |
| 795 | - if( zQ && strcmp(zQ,z)!=0 ){ | |
| 795 | + if( zQ && fossil_strcmp(zQ,z)!=0 ){ | |
| 796 | 796 | login_verify_csrf_secret(); |
| 797 | 797 | db_set(zVar, zQ, 0); |
| 798 | 798 | z = zQ; |
| 799 | 799 | } |
| 800 | 800 | if( rows>0 && cols>0 ){ |
| 801 | 801 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -436,38 +436,38 @@ | |
| 436 | if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; |
| 437 | } |
| 438 | |
| 439 | /* figure out inherited permissions */ |
| 440 | memset(inherit, 0, sizeof(inherit)); |
| 441 | if( strcmp(zLogin, "developer") ){ |
| 442 | char *z1, *z2; |
| 443 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 444 | while( z1 && *z1 ){ |
| 445 | inherit[0x7f & *(z1++)] = |
| 446 | "<span class=\"ueditInheritDeveloper\">•</span>"; |
| 447 | } |
| 448 | free(z2); |
| 449 | } |
| 450 | if( strcmp(zLogin, "reader") ){ |
| 451 | char *z1, *z2; |
| 452 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 453 | while( z1 && *z1 ){ |
| 454 | inherit[0x7f & *(z1++)] = |
| 455 | "<span class=\"ueditInheritReader\">•</span>"; |
| 456 | } |
| 457 | free(z2); |
| 458 | } |
| 459 | if( strcmp(zLogin, "anonymous") ){ |
| 460 | char *z1, *z2; |
| 461 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 462 | while( z1 && *z1 ){ |
| 463 | inherit[0x7f & *(z1++)] = |
| 464 | "<span class=\"ueditInheritAnonymous\">•</span>"; |
| 465 | } |
| 466 | free(z2); |
| 467 | } |
| 468 | if( strcmp(zLogin, "nobody") ){ |
| 469 | char *z1, *z2; |
| 470 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 471 | while( z1 && *z1 ){ |
| 472 | inherit[0x7f & *(z1++)] = |
| 473 | "<span class=\"ueditInheritNobody\">•</span>"; |
| @@ -741,11 +741,11 @@ | |
| 741 | int iVal = db_get_boolean(zVar, dfltVal); |
| 742 | if( zQ==0 && P("submit") ){ |
| 743 | zQ = "off"; |
| 744 | } |
| 745 | if( zQ ){ |
| 746 | int iQ = strcmp(zQ,"on")==0 || atoi(zQ); |
| 747 | if( iQ!=iVal ){ |
| 748 | login_verify_csrf_secret(); |
| 749 | db_set(zVar, iQ ? "1" : "0", 0); |
| 750 | iVal = iQ; |
| 751 | } |
| @@ -768,11 +768,11 @@ | |
| 768 | const char *zQParm, /* The query parameter */ |
| 769 | char *zDflt /* Default value if VAR table entry does not exist */ |
| 770 | ){ |
| 771 | const char *zVal = db_get(zVar, zDflt); |
| 772 | const char *zQ = P(zQParm); |
| 773 | if( zQ && strcmp(zQ,zVal)!=0 ){ |
| 774 | login_verify_csrf_secret(); |
| 775 | db_set(zVar, zQ, 0); |
| 776 | zVal = zQ; |
| 777 | } |
| 778 | @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" /> |
| @@ -790,11 +790,11 @@ | |
| 790 | const char *zQP, /* The query parameter */ |
| 791 | const char *zDflt /* Default value if VAR table entry does not exist */ |
| 792 | ){ |
| 793 | const char *z = db_get(zVar, (char*)zDflt); |
| 794 | const char *zQ = P(zQP); |
| 795 | if( zQ && strcmp(zQ,z)!=0 ){ |
| 796 | login_verify_csrf_secret(); |
| 797 | db_set(zVar, zQ, 0); |
| 798 | z = zQ; |
| 799 | } |
| 800 | if( rows>0 && cols>0 ){ |
| 801 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -436,38 +436,38 @@ | |
| 436 | if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; |
| 437 | } |
| 438 | |
| 439 | /* figure out inherited permissions */ |
| 440 | memset(inherit, 0, sizeof(inherit)); |
| 441 | if( fossil_strcmp(zLogin, "developer") ){ |
| 442 | char *z1, *z2; |
| 443 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 444 | while( z1 && *z1 ){ |
| 445 | inherit[0x7f & *(z1++)] = |
| 446 | "<span class=\"ueditInheritDeveloper\">•</span>"; |
| 447 | } |
| 448 | free(z2); |
| 449 | } |
| 450 | if( fossil_strcmp(zLogin, "reader") ){ |
| 451 | char *z1, *z2; |
| 452 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 453 | while( z1 && *z1 ){ |
| 454 | inherit[0x7f & *(z1++)] = |
| 455 | "<span class=\"ueditInheritReader\">•</span>"; |
| 456 | } |
| 457 | free(z2); |
| 458 | } |
| 459 | if( fossil_strcmp(zLogin, "anonymous") ){ |
| 460 | char *z1, *z2; |
| 461 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 462 | while( z1 && *z1 ){ |
| 463 | inherit[0x7f & *(z1++)] = |
| 464 | "<span class=\"ueditInheritAnonymous\">•</span>"; |
| 465 | } |
| 466 | free(z2); |
| 467 | } |
| 468 | if( fossil_strcmp(zLogin, "nobody") ){ |
| 469 | char *z1, *z2; |
| 470 | z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 471 | while( z1 && *z1 ){ |
| 472 | inherit[0x7f & *(z1++)] = |
| 473 | "<span class=\"ueditInheritNobody\">•</span>"; |
| @@ -741,11 +741,11 @@ | |
| 741 | int iVal = db_get_boolean(zVar, dfltVal); |
| 742 | if( zQ==0 && P("submit") ){ |
| 743 | zQ = "off"; |
| 744 | } |
| 745 | if( zQ ){ |
| 746 | int iQ = fossil_strcmp(zQ,"on")==0 || atoi(zQ); |
| 747 | if( iQ!=iVal ){ |
| 748 | login_verify_csrf_secret(); |
| 749 | db_set(zVar, iQ ? "1" : "0", 0); |
| 750 | iVal = iQ; |
| 751 | } |
| @@ -768,11 +768,11 @@ | |
| 768 | const char *zQParm, /* The query parameter */ |
| 769 | char *zDflt /* Default value if VAR table entry does not exist */ |
| 770 | ){ |
| 771 | const char *zVal = db_get(zVar, zDflt); |
| 772 | const char *zQ = P(zQParm); |
| 773 | if( zQ && fossil_strcmp(zQ,zVal)!=0 ){ |
| 774 | login_verify_csrf_secret(); |
| 775 | db_set(zVar, zQ, 0); |
| 776 | zVal = zQ; |
| 777 | } |
| 778 | @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" /> |
| @@ -790,11 +790,11 @@ | |
| 790 | const char *zQP, /* The query parameter */ |
| 791 | const char *zDflt /* Default value if VAR table entry does not exist */ |
| 792 | ){ |
| 793 | const char *z = db_get(zVar, (char*)zDflt); |
| 794 | const char *zQ = P(zQP); |
| 795 | if( zQ && fossil_strcmp(zQ,z)!=0 ){ |
| 796 | login_verify_csrf_secret(); |
| 797 | db_set(zVar, zQ, 0); |
| 798 | z = zQ; |
| 799 | } |
| 800 | if( rows>0 && cols>0 ){ |
| 801 |
+2
-2
| --- src/sha1.c | ||
| +++ src/sha1.c | ||
| @@ -266,11 +266,11 @@ | ||
| 266 | 266 | FILE *in; |
| 267 | 267 | SHA1Context ctx; |
| 268 | 268 | unsigned char zResult[20]; |
| 269 | 269 | char zBuf[10240]; |
| 270 | 270 | |
| 271 | - in = fopen(zFilename,"rb"); | |
| 271 | + in = fossil_fopen(zFilename,"rb"); | |
| 272 | 272 | if( in==0 ){ |
| 273 | 273 | return 1; |
| 274 | 274 | } |
| 275 | 275 | SHA1Init(&ctx); |
| 276 | 276 | for(;;){ |
| @@ -430,9 +430,9 @@ | ||
| 430 | 430 | blob_read_from_channel(&in, stdin, -1); |
| 431 | 431 | sha1sum_blob(&in, &cksum); |
| 432 | 432 | }else{ |
| 433 | 433 | sha1sum_file(g.argv[i], &cksum); |
| 434 | 434 | } |
| 435 | - printf("%s %s\n", blob_str(&cksum), g.argv[i]); | |
| 435 | + fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); | |
| 436 | 436 | blob_reset(&cksum); |
| 437 | 437 | } |
| 438 | 438 | } |
| 439 | 439 |
| --- src/sha1.c | |
| +++ src/sha1.c | |
| @@ -266,11 +266,11 @@ | |
| 266 | FILE *in; |
| 267 | SHA1Context ctx; |
| 268 | unsigned char zResult[20]; |
| 269 | char zBuf[10240]; |
| 270 | |
| 271 | in = fopen(zFilename,"rb"); |
| 272 | if( in==0 ){ |
| 273 | return 1; |
| 274 | } |
| 275 | SHA1Init(&ctx); |
| 276 | for(;;){ |
| @@ -430,9 +430,9 @@ | |
| 430 | blob_read_from_channel(&in, stdin, -1); |
| 431 | sha1sum_blob(&in, &cksum); |
| 432 | }else{ |
| 433 | sha1sum_file(g.argv[i], &cksum); |
| 434 | } |
| 435 | printf("%s %s\n", blob_str(&cksum), g.argv[i]); |
| 436 | blob_reset(&cksum); |
| 437 | } |
| 438 | } |
| 439 |
| --- src/sha1.c | |
| +++ src/sha1.c | |
| @@ -266,11 +266,11 @@ | |
| 266 | FILE *in; |
| 267 | SHA1Context ctx; |
| 268 | unsigned char zResult[20]; |
| 269 | char zBuf[10240]; |
| 270 | |
| 271 | in = fossil_fopen(zFilename,"rb"); |
| 272 | if( in==0 ){ |
| 273 | return 1; |
| 274 | } |
| 275 | SHA1Init(&ctx); |
| 276 | for(;;){ |
| @@ -430,9 +430,9 @@ | |
| 430 | blob_read_from_channel(&in, stdin, -1); |
| 431 | sha1sum_blob(&in, &cksum); |
| 432 | }else{ |
| 433 | sha1sum_file(g.argv[i], &cksum); |
| 434 | } |
| 435 | fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); |
| 436 | blob_reset(&cksum); |
| 437 | } |
| 438 | } |
| 439 |
+19
-11
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -68,21 +68,21 @@ | ||
| 68 | 68 | * thus we always assume that we have a console. That can be |
| 69 | 69 | * overridden with the -batch command line option. |
| 70 | 70 | */ |
| 71 | 71 | #define isatty(x) 1 |
| 72 | 72 | #endif |
| 73 | + | |
| 74 | +/* True if the timer is enabled */ | |
| 75 | +static int enableTimer = 0; | |
| 73 | 76 | |
| 74 | 77 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) |
| 75 | 78 | #include <sys/time.h> |
| 76 | 79 | #include <sys/resource.h> |
| 77 | 80 | |
| 78 | 81 | /* Saved resource information for the beginning of an operation */ |
| 79 | 82 | static struct rusage sBegin; |
| 80 | 83 | |
| 81 | -/* True if the timer is enabled */ | |
| 82 | -static int enableTimer = 0; | |
| 83 | - | |
| 84 | 84 | /* |
| 85 | 85 | ** Begin timing an operation |
| 86 | 86 | */ |
| 87 | 87 | static void beginTimer(void){ |
| 88 | 88 | if( enableTimer ){ |
| @@ -122,13 +122,10 @@ | ||
| 122 | 122 | static FILETIME ftKernelBegin; |
| 123 | 123 | static FILETIME ftUserBegin; |
| 124 | 124 | typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); |
| 125 | 125 | static GETPROCTIMES getProcessTimesAddr = NULL; |
| 126 | 126 | |
| 127 | -/* True if the timer is enabled */ | |
| 128 | -static int enableTimer = 0; | |
| 129 | - | |
| 130 | 127 | /* |
| 131 | 128 | ** Check to see if we have timer support. Return 1 if necessary |
| 132 | 129 | ** support found (or found previously). |
| 133 | 130 | */ |
| 134 | 131 | static int hasTimer(void){ |
| @@ -2197,12 +2194,12 @@ | ||
| 2197 | 2194 | int i, n; |
| 2198 | 2195 | open_db(p); |
| 2199 | 2196 | |
| 2200 | 2197 | /* convert testctrl text option to value. allow any unique prefix |
| 2201 | 2198 | ** of the option name, or a numerical value. */ |
| 2202 | - n = strlen(azArg[1]); | |
| 2203 | - for(i=0; i<sizeof(aCtrl)/sizeof(aCtrl[0]); i++){ | |
| 2199 | + n = strlen30(azArg[1]); | |
| 2200 | + for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ | |
| 2204 | 2201 | if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ |
| 2205 | 2202 | if( testctrl<0 ){ |
| 2206 | 2203 | testctrl = aCtrl[i].ctrlCode; |
| 2207 | 2204 | }else{ |
| 2208 | 2205 | fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]); |
| @@ -2303,10 +2300,15 @@ | ||
| 2303 | 2300 | && nArg==2 |
| 2304 | 2301 | ){ |
| 2305 | 2302 | enableTimer = booleanValue(azArg[1]); |
| 2306 | 2303 | }else |
| 2307 | 2304 | |
| 2305 | + if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ | |
| 2306 | + printf("SQLite %s %s\n", | |
| 2307 | + sqlite3_libversion(), sqlite3_sourceid()); | |
| 2308 | + }else | |
| 2309 | + | |
| 2308 | 2310 | if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ |
| 2309 | 2311 | int j; |
| 2310 | 2312 | assert( nArg<=ArraySize(azArg) ); |
| 2311 | 2313 | for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ |
| 2312 | 2314 | p->colWidth[j-1] = atoi(azArg[j]); |
| @@ -2650,10 +2652,11 @@ | ||
| 2650 | 2652 | static void main_init(struct callback_data *data) { |
| 2651 | 2653 | memset(data, 0, sizeof(*data)); |
| 2652 | 2654 | data->mode = MODE_List; |
| 2653 | 2655 | memcpy(data->separator,"|", 2); |
| 2654 | 2656 | data->showHeader = 0; |
| 2657 | + sqlite3_config(SQLITE_CONFIG_URI, 1); | |
| 2655 | 2658 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 2656 | 2659 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |
| 2657 | 2660 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); |
| 2658 | 2661 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 2659 | 2662 | } |
| @@ -2664,10 +2667,15 @@ | ||
| 2664 | 2667 | const char *zInitFile = 0; |
| 2665 | 2668 | char *zFirstCmd = 0; |
| 2666 | 2669 | int i; |
| 2667 | 2670 | int rc = 0; |
| 2668 | 2671 | |
| 2672 | + if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ | |
| 2673 | + fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", | |
| 2674 | + sqlite3_sourceid(), SQLITE_SOURCE_ID); | |
| 2675 | + exit(1); | |
| 2676 | + } | |
| 2669 | 2677 | Argv0 = argv[0]; |
| 2670 | 2678 | main_init(&data); |
| 2671 | 2679 | stdin_is_interactive = isatty(0); |
| 2672 | 2680 | |
| 2673 | 2681 | /* Make sure we have a valid signal handler early, before anything |
| @@ -2837,11 +2845,11 @@ | ||
| 2837 | 2845 | }else if( strcmp(z,"-stats")==0 ){ |
| 2838 | 2846 | data.statsOn = 1; |
| 2839 | 2847 | }else if( strcmp(z,"-bail")==0 ){ |
| 2840 | 2848 | bail_on_error = 1; |
| 2841 | 2849 | }else if( strcmp(z,"-version")==0 ){ |
| 2842 | - printf("%s\n", sqlite3_libversion()); | |
| 2850 | + printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); | |
| 2843 | 2851 | return 0; |
| 2844 | 2852 | }else if( strcmp(z,"-interactive")==0 ){ |
| 2845 | 2853 | stdin_is_interactive = 1; |
| 2846 | 2854 | }else if( strcmp(z,"-batch")==0 ){ |
| 2847 | 2855 | stdin_is_interactive = 0; |
| @@ -2882,14 +2890,14 @@ | ||
| 2882 | 2890 | if( stdin_is_interactive ){ |
| 2883 | 2891 | char *zHome; |
| 2884 | 2892 | char *zHistory = 0; |
| 2885 | 2893 | int nHistory; |
| 2886 | 2894 | printf( |
| 2887 | - "SQLite version %s\n" | |
| 2895 | + "SQLite version %s %.19s\n" | |
| 2888 | 2896 | "Enter \".help\" for instructions\n" |
| 2889 | 2897 | "Enter SQL statements terminated with a \";\"\n", |
| 2890 | - sqlite3_libversion() | |
| 2898 | + sqlite3_libversion(), sqlite3_sourceid() | |
| 2891 | 2899 | ); |
| 2892 | 2900 | zHome = find_home_dir(); |
| 2893 | 2901 | if( zHome ){ |
| 2894 | 2902 | nHistory = strlen30(zHome) + 20; |
| 2895 | 2903 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 2896 | 2904 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -68,21 +68,21 @@ | |
| 68 | * thus we always assume that we have a console. That can be |
| 69 | * overridden with the -batch command line option. |
| 70 | */ |
| 71 | #define isatty(x) 1 |
| 72 | #endif |
| 73 | |
| 74 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) |
| 75 | #include <sys/time.h> |
| 76 | #include <sys/resource.h> |
| 77 | |
| 78 | /* Saved resource information for the beginning of an operation */ |
| 79 | static struct rusage sBegin; |
| 80 | |
| 81 | /* True if the timer is enabled */ |
| 82 | static int enableTimer = 0; |
| 83 | |
| 84 | /* |
| 85 | ** Begin timing an operation |
| 86 | */ |
| 87 | static void beginTimer(void){ |
| 88 | if( enableTimer ){ |
| @@ -122,13 +122,10 @@ | |
| 122 | static FILETIME ftKernelBegin; |
| 123 | static FILETIME ftUserBegin; |
| 124 | typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); |
| 125 | static GETPROCTIMES getProcessTimesAddr = NULL; |
| 126 | |
| 127 | /* True if the timer is enabled */ |
| 128 | static int enableTimer = 0; |
| 129 | |
| 130 | /* |
| 131 | ** Check to see if we have timer support. Return 1 if necessary |
| 132 | ** support found (or found previously). |
| 133 | */ |
| 134 | static int hasTimer(void){ |
| @@ -2197,12 +2194,12 @@ | |
| 2197 | int i, n; |
| 2198 | open_db(p); |
| 2199 | |
| 2200 | /* convert testctrl text option to value. allow any unique prefix |
| 2201 | ** of the option name, or a numerical value. */ |
| 2202 | n = strlen(azArg[1]); |
| 2203 | for(i=0; i<sizeof(aCtrl)/sizeof(aCtrl[0]); i++){ |
| 2204 | if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ |
| 2205 | if( testctrl<0 ){ |
| 2206 | testctrl = aCtrl[i].ctrlCode; |
| 2207 | }else{ |
| 2208 | fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]); |
| @@ -2303,10 +2300,15 @@ | |
| 2303 | && nArg==2 |
| 2304 | ){ |
| 2305 | enableTimer = booleanValue(azArg[1]); |
| 2306 | }else |
| 2307 | |
| 2308 | if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ |
| 2309 | int j; |
| 2310 | assert( nArg<=ArraySize(azArg) ); |
| 2311 | for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ |
| 2312 | p->colWidth[j-1] = atoi(azArg[j]); |
| @@ -2650,10 +2652,11 @@ | |
| 2650 | static void main_init(struct callback_data *data) { |
| 2651 | memset(data, 0, sizeof(*data)); |
| 2652 | data->mode = MODE_List; |
| 2653 | memcpy(data->separator,"|", 2); |
| 2654 | data->showHeader = 0; |
| 2655 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 2656 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |
| 2657 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); |
| 2658 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 2659 | } |
| @@ -2664,10 +2667,15 @@ | |
| 2664 | const char *zInitFile = 0; |
| 2665 | char *zFirstCmd = 0; |
| 2666 | int i; |
| 2667 | int rc = 0; |
| 2668 | |
| 2669 | Argv0 = argv[0]; |
| 2670 | main_init(&data); |
| 2671 | stdin_is_interactive = isatty(0); |
| 2672 | |
| 2673 | /* Make sure we have a valid signal handler early, before anything |
| @@ -2837,11 +2845,11 @@ | |
| 2837 | }else if( strcmp(z,"-stats")==0 ){ |
| 2838 | data.statsOn = 1; |
| 2839 | }else if( strcmp(z,"-bail")==0 ){ |
| 2840 | bail_on_error = 1; |
| 2841 | }else if( strcmp(z,"-version")==0 ){ |
| 2842 | printf("%s\n", sqlite3_libversion()); |
| 2843 | return 0; |
| 2844 | }else if( strcmp(z,"-interactive")==0 ){ |
| 2845 | stdin_is_interactive = 1; |
| 2846 | }else if( strcmp(z,"-batch")==0 ){ |
| 2847 | stdin_is_interactive = 0; |
| @@ -2882,14 +2890,14 @@ | |
| 2882 | if( stdin_is_interactive ){ |
| 2883 | char *zHome; |
| 2884 | char *zHistory = 0; |
| 2885 | int nHistory; |
| 2886 | printf( |
| 2887 | "SQLite version %s\n" |
| 2888 | "Enter \".help\" for instructions\n" |
| 2889 | "Enter SQL statements terminated with a \";\"\n", |
| 2890 | sqlite3_libversion() |
| 2891 | ); |
| 2892 | zHome = find_home_dir(); |
| 2893 | if( zHome ){ |
| 2894 | nHistory = strlen30(zHome) + 20; |
| 2895 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 2896 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -68,21 +68,21 @@ | |
| 68 | * thus we always assume that we have a console. That can be |
| 69 | * overridden with the -batch command line option. |
| 70 | */ |
| 71 | #define isatty(x) 1 |
| 72 | #endif |
| 73 | |
| 74 | /* True if the timer is enabled */ |
| 75 | static int enableTimer = 0; |
| 76 | |
| 77 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) |
| 78 | #include <sys/time.h> |
| 79 | #include <sys/resource.h> |
| 80 | |
| 81 | /* Saved resource information for the beginning of an operation */ |
| 82 | static struct rusage sBegin; |
| 83 | |
| 84 | /* |
| 85 | ** Begin timing an operation |
| 86 | */ |
| 87 | static void beginTimer(void){ |
| 88 | if( enableTimer ){ |
| @@ -122,13 +122,10 @@ | |
| 122 | static FILETIME ftKernelBegin; |
| 123 | static FILETIME ftUserBegin; |
| 124 | typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); |
| 125 | static GETPROCTIMES getProcessTimesAddr = NULL; |
| 126 | |
| 127 | /* |
| 128 | ** Check to see if we have timer support. Return 1 if necessary |
| 129 | ** support found (or found previously). |
| 130 | */ |
| 131 | static int hasTimer(void){ |
| @@ -2197,12 +2194,12 @@ | |
| 2194 | int i, n; |
| 2195 | open_db(p); |
| 2196 | |
| 2197 | /* convert testctrl text option to value. allow any unique prefix |
| 2198 | ** of the option name, or a numerical value. */ |
| 2199 | n = strlen30(azArg[1]); |
| 2200 | for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ |
| 2201 | if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ |
| 2202 | if( testctrl<0 ){ |
| 2203 | testctrl = aCtrl[i].ctrlCode; |
| 2204 | }else{ |
| 2205 | fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]); |
| @@ -2303,10 +2300,15 @@ | |
| 2300 | && nArg==2 |
| 2301 | ){ |
| 2302 | enableTimer = booleanValue(azArg[1]); |
| 2303 | }else |
| 2304 | |
| 2305 | if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ |
| 2306 | printf("SQLite %s %s\n", |
| 2307 | sqlite3_libversion(), sqlite3_sourceid()); |
| 2308 | }else |
| 2309 | |
| 2310 | if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ |
| 2311 | int j; |
| 2312 | assert( nArg<=ArraySize(azArg) ); |
| 2313 | for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ |
| 2314 | p->colWidth[j-1] = atoi(azArg[j]); |
| @@ -2650,10 +2652,11 @@ | |
| 2652 | static void main_init(struct callback_data *data) { |
| 2653 | memset(data, 0, sizeof(*data)); |
| 2654 | data->mode = MODE_List; |
| 2655 | memcpy(data->separator,"|", 2); |
| 2656 | data->showHeader = 0; |
| 2657 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 2658 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 2659 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |
| 2660 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); |
| 2661 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 2662 | } |
| @@ -2664,10 +2667,15 @@ | |
| 2667 | const char *zInitFile = 0; |
| 2668 | char *zFirstCmd = 0; |
| 2669 | int i; |
| 2670 | int rc = 0; |
| 2671 | |
| 2672 | if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ |
| 2673 | fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", |
| 2674 | sqlite3_sourceid(), SQLITE_SOURCE_ID); |
| 2675 | exit(1); |
| 2676 | } |
| 2677 | Argv0 = argv[0]; |
| 2678 | main_init(&data); |
| 2679 | stdin_is_interactive = isatty(0); |
| 2680 | |
| 2681 | /* Make sure we have a valid signal handler early, before anything |
| @@ -2837,11 +2845,11 @@ | |
| 2845 | }else if( strcmp(z,"-stats")==0 ){ |
| 2846 | data.statsOn = 1; |
| 2847 | }else if( strcmp(z,"-bail")==0 ){ |
| 2848 | bail_on_error = 1; |
| 2849 | }else if( strcmp(z,"-version")==0 ){ |
| 2850 | printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); |
| 2851 | return 0; |
| 2852 | }else if( strcmp(z,"-interactive")==0 ){ |
| 2853 | stdin_is_interactive = 1; |
| 2854 | }else if( strcmp(z,"-batch")==0 ){ |
| 2855 | stdin_is_interactive = 0; |
| @@ -2882,14 +2890,14 @@ | |
| 2890 | if( stdin_is_interactive ){ |
| 2891 | char *zHome; |
| 2892 | char *zHistory = 0; |
| 2893 | int nHistory; |
| 2894 | printf( |
| 2895 | "SQLite version %s %.19s\n" |
| 2896 | "Enter \".help\" for instructions\n" |
| 2897 | "Enter SQL statements terminated with a \";\"\n", |
| 2898 | sqlite3_libversion(), sqlite3_sourceid() |
| 2899 | ); |
| 2900 | zHome = find_home_dir(); |
| 2901 | if( zHome ){ |
| 2902 | nHistory = strlen30(zHome) + 20; |
| 2903 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 2904 |
+5
-5
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -1053,11 +1053,11 @@ | ||
| 1053 | 1053 | setDefaultSkin(); |
| 1054 | 1054 | zCurrent = getSkin(0); |
| 1055 | 1055 | |
| 1056 | 1056 | if( P("save")!=0 && (zName = skinVarName(P("save"),0))!=0 ){ |
| 1057 | 1057 | if( db_exists("SELECT 1 FROM config WHERE name=%Q", zName) |
| 1058 | - || strcmp(zName, "Default")==0 ){ | |
| 1058 | + || fossil_strcmp(zName, "Default")==0 ){ | |
| 1059 | 1059 | zErr = mprintf("Skin name \"%h\" already exists. " |
| 1060 | 1060 | "Choose a different name.", P("sn")); |
| 1061 | 1061 | }else{ |
| 1062 | 1062 | db_multi_exec("INSERT INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 1063 | 1063 | zName, zCurrent |
| @@ -1067,11 +1067,11 @@ | ||
| 1067 | 1067 | |
| 1068 | 1068 | /* The user pressed the "Use This Skin" button. */ |
| 1069 | 1069 | if( P("load") && (z = P("sn"))!=0 && z[0] ){ |
| 1070 | 1070 | int seen = 0; |
| 1071 | 1071 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1072 | - if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ | |
| 1072 | + if( fossil_strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ | |
| 1073 | 1073 | seen = 1; |
| 1074 | 1074 | break; |
| 1075 | 1075 | } |
| 1076 | 1076 | } |
| 1077 | 1077 | if( !seen ){ |
| @@ -1085,11 +1085,11 @@ | ||
| 1085 | 1085 | " %Q,now())", zCurrent |
| 1086 | 1086 | ); |
| 1087 | 1087 | } |
| 1088 | 1088 | seen = 0; |
| 1089 | 1089 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1090 | - if( strcmp(aBuiltinSkin[i].zName, z)==0 ){ | |
| 1090 | + if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){ | |
| 1091 | 1091 | seen = 1; |
| 1092 | 1092 | zCurrent = aBuiltinSkin[i].zValue; |
| 1093 | 1093 | db_multi_exec("%s", zCurrent); |
| 1094 | 1094 | break; |
| 1095 | 1095 | } |
| @@ -1111,11 +1111,11 @@ | ||
| 1111 | 1111 | @ |
| 1112 | 1112 | @ <h2>Available Skins:</h2> |
| 1113 | 1113 | @ <ol> |
| 1114 | 1114 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1115 | 1115 | z = aBuiltinSkin[i].zName; |
| 1116 | - if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ | |
| 1116 | + if( fossil_strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ | |
| 1117 | 1117 | @ <li><p>%h(z). <b>Currently In Use</b></p> |
| 1118 | 1118 | }else{ |
| 1119 | 1119 | @ <li><form action="%s(g.zTop)/setup_skin" method="post"><div> |
| 1120 | 1120 | @ %h(z). |
| 1121 | 1121 | @ <input type="hidden" name="sn" value="%h(z)" /> |
| @@ -1129,11 +1129,11 @@ | ||
| 1129 | 1129 | " ORDER BY name" |
| 1130 | 1130 | ); |
| 1131 | 1131 | while( db_step(&q)==SQLITE_ROW ){ |
| 1132 | 1132 | const char *zN = db_column_text(&q, 0); |
| 1133 | 1133 | const char *zV = db_column_text(&q, 1); |
| 1134 | - if( strcmp(zV, zCurrent)==0 ){ | |
| 1134 | + if( fossil_strcmp(zV, zCurrent)==0 ){ | |
| 1135 | 1135 | @ <li><p>%h(zN). <b>Currently In Use</b></p> |
| 1136 | 1136 | }else{ |
| 1137 | 1137 | @ <li><form action="%s(g.zTop)/setup_skin" method="post"> |
| 1138 | 1138 | @ %h(zN). |
| 1139 | 1139 | @ <input type="hidden" name="sn" value="%h(zN)"> |
| 1140 | 1140 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -1053,11 +1053,11 @@ | |
| 1053 | setDefaultSkin(); |
| 1054 | zCurrent = getSkin(0); |
| 1055 | |
| 1056 | if( P("save")!=0 && (zName = skinVarName(P("save"),0))!=0 ){ |
| 1057 | if( db_exists("SELECT 1 FROM config WHERE name=%Q", zName) |
| 1058 | || strcmp(zName, "Default")==0 ){ |
| 1059 | zErr = mprintf("Skin name \"%h\" already exists. " |
| 1060 | "Choose a different name.", P("sn")); |
| 1061 | }else{ |
| 1062 | db_multi_exec("INSERT INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 1063 | zName, zCurrent |
| @@ -1067,11 +1067,11 @@ | |
| 1067 | |
| 1068 | /* The user pressed the "Use This Skin" button. */ |
| 1069 | if( P("load") && (z = P("sn"))!=0 && z[0] ){ |
| 1070 | int seen = 0; |
| 1071 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1072 | if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 1073 | seen = 1; |
| 1074 | break; |
| 1075 | } |
| 1076 | } |
| 1077 | if( !seen ){ |
| @@ -1085,11 +1085,11 @@ | |
| 1085 | " %Q,now())", zCurrent |
| 1086 | ); |
| 1087 | } |
| 1088 | seen = 0; |
| 1089 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1090 | if( strcmp(aBuiltinSkin[i].zName, z)==0 ){ |
| 1091 | seen = 1; |
| 1092 | zCurrent = aBuiltinSkin[i].zValue; |
| 1093 | db_multi_exec("%s", zCurrent); |
| 1094 | break; |
| 1095 | } |
| @@ -1111,11 +1111,11 @@ | |
| 1111 | @ |
| 1112 | @ <h2>Available Skins:</h2> |
| 1113 | @ <ol> |
| 1114 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1115 | z = aBuiltinSkin[i].zName; |
| 1116 | if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 1117 | @ <li><p>%h(z). <b>Currently In Use</b></p> |
| 1118 | }else{ |
| 1119 | @ <li><form action="%s(g.zTop)/setup_skin" method="post"><div> |
| 1120 | @ %h(z). |
| 1121 | @ <input type="hidden" name="sn" value="%h(z)" /> |
| @@ -1129,11 +1129,11 @@ | |
| 1129 | " ORDER BY name" |
| 1130 | ); |
| 1131 | while( db_step(&q)==SQLITE_ROW ){ |
| 1132 | const char *zN = db_column_text(&q, 0); |
| 1133 | const char *zV = db_column_text(&q, 1); |
| 1134 | if( strcmp(zV, zCurrent)==0 ){ |
| 1135 | @ <li><p>%h(zN). <b>Currently In Use</b></p> |
| 1136 | }else{ |
| 1137 | @ <li><form action="%s(g.zTop)/setup_skin" method="post"> |
| 1138 | @ %h(zN). |
| 1139 | @ <input type="hidden" name="sn" value="%h(zN)"> |
| 1140 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -1053,11 +1053,11 @@ | |
| 1053 | setDefaultSkin(); |
| 1054 | zCurrent = getSkin(0); |
| 1055 | |
| 1056 | if( P("save")!=0 && (zName = skinVarName(P("save"),0))!=0 ){ |
| 1057 | if( db_exists("SELECT 1 FROM config WHERE name=%Q", zName) |
| 1058 | || fossil_strcmp(zName, "Default")==0 ){ |
| 1059 | zErr = mprintf("Skin name \"%h\" already exists. " |
| 1060 | "Choose a different name.", P("sn")); |
| 1061 | }else{ |
| 1062 | db_multi_exec("INSERT INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 1063 | zName, zCurrent |
| @@ -1067,11 +1067,11 @@ | |
| 1067 | |
| 1068 | /* The user pressed the "Use This Skin" button. */ |
| 1069 | if( P("load") && (z = P("sn"))!=0 && z[0] ){ |
| 1070 | int seen = 0; |
| 1071 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1072 | if( fossil_strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 1073 | seen = 1; |
| 1074 | break; |
| 1075 | } |
| 1076 | } |
| 1077 | if( !seen ){ |
| @@ -1085,11 +1085,11 @@ | |
| 1085 | " %Q,now())", zCurrent |
| 1086 | ); |
| 1087 | } |
| 1088 | seen = 0; |
| 1089 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1090 | if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){ |
| 1091 | seen = 1; |
| 1092 | zCurrent = aBuiltinSkin[i].zValue; |
| 1093 | db_multi_exec("%s", zCurrent); |
| 1094 | break; |
| 1095 | } |
| @@ -1111,11 +1111,11 @@ | |
| 1111 | @ |
| 1112 | @ <h2>Available Skins:</h2> |
| 1113 | @ <ol> |
| 1114 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 1115 | z = aBuiltinSkin[i].zName; |
| 1116 | if( fossil_strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ |
| 1117 | @ <li><p>%h(z). <b>Currently In Use</b></p> |
| 1118 | }else{ |
| 1119 | @ <li><form action="%s(g.zTop)/setup_skin" method="post"><div> |
| 1120 | @ %h(z). |
| 1121 | @ <input type="hidden" name="sn" value="%h(z)" /> |
| @@ -1129,11 +1129,11 @@ | |
| 1129 | " ORDER BY name" |
| 1130 | ); |
| 1131 | while( db_step(&q)==SQLITE_ROW ){ |
| 1132 | const char *zN = db_column_text(&q, 0); |
| 1133 | const char *zV = db_column_text(&q, 1); |
| 1134 | if( fossil_strcmp(zV, zCurrent)==0 ){ |
| 1135 | @ <li><p>%h(zN). <b>Currently In Use</b></p> |
| 1136 | }else{ |
| 1137 | @ <li><form action="%s(g.zTop)/setup_skin" method="post"> |
| 1138 | @ %h(zN). |
| 1139 | @ <input type="hidden" name="sn" value="%h(zN)"> |
| 1140 |
+428
-282
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -650,11 +650,11 @@ | ||
| 650 | 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | 652 | */ |
| 653 | 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | -#define SQLITE_SOURCE_ID "2011-05-18 03:02:10 186d7ff1d9804d508e472e4939608bf2be67bdc2" | |
| 655 | +#define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" | |
| 656 | 656 | |
| 657 | 657 | /* |
| 658 | 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | 660 | ** |
| @@ -1000,10 +1000,12 @@ | ||
| 1000 | 1000 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1001 | 1001 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1002 | 1002 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1003 | 1003 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1004 | 1004 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1005 | +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) | |
| 1006 | +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) | |
| 1005 | 1007 | |
| 1006 | 1008 | /* |
| 1007 | 1009 | ** CAPI3REF: Flags For File Open Operations |
| 1008 | 1010 | ** |
| 1009 | 1011 | ** These bit values are intended for use in the |
| @@ -1305,15 +1307,15 @@ | ||
| 1305 | 1307 | */ |
| 1306 | 1308 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 1307 | 1309 | |
| 1308 | 1310 | /* |
| 1309 | 1311 | ** CAPI3REF: OS Interface Object |
| 1310 | -** KEYWORDS: VFS VFSes | |
| 1311 | 1312 | ** |
| 1312 | 1313 | ** An instance of the sqlite3_vfs object defines the interface between |
| 1313 | 1314 | ** the SQLite core and the underlying operating system. The "vfs" |
| 1314 | -** in the name of the object stands for "virtual file system". | |
| 1315 | +** in the name of the object stands for "virtual file system". See | |
| 1316 | +** the [VFS | VFS documentation] for further information. | |
| 1315 | 1317 | ** |
| 1316 | 1318 | ** The value of the iVersion field is initially 1 but may be larger in |
| 1317 | 1319 | ** future versions of SQLite. Additional fields may be appended to this |
| 1318 | 1320 | ** object when the iVersion value is increased. Note that the structure |
| 1319 | 1321 | ** of the sqlite3_vfs object changes in the transaction between |
| @@ -8494,19 +8496,20 @@ | ||
| 8494 | 8496 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 8495 | 8497 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); |
| 8496 | 8498 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| 8497 | 8499 | SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); |
| 8498 | 8500 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); |
| 8499 | -SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); | |
| 8501 | +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); | |
| 8500 | 8502 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 8501 | 8503 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 8502 | 8504 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 8503 | 8505 | #ifdef SQLITE_DEBUG |
| 8504 | 8506 | SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); |
| 8505 | 8507 | SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); |
| 8506 | 8508 | #endif |
| 8507 | 8509 | SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); |
| 8510 | +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); | |
| 8508 | 8511 | SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); |
| 8509 | 8512 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); |
| 8510 | 8513 | SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); |
| 8511 | 8514 | SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); |
| 8512 | 8515 | SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); |
| @@ -9832,10 +9835,11 @@ | ||
| 9832 | 9835 | sqlite3 *db; /* Database connection associated with this table */ |
| 9833 | 9836 | Module *pMod; /* Pointer to module implementation */ |
| 9834 | 9837 | sqlite3_vtab *pVtab; /* Pointer to vtab instance */ |
| 9835 | 9838 | int nRef; /* Number of pointers to this structure */ |
| 9836 | 9839 | u8 bConstraint; /* True if constraints are supported */ |
| 9840 | + int iSavepoint; /* Depth of the SAVEPOINT stack */ | |
| 9837 | 9841 | VTable *pNext; /* Next in linked list (see above) */ |
| 9838 | 9842 | }; |
| 9839 | 9843 | |
| 9840 | 9844 | /* |
| 9841 | 9845 | ** Each SQL table is represented in memory by an instance of the |
| @@ -10826,13 +10830,12 @@ | ||
| 10826 | 10830 | |
| 10827 | 10831 | /* Above is constant between recursions. Below is reset before and after |
| 10828 | 10832 | ** each recursion */ |
| 10829 | 10833 | |
| 10830 | 10834 | int nVar; /* Number of '?' variables seen in the SQL so far */ |
| 10831 | - int nVarExpr; /* Number of used slots in apVarExpr[] */ | |
| 10832 | - int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */ | |
| 10833 | - Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */ | |
| 10835 | + int nzVar; /* Number of available slots in azVar[] */ | |
| 10836 | + char **azVar; /* Pointers to names of parameters */ | |
| 10834 | 10837 | Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ |
| 10835 | 10838 | int nAlias; /* Number of aliased result set columns */ |
| 10836 | 10839 | int nAliasAlloc; /* Number of allocated slots for aAlias[] */ |
| 10837 | 10840 | int *aAlias; /* Register used to hold aliased result */ |
| 10838 | 10841 | u8 explain; /* True if the EXPLAIN flag is found on the query */ |
| @@ -12761,15 +12764,15 @@ | ||
| 12761 | 12764 | Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ |
| 12762 | 12765 | VdbeCursor **apCsr; /* One element of this array for each open cursor */ |
| 12763 | 12766 | Mem *aVar; /* Values for the OP_Variable opcode. */ |
| 12764 | 12767 | char **azVar; /* Name of variables */ |
| 12765 | 12768 | ynVar nVar; /* Number of entries in aVar[] */ |
| 12769 | + ynVar nzVar; /* Number of entries in azVar[] */ | |
| 12766 | 12770 | u32 cacheCtr; /* VdbeCursor row cache generation counter */ |
| 12767 | 12771 | int pc; /* The program counter */ |
| 12768 | 12772 | int rc; /* Value to return */ |
| 12769 | 12773 | u8 errorAction; /* Recovery action to do in case of an error */ |
| 12770 | - u8 okVar; /* True if azVar[] has been initialized */ | |
| 12771 | 12774 | u8 explain; /* True if EXPLAIN present on SQL command */ |
| 12772 | 12775 | u8 changeCntOn; /* True to update the change-counter */ |
| 12773 | 12776 | u8 expired; /* True if the VM needs to be recompiled */ |
| 12774 | 12777 | u8 runOnlyOnce; /* Automatically expire on reset */ |
| 12775 | 12778 | u8 minWriteFileFormat; /* Minimum file format for writable database files */ |
| @@ -27963,11 +27966,12 @@ | ||
| 27963 | 27966 | unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ |
| 27964 | 27967 | sqlite3_mutex *mutex; /* Mutex to access this object */ |
| 27965 | 27968 | char *zFilename; /* Name of the mmapped file */ |
| 27966 | 27969 | int h; /* Open file descriptor */ |
| 27967 | 27970 | int szRegion; /* Size of shared-memory regions */ |
| 27968 | - int nRegion; /* Size of array apRegion */ | |
| 27971 | + u16 nRegion; /* Size of array apRegion */ | |
| 27972 | + u8 isReadonly; /* True if read-only */ | |
| 27969 | 27973 | char **apRegion; /* Array of mapped shared-memory regions */ |
| 27970 | 27974 | int nRef; /* Number of unixShm objects pointing to this */ |
| 27971 | 27975 | unixShm *pFirst; /* All unixShm objects pointing to this */ |
| 27972 | 27976 | #ifdef SQLITE_DEBUG |
| 27973 | 27977 | u8 exclMask; /* Mask of exclusive locks held */ |
| @@ -28210,12 +28214,21 @@ | ||
| 28210 | 28214 | |
| 28211 | 28215 | if( pInode->bProcessLock==0 ){ |
| 28212 | 28216 | pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, |
| 28213 | 28217 | (sStat.st_mode & 0777)); |
| 28214 | 28218 | if( pShmNode->h<0 ){ |
| 28215 | - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); | |
| 28216 | - goto shm_open_err; | |
| 28219 | + const char *zRO; | |
| 28220 | + zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); | |
| 28221 | + if( zRO && sqlite3GetBoolean(zRO) ){ | |
| 28222 | + pShmNode->h = robust_open(zShmFilename, O_RDONLY, | |
| 28223 | + (sStat.st_mode & 0777)); | |
| 28224 | + pShmNode->isReadonly = 1; | |
| 28225 | + } | |
| 28226 | + if( pShmNode->h<0 ){ | |
| 28227 | + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); | |
| 28228 | + goto shm_open_err; | |
| 28229 | + } | |
| 28217 | 28230 | } |
| 28218 | 28231 | |
| 28219 | 28232 | /* Check to see if another process is holding the dead-man switch. |
| 28220 | 28233 | ** If not, truncate the file to zero length. |
| 28221 | 28234 | */ |
| @@ -28350,11 +28363,12 @@ | ||
| 28350 | 28363 | } |
| 28351 | 28364 | pShmNode->apRegion = apNew; |
| 28352 | 28365 | while(pShmNode->nRegion<=iRegion){ |
| 28353 | 28366 | void *pMem; |
| 28354 | 28367 | if( pShmNode->h>=0 ){ |
| 28355 | - pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, | |
| 28368 | + pMem = mmap(0, szRegion, | |
| 28369 | + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, | |
| 28356 | 28370 | MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 28357 | 28371 | ); |
| 28358 | 28372 | if( pMem==MAP_FAILED ){ |
| 28359 | 28373 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| 28360 | 28374 | goto shmpage_out; |
| @@ -28376,10 +28390,11 @@ | ||
| 28376 | 28390 | if( pShmNode->nRegion>iRegion ){ |
| 28377 | 28391 | *pp = pShmNode->apRegion[iRegion]; |
| 28378 | 28392 | }else{ |
| 28379 | 28393 | *pp = 0; |
| 28380 | 28394 | } |
| 28395 | + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; | |
| 28381 | 28396 | sqlite3_mutex_leave(pShmNode->mutex); |
| 28382 | 28397 | return rc; |
| 28383 | 28398 | } |
| 28384 | 28399 | |
| 28385 | 28400 | /* |
| @@ -34873,10 +34888,17 @@ | ||
| 34873 | 34888 | if( !pPg ){ |
| 34874 | 34889 | for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
| 34875 | 34890 | } |
| 34876 | 34891 | if( pPg ){ |
| 34877 | 34892 | int rc; |
| 34893 | +#ifdef SQLITE_LOG_CACHE_SPILL | |
| 34894 | + sqlite3_log(SQLITE_FULL, | |
| 34895 | + "spill page %d making room for %d - cache used: %d/%d", | |
| 34896 | + pPg->pgno, pgno, | |
| 34897 | + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), | |
| 34898 | + pCache->nMax); | |
| 34899 | +#endif | |
| 34878 | 34900 | rc = pCache->xStress(pCache->pStress, pPg); |
| 34879 | 34901 | if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
| 34880 | 34902 | return rc; |
| 34881 | 34903 | } |
| 34882 | 34904 | } |
| @@ -42472,15 +42494,25 @@ | ||
| 42472 | 42494 | */ |
| 42473 | 42495 | sqlite3BackupRestart(pPager->pBackup); |
| 42474 | 42496 | }else{ |
| 42475 | 42497 | if( pagerUseWal(pPager) ){ |
| 42476 | 42498 | PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); |
| 42477 | - if( pList ){ | |
| 42499 | + PgHdr *pPageOne = 0; | |
| 42500 | + if( pList==0 ){ | |
| 42501 | + /* Must have at least one page for the WAL commit flag. | |
| 42502 | + ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ | |
| 42503 | + rc = sqlite3PagerGet(pPager, 1, &pPageOne); | |
| 42504 | + pList = pPageOne; | |
| 42505 | + pList->pDirty = 0; | |
| 42506 | + } | |
| 42507 | + assert( rc==SQLITE_OK ); | |
| 42508 | + if( ALWAYS(pList) ){ | |
| 42478 | 42509 | rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, |
| 42479 | 42510 | (pPager->fullSync ? pPager->syncFlags : 0) |
| 42480 | 42511 | ); |
| 42481 | 42512 | } |
| 42513 | + sqlite3PagerUnref(pPageOne); | |
| 42482 | 42514 | if( rc==SQLITE_OK ){ |
| 42483 | 42515 | sqlite3PcacheCleanAll(pPager->pPCache); |
| 42484 | 42516 | } |
| 42485 | 42517 | }else{ |
| 42486 | 42518 | /* The following block updates the change-counter. Exactly how it |
| @@ -43967,11 +43999,11 @@ | ||
| 43967 | 43999 | u32 szPage; /* Database page size */ |
| 43968 | 44000 | i16 readLock; /* Which read lock is being held. -1 for none */ |
| 43969 | 44001 | u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ |
| 43970 | 44002 | u8 writeLock; /* True if in a write transaction */ |
| 43971 | 44003 | u8 ckptLock; /* True if holding a checkpoint lock */ |
| 43972 | - u8 readOnly; /* True if the WAL file is open read-only */ | |
| 44004 | + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ | |
| 43973 | 44005 | WalIndexHdr hdr; /* Wal-index header for current transaction */ |
| 43974 | 44006 | const char *zWalName; /* Name of WAL file */ |
| 43975 | 44007 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 43976 | 44008 | #ifdef SQLITE_DEBUG |
| 43977 | 44009 | u8 lockError; /* True if a locking error has occurred */ |
| @@ -43983,10 +44015,17 @@ | ||
| 43983 | 44015 | */ |
| 43984 | 44016 | #define WAL_NORMAL_MODE 0 |
| 43985 | 44017 | #define WAL_EXCLUSIVE_MODE 1 |
| 43986 | 44018 | #define WAL_HEAPMEMORY_MODE 2 |
| 43987 | 44019 | |
| 44020 | +/* | |
| 44021 | +** Possible values for WAL.readOnly | |
| 44022 | +*/ | |
| 44023 | +#define WAL_RDWR 0 /* Normal read/write connection */ | |
| 44024 | +#define WAL_RDONLY 1 /* The WAL file is readonly */ | |
| 44025 | +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ | |
| 44026 | + | |
| 43988 | 44027 | /* |
| 43989 | 44028 | ** Each page of the wal-index mapping contains a hash-table made up of |
| 43990 | 44029 | ** an array of HASHTABLE_NSLOT elements of the following type. |
| 43991 | 44030 | */ |
| 43992 | 44031 | typedef u16 ht_slot; |
| @@ -44076,10 +44115,14 @@ | ||
| 44076 | 44115 | if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; |
| 44077 | 44116 | }else{ |
| 44078 | 44117 | rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, |
| 44079 | 44118 | pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] |
| 44080 | 44119 | ); |
| 44120 | + if( rc==SQLITE_READONLY ){ | |
| 44121 | + pWal->readOnly |= WAL_SHM_RDONLY; | |
| 44122 | + rc = SQLITE_OK; | |
| 44123 | + } | |
| 44081 | 44124 | } |
| 44082 | 44125 | } |
| 44083 | 44126 | |
| 44084 | 44127 | *ppPage = pWal->apWiData[iPage]; |
| 44085 | 44128 | assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); |
| @@ -44823,11 +44866,11 @@ | ||
| 44823 | 44866 | |
| 44824 | 44867 | /* Open file handle on the write-ahead log file. */ |
| 44825 | 44868 | flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); |
| 44826 | 44869 | rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); |
| 44827 | 44870 | if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ |
| 44828 | - pRet->readOnly = 1; | |
| 44871 | + pRet->readOnly = WAL_RDONLY; | |
| 44829 | 44872 | } |
| 44830 | 44873 | |
| 44831 | 44874 | if( rc!=SQLITE_OK ){ |
| 44832 | 44875 | walIndexClose(pRet, 0); |
| 44833 | 44876 | sqlite3OsClose(pRet->pWalFd); |
| @@ -45464,25 +45507,32 @@ | ||
| 45464 | 45507 | |
| 45465 | 45508 | /* If the first attempt failed, it might have been due to a race |
| 45466 | 45509 | ** with a writer. So get a WRITE lock and try again. |
| 45467 | 45510 | */ |
| 45468 | 45511 | assert( badHdr==0 || pWal->writeLock==0 ); |
| 45469 | - if( badHdr && SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ | |
| 45470 | - pWal->writeLock = 1; | |
| 45471 | - if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ | |
| 45472 | - badHdr = walIndexTryHdr(pWal, pChanged); | |
| 45473 | - if( badHdr ){ | |
| 45474 | - /* If the wal-index header is still malformed even while holding | |
| 45475 | - ** a WRITE lock, it can only mean that the header is corrupted and | |
| 45476 | - ** needs to be reconstructed. So run recovery to do exactly that. | |
| 45477 | - */ | |
| 45478 | - rc = walIndexRecover(pWal); | |
| 45479 | - *pChanged = 1; | |
| 45480 | - } | |
| 45481 | - } | |
| 45482 | - pWal->writeLock = 0; | |
| 45483 | - walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); | |
| 45512 | + if( badHdr ){ | |
| 45513 | + if( pWal->readOnly & WAL_SHM_RDONLY ){ | |
| 45514 | + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ | |
| 45515 | + walUnlockShared(pWal, WAL_WRITE_LOCK); | |
| 45516 | + rc = SQLITE_READONLY_RECOVERY; | |
| 45517 | + } | |
| 45518 | + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ | |
| 45519 | + pWal->writeLock = 1; | |
| 45520 | + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ | |
| 45521 | + badHdr = walIndexTryHdr(pWal, pChanged); | |
| 45522 | + if( badHdr ){ | |
| 45523 | + /* If the wal-index header is still malformed even while holding | |
| 45524 | + ** a WRITE lock, it can only mean that the header is corrupted and | |
| 45525 | + ** needs to be reconstructed. So run recovery to do exactly that. | |
| 45526 | + */ | |
| 45527 | + rc = walIndexRecover(pWal); | |
| 45528 | + *pChanged = 1; | |
| 45529 | + } | |
| 45530 | + } | |
| 45531 | + pWal->writeLock = 0; | |
| 45532 | + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); | |
| 45533 | + } | |
| 45484 | 45534 | } |
| 45485 | 45535 | |
| 45486 | 45536 | /* If the header is read successfully, check the version number to make |
| 45487 | 45537 | ** sure the wal-index was not constructed with some future format that |
| 45488 | 45538 | ** this version of SQLite cannot understand. |
| @@ -45665,11 +45715,13 @@ | ||
| 45665 | 45715 | mxI = i; |
| 45666 | 45716 | } |
| 45667 | 45717 | } |
| 45668 | 45718 | /* There was once an "if" here. The extra "{" is to preserve indentation. */ |
| 45669 | 45719 | { |
| 45670 | - if( mxReadMark < pWal->hdr.mxFrame || mxI==0 ){ | |
| 45720 | + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 | |
| 45721 | + && (mxReadMark<pWal->hdr.mxFrame || mxI==0) | |
| 45722 | + ){ | |
| 45671 | 45723 | for(i=1; i<WAL_NREADER; i++){ |
| 45672 | 45724 | rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45673 | 45725 | if( rc==SQLITE_OK ){ |
| 45674 | 45726 | mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; |
| 45675 | 45727 | mxI = i; |
| @@ -45679,12 +45731,12 @@ | ||
| 45679 | 45731 | return rc; |
| 45680 | 45732 | } |
| 45681 | 45733 | } |
| 45682 | 45734 | } |
| 45683 | 45735 | if( mxI==0 ){ |
| 45684 | - assert( rc==SQLITE_BUSY ); | |
| 45685 | - return WAL_RETRY; | |
| 45736 | + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); | |
| 45737 | + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; | |
| 45686 | 45738 | } |
| 45687 | 45739 | |
| 45688 | 45740 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); |
| 45689 | 45741 | if( rc ){ |
| 45690 | 45742 | return rc==SQLITE_BUSY ? WAL_RETRY : rc; |
| @@ -46086,14 +46138,16 @@ | ||
| 46086 | 46138 | ** set to a non-negative value. Log errors encountered |
| 46087 | 46139 | ** during the truncation attempt. */ |
| 46088 | 46140 | if( pWal->mxWalSize>=0 ){ |
| 46089 | 46141 | i64 sz; |
| 46090 | 46142 | int rx; |
| 46143 | + sqlite3BeginBenignMalloc(); | |
| 46091 | 46144 | rx = sqlite3OsFileSize(pWal->pWalFd, &sz); |
| 46092 | 46145 | if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ |
| 46093 | 46146 | rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); |
| 46094 | 46147 | } |
| 46148 | + sqlite3EndBenignMalloc(); | |
| 46095 | 46149 | if( rx ){ |
| 46096 | 46150 | sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); |
| 46097 | 46151 | } |
| 46098 | 46152 | } |
| 46099 | 46153 | |
| @@ -46320,10 +46374,11 @@ | ||
| 46320 | 46374 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 46321 | 46375 | |
| 46322 | 46376 | assert( pWal->ckptLock==0 ); |
| 46323 | 46377 | assert( pWal->writeLock==0 ); |
| 46324 | 46378 | |
| 46379 | + if( pWal->readOnly ) return SQLITE_READONLY; | |
| 46325 | 46380 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 46326 | 46381 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 46327 | 46382 | if( rc ){ |
| 46328 | 46383 | /* Usually this is SQLITE_BUSY meaning that another thread or process |
| 46329 | 46384 | ** is already running a checkpoint, or maybe a recovery. But it might |
| @@ -52802,14 +52857,14 @@ | ||
| 52802 | 52857 | ** removes the reference to the cell from pPage. |
| 52803 | 52858 | ** |
| 52804 | 52859 | ** "sz" must be the number of bytes in the cell. |
| 52805 | 52860 | */ |
| 52806 | 52861 | static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ |
| 52807 | - int i; /* Loop counter */ | |
| 52808 | 52862 | u32 pc; /* Offset to cell content of cell being deleted */ |
| 52809 | 52863 | u8 *data; /* pPage->aData */ |
| 52810 | 52864 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 52865 | + u8 *endPtr; /* End of loop */ | |
| 52811 | 52866 | int rc; /* The return code */ |
| 52812 | 52867 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 52813 | 52868 | |
| 52814 | 52869 | if( *pRC ) return; |
| 52815 | 52870 | |
| @@ -52830,13 +52885,15 @@ | ||
| 52830 | 52885 | rc = freeSpace(pPage, pc, sz); |
| 52831 | 52886 | if( rc ){ |
| 52832 | 52887 | *pRC = rc; |
| 52833 | 52888 | return; |
| 52834 | 52889 | } |
| 52835 | - for(i=idx+1; i<pPage->nCell; i++, ptr+=2){ | |
| 52890 | + endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; | |
| 52891 | + while( ptr<endPtr ){ | |
| 52836 | 52892 | ptr[0] = ptr[2]; |
| 52837 | 52893 | ptr[1] = ptr[3]; |
| 52894 | + ptr += 2; | |
| 52838 | 52895 | } |
| 52839 | 52896 | pPage->nCell--; |
| 52840 | 52897 | put2byte(&data[hdr+3], pPage->nCell); |
| 52841 | 52898 | pPage->nFree += 2; |
| 52842 | 52899 | } |
| @@ -58815,38 +58872,17 @@ | ||
| 58815 | 58872 | } |
| 58816 | 58873 | return pBuf; |
| 58817 | 58874 | } |
| 58818 | 58875 | |
| 58819 | 58876 | /* |
| 58820 | -** Prepare a virtual machine for execution. This involves things such | |
| 58821 | -** as allocating stack space and initializing the program counter. | |
| 58822 | -** After the VDBE has be prepped, it can be executed by one or more | |
| 58823 | -** calls to sqlite3VdbeExec(). | |
| 58824 | -** | |
| 58825 | -** This is the only way to move a VDBE from VDBE_MAGIC_INIT to | |
| 58826 | -** VDBE_MAGIC_RUN. | |
| 58827 | -** | |
| 58828 | -** This function may be called more than once on a single virtual machine. | |
| 58829 | -** The first call is made while compiling the SQL statement. Subsequent | |
| 58830 | -** calls are made as part of the process of resetting a statement to be | |
| 58831 | -** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor | |
| 58832 | -** and isExplain parameters are only passed correct values the first time | |
| 58833 | -** the function is called. On subsequent calls, from sqlite3_reset(), nVar | |
| 58834 | -** is passed -1 and nMem, nCursor and isExplain are all passed zero. | |
| 58877 | +** Rewind the VDBE back to the beginning in preparation for | |
| 58878 | +** running it. | |
| 58835 | 58879 | */ |
| 58836 | -SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |
| 58837 | - Vdbe *p, /* The VDBE */ | |
| 58838 | - int nVar, /* Number of '?' see in the SQL statement */ | |
| 58839 | - int nMem, /* Number of memory cells to allocate */ | |
| 58840 | - int nCursor, /* Number of cursors to allocate */ | |
| 58841 | - int nArg, /* Maximum number of args in SubPrograms */ | |
| 58842 | - int isExplain, /* True if the EXPLAIN keywords is present */ | |
| 58843 | - int usesStmtJournal /* True to set Vdbe.usesStmtJournal */ | |
| 58844 | -){ | |
| 58845 | - int n; | |
| 58846 | - sqlite3 *db = p->db; | |
| 58847 | - | |
| 58880 | +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ | |
| 58881 | +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) | |
| 58882 | + int i; | |
| 58883 | +#endif | |
| 58848 | 58884 | assert( p!=0 ); |
| 58849 | 58885 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 58850 | 58886 | |
| 58851 | 58887 | /* There should be at least one opcode. |
| 58852 | 58888 | */ |
| @@ -58853,10 +58889,75 @@ | ||
| 58853 | 58889 | assert( p->nOp>0 ); |
| 58854 | 58890 | |
| 58855 | 58891 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 58856 | 58892 | p->magic = VDBE_MAGIC_RUN; |
| 58857 | 58893 | |
| 58894 | +#ifdef SQLITE_DEBUG | |
| 58895 | + for(i=1; i<p->nMem; i++){ | |
| 58896 | + assert( p->aMem[i].db==p->db ); | |
| 58897 | + } | |
| 58898 | +#endif | |
| 58899 | + p->pc = -1; | |
| 58900 | + p->rc = SQLITE_OK; | |
| 58901 | + p->errorAction = OE_Abort; | |
| 58902 | + p->magic = VDBE_MAGIC_RUN; | |
| 58903 | + p->nChange = 0; | |
| 58904 | + p->cacheCtr = 1; | |
| 58905 | + p->minWriteFileFormat = 255; | |
| 58906 | + p->iStatement = 0; | |
| 58907 | + p->nFkConstraint = 0; | |
| 58908 | +#ifdef VDBE_PROFILE | |
| 58909 | + for(i=0; i<p->nOp; i++){ | |
| 58910 | + p->aOp[i].cnt = 0; | |
| 58911 | + p->aOp[i].cycles = 0; | |
| 58912 | + } | |
| 58913 | +#endif | |
| 58914 | +} | |
| 58915 | + | |
| 58916 | +/* | |
| 58917 | +** Prepare a virtual machine for execution for the first time after | |
| 58918 | +** creating the virtual machine. This involves things such | |
| 58919 | +** as allocating stack space and initializing the program counter. | |
| 58920 | +** After the VDBE has be prepped, it can be executed by one or more | |
| 58921 | +** calls to sqlite3VdbeExec(). | |
| 58922 | +** | |
| 58923 | +** This function may be called exact once on a each virtual machine. | |
| 58924 | +** After this routine is called the VM has been "packaged" and is ready | |
| 58925 | +** to run. After this routine is called, futher calls to | |
| 58926 | +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects | |
| 58927 | +** the Vdbe from the Parse object that helped generate it so that the | |
| 58928 | +** the Vdbe becomes an independent entity and the Parse object can be | |
| 58929 | +** destroyed. | |
| 58930 | +** | |
| 58931 | +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back | |
| 58932 | +** to its initial state after it has been run. | |
| 58933 | +*/ | |
| 58934 | +SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |
| 58935 | + Vdbe *p, /* The VDBE */ | |
| 58936 | + Parse *pParse /* Parsing context */ | |
| 58937 | +){ | |
| 58938 | + sqlite3 *db; /* The database connection */ | |
| 58939 | + int nVar; /* Number of parameters */ | |
| 58940 | + int nMem; /* Number of VM memory registers */ | |
| 58941 | + int nCursor; /* Number of cursors required */ | |
| 58942 | + int nArg; /* Number of arguments in subprograms */ | |
| 58943 | + int n; /* Loop counter */ | |
| 58944 | + u8 *zCsr; /* Memory available for allocation */ | |
| 58945 | + u8 *zEnd; /* First byte past allocated memory */ | |
| 58946 | + int nByte; /* How much extra memory is needed */ | |
| 58947 | + | |
| 58948 | + assert( p!=0 ); | |
| 58949 | + assert( p->nOp>0 ); | |
| 58950 | + assert( pParse!=0 ); | |
| 58951 | + assert( p->magic==VDBE_MAGIC_INIT ); | |
| 58952 | + db = p->db; | |
| 58953 | + assert( db->mallocFailed==0 ); | |
| 58954 | + nVar = pParse->nVar; | |
| 58955 | + nMem = pParse->nMem; | |
| 58956 | + nCursor = pParse->nTab; | |
| 58957 | + nArg = pParse->nMaxArg; | |
| 58958 | + | |
| 58858 | 58959 | /* For each cursor required, also allocate a memory cell. Memory |
| 58859 | 58960 | ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by |
| 58860 | 58961 | ** the vdbe program. Instead they are used to allocate space for |
| 58861 | 58962 | ** VdbeCursor/BtCursor structures. The blob of memory associated with |
| 58862 | 58963 | ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) |
| @@ -58865,95 +58966,72 @@ | ||
| 58865 | 58966 | ** See also: allocateCursor(). |
| 58866 | 58967 | */ |
| 58867 | 58968 | nMem += nCursor; |
| 58868 | 58969 | |
| 58869 | 58970 | /* Allocate space for memory registers, SQL variables, VDBE cursors and |
| 58870 | - ** an array to marshal SQL function arguments in. This is only done the | |
| 58871 | - ** first time this function is called for a given VDBE, not when it is | |
| 58872 | - ** being called from sqlite3_reset() to reset the virtual machine. | |
| 58873 | - */ | |
| 58874 | - if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){ | |
| 58875 | - u8 *zCsr = (u8 *)&p->aOp[p->nOp]; /* Memory avaliable for alloation */ | |
| 58876 | - u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; /* First byte past available mem */ | |
| 58877 | - int nByte; /* How much extra memory needed */ | |
| 58878 | - | |
| 58879 | - resolveP2Values(p, &nArg); | |
| 58880 | - p->usesStmtJournal = (u8)usesStmtJournal; | |
| 58881 | - if( isExplain && nMem<10 ){ | |
| 58882 | - nMem = 10; | |
| 58883 | - } | |
| 58884 | - memset(zCsr, 0, zEnd-zCsr); | |
| 58885 | - zCsr += (zCsr - (u8*)0)&7; | |
| 58886 | - assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); | |
| 58887 | - | |
| 58888 | - /* Memory for registers, parameters, cursor, etc, is allocated in two | |
| 58889 | - ** passes. On the first pass, we try to reuse unused space at the | |
| 58890 | - ** end of the opcode array. If we are unable to satisfy all memory | |
| 58891 | - ** requirements by reusing the opcode array tail, then the second | |
| 58892 | - ** pass will fill in the rest using a fresh allocation. | |
| 58893 | - ** | |
| 58894 | - ** This two-pass approach that reuses as much memory as possible from | |
| 58895 | - ** the leftover space at the end of the opcode array can significantly | |
| 58896 | - ** reduce the amount of memory held by a prepared statement. | |
| 58897 | - */ | |
| 58898 | - do { | |
| 58899 | - nByte = 0; | |
| 58900 | - p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); | |
| 58901 | - p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); | |
| 58902 | - p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); | |
| 58903 | - p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); | |
| 58904 | - p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), | |
| 58905 | - &zCsr, zEnd, &nByte); | |
| 58906 | - if( nByte ){ | |
| 58907 | - p->pFree = sqlite3DbMallocZero(db, nByte); | |
| 58908 | - } | |
| 58909 | - zCsr = p->pFree; | |
| 58910 | - zEnd = &zCsr[nByte]; | |
| 58911 | - }while( nByte && !db->mallocFailed ); | |
| 58912 | - | |
| 58913 | - p->nCursor = (u16)nCursor; | |
| 58914 | - if( p->aVar ){ | |
| 58915 | - p->nVar = (ynVar)nVar; | |
| 58916 | - for(n=0; n<nVar; n++){ | |
| 58917 | - p->aVar[n].flags = MEM_Null; | |
| 58918 | - p->aVar[n].db = db; | |
| 58919 | - } | |
| 58920 | - } | |
| 58921 | - if( p->aMem ){ | |
| 58922 | - p->aMem--; /* aMem[] goes from 1..nMem */ | |
| 58923 | - p->nMem = nMem; /* not from 0..nMem-1 */ | |
| 58924 | - for(n=1; n<=nMem; n++){ | |
| 58925 | - p->aMem[n].flags = MEM_Null; | |
| 58926 | - p->aMem[n].db = db; | |
| 58927 | - } | |
| 58928 | - } | |
| 58929 | - } | |
| 58930 | -#ifdef SQLITE_DEBUG | |
| 58931 | - for(n=1; n<p->nMem; n++){ | |
| 58932 | - assert( p->aMem[n].db==db ); | |
| 58933 | - } | |
| 58934 | -#endif | |
| 58935 | - | |
| 58936 | - p->pc = -1; | |
| 58937 | - p->rc = SQLITE_OK; | |
| 58938 | - p->errorAction = OE_Abort; | |
| 58939 | - p->explain |= isExplain; | |
| 58940 | - p->magic = VDBE_MAGIC_RUN; | |
| 58941 | - p->nChange = 0; | |
| 58942 | - p->cacheCtr = 1; | |
| 58943 | - p->minWriteFileFormat = 255; | |
| 58944 | - p->iStatement = 0; | |
| 58945 | - p->nFkConstraint = 0; | |
| 58946 | -#ifdef VDBE_PROFILE | |
| 58947 | - { | |
| 58948 | - int i; | |
| 58949 | - for(i=0; i<p->nOp; i++){ | |
| 58950 | - p->aOp[i].cnt = 0; | |
| 58951 | - p->aOp[i].cycles = 0; | |
| 58952 | - } | |
| 58953 | - } | |
| 58954 | -#endif | |
| 58971 | + ** an array to marshal SQL function arguments in. | |
| 58972 | + */ | |
| 58973 | + zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ | |
| 58974 | + zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ | |
| 58975 | + | |
| 58976 | + resolveP2Values(p, &nArg); | |
| 58977 | + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); | |
| 58978 | + if( pParse->explain && nMem<10 ){ | |
| 58979 | + nMem = 10; | |
| 58980 | + } | |
| 58981 | + memset(zCsr, 0, zEnd-zCsr); | |
| 58982 | + zCsr += (zCsr - (u8*)0)&7; | |
| 58983 | + assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); | |
| 58984 | + | |
| 58985 | + /* Memory for registers, parameters, cursor, etc, is allocated in two | |
| 58986 | + ** passes. On the first pass, we try to reuse unused space at the | |
| 58987 | + ** end of the opcode array. If we are unable to satisfy all memory | |
| 58988 | + ** requirements by reusing the opcode array tail, then the second | |
| 58989 | + ** pass will fill in the rest using a fresh allocation. | |
| 58990 | + ** | |
| 58991 | + ** This two-pass approach that reuses as much memory as possible from | |
| 58992 | + ** the leftover space at the end of the opcode array can significantly | |
| 58993 | + ** reduce the amount of memory held by a prepared statement. | |
| 58994 | + */ | |
| 58995 | + do { | |
| 58996 | + nByte = 0; | |
| 58997 | + p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); | |
| 58998 | + p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); | |
| 58999 | + p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); | |
| 59000 | + p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); | |
| 59001 | + p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), | |
| 59002 | + &zCsr, zEnd, &nByte); | |
| 59003 | + if( nByte ){ | |
| 59004 | + p->pFree = sqlite3DbMallocZero(db, nByte); | |
| 59005 | + } | |
| 59006 | + zCsr = p->pFree; | |
| 59007 | + zEnd = &zCsr[nByte]; | |
| 59008 | + }while( nByte && !db->mallocFailed ); | |
| 59009 | + | |
| 59010 | + p->nCursor = (u16)nCursor; | |
| 59011 | + if( p->aVar ){ | |
| 59012 | + p->nVar = (ynVar)nVar; | |
| 59013 | + for(n=0; n<nVar; n++){ | |
| 59014 | + p->aVar[n].flags = MEM_Null; | |
| 59015 | + p->aVar[n].db = db; | |
| 59016 | + } | |
| 59017 | + } | |
| 59018 | + if( p->azVar ){ | |
| 59019 | + p->nzVar = pParse->nzVar; | |
| 59020 | + memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); | |
| 59021 | + memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); | |
| 59022 | + } | |
| 59023 | + if( p->aMem ){ | |
| 59024 | + p->aMem--; /* aMem[] goes from 1..nMem */ | |
| 59025 | + p->nMem = nMem; /* not from 0..nMem-1 */ | |
| 59026 | + for(n=1; n<=nMem; n++){ | |
| 59027 | + p->aMem[n].flags = MEM_Null; | |
| 59028 | + p->aMem[n].db = db; | |
| 59029 | + } | |
| 59030 | + } | |
| 59031 | + p->explain = pParse->explain; | |
| 59032 | + sqlite3VdbeRewind(p); | |
| 58955 | 59033 | } |
| 58956 | 59034 | |
| 58957 | 59035 | /* |
| 58958 | 59036 | ** Close a VDBE cursor and release all the resources that cursor |
| 58959 | 59037 | ** happens to hold. |
| @@ -59626,21 +59704,15 @@ | ||
| 59626 | 59704 | /* If eStatementOp is non-zero, then a statement transaction needs to |
| 59627 | 59705 | ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to |
| 59628 | 59706 | ** do so. If this operation returns an error, and the current statement |
| 59629 | 59707 | ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the |
| 59630 | 59708 | ** current statement error code. |
| 59631 | - ** | |
| 59632 | - ** Note that sqlite3VdbeCloseStatement() can only fail if eStatementOp | |
| 59633 | - ** is SAVEPOINT_ROLLBACK. But if p->rc==SQLITE_OK then eStatementOp | |
| 59634 | - ** must be SAVEPOINT_RELEASE. Hence the NEVER(p->rc==SQLITE_OK) in | |
| 59635 | - ** the following code. | |
| 59636 | 59709 | */ |
| 59637 | 59710 | if( eStatementOp ){ |
| 59638 | 59711 | rc = sqlite3VdbeCloseStatement(p, eStatementOp); |
| 59639 | 59712 | if( rc ){ |
| 59640 | - assert( eStatementOp==SAVEPOINT_ROLLBACK ); | |
| 59641 | - if( NEVER(p->rc==SQLITE_OK) || p->rc==SQLITE_CONSTRAINT ){ | |
| 59713 | + if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ | |
| 59642 | 59714 | p->rc = rc; |
| 59643 | 59715 | sqlite3DbFree(db, p->zErrMsg); |
| 59644 | 59716 | p->zErrMsg = 0; |
| 59645 | 59717 | } |
| 59646 | 59718 | invalidateCursorsOnModifiedBtrees(db); |
| @@ -59829,18 +59901,20 @@ | ||
| 59829 | 59901 | ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with |
| 59830 | 59902 | ** the database connection. |
| 59831 | 59903 | */ |
| 59832 | 59904 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ |
| 59833 | 59905 | SubProgram *pSub, *pNext; |
| 59906 | + int i; | |
| 59834 | 59907 | assert( p->db==0 || p->db==db ); |
| 59835 | 59908 | releaseMemArray(p->aVar, p->nVar); |
| 59836 | 59909 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); |
| 59837 | 59910 | for(pSub=p->pProgram; pSub; pSub=pNext){ |
| 59838 | 59911 | pNext = pSub->pNext; |
| 59839 | 59912 | vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); |
| 59840 | 59913 | sqlite3DbFree(db, pSub); |
| 59841 | 59914 | } |
| 59915 | + for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); | |
| 59842 | 59916 | vdbeFreeOpArray(db, p->aOp, p->nOp); |
| 59843 | 59917 | sqlite3DbFree(db, p->aLabel); |
| 59844 | 59918 | sqlite3DbFree(db, p->aColName); |
| 59845 | 59919 | sqlite3DbFree(db, p->zSql); |
| 59846 | 59920 | sqlite3DbFree(db, p->pFree); |
| @@ -60282,11 +60356,11 @@ | ||
| 60282 | 60356 | u32 serial_type; |
| 60283 | 60357 | |
| 60284 | 60358 | idx += getVarint32(&aKey[idx], serial_type); |
| 60285 | 60359 | pMem->enc = pKeyInfo->enc; |
| 60286 | 60360 | pMem->db = pKeyInfo->db; |
| 60287 | - pMem->flags = 0; | |
| 60361 | + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ | |
| 60288 | 60362 | pMem->zMalloc = 0; |
| 60289 | 60363 | d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); |
| 60290 | 60364 | pMem++; |
| 60291 | 60365 | u++; |
| 60292 | 60366 | } |
| @@ -60297,10 +60371,11 @@ | ||
| 60297 | 60371 | |
| 60298 | 60372 | /* |
| 60299 | 60373 | ** This routine destroys a UnpackedRecord object. |
| 60300 | 60374 | */ |
| 60301 | 60375 | SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ |
| 60376 | +#ifdef SQLITE_DEBUG | |
| 60302 | 60377 | int i; |
| 60303 | 60378 | Mem *pMem; |
| 60304 | 60379 | |
| 60305 | 60380 | assert( p!=0 ); |
| 60306 | 60381 | assert( p->flags & UNPACKED_NEED_DESTROY ); |
| @@ -60310,10 +60385,11 @@ | ||
| 60310 | 60385 | ** strings and blobs static. And none of the elements are |
| 60311 | 60386 | ** ever transformed, so there is never anything to delete. |
| 60312 | 60387 | */ |
| 60313 | 60388 | if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); |
| 60314 | 60389 | } |
| 60390 | +#endif | |
| 60315 | 60391 | if( p->flags & UNPACKED_NEED_FREE ){ |
| 60316 | 60392 | sqlite3DbFree(p->pKeyInfo->db, p); |
| 60317 | 60393 | } |
| 60318 | 60394 | } |
| 60319 | 60395 | |
| @@ -60745,11 +60821,11 @@ | ||
| 60745 | 60821 | rc = SQLITE_OK; |
| 60746 | 60822 | }else{ |
| 60747 | 60823 | Vdbe *v = (Vdbe*)pStmt; |
| 60748 | 60824 | sqlite3_mutex_enter(v->db->mutex); |
| 60749 | 60825 | rc = sqlite3VdbeReset(v); |
| 60750 | - sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0); | |
| 60826 | + sqlite3VdbeRewind(v); | |
| 60751 | 60827 | assert( (rc & (v->db->errMask))==rc ); |
| 60752 | 60828 | rc = sqlite3ApiExit(v->db, rc); |
| 60753 | 60829 | sqlite3_mutex_leave(v->db->mutex); |
| 60754 | 60830 | } |
| 60755 | 60831 | return rc; |
| @@ -61810,48 +61886,21 @@ | ||
| 61810 | 61886 | SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ |
| 61811 | 61887 | Vdbe *p = (Vdbe*)pStmt; |
| 61812 | 61888 | return p ? p->nVar : 0; |
| 61813 | 61889 | } |
| 61814 | 61890 | |
| 61815 | -/* | |
| 61816 | -** Create a mapping from variable numbers to variable names | |
| 61817 | -** in the Vdbe.azVar[] array, if such a mapping does not already | |
| 61818 | -** exist. | |
| 61819 | -*/ | |
| 61820 | -static void createVarMap(Vdbe *p){ | |
| 61821 | - if( !p->okVar ){ | |
| 61822 | - int j; | |
| 61823 | - Op *pOp; | |
| 61824 | - sqlite3_mutex_enter(p->db->mutex); | |
| 61825 | - /* The race condition here is harmless. If two threads call this | |
| 61826 | - ** routine on the same Vdbe at the same time, they both might end | |
| 61827 | - ** up initializing the Vdbe.azVar[] array. That is a little extra | |
| 61828 | - ** work but it results in the same answer. | |
| 61829 | - */ | |
| 61830 | - for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){ | |
| 61831 | - if( pOp->opcode==OP_Variable ){ | |
| 61832 | - assert( pOp->p1>0 && pOp->p1<=p->nVar ); | |
| 61833 | - p->azVar[pOp->p1-1] = pOp->p4.z; | |
| 61834 | - } | |
| 61835 | - } | |
| 61836 | - p->okVar = 1; | |
| 61837 | - sqlite3_mutex_leave(p->db->mutex); | |
| 61838 | - } | |
| 61839 | -} | |
| 61840 | - | |
| 61841 | 61891 | /* |
| 61842 | 61892 | ** Return the name of a wildcard parameter. Return NULL if the index |
| 61843 | 61893 | ** is out of range or if the wildcard is unnamed. |
| 61844 | 61894 | ** |
| 61845 | 61895 | ** The result is always UTF-8. |
| 61846 | 61896 | */ |
| 61847 | 61897 | SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ |
| 61848 | 61898 | Vdbe *p = (Vdbe*)pStmt; |
| 61849 | - if( p==0 || i<1 || i>p->nVar ){ | |
| 61899 | + if( p==0 || i<1 || i>p->nzVar ){ | |
| 61850 | 61900 | return 0; |
| 61851 | 61901 | } |
| 61852 | - createVarMap(p); | |
| 61853 | 61902 | return p->azVar[i-1]; |
| 61854 | 61903 | } |
| 61855 | 61904 | |
| 61856 | 61905 | /* |
| 61857 | 61906 | ** Given a wildcard parameter name, return the index of the variable |
| @@ -61861,13 +61910,12 @@ | ||
| 61861 | 61910 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ |
| 61862 | 61911 | int i; |
| 61863 | 61912 | if( p==0 ){ |
| 61864 | 61913 | return 0; |
| 61865 | 61914 | } |
| 61866 | - createVarMap(p); | |
| 61867 | 61915 | if( zName ){ |
| 61868 | - for(i=0; i<p->nVar; i++){ | |
| 61916 | + for(i=0; i<p->nzVar; i++){ | |
| 61869 | 61917 | const char *z = p->azVar[i]; |
| 61870 | 61918 | if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ |
| 61871 | 61919 | return i+1; |
| 61872 | 61920 | } |
| 61873 | 61921 | } |
| @@ -63187,10 +63235,11 @@ | ||
| 63187 | 63235 | Mem **apArg; |
| 63188 | 63236 | Mem *pX; |
| 63189 | 63237 | } cm; |
| 63190 | 63238 | struct OP_Trace_stack_vars { |
| 63191 | 63239 | char *zTrace; |
| 63240 | + char *z; | |
| 63192 | 63241 | } cn; |
| 63193 | 63242 | } u; |
| 63194 | 63243 | /* End automatically generated code |
| 63195 | 63244 | ********************************************************************/ |
| 63196 | 63245 | |
| @@ -63613,10 +63662,11 @@ | ||
| 63613 | 63662 | #if 0 /* local variables moved into u.ab */ |
| 63614 | 63663 | Mem *pVar; /* Value being transferred */ |
| 63615 | 63664 | #endif /* local variables moved into u.ab */ |
| 63616 | 63665 | |
| 63617 | 63666 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 63667 | + assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); | |
| 63618 | 63668 | u.ab.pVar = &p->aVar[pOp->p1 - 1]; |
| 63619 | 63669 | if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ |
| 63620 | 63670 | goto too_big; |
| 63621 | 63671 | } |
| 63622 | 63672 | sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); |
| @@ -64405,19 +64455,19 @@ | ||
| 64405 | 64455 | |
| 64406 | 64456 | pIn1 = &aMem[pOp->p1]; |
| 64407 | 64457 | pIn3 = &aMem[pOp->p3]; |
| 64408 | 64458 | u.ai.flags1 = pIn1->flags; |
| 64409 | 64459 | u.ai.flags3 = pIn3->flags; |
| 64410 | - if( (pIn1->flags | pIn3->flags)&MEM_Null ){ | |
| 64460 | + if( (u.ai.flags1 | u.ai.flags3)&MEM_Null ){ | |
| 64411 | 64461 | /* One or both operands are NULL */ |
| 64412 | 64462 | if( pOp->p5 & SQLITE_NULLEQ ){ |
| 64413 | 64463 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
| 64414 | 64464 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
| 64415 | 64465 | ** or not both operands are null. |
| 64416 | 64466 | */ |
| 64417 | 64467 | assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); |
| 64418 | - u.ai.res = (pIn1->flags & pIn3->flags & MEM_Null)==0; | |
| 64468 | + u.ai.res = (u.ai.flags1 & u.ai.flags3 & MEM_Null)==0; | |
| 64419 | 64469 | }else{ |
| 64420 | 64470 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 64421 | 64471 | ** then the result is always NULL. |
| 64422 | 64472 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| 64423 | 64473 | */ |
| @@ -65239,17 +65289,20 @@ | ||
| 65239 | 65289 | "SQL statements in progress"); |
| 65240 | 65290 | rc = SQLITE_BUSY; |
| 65241 | 65291 | }else{ |
| 65242 | 65292 | u.aq.nName = sqlite3Strlen30(u.aq.zName); |
| 65243 | 65293 | |
| 65294 | +#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 65244 | 65295 | /* This call is Ok even if this savepoint is actually a transaction |
| 65245 | 65296 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
| 65246 | 65297 | ** If this is a transaction savepoint being opened, it is guaranteed |
| 65247 | 65298 | ** that the db->aVTrans[] array is empty. */ |
| 65248 | 65299 | assert( db->autoCommit==0 || db->nVTrans==0 ); |
| 65249 | - rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement); | |
| 65300 | + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, | |
| 65301 | + db->nStatement+db->nSavepoint); | |
| 65250 | 65302 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 65303 | +#endif | |
| 65251 | 65304 | |
| 65252 | 65305 | /* Create a new savepoint structure. */ |
| 65253 | 65306 | u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); |
| 65254 | 65307 | if( u.aq.pNew ){ |
| 65255 | 65308 | u.aq.pNew->zName = (char *)&u.aq.pNew[1]; |
| @@ -65498,11 +65551,11 @@ | ||
| 65498 | 65551 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 65499 | 65552 | db->nStatement++; |
| 65500 | 65553 | p->iStatement = db->nSavepoint + db->nStatement; |
| 65501 | 65554 | } |
| 65502 | 65555 | |
| 65503 | - rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement); | |
| 65556 | + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); | |
| 65504 | 65557 | if( rc==SQLITE_OK ){ |
| 65505 | 65558 | rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); |
| 65506 | 65559 | } |
| 65507 | 65560 | |
| 65508 | 65561 | /* Store the current value of the database handles deferred constraint |
| @@ -68631,25 +68684,25 @@ | ||
| 68631 | 68684 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 68632 | 68685 | */ |
| 68633 | 68686 | case OP_Trace: { |
| 68634 | 68687 | #if 0 /* local variables moved into u.cn */ |
| 68635 | 68688 | char *zTrace; |
| 68689 | + char *z; | |
| 68636 | 68690 | #endif /* local variables moved into u.cn */ |
| 68637 | 68691 | |
| 68638 | - u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); | |
| 68639 | - if( u.cn.zTrace ){ | |
| 68640 | - if( db->xTrace ){ | |
| 68641 | - char *z = sqlite3VdbeExpandSql(p, u.cn.zTrace); | |
| 68642 | - db->xTrace(db->pTraceArg, z); | |
| 68643 | - sqlite3DbFree(db, z); | |
| 68644 | - } | |
| 68692 | + if( db->xTrace && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ | |
| 68693 | + u.cn.z = sqlite3VdbeExpandSql(p, u.cn.zTrace); | |
| 68694 | + db->xTrace(db->pTraceArg, u.cn.z); | |
| 68695 | + sqlite3DbFree(db, u.cn.z); | |
| 68696 | + } | |
| 68645 | 68697 | #ifdef SQLITE_DEBUG |
| 68646 | - if( (db->flags & SQLITE_SqlTrace)!=0 ){ | |
| 68647 | - sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); | |
| 68648 | - } | |
| 68698 | + if( (db->flags & SQLITE_SqlTrace)!=0 | |
| 68699 | + && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 | |
| 68700 | + ){ | |
| 68701 | + sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); | |
| 68702 | + } | |
| 68649 | 68703 | #endif /* SQLITE_DEBUG */ |
| 68650 | - } | |
| 68651 | 68704 | break; |
| 68652 | 68705 | } |
| 68653 | 68706 | #endif |
| 68654 | 68707 | |
| 68655 | 68708 | |
| @@ -69070,11 +69123,14 @@ | ||
| 69070 | 69123 | ** and offset cache without causing any IO. |
| 69071 | 69124 | */ |
| 69072 | 69125 | sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); |
| 69073 | 69126 | sqlite3VdbeChangeP2(v, 7, pTab->nCol); |
| 69074 | 69127 | if( !db->mallocFailed ){ |
| 69075 | - sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); | |
| 69128 | + pParse->nVar = 1; | |
| 69129 | + pParse->nMem = 1; | |
| 69130 | + pParse->nTab = 1; | |
| 69131 | + sqlite3VdbeMakeReady(v, pParse); | |
| 69076 | 69132 | } |
| 69077 | 69133 | } |
| 69078 | 69134 | |
| 69079 | 69135 | pBlob->flags = flags; |
| 69080 | 69136 | pBlob->iCol = iCol; |
| @@ -71637,57 +71693,57 @@ | ||
| 71637 | 71693 | assert( z[0]!=0 ); |
| 71638 | 71694 | if( z[1]==0 ){ |
| 71639 | 71695 | /* Wildcard of the form "?". Assign the next variable number */ |
| 71640 | 71696 | assert( z[0]=='?' ); |
| 71641 | 71697 | pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71642 | - }else if( z[0]=='?' ){ | |
| 71643 | - /* Wildcard of the form "?nnn". Convert "nnn" to an integer and | |
| 71644 | - ** use it as the variable number */ | |
| 71645 | - i64 i; | |
| 71646 | - int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); | |
| 71647 | - pExpr->iColumn = (ynVar)i; | |
| 71648 | - testcase( i==0 ); | |
| 71649 | - testcase( i==1 ); | |
| 71650 | - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); | |
| 71651 | - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); | |
| 71652 | - if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ | |
| 71653 | - sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", | |
| 71654 | - db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); | |
| 71655 | - } | |
| 71656 | - if( i>pParse->nVar ){ | |
| 71657 | - pParse->nVar = (int)i; | |
| 71658 | - } | |
| 71659 | - }else{ | |
| 71660 | - /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable | |
| 71661 | - ** number as the prior appearance of the same name, or if the name | |
| 71662 | - ** has never appeared before, reuse the same variable number | |
| 71663 | - */ | |
| 71664 | - int i; | |
| 71665 | - u32 n; | |
| 71666 | - n = sqlite3Strlen30(z); | |
| 71667 | - for(i=0; i<pParse->nVarExpr; i++){ | |
| 71668 | - Expr *pE = pParse->apVarExpr[i]; | |
| 71669 | - assert( pE!=0 ); | |
| 71670 | - if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){ | |
| 71671 | - pExpr->iColumn = pE->iColumn; | |
| 71672 | - break; | |
| 71673 | - } | |
| 71674 | - } | |
| 71675 | - if( i>=pParse->nVarExpr ){ | |
| 71676 | - pExpr->iColumn = (ynVar)(++pParse->nVar); | |
| 71677 | - if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ | |
| 71678 | - pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; | |
| 71679 | - pParse->apVarExpr = | |
| 71680 | - sqlite3DbReallocOrFree( | |
| 71681 | - db, | |
| 71682 | - pParse->apVarExpr, | |
| 71683 | - pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) | |
| 71684 | - ); | |
| 71685 | - } | |
| 71686 | - if( !db->mallocFailed ){ | |
| 71687 | - assert( pParse->apVarExpr!=0 ); | |
| 71688 | - pParse->apVarExpr[pParse->nVarExpr++] = pExpr; | |
| 71698 | + }else{ | |
| 71699 | + ynVar x = 0; | |
| 71700 | + u32 n = sqlite3Strlen30(z); | |
| 71701 | + if( z[0]=='?' ){ | |
| 71702 | + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and | |
| 71703 | + ** use it as the variable number */ | |
| 71704 | + i64 i; | |
| 71705 | + int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); | |
| 71706 | + pExpr->iColumn = x = (ynVar)i; | |
| 71707 | + testcase( i==0 ); | |
| 71708 | + testcase( i==1 ); | |
| 71709 | + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); | |
| 71710 | + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); | |
| 71711 | + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ | |
| 71712 | + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", | |
| 71713 | + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); | |
| 71714 | + x = 0; | |
| 71715 | + } | |
| 71716 | + if( i>pParse->nVar ){ | |
| 71717 | + pParse->nVar = (int)i; | |
| 71718 | + } | |
| 71719 | + }else{ | |
| 71720 | + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable | |
| 71721 | + ** number as the prior appearance of the same name, or if the name | |
| 71722 | + ** has never appeared before, reuse the same variable number | |
| 71723 | + */ | |
| 71724 | + ynVar i; | |
| 71725 | + for(i=0; i<pParse->nzVar; i++){ | |
| 71726 | + if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ | |
| 71727 | + pExpr->iColumn = x = (ynVar)i+1; | |
| 71728 | + break; | |
| 71729 | + } | |
| 71730 | + } | |
| 71731 | + if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); | |
| 71732 | + } | |
| 71733 | + if( x>0 ){ | |
| 71734 | + if( x>pParse->nzVar ){ | |
| 71735 | + char **a; | |
| 71736 | + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); | |
| 71737 | + if( a==0 ) return; /* Error reported through db->mallocFailed */ | |
| 71738 | + pParse->azVar = a; | |
| 71739 | + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); | |
| 71740 | + pParse->nzVar = x; | |
| 71741 | + } | |
| 71742 | + if( z[0]!='?' || pParse->azVar[x-1]==0 ){ | |
| 71743 | + sqlite3DbFree(db, pParse->azVar[x-1]); | |
| 71744 | + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); | |
| 71689 | 71745 | } |
| 71690 | 71746 | } |
| 71691 | 71747 | } |
| 71692 | 71748 | if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71693 | 71749 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| @@ -73427,11 +73483,13 @@ | ||
| 73427 | 73483 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 73428 | 73484 | assert( pExpr->u.zToken!=0 ); |
| 73429 | 73485 | assert( pExpr->u.zToken[0]!=0 ); |
| 73430 | 73486 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); |
| 73431 | 73487 | if( pExpr->u.zToken[1]!=0 ){ |
| 73432 | - sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, P4_TRANSIENT); | |
| 73488 | + assert( pExpr->u.zToken[0]=='?' | |
| 73489 | + || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); | |
| 73490 | + sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); | |
| 73433 | 73491 | } |
| 73434 | 73492 | break; |
| 73435 | 73493 | } |
| 73436 | 73494 | case TK_REGISTER: { |
| 73437 | 73495 | inReg = pExpr->iTable; |
| @@ -77398,13 +77456,11 @@ | ||
| 77398 | 77456 | #endif |
| 77399 | 77457 | assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ |
| 77400 | 77458 | /* A minimum of one cursor is required if autoincrement is used |
| 77401 | 77459 | * See ticket [a696379c1f08866] */ |
| 77402 | 77460 | if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; |
| 77403 | - sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem, | |
| 77404 | - pParse->nTab, pParse->nMaxArg, pParse->explain, | |
| 77405 | - pParse->isMultiWrite && pParse->mayAbort); | |
| 77461 | + sqlite3VdbeMakeReady(v, pParse); | |
| 77406 | 77462 | pParse->rc = SQLITE_DONE; |
| 77407 | 77463 | pParse->colNamesSet = 0; |
| 77408 | 77464 | }else{ |
| 77409 | 77465 | pParse->rc = SQLITE_ERROR; |
| 77410 | 77466 | } |
| @@ -81817,10 +81873,11 @@ | ||
| 81817 | 81873 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 81818 | 81874 | if( IsVirtual(pTab) ){ |
| 81819 | 81875 | const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); |
| 81820 | 81876 | sqlite3VtabMakeWritable(pParse, pTab); |
| 81821 | 81877 | sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); |
| 81878 | + sqlite3VdbeChangeP5(v, OE_Abort); | |
| 81822 | 81879 | sqlite3MayAbort(pParse); |
| 81823 | 81880 | }else |
| 81824 | 81881 | #endif |
| 81825 | 81882 | { |
| 81826 | 81883 | int count = (pParse->nested==0); /* True to count changes */ |
| @@ -87937,14 +87994,10 @@ | ||
| 87937 | 87994 | ** |
| 87938 | 87995 | ************************************************************************* |
| 87939 | 87996 | ** This file contains code used to implement the PRAGMA command. |
| 87940 | 87997 | */ |
| 87941 | 87998 | |
| 87942 | -/* Ignore this whole file if pragmas are disabled | |
| 87943 | -*/ | |
| 87944 | -#if !defined(SQLITE_OMIT_PRAGMA) | |
| 87945 | - | |
| 87946 | 87999 | /* |
| 87947 | 88000 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| 87948 | 88001 | ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or |
| 87949 | 88002 | ** unrecognized string argument. |
| 87950 | 88003 | ** |
| @@ -87976,10 +88029,16 @@ | ||
| 87976 | 88029 | ** Interpret the given string as a boolean value. |
| 87977 | 88030 | */ |
| 87978 | 88031 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ |
| 87979 | 88032 | return getSafetyLevel(z)&1; |
| 87980 | 88033 | } |
| 88034 | + | |
| 88035 | +/* The sqlite3GetBoolean() function is used by other modules but the | |
| 88036 | +** remainder of this file is specific to PRAGMA processing. So omit | |
| 88037 | +** the rest of the file if PRAGMAs are omitted from the build. | |
| 88038 | +*/ | |
| 88039 | +#if !defined(SQLITE_OMIT_PRAGMA) | |
| 87981 | 88040 | |
| 87982 | 88041 | /* |
| 87983 | 88042 | ** Interpret the given string as a locking mode value. |
| 87984 | 88043 | */ |
| 87985 | 88044 | static int getLockingMode(const char *z){ |
| @@ -97682,15 +97741,15 @@ | ||
| 97682 | 97741 | sqlite3DbFree(db, zErr); |
| 97683 | 97742 | } |
| 97684 | 97743 | |
| 97685 | 97744 | return rc; |
| 97686 | 97745 | } |
| 97687 | - | |
| 97688 | 97746 | /* |
| 97689 | -** Add the virtual table pVTab to the array sqlite3.aVTrans[]. | |
| 97747 | +** Grow the db->aVTrans[] array so that there is room for at least one | |
| 97748 | +** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. | |
| 97690 | 97749 | */ |
| 97691 | -static int addToVTrans(sqlite3 *db, VTable *pVTab){ | |
| 97750 | +static int growVTrans(sqlite3 *db){ | |
| 97692 | 97751 | const int ARRAY_INCR = 5; |
| 97693 | 97752 | |
| 97694 | 97753 | /* Grow the sqlite3.aVTrans array if required */ |
| 97695 | 97754 | if( (db->nVTrans%ARRAY_INCR)==0 ){ |
| 97696 | 97755 | VTable **aVTrans; |
| @@ -97701,14 +97760,21 @@ | ||
| 97701 | 97760 | } |
| 97702 | 97761 | memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); |
| 97703 | 97762 | db->aVTrans = aVTrans; |
| 97704 | 97763 | } |
| 97705 | 97764 | |
| 97765 | + return SQLITE_OK; | |
| 97766 | +} | |
| 97767 | + | |
| 97768 | +/* | |
| 97769 | +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should | |
| 97770 | +** have already been reserved using growVTrans(). | |
| 97771 | +*/ | |
| 97772 | +static void addToVTrans(sqlite3 *db, VTable *pVTab){ | |
| 97706 | 97773 | /* Add pVtab to the end of sqlite3.aVTrans */ |
| 97707 | 97774 | db->aVTrans[db->nVTrans++] = pVTab; |
| 97708 | 97775 | sqlite3VtabLock(pVTab); |
| 97709 | - return SQLITE_OK; | |
| 97710 | 97776 | } |
| 97711 | 97777 | |
| 97712 | 97778 | /* |
| 97713 | 97779 | ** This function is invoked by the vdbe to call the xCreate method |
| 97714 | 97780 | ** of the virtual table named zTab in database iDb. |
| @@ -97742,11 +97808,14 @@ | ||
| 97742 | 97808 | } |
| 97743 | 97809 | |
| 97744 | 97810 | /* Justification of ALWAYS(): The xConstructor method is required to |
| 97745 | 97811 | ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ |
| 97746 | 97812 | if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ |
| 97747 | - rc = addToVTrans(db, sqlite3GetVTable(db, pTab)); | |
| 97813 | + rc = growVTrans(db); | |
| 97814 | + if( rc==SQLITE_OK ){ | |
| 97815 | + addToVTrans(db, sqlite3GetVTable(db, pTab)); | |
| 97816 | + } | |
| 97748 | 97817 | } |
| 97749 | 97818 | |
| 97750 | 97819 | return rc; |
| 97751 | 97820 | } |
| 97752 | 97821 | |
| @@ -97858,10 +97927,11 @@ | ||
| 97858 | 97927 | if( p ){ |
| 97859 | 97928 | int (*x)(sqlite3_vtab *); |
| 97860 | 97929 | x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); |
| 97861 | 97930 | if( x ) x(p); |
| 97862 | 97931 | } |
| 97932 | + pVTab->iSavepoint = 0; | |
| 97863 | 97933 | sqlite3VtabUnlock(pVTab); |
| 97864 | 97934 | } |
| 97865 | 97935 | sqlite3DbFree(db, db->aVTrans); |
| 97866 | 97936 | db->nVTrans = 0; |
| 97867 | 97937 | db->aVTrans = 0; |
| @@ -97947,14 +98017,18 @@ | ||
| 97947 | 98017 | if( db->aVTrans[i]==pVTab ){ |
| 97948 | 98018 | return SQLITE_OK; |
| 97949 | 98019 | } |
| 97950 | 98020 | } |
| 97951 | 98021 | |
| 97952 | - /* Invoke the xBegin method */ | |
| 97953 | - rc = pModule->xBegin(pVTab->pVtab); | |
| 98022 | + /* Invoke the xBegin method. If successful, add the vtab to the | |
| 98023 | + ** sqlite3.aVTrans[] array. */ | |
| 98024 | + rc = growVTrans(db); | |
| 97954 | 98025 | if( rc==SQLITE_OK ){ |
| 97955 | - rc = addToVTrans(db, pVTab); | |
| 98026 | + rc = pModule->xBegin(pVTab->pVtab); | |
| 98027 | + if( rc==SQLITE_OK ){ | |
| 98028 | + addToVTrans(db, pVTab); | |
| 98029 | + } | |
| 97956 | 98030 | } |
| 97957 | 98031 | } |
| 97958 | 98032 | return rc; |
| 97959 | 98033 | } |
| 97960 | 98034 | |
| @@ -97975,28 +98049,33 @@ | ||
| 97975 | 98049 | */ |
| 97976 | 98050 | SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ |
| 97977 | 98051 | int rc = SQLITE_OK; |
| 97978 | 98052 | |
| 97979 | 98053 | assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); |
| 98054 | + assert( iSavepoint>=0 ); | |
| 97980 | 98055 | if( db->aVTrans ){ |
| 97981 | 98056 | int i; |
| 97982 | 98057 | for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ |
| 97983 | - const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule; | |
| 98058 | + VTable *pVTab = db->aVTrans[i]; | |
| 98059 | + const sqlite3_module *pMod = pVTab->pMod->pModule; | |
| 97984 | 98060 | if( pMod->iVersion>=2 ){ |
| 97985 | 98061 | int (*xMethod)(sqlite3_vtab *, int); |
| 97986 | 98062 | switch( op ){ |
| 97987 | 98063 | case SAVEPOINT_BEGIN: |
| 97988 | 98064 | xMethod = pMod->xSavepoint; |
| 98065 | + pVTab->iSavepoint = iSavepoint+1; | |
| 97989 | 98066 | break; |
| 97990 | 98067 | case SAVEPOINT_ROLLBACK: |
| 97991 | 98068 | xMethod = pMod->xRollbackTo; |
| 97992 | 98069 | break; |
| 97993 | 98070 | default: |
| 97994 | 98071 | xMethod = pMod->xRelease; |
| 97995 | 98072 | break; |
| 97996 | 98073 | } |
| 97997 | - if( xMethod ) rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); | |
| 98074 | + if( xMethod && pVTab->iSavepoint>iSavepoint ){ | |
| 98075 | + rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); | |
| 98076 | + } | |
| 97998 | 98077 | } |
| 97999 | 98078 | } |
| 98000 | 98079 | } |
| 98001 | 98080 | return rc; |
| 98002 | 98081 | } |
| @@ -107254,13 +107333,12 @@ | ||
| 107254 | 107333 | return SQLITE_NOMEM; |
| 107255 | 107334 | } |
| 107256 | 107335 | assert( pParse->pNewTable==0 ); |
| 107257 | 107336 | assert( pParse->pNewTrigger==0 ); |
| 107258 | 107337 | assert( pParse->nVar==0 ); |
| 107259 | - assert( pParse->nVarExpr==0 ); | |
| 107260 | - assert( pParse->nVarExprAlloc==0 ); | |
| 107261 | - assert( pParse->apVarExpr==0 ); | |
| 107338 | + assert( pParse->nzVar==0 ); | |
| 107339 | + assert( pParse->azVar==0 ); | |
| 107262 | 107340 | enableLookaside = db->lookaside.bEnabled; |
| 107263 | 107341 | if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; |
| 107264 | 107342 | while( !db->mallocFailed && zSql[i]!=0 ){ |
| 107265 | 107343 | assert( i>=0 ); |
| 107266 | 107344 | pParse->sLastToken.z = &zSql[i]; |
| @@ -107350,11 +107428,12 @@ | ||
| 107350 | 107428 | */ |
| 107351 | 107429 | sqlite3DeleteTable(db, pParse->pNewTable); |
| 107352 | 107430 | } |
| 107353 | 107431 | |
| 107354 | 107432 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); |
| 107355 | - sqlite3DbFree(db, pParse->apVarExpr); | |
| 107433 | + for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); | |
| 107434 | + sqlite3DbFree(db, pParse->azVar); | |
| 107356 | 107435 | sqlite3DbFree(db, pParse->aAlias); |
| 107357 | 107436 | while( pParse->pAinc ){ |
| 107358 | 107437 | AutoincInfo *p = pParse->pAinc; |
| 107359 | 107438 | pParse->pAinc = p->pNext; |
| 107360 | 107439 | sqlite3DbFree(db, p); |
| @@ -109682,13 +109761,13 @@ | ||
| 109682 | 109761 | }else{ |
| 109683 | 109762 | struct OpenMode { |
| 109684 | 109763 | const char *z; |
| 109685 | 109764 | int mode; |
| 109686 | 109765 | } *aMode = 0; |
| 109687 | - char *zModeType; | |
| 109688 | - int mask; | |
| 109689 | - int limit; | |
| 109766 | + char *zModeType = 0; | |
| 109767 | + int mask = 0; | |
| 109768 | + int limit = 0; | |
| 109690 | 109769 | |
| 109691 | 109770 | if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ |
| 109692 | 109771 | static struct OpenMode aCacheMode[] = { |
| 109693 | 109772 | { "shared", SQLITE_OPEN_SHAREDCACHE }, |
| 109694 | 109773 | { "private", SQLITE_OPEN_PRIVATECACHE }, |
| @@ -111676,15 +111755,35 @@ | ||
| 111676 | 111755 | */ |
| 111677 | 111756 | typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ |
| 111678 | 111757 | typedef short int i16; /* 2-byte (or larger) signed integer */ |
| 111679 | 111758 | typedef unsigned int u32; /* 4-byte unsigned integer */ |
| 111680 | 111759 | typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ |
| 111760 | + | |
| 111681 | 111761 | /* |
| 111682 | 111762 | ** Macro used to suppress compiler warnings for unused parameters. |
| 111683 | 111763 | */ |
| 111684 | 111764 | #define UNUSED_PARAMETER(x) (void)(x) |
| 111765 | + | |
| 111766 | +/* | |
| 111767 | +** Activate assert() only if SQLITE_TEST is enabled. | |
| 111768 | +*/ | |
| 111769 | +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) | |
| 111770 | +# define NDEBUG 1 | |
| 111771 | +#endif | |
| 111772 | + | |
| 111773 | +/* | |
| 111774 | +** The TESTONLY macro is used to enclose variable declarations or | |
| 111775 | +** other bits of code that are needed to support the arguments | |
| 111776 | +** within testcase() and assert() macros. | |
| 111777 | +*/ | |
| 111778 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) | |
| 111779 | +# define TESTONLY(X) X | |
| 111780 | +#else | |
| 111781 | +# define TESTONLY(X) | |
| 111685 | 111782 | #endif |
| 111783 | + | |
| 111784 | +#endif /* SQLITE_AMALGAMATION */ | |
| 111686 | 111785 | |
| 111687 | 111786 | typedef struct Fts3Table Fts3Table; |
| 111688 | 111787 | typedef struct Fts3Cursor Fts3Cursor; |
| 111689 | 111788 | typedef struct Fts3Expr Fts3Expr; |
| 111690 | 111789 | typedef struct Fts3Phrase Fts3Phrase; |
| @@ -111735,10 +111834,20 @@ | ||
| 111735 | 111834 | */ |
| 111736 | 111835 | int nMaxPendingData; |
| 111737 | 111836 | int nPendingData; |
| 111738 | 111837 | sqlite_int64 iPrevDocid; |
| 111739 | 111838 | Fts3Hash pendingTerms; |
| 111839 | + | |
| 111840 | +#if defined(SQLITE_DEBUG) | |
| 111841 | + /* State variables used for validating that the transaction control | |
| 111842 | + ** methods of the virtual table are called at appropriate times. These | |
| 111843 | + ** values do not contribution to the FTS computation; they are used for | |
| 111844 | + ** verifying the SQLite core. | |
| 111845 | + */ | |
| 111846 | + int inTransaction; /* True after xBegin but before xCommit/xRollback */ | |
| 111847 | + int mxSavepoint; /* Largest valid xSavepoint integer */ | |
| 111848 | +#endif | |
| 111740 | 111849 | }; |
| 111741 | 111850 | |
| 111742 | 111851 | /* |
| 111743 | 111852 | ** When the core wants to read from the virtual table, it creates a |
| 111744 | 111853 | ** virtual table cursor (an instance of the following structure) using |
| @@ -112645,10 +112754,12 @@ | ||
| 112645 | 112754 | p->pTokenizer = pTokenizer; |
| 112646 | 112755 | p->nNodeSize = 1000; |
| 112647 | 112756 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 112648 | 112757 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 112649 | 112758 | p->bHasStat = isFts4; |
| 112759 | + TESTONLY( p->inTransaction = -1 ); | |
| 112760 | + TESTONLY( p->mxSavepoint = -1 ); | |
| 112650 | 112761 | fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); |
| 112651 | 112762 | |
| 112652 | 112763 | /* Fill in the zName and zDb fields of the vtab structure. */ |
| 112653 | 112764 | zCsr = (char *)&p->azColumn[nCol]; |
| 112654 | 112765 | p->zName = zCsr; |
| @@ -114942,11 +115053,15 @@ | ||
| 114942 | 115053 | /* |
| 114943 | 115054 | ** Implementation of xBegin() method. This is a no-op. |
| 114944 | 115055 | */ |
| 114945 | 115056 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 114946 | 115057 | UNUSED_PARAMETER(pVtab); |
| 114947 | - assert( ((Fts3Table *)pVtab)->nPendingData==0 ); | |
| 115058 | + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); | |
| 115059 | + assert( p->nPendingData==0 ); | |
| 115060 | + assert( p->inTransaction!=1 ); | |
| 115061 | + TESTONLY( p->inTransaction = 1 ); | |
| 115062 | + TESTONLY( p->mxSavepoint = -1; ); | |
| 114948 | 115063 | return SQLITE_OK; |
| 114949 | 115064 | } |
| 114950 | 115065 | |
| 114951 | 115066 | /* |
| 114952 | 115067 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| @@ -114953,20 +115068,28 @@ | ||
| 114953 | 115068 | ** the pending-terms hash-table have already been flushed into the database |
| 114954 | 115069 | ** by fts3SyncMethod(). |
| 114955 | 115070 | */ |
| 114956 | 115071 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 114957 | 115072 | UNUSED_PARAMETER(pVtab); |
| 114958 | - assert( ((Fts3Table *)pVtab)->nPendingData==0 ); | |
| 115073 | + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); | |
| 115074 | + assert( p->nPendingData==0 ); | |
| 115075 | + assert( p->inTransaction!=0 ); | |
| 115076 | + TESTONLY( p->inTransaction = 0 ); | |
| 115077 | + TESTONLY( p->mxSavepoint = -1; ); | |
| 114959 | 115078 | return SQLITE_OK; |
| 114960 | 115079 | } |
| 114961 | 115080 | |
| 114962 | 115081 | /* |
| 114963 | 115082 | ** Implementation of xRollback(). Discard the contents of the pending-terms |
| 114964 | 115083 | ** hash-table. Any changes made to the database are reverted by SQLite. |
| 114965 | 115084 | */ |
| 114966 | 115085 | static int fts3RollbackMethod(sqlite3_vtab *pVtab){ |
| 114967 | - sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); | |
| 115086 | + Fts3Table *p = (Fts3Table*)pVtab; | |
| 115087 | + sqlite3Fts3PendingTermsClear(p); | |
| 115088 | + assert( p->inTransaction!=0 ); | |
| 115089 | + TESTONLY( p->inTransaction = 0 ); | |
| 115090 | + TESTONLY( p->mxSavepoint = -1; ); | |
| 114968 | 115091 | return SQLITE_OK; |
| 114969 | 115092 | } |
| 114970 | 115093 | |
| 114971 | 115094 | /* |
| 114972 | 115095 | ** Load the doclist associated with expression pExpr to pExpr->aDoclist. |
| @@ -115318,17 +115441,33 @@ | ||
| 115318 | 115441 | ); |
| 115319 | 115442 | return rc; |
| 115320 | 115443 | } |
| 115321 | 115444 | |
| 115322 | 115445 | static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115323 | - return sqlite3Fts3PendingTermsFlush((Fts3Table *)pVtab); | |
| 115446 | + Fts3Table *p = (Fts3Table*)pVtab; | |
| 115447 | + UNUSED_PARAMETER(iSavepoint); | |
| 115448 | + assert( p->inTransaction ); | |
| 115449 | + assert( p->mxSavepoint < iSavepoint ); | |
| 115450 | + TESTONLY( p->mxSavepoint = iSavepoint ); | |
| 115451 | + return sqlite3Fts3PendingTermsFlush(p); | |
| 115324 | 115452 | } |
| 115325 | 115453 | static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115454 | + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); | |
| 115455 | + UNUSED_PARAMETER(iSavepoint); | |
| 115456 | + UNUSED_PARAMETER(pVtab); | |
| 115457 | + assert( p->inTransaction ); | |
| 115458 | + assert( p->mxSavepoint >= iSavepoint ); | |
| 115459 | + TESTONLY( p->mxSavepoint = iSavepoint-1 ); | |
| 115326 | 115460 | return SQLITE_OK; |
| 115327 | 115461 | } |
| 115328 | 115462 | static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115329 | - sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); | |
| 115463 | + Fts3Table *p = (Fts3Table*)pVtab; | |
| 115464 | + UNUSED_PARAMETER(iSavepoint); | |
| 115465 | + assert( p->inTransaction ); | |
| 115466 | + assert( p->mxSavepoint >= iSavepoint ); | |
| 115467 | + TESTONLY( p->mxSavepoint = iSavepoint ); | |
| 115468 | + sqlite3Fts3PendingTermsClear(p); | |
| 115330 | 115469 | return SQLITE_OK; |
| 115331 | 115470 | } |
| 115332 | 115471 | |
| 115333 | 115472 | static const sqlite3_module fts3Module = { |
| 115334 | 115473 | /* iVersion */ 2, |
| @@ -115823,10 +115962,11 @@ | ||
| 115823 | 115962 | Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; |
| 115824 | 115963 | int rc; |
| 115825 | 115964 | int isScan; |
| 115826 | 115965 | |
| 115827 | 115966 | UNUSED_PARAMETER(nVal); |
| 115967 | + UNUSED_PARAMETER(idxStr); | |
| 115828 | 115968 | |
| 115829 | 115969 | assert( idxStr==0 ); |
| 115830 | 115970 | assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 |
| 115831 | 115971 | || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT |
| 115832 | 115972 | || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) |
| @@ -115940,11 +116080,14 @@ | ||
| 115940 | 116080 | 0, /* xBegin */ |
| 115941 | 116081 | 0, /* xSync */ |
| 115942 | 116082 | 0, /* xCommit */ |
| 115943 | 116083 | 0, /* xRollback */ |
| 115944 | 116084 | 0, /* xFindFunction */ |
| 115945 | - 0 /* xRename */ | |
| 116085 | + 0, /* xRename */ | |
| 116086 | + 0, /* xSavepoint */ | |
| 116087 | + 0, /* xRelease */ | |
| 116088 | + 0 /* xRollbackTo */ | |
| 115946 | 116089 | }; |
| 115947 | 116090 | int rc; /* Return code */ |
| 115948 | 116091 | |
| 115949 | 116092 | rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); |
| 115950 | 116093 | return rc; |
| @@ -125919,11 +126062,11 @@ | ||
| 125919 | 126062 | } |
| 125920 | 126063 | return rc; |
| 125921 | 126064 | } |
| 125922 | 126065 | |
| 125923 | 126066 | static sqlite3_module rtreeModule = { |
| 125924 | - 0, /* iVersion */ | |
| 126067 | + 0, /* iVersion */ | |
| 125925 | 126068 | rtreeCreate, /* xCreate - create a table */ |
| 125926 | 126069 | rtreeConnect, /* xConnect - connect to an existing table */ |
| 125927 | 126070 | rtreeBestIndex, /* xBestIndex - Determine search strategy */ |
| 125928 | 126071 | rtreeDisconnect, /* xDisconnect - Disconnect from a table */ |
| 125929 | 126072 | rtreeDestroy, /* xDestroy - Drop a table */ |
| @@ -125938,11 +126081,14 @@ | ||
| 125938 | 126081 | 0, /* xBegin - begin transaction */ |
| 125939 | 126082 | 0, /* xSync - sync transaction */ |
| 125940 | 126083 | 0, /* xCommit - commit transaction */ |
| 125941 | 126084 | 0, /* xRollback - rollback transaction */ |
| 125942 | 126085 | 0, /* xFindFunction - function overloading */ |
| 125943 | - rtreeRename /* xRename - rename the table */ | |
| 126086 | + rtreeRename, /* xRename - rename the table */ | |
| 126087 | + 0, /* xSavepoint */ | |
| 126088 | + 0, /* xRelease */ | |
| 126089 | + 0 /* xRollbackTo */ | |
| 125944 | 126090 | }; |
| 125945 | 126091 | |
| 125946 | 126092 | static int rtreeSqlInit( |
| 125947 | 126093 | Rtree *pRtree, |
| 125948 | 126094 | sqlite3 *db, |
| 125949 | 126095 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -650,11 +650,11 @@ | |
| 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | */ |
| 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | #define SQLITE_SOURCE_ID "2011-05-18 03:02:10 186d7ff1d9804d508e472e4939608bf2be67bdc2" |
| 656 | |
| 657 | /* |
| 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | ** |
| @@ -1000,10 +1000,12 @@ | |
| 1000 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1001 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1002 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1003 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1004 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1005 | |
| 1006 | /* |
| 1007 | ** CAPI3REF: Flags For File Open Operations |
| 1008 | ** |
| 1009 | ** These bit values are intended for use in the |
| @@ -1305,15 +1307,15 @@ | |
| 1305 | */ |
| 1306 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 1307 | |
| 1308 | /* |
| 1309 | ** CAPI3REF: OS Interface Object |
| 1310 | ** KEYWORDS: VFS VFSes |
| 1311 | ** |
| 1312 | ** An instance of the sqlite3_vfs object defines the interface between |
| 1313 | ** the SQLite core and the underlying operating system. The "vfs" |
| 1314 | ** in the name of the object stands for "virtual file system". |
| 1315 | ** |
| 1316 | ** The value of the iVersion field is initially 1 but may be larger in |
| 1317 | ** future versions of SQLite. Additional fields may be appended to this |
| 1318 | ** object when the iVersion value is increased. Note that the structure |
| 1319 | ** of the sqlite3_vfs object changes in the transaction between |
| @@ -8494,19 +8496,20 @@ | |
| 8494 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 8495 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); |
| 8496 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| 8497 | SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); |
| 8498 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); |
| 8499 | SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); |
| 8500 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 8501 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 8502 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 8503 | #ifdef SQLITE_DEBUG |
| 8504 | SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); |
| 8505 | SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); |
| 8506 | #endif |
| 8507 | SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); |
| 8508 | SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); |
| 8509 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); |
| 8510 | SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); |
| 8511 | SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); |
| 8512 | SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); |
| @@ -9832,10 +9835,11 @@ | |
| 9832 | sqlite3 *db; /* Database connection associated with this table */ |
| 9833 | Module *pMod; /* Pointer to module implementation */ |
| 9834 | sqlite3_vtab *pVtab; /* Pointer to vtab instance */ |
| 9835 | int nRef; /* Number of pointers to this structure */ |
| 9836 | u8 bConstraint; /* True if constraints are supported */ |
| 9837 | VTable *pNext; /* Next in linked list (see above) */ |
| 9838 | }; |
| 9839 | |
| 9840 | /* |
| 9841 | ** Each SQL table is represented in memory by an instance of the |
| @@ -10826,13 +10830,12 @@ | |
| 10826 | |
| 10827 | /* Above is constant between recursions. Below is reset before and after |
| 10828 | ** each recursion */ |
| 10829 | |
| 10830 | int nVar; /* Number of '?' variables seen in the SQL so far */ |
| 10831 | int nVarExpr; /* Number of used slots in apVarExpr[] */ |
| 10832 | int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */ |
| 10833 | Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */ |
| 10834 | Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ |
| 10835 | int nAlias; /* Number of aliased result set columns */ |
| 10836 | int nAliasAlloc; /* Number of allocated slots for aAlias[] */ |
| 10837 | int *aAlias; /* Register used to hold aliased result */ |
| 10838 | u8 explain; /* True if the EXPLAIN flag is found on the query */ |
| @@ -12761,15 +12764,15 @@ | |
| 12761 | Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ |
| 12762 | VdbeCursor **apCsr; /* One element of this array for each open cursor */ |
| 12763 | Mem *aVar; /* Values for the OP_Variable opcode. */ |
| 12764 | char **azVar; /* Name of variables */ |
| 12765 | ynVar nVar; /* Number of entries in aVar[] */ |
| 12766 | u32 cacheCtr; /* VdbeCursor row cache generation counter */ |
| 12767 | int pc; /* The program counter */ |
| 12768 | int rc; /* Value to return */ |
| 12769 | u8 errorAction; /* Recovery action to do in case of an error */ |
| 12770 | u8 okVar; /* True if azVar[] has been initialized */ |
| 12771 | u8 explain; /* True if EXPLAIN present on SQL command */ |
| 12772 | u8 changeCntOn; /* True to update the change-counter */ |
| 12773 | u8 expired; /* True if the VM needs to be recompiled */ |
| 12774 | u8 runOnlyOnce; /* Automatically expire on reset */ |
| 12775 | u8 minWriteFileFormat; /* Minimum file format for writable database files */ |
| @@ -27963,11 +27966,12 @@ | |
| 27963 | unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ |
| 27964 | sqlite3_mutex *mutex; /* Mutex to access this object */ |
| 27965 | char *zFilename; /* Name of the mmapped file */ |
| 27966 | int h; /* Open file descriptor */ |
| 27967 | int szRegion; /* Size of shared-memory regions */ |
| 27968 | int nRegion; /* Size of array apRegion */ |
| 27969 | char **apRegion; /* Array of mapped shared-memory regions */ |
| 27970 | int nRef; /* Number of unixShm objects pointing to this */ |
| 27971 | unixShm *pFirst; /* All unixShm objects pointing to this */ |
| 27972 | #ifdef SQLITE_DEBUG |
| 27973 | u8 exclMask; /* Mask of exclusive locks held */ |
| @@ -28210,12 +28214,21 @@ | |
| 28210 | |
| 28211 | if( pInode->bProcessLock==0 ){ |
| 28212 | pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, |
| 28213 | (sStat.st_mode & 0777)); |
| 28214 | if( pShmNode->h<0 ){ |
| 28215 | rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 28216 | goto shm_open_err; |
| 28217 | } |
| 28218 | |
| 28219 | /* Check to see if another process is holding the dead-man switch. |
| 28220 | ** If not, truncate the file to zero length. |
| 28221 | */ |
| @@ -28350,11 +28363,12 @@ | |
| 28350 | } |
| 28351 | pShmNode->apRegion = apNew; |
| 28352 | while(pShmNode->nRegion<=iRegion){ |
| 28353 | void *pMem; |
| 28354 | if( pShmNode->h>=0 ){ |
| 28355 | pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, |
| 28356 | MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 28357 | ); |
| 28358 | if( pMem==MAP_FAILED ){ |
| 28359 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| 28360 | goto shmpage_out; |
| @@ -28376,10 +28390,11 @@ | |
| 28376 | if( pShmNode->nRegion>iRegion ){ |
| 28377 | *pp = pShmNode->apRegion[iRegion]; |
| 28378 | }else{ |
| 28379 | *pp = 0; |
| 28380 | } |
| 28381 | sqlite3_mutex_leave(pShmNode->mutex); |
| 28382 | return rc; |
| 28383 | } |
| 28384 | |
| 28385 | /* |
| @@ -34873,10 +34888,17 @@ | |
| 34873 | if( !pPg ){ |
| 34874 | for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
| 34875 | } |
| 34876 | if( pPg ){ |
| 34877 | int rc; |
| 34878 | rc = pCache->xStress(pCache->pStress, pPg); |
| 34879 | if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
| 34880 | return rc; |
| 34881 | } |
| 34882 | } |
| @@ -42472,15 +42494,25 @@ | |
| 42472 | */ |
| 42473 | sqlite3BackupRestart(pPager->pBackup); |
| 42474 | }else{ |
| 42475 | if( pagerUseWal(pPager) ){ |
| 42476 | PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); |
| 42477 | if( pList ){ |
| 42478 | rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, |
| 42479 | (pPager->fullSync ? pPager->syncFlags : 0) |
| 42480 | ); |
| 42481 | } |
| 42482 | if( rc==SQLITE_OK ){ |
| 42483 | sqlite3PcacheCleanAll(pPager->pPCache); |
| 42484 | } |
| 42485 | }else{ |
| 42486 | /* The following block updates the change-counter. Exactly how it |
| @@ -43967,11 +43999,11 @@ | |
| 43967 | u32 szPage; /* Database page size */ |
| 43968 | i16 readLock; /* Which read lock is being held. -1 for none */ |
| 43969 | u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ |
| 43970 | u8 writeLock; /* True if in a write transaction */ |
| 43971 | u8 ckptLock; /* True if holding a checkpoint lock */ |
| 43972 | u8 readOnly; /* True if the WAL file is open read-only */ |
| 43973 | WalIndexHdr hdr; /* Wal-index header for current transaction */ |
| 43974 | const char *zWalName; /* Name of WAL file */ |
| 43975 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 43976 | #ifdef SQLITE_DEBUG |
| 43977 | u8 lockError; /* True if a locking error has occurred */ |
| @@ -43983,10 +44015,17 @@ | |
| 43983 | */ |
| 43984 | #define WAL_NORMAL_MODE 0 |
| 43985 | #define WAL_EXCLUSIVE_MODE 1 |
| 43986 | #define WAL_HEAPMEMORY_MODE 2 |
| 43987 | |
| 43988 | /* |
| 43989 | ** Each page of the wal-index mapping contains a hash-table made up of |
| 43990 | ** an array of HASHTABLE_NSLOT elements of the following type. |
| 43991 | */ |
| 43992 | typedef u16 ht_slot; |
| @@ -44076,10 +44115,14 @@ | |
| 44076 | if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; |
| 44077 | }else{ |
| 44078 | rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, |
| 44079 | pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] |
| 44080 | ); |
| 44081 | } |
| 44082 | } |
| 44083 | |
| 44084 | *ppPage = pWal->apWiData[iPage]; |
| 44085 | assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); |
| @@ -44823,11 +44866,11 @@ | |
| 44823 | |
| 44824 | /* Open file handle on the write-ahead log file. */ |
| 44825 | flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); |
| 44826 | rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); |
| 44827 | if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ |
| 44828 | pRet->readOnly = 1; |
| 44829 | } |
| 44830 | |
| 44831 | if( rc!=SQLITE_OK ){ |
| 44832 | walIndexClose(pRet, 0); |
| 44833 | sqlite3OsClose(pRet->pWalFd); |
| @@ -45464,25 +45507,32 @@ | |
| 45464 | |
| 45465 | /* If the first attempt failed, it might have been due to a race |
| 45466 | ** with a writer. So get a WRITE lock and try again. |
| 45467 | */ |
| 45468 | assert( badHdr==0 || pWal->writeLock==0 ); |
| 45469 | if( badHdr && SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ |
| 45470 | pWal->writeLock = 1; |
| 45471 | if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ |
| 45472 | badHdr = walIndexTryHdr(pWal, pChanged); |
| 45473 | if( badHdr ){ |
| 45474 | /* If the wal-index header is still malformed even while holding |
| 45475 | ** a WRITE lock, it can only mean that the header is corrupted and |
| 45476 | ** needs to be reconstructed. So run recovery to do exactly that. |
| 45477 | */ |
| 45478 | rc = walIndexRecover(pWal); |
| 45479 | *pChanged = 1; |
| 45480 | } |
| 45481 | } |
| 45482 | pWal->writeLock = 0; |
| 45483 | walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); |
| 45484 | } |
| 45485 | |
| 45486 | /* If the header is read successfully, check the version number to make |
| 45487 | ** sure the wal-index was not constructed with some future format that |
| 45488 | ** this version of SQLite cannot understand. |
| @@ -45665,11 +45715,13 @@ | |
| 45665 | mxI = i; |
| 45666 | } |
| 45667 | } |
| 45668 | /* There was once an "if" here. The extra "{" is to preserve indentation. */ |
| 45669 | { |
| 45670 | if( mxReadMark < pWal->hdr.mxFrame || mxI==0 ){ |
| 45671 | for(i=1; i<WAL_NREADER; i++){ |
| 45672 | rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45673 | if( rc==SQLITE_OK ){ |
| 45674 | mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; |
| 45675 | mxI = i; |
| @@ -45679,12 +45731,12 @@ | |
| 45679 | return rc; |
| 45680 | } |
| 45681 | } |
| 45682 | } |
| 45683 | if( mxI==0 ){ |
| 45684 | assert( rc==SQLITE_BUSY ); |
| 45685 | return WAL_RETRY; |
| 45686 | } |
| 45687 | |
| 45688 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); |
| 45689 | if( rc ){ |
| 45690 | return rc==SQLITE_BUSY ? WAL_RETRY : rc; |
| @@ -46086,14 +46138,16 @@ | |
| 46086 | ** set to a non-negative value. Log errors encountered |
| 46087 | ** during the truncation attempt. */ |
| 46088 | if( pWal->mxWalSize>=0 ){ |
| 46089 | i64 sz; |
| 46090 | int rx; |
| 46091 | rx = sqlite3OsFileSize(pWal->pWalFd, &sz); |
| 46092 | if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ |
| 46093 | rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); |
| 46094 | } |
| 46095 | if( rx ){ |
| 46096 | sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); |
| 46097 | } |
| 46098 | } |
| 46099 | |
| @@ -46320,10 +46374,11 @@ | |
| 46320 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 46321 | |
| 46322 | assert( pWal->ckptLock==0 ); |
| 46323 | assert( pWal->writeLock==0 ); |
| 46324 | |
| 46325 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 46326 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 46327 | if( rc ){ |
| 46328 | /* Usually this is SQLITE_BUSY meaning that another thread or process |
| 46329 | ** is already running a checkpoint, or maybe a recovery. But it might |
| @@ -52802,14 +52857,14 @@ | |
| 52802 | ** removes the reference to the cell from pPage. |
| 52803 | ** |
| 52804 | ** "sz" must be the number of bytes in the cell. |
| 52805 | */ |
| 52806 | static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ |
| 52807 | int i; /* Loop counter */ |
| 52808 | u32 pc; /* Offset to cell content of cell being deleted */ |
| 52809 | u8 *data; /* pPage->aData */ |
| 52810 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 52811 | int rc; /* The return code */ |
| 52812 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 52813 | |
| 52814 | if( *pRC ) return; |
| 52815 | |
| @@ -52830,13 +52885,15 @@ | |
| 52830 | rc = freeSpace(pPage, pc, sz); |
| 52831 | if( rc ){ |
| 52832 | *pRC = rc; |
| 52833 | return; |
| 52834 | } |
| 52835 | for(i=idx+1; i<pPage->nCell; i++, ptr+=2){ |
| 52836 | ptr[0] = ptr[2]; |
| 52837 | ptr[1] = ptr[3]; |
| 52838 | } |
| 52839 | pPage->nCell--; |
| 52840 | put2byte(&data[hdr+3], pPage->nCell); |
| 52841 | pPage->nFree += 2; |
| 52842 | } |
| @@ -58815,38 +58872,17 @@ | |
| 58815 | } |
| 58816 | return pBuf; |
| 58817 | } |
| 58818 | |
| 58819 | /* |
| 58820 | ** Prepare a virtual machine for execution. This involves things such |
| 58821 | ** as allocating stack space and initializing the program counter. |
| 58822 | ** After the VDBE has be prepped, it can be executed by one or more |
| 58823 | ** calls to sqlite3VdbeExec(). |
| 58824 | ** |
| 58825 | ** This is the only way to move a VDBE from VDBE_MAGIC_INIT to |
| 58826 | ** VDBE_MAGIC_RUN. |
| 58827 | ** |
| 58828 | ** This function may be called more than once on a single virtual machine. |
| 58829 | ** The first call is made while compiling the SQL statement. Subsequent |
| 58830 | ** calls are made as part of the process of resetting a statement to be |
| 58831 | ** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor |
| 58832 | ** and isExplain parameters are only passed correct values the first time |
| 58833 | ** the function is called. On subsequent calls, from sqlite3_reset(), nVar |
| 58834 | ** is passed -1 and nMem, nCursor and isExplain are all passed zero. |
| 58835 | */ |
| 58836 | SQLITE_PRIVATE void sqlite3VdbeMakeReady( |
| 58837 | Vdbe *p, /* The VDBE */ |
| 58838 | int nVar, /* Number of '?' see in the SQL statement */ |
| 58839 | int nMem, /* Number of memory cells to allocate */ |
| 58840 | int nCursor, /* Number of cursors to allocate */ |
| 58841 | int nArg, /* Maximum number of args in SubPrograms */ |
| 58842 | int isExplain, /* True if the EXPLAIN keywords is present */ |
| 58843 | int usesStmtJournal /* True to set Vdbe.usesStmtJournal */ |
| 58844 | ){ |
| 58845 | int n; |
| 58846 | sqlite3 *db = p->db; |
| 58847 | |
| 58848 | assert( p!=0 ); |
| 58849 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 58850 | |
| 58851 | /* There should be at least one opcode. |
| 58852 | */ |
| @@ -58853,10 +58889,75 @@ | |
| 58853 | assert( p->nOp>0 ); |
| 58854 | |
| 58855 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 58856 | p->magic = VDBE_MAGIC_RUN; |
| 58857 | |
| 58858 | /* For each cursor required, also allocate a memory cell. Memory |
| 58859 | ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by |
| 58860 | ** the vdbe program. Instead they are used to allocate space for |
| 58861 | ** VdbeCursor/BtCursor structures. The blob of memory associated with |
| 58862 | ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) |
| @@ -58865,95 +58966,72 @@ | |
| 58865 | ** See also: allocateCursor(). |
| 58866 | */ |
| 58867 | nMem += nCursor; |
| 58868 | |
| 58869 | /* Allocate space for memory registers, SQL variables, VDBE cursors and |
| 58870 | ** an array to marshal SQL function arguments in. This is only done the |
| 58871 | ** first time this function is called for a given VDBE, not when it is |
| 58872 | ** being called from sqlite3_reset() to reset the virtual machine. |
| 58873 | */ |
| 58874 | if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){ |
| 58875 | u8 *zCsr = (u8 *)&p->aOp[p->nOp]; /* Memory avaliable for alloation */ |
| 58876 | u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; /* First byte past available mem */ |
| 58877 | int nByte; /* How much extra memory needed */ |
| 58878 | |
| 58879 | resolveP2Values(p, &nArg); |
| 58880 | p->usesStmtJournal = (u8)usesStmtJournal; |
| 58881 | if( isExplain && nMem<10 ){ |
| 58882 | nMem = 10; |
| 58883 | } |
| 58884 | memset(zCsr, 0, zEnd-zCsr); |
| 58885 | zCsr += (zCsr - (u8*)0)&7; |
| 58886 | assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); |
| 58887 | |
| 58888 | /* Memory for registers, parameters, cursor, etc, is allocated in two |
| 58889 | ** passes. On the first pass, we try to reuse unused space at the |
| 58890 | ** end of the opcode array. If we are unable to satisfy all memory |
| 58891 | ** requirements by reusing the opcode array tail, then the second |
| 58892 | ** pass will fill in the rest using a fresh allocation. |
| 58893 | ** |
| 58894 | ** This two-pass approach that reuses as much memory as possible from |
| 58895 | ** the leftover space at the end of the opcode array can significantly |
| 58896 | ** reduce the amount of memory held by a prepared statement. |
| 58897 | */ |
| 58898 | do { |
| 58899 | nByte = 0; |
| 58900 | p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58901 | p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58902 | p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); |
| 58903 | p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); |
| 58904 | p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), |
| 58905 | &zCsr, zEnd, &nByte); |
| 58906 | if( nByte ){ |
| 58907 | p->pFree = sqlite3DbMallocZero(db, nByte); |
| 58908 | } |
| 58909 | zCsr = p->pFree; |
| 58910 | zEnd = &zCsr[nByte]; |
| 58911 | }while( nByte && !db->mallocFailed ); |
| 58912 | |
| 58913 | p->nCursor = (u16)nCursor; |
| 58914 | if( p->aVar ){ |
| 58915 | p->nVar = (ynVar)nVar; |
| 58916 | for(n=0; n<nVar; n++){ |
| 58917 | p->aVar[n].flags = MEM_Null; |
| 58918 | p->aVar[n].db = db; |
| 58919 | } |
| 58920 | } |
| 58921 | if( p->aMem ){ |
| 58922 | p->aMem--; /* aMem[] goes from 1..nMem */ |
| 58923 | p->nMem = nMem; /* not from 0..nMem-1 */ |
| 58924 | for(n=1; n<=nMem; n++){ |
| 58925 | p->aMem[n].flags = MEM_Null; |
| 58926 | p->aMem[n].db = db; |
| 58927 | } |
| 58928 | } |
| 58929 | } |
| 58930 | #ifdef SQLITE_DEBUG |
| 58931 | for(n=1; n<p->nMem; n++){ |
| 58932 | assert( p->aMem[n].db==db ); |
| 58933 | } |
| 58934 | #endif |
| 58935 | |
| 58936 | p->pc = -1; |
| 58937 | p->rc = SQLITE_OK; |
| 58938 | p->errorAction = OE_Abort; |
| 58939 | p->explain |= isExplain; |
| 58940 | p->magic = VDBE_MAGIC_RUN; |
| 58941 | p->nChange = 0; |
| 58942 | p->cacheCtr = 1; |
| 58943 | p->minWriteFileFormat = 255; |
| 58944 | p->iStatement = 0; |
| 58945 | p->nFkConstraint = 0; |
| 58946 | #ifdef VDBE_PROFILE |
| 58947 | { |
| 58948 | int i; |
| 58949 | for(i=0; i<p->nOp; i++){ |
| 58950 | p->aOp[i].cnt = 0; |
| 58951 | p->aOp[i].cycles = 0; |
| 58952 | } |
| 58953 | } |
| 58954 | #endif |
| 58955 | } |
| 58956 | |
| 58957 | /* |
| 58958 | ** Close a VDBE cursor and release all the resources that cursor |
| 58959 | ** happens to hold. |
| @@ -59626,21 +59704,15 @@ | |
| 59626 | /* If eStatementOp is non-zero, then a statement transaction needs to |
| 59627 | ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to |
| 59628 | ** do so. If this operation returns an error, and the current statement |
| 59629 | ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the |
| 59630 | ** current statement error code. |
| 59631 | ** |
| 59632 | ** Note that sqlite3VdbeCloseStatement() can only fail if eStatementOp |
| 59633 | ** is SAVEPOINT_ROLLBACK. But if p->rc==SQLITE_OK then eStatementOp |
| 59634 | ** must be SAVEPOINT_RELEASE. Hence the NEVER(p->rc==SQLITE_OK) in |
| 59635 | ** the following code. |
| 59636 | */ |
| 59637 | if( eStatementOp ){ |
| 59638 | rc = sqlite3VdbeCloseStatement(p, eStatementOp); |
| 59639 | if( rc ){ |
| 59640 | assert( eStatementOp==SAVEPOINT_ROLLBACK ); |
| 59641 | if( NEVER(p->rc==SQLITE_OK) || p->rc==SQLITE_CONSTRAINT ){ |
| 59642 | p->rc = rc; |
| 59643 | sqlite3DbFree(db, p->zErrMsg); |
| 59644 | p->zErrMsg = 0; |
| 59645 | } |
| 59646 | invalidateCursorsOnModifiedBtrees(db); |
| @@ -59829,18 +59901,20 @@ | |
| 59829 | ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with |
| 59830 | ** the database connection. |
| 59831 | */ |
| 59832 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ |
| 59833 | SubProgram *pSub, *pNext; |
| 59834 | assert( p->db==0 || p->db==db ); |
| 59835 | releaseMemArray(p->aVar, p->nVar); |
| 59836 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); |
| 59837 | for(pSub=p->pProgram; pSub; pSub=pNext){ |
| 59838 | pNext = pSub->pNext; |
| 59839 | vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); |
| 59840 | sqlite3DbFree(db, pSub); |
| 59841 | } |
| 59842 | vdbeFreeOpArray(db, p->aOp, p->nOp); |
| 59843 | sqlite3DbFree(db, p->aLabel); |
| 59844 | sqlite3DbFree(db, p->aColName); |
| 59845 | sqlite3DbFree(db, p->zSql); |
| 59846 | sqlite3DbFree(db, p->pFree); |
| @@ -60282,11 +60356,11 @@ | |
| 60282 | u32 serial_type; |
| 60283 | |
| 60284 | idx += getVarint32(&aKey[idx], serial_type); |
| 60285 | pMem->enc = pKeyInfo->enc; |
| 60286 | pMem->db = pKeyInfo->db; |
| 60287 | pMem->flags = 0; |
| 60288 | pMem->zMalloc = 0; |
| 60289 | d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); |
| 60290 | pMem++; |
| 60291 | u++; |
| 60292 | } |
| @@ -60297,10 +60371,11 @@ | |
| 60297 | |
| 60298 | /* |
| 60299 | ** This routine destroys a UnpackedRecord object. |
| 60300 | */ |
| 60301 | SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ |
| 60302 | int i; |
| 60303 | Mem *pMem; |
| 60304 | |
| 60305 | assert( p!=0 ); |
| 60306 | assert( p->flags & UNPACKED_NEED_DESTROY ); |
| @@ -60310,10 +60385,11 @@ | |
| 60310 | ** strings and blobs static. And none of the elements are |
| 60311 | ** ever transformed, so there is never anything to delete. |
| 60312 | */ |
| 60313 | if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); |
| 60314 | } |
| 60315 | if( p->flags & UNPACKED_NEED_FREE ){ |
| 60316 | sqlite3DbFree(p->pKeyInfo->db, p); |
| 60317 | } |
| 60318 | } |
| 60319 | |
| @@ -60745,11 +60821,11 @@ | |
| 60745 | rc = SQLITE_OK; |
| 60746 | }else{ |
| 60747 | Vdbe *v = (Vdbe*)pStmt; |
| 60748 | sqlite3_mutex_enter(v->db->mutex); |
| 60749 | rc = sqlite3VdbeReset(v); |
| 60750 | sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0); |
| 60751 | assert( (rc & (v->db->errMask))==rc ); |
| 60752 | rc = sqlite3ApiExit(v->db, rc); |
| 60753 | sqlite3_mutex_leave(v->db->mutex); |
| 60754 | } |
| 60755 | return rc; |
| @@ -61810,48 +61886,21 @@ | |
| 61810 | SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ |
| 61811 | Vdbe *p = (Vdbe*)pStmt; |
| 61812 | return p ? p->nVar : 0; |
| 61813 | } |
| 61814 | |
| 61815 | /* |
| 61816 | ** Create a mapping from variable numbers to variable names |
| 61817 | ** in the Vdbe.azVar[] array, if such a mapping does not already |
| 61818 | ** exist. |
| 61819 | */ |
| 61820 | static void createVarMap(Vdbe *p){ |
| 61821 | if( !p->okVar ){ |
| 61822 | int j; |
| 61823 | Op *pOp; |
| 61824 | sqlite3_mutex_enter(p->db->mutex); |
| 61825 | /* The race condition here is harmless. If two threads call this |
| 61826 | ** routine on the same Vdbe at the same time, they both might end |
| 61827 | ** up initializing the Vdbe.azVar[] array. That is a little extra |
| 61828 | ** work but it results in the same answer. |
| 61829 | */ |
| 61830 | for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){ |
| 61831 | if( pOp->opcode==OP_Variable ){ |
| 61832 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 61833 | p->azVar[pOp->p1-1] = pOp->p4.z; |
| 61834 | } |
| 61835 | } |
| 61836 | p->okVar = 1; |
| 61837 | sqlite3_mutex_leave(p->db->mutex); |
| 61838 | } |
| 61839 | } |
| 61840 | |
| 61841 | /* |
| 61842 | ** Return the name of a wildcard parameter. Return NULL if the index |
| 61843 | ** is out of range or if the wildcard is unnamed. |
| 61844 | ** |
| 61845 | ** The result is always UTF-8. |
| 61846 | */ |
| 61847 | SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ |
| 61848 | Vdbe *p = (Vdbe*)pStmt; |
| 61849 | if( p==0 || i<1 || i>p->nVar ){ |
| 61850 | return 0; |
| 61851 | } |
| 61852 | createVarMap(p); |
| 61853 | return p->azVar[i-1]; |
| 61854 | } |
| 61855 | |
| 61856 | /* |
| 61857 | ** Given a wildcard parameter name, return the index of the variable |
| @@ -61861,13 +61910,12 @@ | |
| 61861 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ |
| 61862 | int i; |
| 61863 | if( p==0 ){ |
| 61864 | return 0; |
| 61865 | } |
| 61866 | createVarMap(p); |
| 61867 | if( zName ){ |
| 61868 | for(i=0; i<p->nVar; i++){ |
| 61869 | const char *z = p->azVar[i]; |
| 61870 | if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ |
| 61871 | return i+1; |
| 61872 | } |
| 61873 | } |
| @@ -63187,10 +63235,11 @@ | |
| 63187 | Mem **apArg; |
| 63188 | Mem *pX; |
| 63189 | } cm; |
| 63190 | struct OP_Trace_stack_vars { |
| 63191 | char *zTrace; |
| 63192 | } cn; |
| 63193 | } u; |
| 63194 | /* End automatically generated code |
| 63195 | ********************************************************************/ |
| 63196 | |
| @@ -63613,10 +63662,11 @@ | |
| 63613 | #if 0 /* local variables moved into u.ab */ |
| 63614 | Mem *pVar; /* Value being transferred */ |
| 63615 | #endif /* local variables moved into u.ab */ |
| 63616 | |
| 63617 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 63618 | u.ab.pVar = &p->aVar[pOp->p1 - 1]; |
| 63619 | if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ |
| 63620 | goto too_big; |
| 63621 | } |
| 63622 | sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); |
| @@ -64405,19 +64455,19 @@ | |
| 64405 | |
| 64406 | pIn1 = &aMem[pOp->p1]; |
| 64407 | pIn3 = &aMem[pOp->p3]; |
| 64408 | u.ai.flags1 = pIn1->flags; |
| 64409 | u.ai.flags3 = pIn3->flags; |
| 64410 | if( (pIn1->flags | pIn3->flags)&MEM_Null ){ |
| 64411 | /* One or both operands are NULL */ |
| 64412 | if( pOp->p5 & SQLITE_NULLEQ ){ |
| 64413 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
| 64414 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
| 64415 | ** or not both operands are null. |
| 64416 | */ |
| 64417 | assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); |
| 64418 | u.ai.res = (pIn1->flags & pIn3->flags & MEM_Null)==0; |
| 64419 | }else{ |
| 64420 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 64421 | ** then the result is always NULL. |
| 64422 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| 64423 | */ |
| @@ -65239,17 +65289,20 @@ | |
| 65239 | "SQL statements in progress"); |
| 65240 | rc = SQLITE_BUSY; |
| 65241 | }else{ |
| 65242 | u.aq.nName = sqlite3Strlen30(u.aq.zName); |
| 65243 | |
| 65244 | /* This call is Ok even if this savepoint is actually a transaction |
| 65245 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
| 65246 | ** If this is a transaction savepoint being opened, it is guaranteed |
| 65247 | ** that the db->aVTrans[] array is empty. */ |
| 65248 | assert( db->autoCommit==0 || db->nVTrans==0 ); |
| 65249 | rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement); |
| 65250 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 65251 | |
| 65252 | /* Create a new savepoint structure. */ |
| 65253 | u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); |
| 65254 | if( u.aq.pNew ){ |
| 65255 | u.aq.pNew->zName = (char *)&u.aq.pNew[1]; |
| @@ -65498,11 +65551,11 @@ | |
| 65498 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 65499 | db->nStatement++; |
| 65500 | p->iStatement = db->nSavepoint + db->nStatement; |
| 65501 | } |
| 65502 | |
| 65503 | rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement); |
| 65504 | if( rc==SQLITE_OK ){ |
| 65505 | rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); |
| 65506 | } |
| 65507 | |
| 65508 | /* Store the current value of the database handles deferred constraint |
| @@ -68631,25 +68684,25 @@ | |
| 68631 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 68632 | */ |
| 68633 | case OP_Trace: { |
| 68634 | #if 0 /* local variables moved into u.cn */ |
| 68635 | char *zTrace; |
| 68636 | #endif /* local variables moved into u.cn */ |
| 68637 | |
| 68638 | u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 68639 | if( u.cn.zTrace ){ |
| 68640 | if( db->xTrace ){ |
| 68641 | char *z = sqlite3VdbeExpandSql(p, u.cn.zTrace); |
| 68642 | db->xTrace(db->pTraceArg, z); |
| 68643 | sqlite3DbFree(db, z); |
| 68644 | } |
| 68645 | #ifdef SQLITE_DEBUG |
| 68646 | if( (db->flags & SQLITE_SqlTrace)!=0 ){ |
| 68647 | sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); |
| 68648 | } |
| 68649 | #endif /* SQLITE_DEBUG */ |
| 68650 | } |
| 68651 | break; |
| 68652 | } |
| 68653 | #endif |
| 68654 | |
| 68655 | |
| @@ -69070,11 +69123,14 @@ | |
| 69070 | ** and offset cache without causing any IO. |
| 69071 | */ |
| 69072 | sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); |
| 69073 | sqlite3VdbeChangeP2(v, 7, pTab->nCol); |
| 69074 | if( !db->mallocFailed ){ |
| 69075 | sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); |
| 69076 | } |
| 69077 | } |
| 69078 | |
| 69079 | pBlob->flags = flags; |
| 69080 | pBlob->iCol = iCol; |
| @@ -71637,57 +71693,57 @@ | |
| 71637 | assert( z[0]!=0 ); |
| 71638 | if( z[1]==0 ){ |
| 71639 | /* Wildcard of the form "?". Assign the next variable number */ |
| 71640 | assert( z[0]=='?' ); |
| 71641 | pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71642 | }else if( z[0]=='?' ){ |
| 71643 | /* Wildcard of the form "?nnn". Convert "nnn" to an integer and |
| 71644 | ** use it as the variable number */ |
| 71645 | i64 i; |
| 71646 | int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); |
| 71647 | pExpr->iColumn = (ynVar)i; |
| 71648 | testcase( i==0 ); |
| 71649 | testcase( i==1 ); |
| 71650 | testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); |
| 71651 | testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); |
| 71652 | if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71653 | sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", |
| 71654 | db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); |
| 71655 | } |
| 71656 | if( i>pParse->nVar ){ |
| 71657 | pParse->nVar = (int)i; |
| 71658 | } |
| 71659 | }else{ |
| 71660 | /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable |
| 71661 | ** number as the prior appearance of the same name, or if the name |
| 71662 | ** has never appeared before, reuse the same variable number |
| 71663 | */ |
| 71664 | int i; |
| 71665 | u32 n; |
| 71666 | n = sqlite3Strlen30(z); |
| 71667 | for(i=0; i<pParse->nVarExpr; i++){ |
| 71668 | Expr *pE = pParse->apVarExpr[i]; |
| 71669 | assert( pE!=0 ); |
| 71670 | if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){ |
| 71671 | pExpr->iColumn = pE->iColumn; |
| 71672 | break; |
| 71673 | } |
| 71674 | } |
| 71675 | if( i>=pParse->nVarExpr ){ |
| 71676 | pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71677 | if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ |
| 71678 | pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; |
| 71679 | pParse->apVarExpr = |
| 71680 | sqlite3DbReallocOrFree( |
| 71681 | db, |
| 71682 | pParse->apVarExpr, |
| 71683 | pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) |
| 71684 | ); |
| 71685 | } |
| 71686 | if( !db->mallocFailed ){ |
| 71687 | assert( pParse->apVarExpr!=0 ); |
| 71688 | pParse->apVarExpr[pParse->nVarExpr++] = pExpr; |
| 71689 | } |
| 71690 | } |
| 71691 | } |
| 71692 | if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71693 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| @@ -73427,11 +73483,13 @@ | |
| 73427 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 73428 | assert( pExpr->u.zToken!=0 ); |
| 73429 | assert( pExpr->u.zToken[0]!=0 ); |
| 73430 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); |
| 73431 | if( pExpr->u.zToken[1]!=0 ){ |
| 73432 | sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, P4_TRANSIENT); |
| 73433 | } |
| 73434 | break; |
| 73435 | } |
| 73436 | case TK_REGISTER: { |
| 73437 | inReg = pExpr->iTable; |
| @@ -77398,13 +77456,11 @@ | |
| 77398 | #endif |
| 77399 | assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ |
| 77400 | /* A minimum of one cursor is required if autoincrement is used |
| 77401 | * See ticket [a696379c1f08866] */ |
| 77402 | if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; |
| 77403 | sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem, |
| 77404 | pParse->nTab, pParse->nMaxArg, pParse->explain, |
| 77405 | pParse->isMultiWrite && pParse->mayAbort); |
| 77406 | pParse->rc = SQLITE_DONE; |
| 77407 | pParse->colNamesSet = 0; |
| 77408 | }else{ |
| 77409 | pParse->rc = SQLITE_ERROR; |
| 77410 | } |
| @@ -81817,10 +81873,11 @@ | |
| 81817 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 81818 | if( IsVirtual(pTab) ){ |
| 81819 | const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); |
| 81820 | sqlite3VtabMakeWritable(pParse, pTab); |
| 81821 | sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); |
| 81822 | sqlite3MayAbort(pParse); |
| 81823 | }else |
| 81824 | #endif |
| 81825 | { |
| 81826 | int count = (pParse->nested==0); /* True to count changes */ |
| @@ -87937,14 +87994,10 @@ | |
| 87937 | ** |
| 87938 | ************************************************************************* |
| 87939 | ** This file contains code used to implement the PRAGMA command. |
| 87940 | */ |
| 87941 | |
| 87942 | /* Ignore this whole file if pragmas are disabled |
| 87943 | */ |
| 87944 | #if !defined(SQLITE_OMIT_PRAGMA) |
| 87945 | |
| 87946 | /* |
| 87947 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| 87948 | ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or |
| 87949 | ** unrecognized string argument. |
| 87950 | ** |
| @@ -87976,10 +88029,16 @@ | |
| 87976 | ** Interpret the given string as a boolean value. |
| 87977 | */ |
| 87978 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ |
| 87979 | return getSafetyLevel(z)&1; |
| 87980 | } |
| 87981 | |
| 87982 | /* |
| 87983 | ** Interpret the given string as a locking mode value. |
| 87984 | */ |
| 87985 | static int getLockingMode(const char *z){ |
| @@ -97682,15 +97741,15 @@ | |
| 97682 | sqlite3DbFree(db, zErr); |
| 97683 | } |
| 97684 | |
| 97685 | return rc; |
| 97686 | } |
| 97687 | |
| 97688 | /* |
| 97689 | ** Add the virtual table pVTab to the array sqlite3.aVTrans[]. |
| 97690 | */ |
| 97691 | static int addToVTrans(sqlite3 *db, VTable *pVTab){ |
| 97692 | const int ARRAY_INCR = 5; |
| 97693 | |
| 97694 | /* Grow the sqlite3.aVTrans array if required */ |
| 97695 | if( (db->nVTrans%ARRAY_INCR)==0 ){ |
| 97696 | VTable **aVTrans; |
| @@ -97701,14 +97760,21 @@ | |
| 97701 | } |
| 97702 | memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); |
| 97703 | db->aVTrans = aVTrans; |
| 97704 | } |
| 97705 | |
| 97706 | /* Add pVtab to the end of sqlite3.aVTrans */ |
| 97707 | db->aVTrans[db->nVTrans++] = pVTab; |
| 97708 | sqlite3VtabLock(pVTab); |
| 97709 | return SQLITE_OK; |
| 97710 | } |
| 97711 | |
| 97712 | /* |
| 97713 | ** This function is invoked by the vdbe to call the xCreate method |
| 97714 | ** of the virtual table named zTab in database iDb. |
| @@ -97742,11 +97808,14 @@ | |
| 97742 | } |
| 97743 | |
| 97744 | /* Justification of ALWAYS(): The xConstructor method is required to |
| 97745 | ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ |
| 97746 | if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ |
| 97747 | rc = addToVTrans(db, sqlite3GetVTable(db, pTab)); |
| 97748 | } |
| 97749 | |
| 97750 | return rc; |
| 97751 | } |
| 97752 | |
| @@ -97858,10 +97927,11 @@ | |
| 97858 | if( p ){ |
| 97859 | int (*x)(sqlite3_vtab *); |
| 97860 | x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); |
| 97861 | if( x ) x(p); |
| 97862 | } |
| 97863 | sqlite3VtabUnlock(pVTab); |
| 97864 | } |
| 97865 | sqlite3DbFree(db, db->aVTrans); |
| 97866 | db->nVTrans = 0; |
| 97867 | db->aVTrans = 0; |
| @@ -97947,14 +98017,18 @@ | |
| 97947 | if( db->aVTrans[i]==pVTab ){ |
| 97948 | return SQLITE_OK; |
| 97949 | } |
| 97950 | } |
| 97951 | |
| 97952 | /* Invoke the xBegin method */ |
| 97953 | rc = pModule->xBegin(pVTab->pVtab); |
| 97954 | if( rc==SQLITE_OK ){ |
| 97955 | rc = addToVTrans(db, pVTab); |
| 97956 | } |
| 97957 | } |
| 97958 | return rc; |
| 97959 | } |
| 97960 | |
| @@ -97975,28 +98049,33 @@ | |
| 97975 | */ |
| 97976 | SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ |
| 97977 | int rc = SQLITE_OK; |
| 97978 | |
| 97979 | assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); |
| 97980 | if( db->aVTrans ){ |
| 97981 | int i; |
| 97982 | for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ |
| 97983 | const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule; |
| 97984 | if( pMod->iVersion>=2 ){ |
| 97985 | int (*xMethod)(sqlite3_vtab *, int); |
| 97986 | switch( op ){ |
| 97987 | case SAVEPOINT_BEGIN: |
| 97988 | xMethod = pMod->xSavepoint; |
| 97989 | break; |
| 97990 | case SAVEPOINT_ROLLBACK: |
| 97991 | xMethod = pMod->xRollbackTo; |
| 97992 | break; |
| 97993 | default: |
| 97994 | xMethod = pMod->xRelease; |
| 97995 | break; |
| 97996 | } |
| 97997 | if( xMethod ) rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); |
| 97998 | } |
| 97999 | } |
| 98000 | } |
| 98001 | return rc; |
| 98002 | } |
| @@ -107254,13 +107333,12 @@ | |
| 107254 | return SQLITE_NOMEM; |
| 107255 | } |
| 107256 | assert( pParse->pNewTable==0 ); |
| 107257 | assert( pParse->pNewTrigger==0 ); |
| 107258 | assert( pParse->nVar==0 ); |
| 107259 | assert( pParse->nVarExpr==0 ); |
| 107260 | assert( pParse->nVarExprAlloc==0 ); |
| 107261 | assert( pParse->apVarExpr==0 ); |
| 107262 | enableLookaside = db->lookaside.bEnabled; |
| 107263 | if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; |
| 107264 | while( !db->mallocFailed && zSql[i]!=0 ){ |
| 107265 | assert( i>=0 ); |
| 107266 | pParse->sLastToken.z = &zSql[i]; |
| @@ -107350,11 +107428,12 @@ | |
| 107350 | */ |
| 107351 | sqlite3DeleteTable(db, pParse->pNewTable); |
| 107352 | } |
| 107353 | |
| 107354 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); |
| 107355 | sqlite3DbFree(db, pParse->apVarExpr); |
| 107356 | sqlite3DbFree(db, pParse->aAlias); |
| 107357 | while( pParse->pAinc ){ |
| 107358 | AutoincInfo *p = pParse->pAinc; |
| 107359 | pParse->pAinc = p->pNext; |
| 107360 | sqlite3DbFree(db, p); |
| @@ -109682,13 +109761,13 @@ | |
| 109682 | }else{ |
| 109683 | struct OpenMode { |
| 109684 | const char *z; |
| 109685 | int mode; |
| 109686 | } *aMode = 0; |
| 109687 | char *zModeType; |
| 109688 | int mask; |
| 109689 | int limit; |
| 109690 | |
| 109691 | if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ |
| 109692 | static struct OpenMode aCacheMode[] = { |
| 109693 | { "shared", SQLITE_OPEN_SHAREDCACHE }, |
| 109694 | { "private", SQLITE_OPEN_PRIVATECACHE }, |
| @@ -111676,15 +111755,35 @@ | |
| 111676 | */ |
| 111677 | typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ |
| 111678 | typedef short int i16; /* 2-byte (or larger) signed integer */ |
| 111679 | typedef unsigned int u32; /* 4-byte unsigned integer */ |
| 111680 | typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ |
| 111681 | /* |
| 111682 | ** Macro used to suppress compiler warnings for unused parameters. |
| 111683 | */ |
| 111684 | #define UNUSED_PARAMETER(x) (void)(x) |
| 111685 | #endif |
| 111686 | |
| 111687 | typedef struct Fts3Table Fts3Table; |
| 111688 | typedef struct Fts3Cursor Fts3Cursor; |
| 111689 | typedef struct Fts3Expr Fts3Expr; |
| 111690 | typedef struct Fts3Phrase Fts3Phrase; |
| @@ -111735,10 +111834,20 @@ | |
| 111735 | */ |
| 111736 | int nMaxPendingData; |
| 111737 | int nPendingData; |
| 111738 | sqlite_int64 iPrevDocid; |
| 111739 | Fts3Hash pendingTerms; |
| 111740 | }; |
| 111741 | |
| 111742 | /* |
| 111743 | ** When the core wants to read from the virtual table, it creates a |
| 111744 | ** virtual table cursor (an instance of the following structure) using |
| @@ -112645,10 +112754,12 @@ | |
| 112645 | p->pTokenizer = pTokenizer; |
| 112646 | p->nNodeSize = 1000; |
| 112647 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 112648 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 112649 | p->bHasStat = isFts4; |
| 112650 | fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); |
| 112651 | |
| 112652 | /* Fill in the zName and zDb fields of the vtab structure. */ |
| 112653 | zCsr = (char *)&p->azColumn[nCol]; |
| 112654 | p->zName = zCsr; |
| @@ -114942,11 +115053,15 @@ | |
| 114942 | /* |
| 114943 | ** Implementation of xBegin() method. This is a no-op. |
| 114944 | */ |
| 114945 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 114946 | UNUSED_PARAMETER(pVtab); |
| 114947 | assert( ((Fts3Table *)pVtab)->nPendingData==0 ); |
| 114948 | return SQLITE_OK; |
| 114949 | } |
| 114950 | |
| 114951 | /* |
| 114952 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| @@ -114953,20 +115068,28 @@ | |
| 114953 | ** the pending-terms hash-table have already been flushed into the database |
| 114954 | ** by fts3SyncMethod(). |
| 114955 | */ |
| 114956 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 114957 | UNUSED_PARAMETER(pVtab); |
| 114958 | assert( ((Fts3Table *)pVtab)->nPendingData==0 ); |
| 114959 | return SQLITE_OK; |
| 114960 | } |
| 114961 | |
| 114962 | /* |
| 114963 | ** Implementation of xRollback(). Discard the contents of the pending-terms |
| 114964 | ** hash-table. Any changes made to the database are reverted by SQLite. |
| 114965 | */ |
| 114966 | static int fts3RollbackMethod(sqlite3_vtab *pVtab){ |
| 114967 | sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); |
| 114968 | return SQLITE_OK; |
| 114969 | } |
| 114970 | |
| 114971 | /* |
| 114972 | ** Load the doclist associated with expression pExpr to pExpr->aDoclist. |
| @@ -115318,17 +115441,33 @@ | |
| 115318 | ); |
| 115319 | return rc; |
| 115320 | } |
| 115321 | |
| 115322 | static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115323 | return sqlite3Fts3PendingTermsFlush((Fts3Table *)pVtab); |
| 115324 | } |
| 115325 | static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115326 | return SQLITE_OK; |
| 115327 | } |
| 115328 | static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115329 | sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); |
| 115330 | return SQLITE_OK; |
| 115331 | } |
| 115332 | |
| 115333 | static const sqlite3_module fts3Module = { |
| 115334 | /* iVersion */ 2, |
| @@ -115823,10 +115962,11 @@ | |
| 115823 | Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; |
| 115824 | int rc; |
| 115825 | int isScan; |
| 115826 | |
| 115827 | UNUSED_PARAMETER(nVal); |
| 115828 | |
| 115829 | assert( idxStr==0 ); |
| 115830 | assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 |
| 115831 | || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT |
| 115832 | || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) |
| @@ -115940,11 +116080,14 @@ | |
| 115940 | 0, /* xBegin */ |
| 115941 | 0, /* xSync */ |
| 115942 | 0, /* xCommit */ |
| 115943 | 0, /* xRollback */ |
| 115944 | 0, /* xFindFunction */ |
| 115945 | 0 /* xRename */ |
| 115946 | }; |
| 115947 | int rc; /* Return code */ |
| 115948 | |
| 115949 | rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); |
| 115950 | return rc; |
| @@ -125919,11 +126062,11 @@ | |
| 125919 | } |
| 125920 | return rc; |
| 125921 | } |
| 125922 | |
| 125923 | static sqlite3_module rtreeModule = { |
| 125924 | 0, /* iVersion */ |
| 125925 | rtreeCreate, /* xCreate - create a table */ |
| 125926 | rtreeConnect, /* xConnect - connect to an existing table */ |
| 125927 | rtreeBestIndex, /* xBestIndex - Determine search strategy */ |
| 125928 | rtreeDisconnect, /* xDisconnect - Disconnect from a table */ |
| 125929 | rtreeDestroy, /* xDestroy - Drop a table */ |
| @@ -125938,11 +126081,14 @@ | |
| 125938 | 0, /* xBegin - begin transaction */ |
| 125939 | 0, /* xSync - sync transaction */ |
| 125940 | 0, /* xCommit - commit transaction */ |
| 125941 | 0, /* xRollback - rollback transaction */ |
| 125942 | 0, /* xFindFunction - function overloading */ |
| 125943 | rtreeRename /* xRename - rename the table */ |
| 125944 | }; |
| 125945 | |
| 125946 | static int rtreeSqlInit( |
| 125947 | Rtree *pRtree, |
| 125948 | sqlite3 *db, |
| 125949 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -650,11 +650,11 @@ | |
| 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | */ |
| 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | #define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" |
| 656 | |
| 657 | /* |
| 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | ** |
| @@ -1000,10 +1000,12 @@ | |
| 1000 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1001 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1002 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1003 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1004 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1005 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1006 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1007 | |
| 1008 | /* |
| 1009 | ** CAPI3REF: Flags For File Open Operations |
| 1010 | ** |
| 1011 | ** These bit values are intended for use in the |
| @@ -1305,15 +1307,15 @@ | |
| 1307 | */ |
| 1308 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 1309 | |
| 1310 | /* |
| 1311 | ** CAPI3REF: OS Interface Object |
| 1312 | ** |
| 1313 | ** An instance of the sqlite3_vfs object defines the interface between |
| 1314 | ** the SQLite core and the underlying operating system. The "vfs" |
| 1315 | ** in the name of the object stands for "virtual file system". See |
| 1316 | ** the [VFS | VFS documentation] for further information. |
| 1317 | ** |
| 1318 | ** The value of the iVersion field is initially 1 but may be larger in |
| 1319 | ** future versions of SQLite. Additional fields may be appended to this |
| 1320 | ** object when the iVersion value is increased. Note that the structure |
| 1321 | ** of the sqlite3_vfs object changes in the transaction between |
| @@ -8494,19 +8496,20 @@ | |
| 8496 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 8497 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); |
| 8498 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| 8499 | SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); |
| 8500 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); |
| 8501 | SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); |
| 8502 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 8503 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 8504 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 8505 | #ifdef SQLITE_DEBUG |
| 8506 | SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); |
| 8507 | SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); |
| 8508 | #endif |
| 8509 | SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); |
| 8510 | SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); |
| 8511 | SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); |
| 8512 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); |
| 8513 | SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); |
| 8514 | SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); |
| 8515 | SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); |
| @@ -9832,10 +9835,11 @@ | |
| 9835 | sqlite3 *db; /* Database connection associated with this table */ |
| 9836 | Module *pMod; /* Pointer to module implementation */ |
| 9837 | sqlite3_vtab *pVtab; /* Pointer to vtab instance */ |
| 9838 | int nRef; /* Number of pointers to this structure */ |
| 9839 | u8 bConstraint; /* True if constraints are supported */ |
| 9840 | int iSavepoint; /* Depth of the SAVEPOINT stack */ |
| 9841 | VTable *pNext; /* Next in linked list (see above) */ |
| 9842 | }; |
| 9843 | |
| 9844 | /* |
| 9845 | ** Each SQL table is represented in memory by an instance of the |
| @@ -10826,13 +10830,12 @@ | |
| 10830 | |
| 10831 | /* Above is constant between recursions. Below is reset before and after |
| 10832 | ** each recursion */ |
| 10833 | |
| 10834 | int nVar; /* Number of '?' variables seen in the SQL so far */ |
| 10835 | int nzVar; /* Number of available slots in azVar[] */ |
| 10836 | char **azVar; /* Pointers to names of parameters */ |
| 10837 | Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ |
| 10838 | int nAlias; /* Number of aliased result set columns */ |
| 10839 | int nAliasAlloc; /* Number of allocated slots for aAlias[] */ |
| 10840 | int *aAlias; /* Register used to hold aliased result */ |
| 10841 | u8 explain; /* True if the EXPLAIN flag is found on the query */ |
| @@ -12761,15 +12764,15 @@ | |
| 12764 | Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ |
| 12765 | VdbeCursor **apCsr; /* One element of this array for each open cursor */ |
| 12766 | Mem *aVar; /* Values for the OP_Variable opcode. */ |
| 12767 | char **azVar; /* Name of variables */ |
| 12768 | ynVar nVar; /* Number of entries in aVar[] */ |
| 12769 | ynVar nzVar; /* Number of entries in azVar[] */ |
| 12770 | u32 cacheCtr; /* VdbeCursor row cache generation counter */ |
| 12771 | int pc; /* The program counter */ |
| 12772 | int rc; /* Value to return */ |
| 12773 | u8 errorAction; /* Recovery action to do in case of an error */ |
| 12774 | u8 explain; /* True if EXPLAIN present on SQL command */ |
| 12775 | u8 changeCntOn; /* True to update the change-counter */ |
| 12776 | u8 expired; /* True if the VM needs to be recompiled */ |
| 12777 | u8 runOnlyOnce; /* Automatically expire on reset */ |
| 12778 | u8 minWriteFileFormat; /* Minimum file format for writable database files */ |
| @@ -27963,11 +27966,12 @@ | |
| 27966 | unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ |
| 27967 | sqlite3_mutex *mutex; /* Mutex to access this object */ |
| 27968 | char *zFilename; /* Name of the mmapped file */ |
| 27969 | int h; /* Open file descriptor */ |
| 27970 | int szRegion; /* Size of shared-memory regions */ |
| 27971 | u16 nRegion; /* Size of array apRegion */ |
| 27972 | u8 isReadonly; /* True if read-only */ |
| 27973 | char **apRegion; /* Array of mapped shared-memory regions */ |
| 27974 | int nRef; /* Number of unixShm objects pointing to this */ |
| 27975 | unixShm *pFirst; /* All unixShm objects pointing to this */ |
| 27976 | #ifdef SQLITE_DEBUG |
| 27977 | u8 exclMask; /* Mask of exclusive locks held */ |
| @@ -28210,12 +28214,21 @@ | |
| 28214 | |
| 28215 | if( pInode->bProcessLock==0 ){ |
| 28216 | pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, |
| 28217 | (sStat.st_mode & 0777)); |
| 28218 | if( pShmNode->h<0 ){ |
| 28219 | const char *zRO; |
| 28220 | zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); |
| 28221 | if( zRO && sqlite3GetBoolean(zRO) ){ |
| 28222 | pShmNode->h = robust_open(zShmFilename, O_RDONLY, |
| 28223 | (sStat.st_mode & 0777)); |
| 28224 | pShmNode->isReadonly = 1; |
| 28225 | } |
| 28226 | if( pShmNode->h<0 ){ |
| 28227 | rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 28228 | goto shm_open_err; |
| 28229 | } |
| 28230 | } |
| 28231 | |
| 28232 | /* Check to see if another process is holding the dead-man switch. |
| 28233 | ** If not, truncate the file to zero length. |
| 28234 | */ |
| @@ -28350,11 +28363,12 @@ | |
| 28363 | } |
| 28364 | pShmNode->apRegion = apNew; |
| 28365 | while(pShmNode->nRegion<=iRegion){ |
| 28366 | void *pMem; |
| 28367 | if( pShmNode->h>=0 ){ |
| 28368 | pMem = mmap(0, szRegion, |
| 28369 | pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 28370 | MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 28371 | ); |
| 28372 | if( pMem==MAP_FAILED ){ |
| 28373 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| 28374 | goto shmpage_out; |
| @@ -28376,10 +28390,11 @@ | |
| 28390 | if( pShmNode->nRegion>iRegion ){ |
| 28391 | *pp = pShmNode->apRegion[iRegion]; |
| 28392 | }else{ |
| 28393 | *pp = 0; |
| 28394 | } |
| 28395 | if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; |
| 28396 | sqlite3_mutex_leave(pShmNode->mutex); |
| 28397 | return rc; |
| 28398 | } |
| 28399 | |
| 28400 | /* |
| @@ -34873,10 +34888,17 @@ | |
| 34888 | if( !pPg ){ |
| 34889 | for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
| 34890 | } |
| 34891 | if( pPg ){ |
| 34892 | int rc; |
| 34893 | #ifdef SQLITE_LOG_CACHE_SPILL |
| 34894 | sqlite3_log(SQLITE_FULL, |
| 34895 | "spill page %d making room for %d - cache used: %d/%d", |
| 34896 | pPg->pgno, pgno, |
| 34897 | sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), |
| 34898 | pCache->nMax); |
| 34899 | #endif |
| 34900 | rc = pCache->xStress(pCache->pStress, pPg); |
| 34901 | if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
| 34902 | return rc; |
| 34903 | } |
| 34904 | } |
| @@ -42472,15 +42494,25 @@ | |
| 42494 | */ |
| 42495 | sqlite3BackupRestart(pPager->pBackup); |
| 42496 | }else{ |
| 42497 | if( pagerUseWal(pPager) ){ |
| 42498 | PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); |
| 42499 | PgHdr *pPageOne = 0; |
| 42500 | if( pList==0 ){ |
| 42501 | /* Must have at least one page for the WAL commit flag. |
| 42502 | ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ |
| 42503 | rc = sqlite3PagerGet(pPager, 1, &pPageOne); |
| 42504 | pList = pPageOne; |
| 42505 | pList->pDirty = 0; |
| 42506 | } |
| 42507 | assert( rc==SQLITE_OK ); |
| 42508 | if( ALWAYS(pList) ){ |
| 42509 | rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, |
| 42510 | (pPager->fullSync ? pPager->syncFlags : 0) |
| 42511 | ); |
| 42512 | } |
| 42513 | sqlite3PagerUnref(pPageOne); |
| 42514 | if( rc==SQLITE_OK ){ |
| 42515 | sqlite3PcacheCleanAll(pPager->pPCache); |
| 42516 | } |
| 42517 | }else{ |
| 42518 | /* The following block updates the change-counter. Exactly how it |
| @@ -43967,11 +43999,11 @@ | |
| 43999 | u32 szPage; /* Database page size */ |
| 44000 | i16 readLock; /* Which read lock is being held. -1 for none */ |
| 44001 | u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ |
| 44002 | u8 writeLock; /* True if in a write transaction */ |
| 44003 | u8 ckptLock; /* True if holding a checkpoint lock */ |
| 44004 | u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ |
| 44005 | WalIndexHdr hdr; /* Wal-index header for current transaction */ |
| 44006 | const char *zWalName; /* Name of WAL file */ |
| 44007 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 44008 | #ifdef SQLITE_DEBUG |
| 44009 | u8 lockError; /* True if a locking error has occurred */ |
| @@ -43983,10 +44015,17 @@ | |
| 44015 | */ |
| 44016 | #define WAL_NORMAL_MODE 0 |
| 44017 | #define WAL_EXCLUSIVE_MODE 1 |
| 44018 | #define WAL_HEAPMEMORY_MODE 2 |
| 44019 | |
| 44020 | /* |
| 44021 | ** Possible values for WAL.readOnly |
| 44022 | */ |
| 44023 | #define WAL_RDWR 0 /* Normal read/write connection */ |
| 44024 | #define WAL_RDONLY 1 /* The WAL file is readonly */ |
| 44025 | #define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ |
| 44026 | |
| 44027 | /* |
| 44028 | ** Each page of the wal-index mapping contains a hash-table made up of |
| 44029 | ** an array of HASHTABLE_NSLOT elements of the following type. |
| 44030 | */ |
| 44031 | typedef u16 ht_slot; |
| @@ -44076,10 +44115,14 @@ | |
| 44115 | if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; |
| 44116 | }else{ |
| 44117 | rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, |
| 44118 | pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] |
| 44119 | ); |
| 44120 | if( rc==SQLITE_READONLY ){ |
| 44121 | pWal->readOnly |= WAL_SHM_RDONLY; |
| 44122 | rc = SQLITE_OK; |
| 44123 | } |
| 44124 | } |
| 44125 | } |
| 44126 | |
| 44127 | *ppPage = pWal->apWiData[iPage]; |
| 44128 | assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); |
| @@ -44823,11 +44866,11 @@ | |
| 44866 | |
| 44867 | /* Open file handle on the write-ahead log file. */ |
| 44868 | flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); |
| 44869 | rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); |
| 44870 | if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ |
| 44871 | pRet->readOnly = WAL_RDONLY; |
| 44872 | } |
| 44873 | |
| 44874 | if( rc!=SQLITE_OK ){ |
| 44875 | walIndexClose(pRet, 0); |
| 44876 | sqlite3OsClose(pRet->pWalFd); |
| @@ -45464,25 +45507,32 @@ | |
| 45507 | |
| 45508 | /* If the first attempt failed, it might have been due to a race |
| 45509 | ** with a writer. So get a WRITE lock and try again. |
| 45510 | */ |
| 45511 | assert( badHdr==0 || pWal->writeLock==0 ); |
| 45512 | if( badHdr ){ |
| 45513 | if( pWal->readOnly & WAL_SHM_RDONLY ){ |
| 45514 | if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ |
| 45515 | walUnlockShared(pWal, WAL_WRITE_LOCK); |
| 45516 | rc = SQLITE_READONLY_RECOVERY; |
| 45517 | } |
| 45518 | }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ |
| 45519 | pWal->writeLock = 1; |
| 45520 | if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ |
| 45521 | badHdr = walIndexTryHdr(pWal, pChanged); |
| 45522 | if( badHdr ){ |
| 45523 | /* If the wal-index header is still malformed even while holding |
| 45524 | ** a WRITE lock, it can only mean that the header is corrupted and |
| 45525 | ** needs to be reconstructed. So run recovery to do exactly that. |
| 45526 | */ |
| 45527 | rc = walIndexRecover(pWal); |
| 45528 | *pChanged = 1; |
| 45529 | } |
| 45530 | } |
| 45531 | pWal->writeLock = 0; |
| 45532 | walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); |
| 45533 | } |
| 45534 | } |
| 45535 | |
| 45536 | /* If the header is read successfully, check the version number to make |
| 45537 | ** sure the wal-index was not constructed with some future format that |
| 45538 | ** this version of SQLite cannot understand. |
| @@ -45665,11 +45715,13 @@ | |
| 45715 | mxI = i; |
| 45716 | } |
| 45717 | } |
| 45718 | /* There was once an "if" here. The extra "{" is to preserve indentation. */ |
| 45719 | { |
| 45720 | if( (pWal->readOnly & WAL_SHM_RDONLY)==0 |
| 45721 | && (mxReadMark<pWal->hdr.mxFrame || mxI==0) |
| 45722 | ){ |
| 45723 | for(i=1; i<WAL_NREADER; i++){ |
| 45724 | rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45725 | if( rc==SQLITE_OK ){ |
| 45726 | mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; |
| 45727 | mxI = i; |
| @@ -45679,12 +45731,12 @@ | |
| 45731 | return rc; |
| 45732 | } |
| 45733 | } |
| 45734 | } |
| 45735 | if( mxI==0 ){ |
| 45736 | assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); |
| 45737 | return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; |
| 45738 | } |
| 45739 | |
| 45740 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); |
| 45741 | if( rc ){ |
| 45742 | return rc==SQLITE_BUSY ? WAL_RETRY : rc; |
| @@ -46086,14 +46138,16 @@ | |
| 46138 | ** set to a non-negative value. Log errors encountered |
| 46139 | ** during the truncation attempt. */ |
| 46140 | if( pWal->mxWalSize>=0 ){ |
| 46141 | i64 sz; |
| 46142 | int rx; |
| 46143 | sqlite3BeginBenignMalloc(); |
| 46144 | rx = sqlite3OsFileSize(pWal->pWalFd, &sz); |
| 46145 | if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ |
| 46146 | rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); |
| 46147 | } |
| 46148 | sqlite3EndBenignMalloc(); |
| 46149 | if( rx ){ |
| 46150 | sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); |
| 46151 | } |
| 46152 | } |
| 46153 | |
| @@ -46320,10 +46374,11 @@ | |
| 46374 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 46375 | |
| 46376 | assert( pWal->ckptLock==0 ); |
| 46377 | assert( pWal->writeLock==0 ); |
| 46378 | |
| 46379 | if( pWal->readOnly ) return SQLITE_READONLY; |
| 46380 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 46381 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 46382 | if( rc ){ |
| 46383 | /* Usually this is SQLITE_BUSY meaning that another thread or process |
| 46384 | ** is already running a checkpoint, or maybe a recovery. But it might |
| @@ -52802,14 +52857,14 @@ | |
| 52857 | ** removes the reference to the cell from pPage. |
| 52858 | ** |
| 52859 | ** "sz" must be the number of bytes in the cell. |
| 52860 | */ |
| 52861 | static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ |
| 52862 | u32 pc; /* Offset to cell content of cell being deleted */ |
| 52863 | u8 *data; /* pPage->aData */ |
| 52864 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 52865 | u8 *endPtr; /* End of loop */ |
| 52866 | int rc; /* The return code */ |
| 52867 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 52868 | |
| 52869 | if( *pRC ) return; |
| 52870 | |
| @@ -52830,13 +52885,15 @@ | |
| 52885 | rc = freeSpace(pPage, pc, sz); |
| 52886 | if( rc ){ |
| 52887 | *pRC = rc; |
| 52888 | return; |
| 52889 | } |
| 52890 | endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; |
| 52891 | while( ptr<endPtr ){ |
| 52892 | ptr[0] = ptr[2]; |
| 52893 | ptr[1] = ptr[3]; |
| 52894 | ptr += 2; |
| 52895 | } |
| 52896 | pPage->nCell--; |
| 52897 | put2byte(&data[hdr+3], pPage->nCell); |
| 52898 | pPage->nFree += 2; |
| 52899 | } |
| @@ -58815,38 +58872,17 @@ | |
| 58872 | } |
| 58873 | return pBuf; |
| 58874 | } |
| 58875 | |
| 58876 | /* |
| 58877 | ** Rewind the VDBE back to the beginning in preparation for |
| 58878 | ** running it. |
| 58879 | */ |
| 58880 | SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ |
| 58881 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 58882 | int i; |
| 58883 | #endif |
| 58884 | assert( p!=0 ); |
| 58885 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 58886 | |
| 58887 | /* There should be at least one opcode. |
| 58888 | */ |
| @@ -58853,10 +58889,75 @@ | |
| 58889 | assert( p->nOp>0 ); |
| 58890 | |
| 58891 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 58892 | p->magic = VDBE_MAGIC_RUN; |
| 58893 | |
| 58894 | #ifdef SQLITE_DEBUG |
| 58895 | for(i=1; i<p->nMem; i++){ |
| 58896 | assert( p->aMem[i].db==p->db ); |
| 58897 | } |
| 58898 | #endif |
| 58899 | p->pc = -1; |
| 58900 | p->rc = SQLITE_OK; |
| 58901 | p->errorAction = OE_Abort; |
| 58902 | p->magic = VDBE_MAGIC_RUN; |
| 58903 | p->nChange = 0; |
| 58904 | p->cacheCtr = 1; |
| 58905 | p->minWriteFileFormat = 255; |
| 58906 | p->iStatement = 0; |
| 58907 | p->nFkConstraint = 0; |
| 58908 | #ifdef VDBE_PROFILE |
| 58909 | for(i=0; i<p->nOp; i++){ |
| 58910 | p->aOp[i].cnt = 0; |
| 58911 | p->aOp[i].cycles = 0; |
| 58912 | } |
| 58913 | #endif |
| 58914 | } |
| 58915 | |
| 58916 | /* |
| 58917 | ** Prepare a virtual machine for execution for the first time after |
| 58918 | ** creating the virtual machine. This involves things such |
| 58919 | ** as allocating stack space and initializing the program counter. |
| 58920 | ** After the VDBE has be prepped, it can be executed by one or more |
| 58921 | ** calls to sqlite3VdbeExec(). |
| 58922 | ** |
| 58923 | ** This function may be called exact once on a each virtual machine. |
| 58924 | ** After this routine is called the VM has been "packaged" and is ready |
| 58925 | ** to run. After this routine is called, futher calls to |
| 58926 | ** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects |
| 58927 | ** the Vdbe from the Parse object that helped generate it so that the |
| 58928 | ** the Vdbe becomes an independent entity and the Parse object can be |
| 58929 | ** destroyed. |
| 58930 | ** |
| 58931 | ** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back |
| 58932 | ** to its initial state after it has been run. |
| 58933 | */ |
| 58934 | SQLITE_PRIVATE void sqlite3VdbeMakeReady( |
| 58935 | Vdbe *p, /* The VDBE */ |
| 58936 | Parse *pParse /* Parsing context */ |
| 58937 | ){ |
| 58938 | sqlite3 *db; /* The database connection */ |
| 58939 | int nVar; /* Number of parameters */ |
| 58940 | int nMem; /* Number of VM memory registers */ |
| 58941 | int nCursor; /* Number of cursors required */ |
| 58942 | int nArg; /* Number of arguments in subprograms */ |
| 58943 | int n; /* Loop counter */ |
| 58944 | u8 *zCsr; /* Memory available for allocation */ |
| 58945 | u8 *zEnd; /* First byte past allocated memory */ |
| 58946 | int nByte; /* How much extra memory is needed */ |
| 58947 | |
| 58948 | assert( p!=0 ); |
| 58949 | assert( p->nOp>0 ); |
| 58950 | assert( pParse!=0 ); |
| 58951 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 58952 | db = p->db; |
| 58953 | assert( db->mallocFailed==0 ); |
| 58954 | nVar = pParse->nVar; |
| 58955 | nMem = pParse->nMem; |
| 58956 | nCursor = pParse->nTab; |
| 58957 | nArg = pParse->nMaxArg; |
| 58958 | |
| 58959 | /* For each cursor required, also allocate a memory cell. Memory |
| 58960 | ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by |
| 58961 | ** the vdbe program. Instead they are used to allocate space for |
| 58962 | ** VdbeCursor/BtCursor structures. The blob of memory associated with |
| 58963 | ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) |
| @@ -58865,95 +58966,72 @@ | |
| 58966 | ** See also: allocateCursor(). |
| 58967 | */ |
| 58968 | nMem += nCursor; |
| 58969 | |
| 58970 | /* Allocate space for memory registers, SQL variables, VDBE cursors and |
| 58971 | ** an array to marshal SQL function arguments in. |
| 58972 | */ |
| 58973 | zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ |
| 58974 | zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ |
| 58975 | |
| 58976 | resolveP2Values(p, &nArg); |
| 58977 | p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); |
| 58978 | if( pParse->explain && nMem<10 ){ |
| 58979 | nMem = 10; |
| 58980 | } |
| 58981 | memset(zCsr, 0, zEnd-zCsr); |
| 58982 | zCsr += (zCsr - (u8*)0)&7; |
| 58983 | assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); |
| 58984 | |
| 58985 | /* Memory for registers, parameters, cursor, etc, is allocated in two |
| 58986 | ** passes. On the first pass, we try to reuse unused space at the |
| 58987 | ** end of the opcode array. If we are unable to satisfy all memory |
| 58988 | ** requirements by reusing the opcode array tail, then the second |
| 58989 | ** pass will fill in the rest using a fresh allocation. |
| 58990 | ** |
| 58991 | ** This two-pass approach that reuses as much memory as possible from |
| 58992 | ** the leftover space at the end of the opcode array can significantly |
| 58993 | ** reduce the amount of memory held by a prepared statement. |
| 58994 | */ |
| 58995 | do { |
| 58996 | nByte = 0; |
| 58997 | p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58998 | p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58999 | p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); |
| 59000 | p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); |
| 59001 | p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), |
| 59002 | &zCsr, zEnd, &nByte); |
| 59003 | if( nByte ){ |
| 59004 | p->pFree = sqlite3DbMallocZero(db, nByte); |
| 59005 | } |
| 59006 | zCsr = p->pFree; |
| 59007 | zEnd = &zCsr[nByte]; |
| 59008 | }while( nByte && !db->mallocFailed ); |
| 59009 | |
| 59010 | p->nCursor = (u16)nCursor; |
| 59011 | if( p->aVar ){ |
| 59012 | p->nVar = (ynVar)nVar; |
| 59013 | for(n=0; n<nVar; n++){ |
| 59014 | p->aVar[n].flags = MEM_Null; |
| 59015 | p->aVar[n].db = db; |
| 59016 | } |
| 59017 | } |
| 59018 | if( p->azVar ){ |
| 59019 | p->nzVar = pParse->nzVar; |
| 59020 | memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); |
| 59021 | memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); |
| 59022 | } |
| 59023 | if( p->aMem ){ |
| 59024 | p->aMem--; /* aMem[] goes from 1..nMem */ |
| 59025 | p->nMem = nMem; /* not from 0..nMem-1 */ |
| 59026 | for(n=1; n<=nMem; n++){ |
| 59027 | p->aMem[n].flags = MEM_Null; |
| 59028 | p->aMem[n].db = db; |
| 59029 | } |
| 59030 | } |
| 59031 | p->explain = pParse->explain; |
| 59032 | sqlite3VdbeRewind(p); |
| 59033 | } |
| 59034 | |
| 59035 | /* |
| 59036 | ** Close a VDBE cursor and release all the resources that cursor |
| 59037 | ** happens to hold. |
| @@ -59626,21 +59704,15 @@ | |
| 59704 | /* If eStatementOp is non-zero, then a statement transaction needs to |
| 59705 | ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to |
| 59706 | ** do so. If this operation returns an error, and the current statement |
| 59707 | ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the |
| 59708 | ** current statement error code. |
| 59709 | */ |
| 59710 | if( eStatementOp ){ |
| 59711 | rc = sqlite3VdbeCloseStatement(p, eStatementOp); |
| 59712 | if( rc ){ |
| 59713 | if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ |
| 59714 | p->rc = rc; |
| 59715 | sqlite3DbFree(db, p->zErrMsg); |
| 59716 | p->zErrMsg = 0; |
| 59717 | } |
| 59718 | invalidateCursorsOnModifiedBtrees(db); |
| @@ -59829,18 +59901,20 @@ | |
| 59901 | ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with |
| 59902 | ** the database connection. |
| 59903 | */ |
| 59904 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ |
| 59905 | SubProgram *pSub, *pNext; |
| 59906 | int i; |
| 59907 | assert( p->db==0 || p->db==db ); |
| 59908 | releaseMemArray(p->aVar, p->nVar); |
| 59909 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); |
| 59910 | for(pSub=p->pProgram; pSub; pSub=pNext){ |
| 59911 | pNext = pSub->pNext; |
| 59912 | vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); |
| 59913 | sqlite3DbFree(db, pSub); |
| 59914 | } |
| 59915 | for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); |
| 59916 | vdbeFreeOpArray(db, p->aOp, p->nOp); |
| 59917 | sqlite3DbFree(db, p->aLabel); |
| 59918 | sqlite3DbFree(db, p->aColName); |
| 59919 | sqlite3DbFree(db, p->zSql); |
| 59920 | sqlite3DbFree(db, p->pFree); |
| @@ -60282,11 +60356,11 @@ | |
| 60356 | u32 serial_type; |
| 60357 | |
| 60358 | idx += getVarint32(&aKey[idx], serial_type); |
| 60359 | pMem->enc = pKeyInfo->enc; |
| 60360 | pMem->db = pKeyInfo->db; |
| 60361 | /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ |
| 60362 | pMem->zMalloc = 0; |
| 60363 | d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); |
| 60364 | pMem++; |
| 60365 | u++; |
| 60366 | } |
| @@ -60297,10 +60371,11 @@ | |
| 60371 | |
| 60372 | /* |
| 60373 | ** This routine destroys a UnpackedRecord object. |
| 60374 | */ |
| 60375 | SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ |
| 60376 | #ifdef SQLITE_DEBUG |
| 60377 | int i; |
| 60378 | Mem *pMem; |
| 60379 | |
| 60380 | assert( p!=0 ); |
| 60381 | assert( p->flags & UNPACKED_NEED_DESTROY ); |
| @@ -60310,10 +60385,11 @@ | |
| 60385 | ** strings and blobs static. And none of the elements are |
| 60386 | ** ever transformed, so there is never anything to delete. |
| 60387 | */ |
| 60388 | if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); |
| 60389 | } |
| 60390 | #endif |
| 60391 | if( p->flags & UNPACKED_NEED_FREE ){ |
| 60392 | sqlite3DbFree(p->pKeyInfo->db, p); |
| 60393 | } |
| 60394 | } |
| 60395 | |
| @@ -60745,11 +60821,11 @@ | |
| 60821 | rc = SQLITE_OK; |
| 60822 | }else{ |
| 60823 | Vdbe *v = (Vdbe*)pStmt; |
| 60824 | sqlite3_mutex_enter(v->db->mutex); |
| 60825 | rc = sqlite3VdbeReset(v); |
| 60826 | sqlite3VdbeRewind(v); |
| 60827 | assert( (rc & (v->db->errMask))==rc ); |
| 60828 | rc = sqlite3ApiExit(v->db, rc); |
| 60829 | sqlite3_mutex_leave(v->db->mutex); |
| 60830 | } |
| 60831 | return rc; |
| @@ -61810,48 +61886,21 @@ | |
| 61886 | SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ |
| 61887 | Vdbe *p = (Vdbe*)pStmt; |
| 61888 | return p ? p->nVar : 0; |
| 61889 | } |
| 61890 | |
| 61891 | /* |
| 61892 | ** Return the name of a wildcard parameter. Return NULL if the index |
| 61893 | ** is out of range or if the wildcard is unnamed. |
| 61894 | ** |
| 61895 | ** The result is always UTF-8. |
| 61896 | */ |
| 61897 | SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ |
| 61898 | Vdbe *p = (Vdbe*)pStmt; |
| 61899 | if( p==0 || i<1 || i>p->nzVar ){ |
| 61900 | return 0; |
| 61901 | } |
| 61902 | return p->azVar[i-1]; |
| 61903 | } |
| 61904 | |
| 61905 | /* |
| 61906 | ** Given a wildcard parameter name, return the index of the variable |
| @@ -61861,13 +61910,12 @@ | |
| 61910 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ |
| 61911 | int i; |
| 61912 | if( p==0 ){ |
| 61913 | return 0; |
| 61914 | } |
| 61915 | if( zName ){ |
| 61916 | for(i=0; i<p->nzVar; i++){ |
| 61917 | const char *z = p->azVar[i]; |
| 61918 | if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ |
| 61919 | return i+1; |
| 61920 | } |
| 61921 | } |
| @@ -63187,10 +63235,11 @@ | |
| 63235 | Mem **apArg; |
| 63236 | Mem *pX; |
| 63237 | } cm; |
| 63238 | struct OP_Trace_stack_vars { |
| 63239 | char *zTrace; |
| 63240 | char *z; |
| 63241 | } cn; |
| 63242 | } u; |
| 63243 | /* End automatically generated code |
| 63244 | ********************************************************************/ |
| 63245 | |
| @@ -63613,10 +63662,11 @@ | |
| 63662 | #if 0 /* local variables moved into u.ab */ |
| 63663 | Mem *pVar; /* Value being transferred */ |
| 63664 | #endif /* local variables moved into u.ab */ |
| 63665 | |
| 63666 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 63667 | assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); |
| 63668 | u.ab.pVar = &p->aVar[pOp->p1 - 1]; |
| 63669 | if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ |
| 63670 | goto too_big; |
| 63671 | } |
| 63672 | sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); |
| @@ -64405,19 +64455,19 @@ | |
| 64455 | |
| 64456 | pIn1 = &aMem[pOp->p1]; |
| 64457 | pIn3 = &aMem[pOp->p3]; |
| 64458 | u.ai.flags1 = pIn1->flags; |
| 64459 | u.ai.flags3 = pIn3->flags; |
| 64460 | if( (u.ai.flags1 | u.ai.flags3)&MEM_Null ){ |
| 64461 | /* One or both operands are NULL */ |
| 64462 | if( pOp->p5 & SQLITE_NULLEQ ){ |
| 64463 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
| 64464 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
| 64465 | ** or not both operands are null. |
| 64466 | */ |
| 64467 | assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); |
| 64468 | u.ai.res = (u.ai.flags1 & u.ai.flags3 & MEM_Null)==0; |
| 64469 | }else{ |
| 64470 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 64471 | ** then the result is always NULL. |
| 64472 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| 64473 | */ |
| @@ -65239,17 +65289,20 @@ | |
| 65289 | "SQL statements in progress"); |
| 65290 | rc = SQLITE_BUSY; |
| 65291 | }else{ |
| 65292 | u.aq.nName = sqlite3Strlen30(u.aq.zName); |
| 65293 | |
| 65294 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 65295 | /* This call is Ok even if this savepoint is actually a transaction |
| 65296 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
| 65297 | ** If this is a transaction savepoint being opened, it is guaranteed |
| 65298 | ** that the db->aVTrans[] array is empty. */ |
| 65299 | assert( db->autoCommit==0 || db->nVTrans==0 ); |
| 65300 | rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, |
| 65301 | db->nStatement+db->nSavepoint); |
| 65302 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 65303 | #endif |
| 65304 | |
| 65305 | /* Create a new savepoint structure. */ |
| 65306 | u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); |
| 65307 | if( u.aq.pNew ){ |
| 65308 | u.aq.pNew->zName = (char *)&u.aq.pNew[1]; |
| @@ -65498,11 +65551,11 @@ | |
| 65551 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 65552 | db->nStatement++; |
| 65553 | p->iStatement = db->nSavepoint + db->nStatement; |
| 65554 | } |
| 65555 | |
| 65556 | rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); |
| 65557 | if( rc==SQLITE_OK ){ |
| 65558 | rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); |
| 65559 | } |
| 65560 | |
| 65561 | /* Store the current value of the database handles deferred constraint |
| @@ -68631,25 +68684,25 @@ | |
| 68684 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 68685 | */ |
| 68686 | case OP_Trace: { |
| 68687 | #if 0 /* local variables moved into u.cn */ |
| 68688 | char *zTrace; |
| 68689 | char *z; |
| 68690 | #endif /* local variables moved into u.cn */ |
| 68691 | |
| 68692 | if( db->xTrace && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ |
| 68693 | u.cn.z = sqlite3VdbeExpandSql(p, u.cn.zTrace); |
| 68694 | db->xTrace(db->pTraceArg, u.cn.z); |
| 68695 | sqlite3DbFree(db, u.cn.z); |
| 68696 | } |
| 68697 | #ifdef SQLITE_DEBUG |
| 68698 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 68699 | && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 68700 | ){ |
| 68701 | sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); |
| 68702 | } |
| 68703 | #endif /* SQLITE_DEBUG */ |
| 68704 | break; |
| 68705 | } |
| 68706 | #endif |
| 68707 | |
| 68708 | |
| @@ -69070,11 +69123,14 @@ | |
| 69123 | ** and offset cache without causing any IO. |
| 69124 | */ |
| 69125 | sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); |
| 69126 | sqlite3VdbeChangeP2(v, 7, pTab->nCol); |
| 69127 | if( !db->mallocFailed ){ |
| 69128 | pParse->nVar = 1; |
| 69129 | pParse->nMem = 1; |
| 69130 | pParse->nTab = 1; |
| 69131 | sqlite3VdbeMakeReady(v, pParse); |
| 69132 | } |
| 69133 | } |
| 69134 | |
| 69135 | pBlob->flags = flags; |
| 69136 | pBlob->iCol = iCol; |
| @@ -71637,57 +71693,57 @@ | |
| 71693 | assert( z[0]!=0 ); |
| 71694 | if( z[1]==0 ){ |
| 71695 | /* Wildcard of the form "?". Assign the next variable number */ |
| 71696 | assert( z[0]=='?' ); |
| 71697 | pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71698 | }else{ |
| 71699 | ynVar x = 0; |
| 71700 | u32 n = sqlite3Strlen30(z); |
| 71701 | if( z[0]=='?' ){ |
| 71702 | /* Wildcard of the form "?nnn". Convert "nnn" to an integer and |
| 71703 | ** use it as the variable number */ |
| 71704 | i64 i; |
| 71705 | int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); |
| 71706 | pExpr->iColumn = x = (ynVar)i; |
| 71707 | testcase( i==0 ); |
| 71708 | testcase( i==1 ); |
| 71709 | testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); |
| 71710 | testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); |
| 71711 | if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71712 | sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", |
| 71713 | db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); |
| 71714 | x = 0; |
| 71715 | } |
| 71716 | if( i>pParse->nVar ){ |
| 71717 | pParse->nVar = (int)i; |
| 71718 | } |
| 71719 | }else{ |
| 71720 | /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable |
| 71721 | ** number as the prior appearance of the same name, or if the name |
| 71722 | ** has never appeared before, reuse the same variable number |
| 71723 | */ |
| 71724 | ynVar i; |
| 71725 | for(i=0; i<pParse->nzVar; i++){ |
| 71726 | if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ |
| 71727 | pExpr->iColumn = x = (ynVar)i+1; |
| 71728 | break; |
| 71729 | } |
| 71730 | } |
| 71731 | if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71732 | } |
| 71733 | if( x>0 ){ |
| 71734 | if( x>pParse->nzVar ){ |
| 71735 | char **a; |
| 71736 | a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); |
| 71737 | if( a==0 ) return; /* Error reported through db->mallocFailed */ |
| 71738 | pParse->azVar = a; |
| 71739 | memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); |
| 71740 | pParse->nzVar = x; |
| 71741 | } |
| 71742 | if( z[0]!='?' || pParse->azVar[x-1]==0 ){ |
| 71743 | sqlite3DbFree(db, pParse->azVar[x-1]); |
| 71744 | pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); |
| 71745 | } |
| 71746 | } |
| 71747 | } |
| 71748 | if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71749 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| @@ -73427,11 +73483,13 @@ | |
| 73483 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 73484 | assert( pExpr->u.zToken!=0 ); |
| 73485 | assert( pExpr->u.zToken[0]!=0 ); |
| 73486 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); |
| 73487 | if( pExpr->u.zToken[1]!=0 ){ |
| 73488 | assert( pExpr->u.zToken[0]=='?' |
| 73489 | || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); |
| 73490 | sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); |
| 73491 | } |
| 73492 | break; |
| 73493 | } |
| 73494 | case TK_REGISTER: { |
| 73495 | inReg = pExpr->iTable; |
| @@ -77398,13 +77456,11 @@ | |
| 77456 | #endif |
| 77457 | assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ |
| 77458 | /* A minimum of one cursor is required if autoincrement is used |
| 77459 | * See ticket [a696379c1f08866] */ |
| 77460 | if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; |
| 77461 | sqlite3VdbeMakeReady(v, pParse); |
| 77462 | pParse->rc = SQLITE_DONE; |
| 77463 | pParse->colNamesSet = 0; |
| 77464 | }else{ |
| 77465 | pParse->rc = SQLITE_ERROR; |
| 77466 | } |
| @@ -81817,10 +81873,11 @@ | |
| 81873 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 81874 | if( IsVirtual(pTab) ){ |
| 81875 | const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); |
| 81876 | sqlite3VtabMakeWritable(pParse, pTab); |
| 81877 | sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); |
| 81878 | sqlite3VdbeChangeP5(v, OE_Abort); |
| 81879 | sqlite3MayAbort(pParse); |
| 81880 | }else |
| 81881 | #endif |
| 81882 | { |
| 81883 | int count = (pParse->nested==0); /* True to count changes */ |
| @@ -87937,14 +87994,10 @@ | |
| 87994 | ** |
| 87995 | ************************************************************************* |
| 87996 | ** This file contains code used to implement the PRAGMA command. |
| 87997 | */ |
| 87998 | |
| 87999 | /* |
| 88000 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| 88001 | ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or |
| 88002 | ** unrecognized string argument. |
| 88003 | ** |
| @@ -87976,10 +88029,16 @@ | |
| 88029 | ** Interpret the given string as a boolean value. |
| 88030 | */ |
| 88031 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ |
| 88032 | return getSafetyLevel(z)&1; |
| 88033 | } |
| 88034 | |
| 88035 | /* The sqlite3GetBoolean() function is used by other modules but the |
| 88036 | ** remainder of this file is specific to PRAGMA processing. So omit |
| 88037 | ** the rest of the file if PRAGMAs are omitted from the build. |
| 88038 | */ |
| 88039 | #if !defined(SQLITE_OMIT_PRAGMA) |
| 88040 | |
| 88041 | /* |
| 88042 | ** Interpret the given string as a locking mode value. |
| 88043 | */ |
| 88044 | static int getLockingMode(const char *z){ |
| @@ -97682,15 +97741,15 @@ | |
| 97741 | sqlite3DbFree(db, zErr); |
| 97742 | } |
| 97743 | |
| 97744 | return rc; |
| 97745 | } |
| 97746 | /* |
| 97747 | ** Grow the db->aVTrans[] array so that there is room for at least one |
| 97748 | ** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. |
| 97749 | */ |
| 97750 | static int growVTrans(sqlite3 *db){ |
| 97751 | const int ARRAY_INCR = 5; |
| 97752 | |
| 97753 | /* Grow the sqlite3.aVTrans array if required */ |
| 97754 | if( (db->nVTrans%ARRAY_INCR)==0 ){ |
| 97755 | VTable **aVTrans; |
| @@ -97701,14 +97760,21 @@ | |
| 97760 | } |
| 97761 | memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); |
| 97762 | db->aVTrans = aVTrans; |
| 97763 | } |
| 97764 | |
| 97765 | return SQLITE_OK; |
| 97766 | } |
| 97767 | |
| 97768 | /* |
| 97769 | ** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should |
| 97770 | ** have already been reserved using growVTrans(). |
| 97771 | */ |
| 97772 | static void addToVTrans(sqlite3 *db, VTable *pVTab){ |
| 97773 | /* Add pVtab to the end of sqlite3.aVTrans */ |
| 97774 | db->aVTrans[db->nVTrans++] = pVTab; |
| 97775 | sqlite3VtabLock(pVTab); |
| 97776 | } |
| 97777 | |
| 97778 | /* |
| 97779 | ** This function is invoked by the vdbe to call the xCreate method |
| 97780 | ** of the virtual table named zTab in database iDb. |
| @@ -97742,11 +97808,14 @@ | |
| 97808 | } |
| 97809 | |
| 97810 | /* Justification of ALWAYS(): The xConstructor method is required to |
| 97811 | ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ |
| 97812 | if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ |
| 97813 | rc = growVTrans(db); |
| 97814 | if( rc==SQLITE_OK ){ |
| 97815 | addToVTrans(db, sqlite3GetVTable(db, pTab)); |
| 97816 | } |
| 97817 | } |
| 97818 | |
| 97819 | return rc; |
| 97820 | } |
| 97821 | |
| @@ -97858,10 +97927,11 @@ | |
| 97927 | if( p ){ |
| 97928 | int (*x)(sqlite3_vtab *); |
| 97929 | x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); |
| 97930 | if( x ) x(p); |
| 97931 | } |
| 97932 | pVTab->iSavepoint = 0; |
| 97933 | sqlite3VtabUnlock(pVTab); |
| 97934 | } |
| 97935 | sqlite3DbFree(db, db->aVTrans); |
| 97936 | db->nVTrans = 0; |
| 97937 | db->aVTrans = 0; |
| @@ -97947,14 +98017,18 @@ | |
| 98017 | if( db->aVTrans[i]==pVTab ){ |
| 98018 | return SQLITE_OK; |
| 98019 | } |
| 98020 | } |
| 98021 | |
| 98022 | /* Invoke the xBegin method. If successful, add the vtab to the |
| 98023 | ** sqlite3.aVTrans[] array. */ |
| 98024 | rc = growVTrans(db); |
| 98025 | if( rc==SQLITE_OK ){ |
| 98026 | rc = pModule->xBegin(pVTab->pVtab); |
| 98027 | if( rc==SQLITE_OK ){ |
| 98028 | addToVTrans(db, pVTab); |
| 98029 | } |
| 98030 | } |
| 98031 | } |
| 98032 | return rc; |
| 98033 | } |
| 98034 | |
| @@ -97975,28 +98049,33 @@ | |
| 98049 | */ |
| 98050 | SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ |
| 98051 | int rc = SQLITE_OK; |
| 98052 | |
| 98053 | assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); |
| 98054 | assert( iSavepoint>=0 ); |
| 98055 | if( db->aVTrans ){ |
| 98056 | int i; |
| 98057 | for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ |
| 98058 | VTable *pVTab = db->aVTrans[i]; |
| 98059 | const sqlite3_module *pMod = pVTab->pMod->pModule; |
| 98060 | if( pMod->iVersion>=2 ){ |
| 98061 | int (*xMethod)(sqlite3_vtab *, int); |
| 98062 | switch( op ){ |
| 98063 | case SAVEPOINT_BEGIN: |
| 98064 | xMethod = pMod->xSavepoint; |
| 98065 | pVTab->iSavepoint = iSavepoint+1; |
| 98066 | break; |
| 98067 | case SAVEPOINT_ROLLBACK: |
| 98068 | xMethod = pMod->xRollbackTo; |
| 98069 | break; |
| 98070 | default: |
| 98071 | xMethod = pMod->xRelease; |
| 98072 | break; |
| 98073 | } |
| 98074 | if( xMethod && pVTab->iSavepoint>iSavepoint ){ |
| 98075 | rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); |
| 98076 | } |
| 98077 | } |
| 98078 | } |
| 98079 | } |
| 98080 | return rc; |
| 98081 | } |
| @@ -107254,13 +107333,12 @@ | |
| 107333 | return SQLITE_NOMEM; |
| 107334 | } |
| 107335 | assert( pParse->pNewTable==0 ); |
| 107336 | assert( pParse->pNewTrigger==0 ); |
| 107337 | assert( pParse->nVar==0 ); |
| 107338 | assert( pParse->nzVar==0 ); |
| 107339 | assert( pParse->azVar==0 ); |
| 107340 | enableLookaside = db->lookaside.bEnabled; |
| 107341 | if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; |
| 107342 | while( !db->mallocFailed && zSql[i]!=0 ){ |
| 107343 | assert( i>=0 ); |
| 107344 | pParse->sLastToken.z = &zSql[i]; |
| @@ -107350,11 +107428,12 @@ | |
| 107428 | */ |
| 107429 | sqlite3DeleteTable(db, pParse->pNewTable); |
| 107430 | } |
| 107431 | |
| 107432 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); |
| 107433 | for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); |
| 107434 | sqlite3DbFree(db, pParse->azVar); |
| 107435 | sqlite3DbFree(db, pParse->aAlias); |
| 107436 | while( pParse->pAinc ){ |
| 107437 | AutoincInfo *p = pParse->pAinc; |
| 107438 | pParse->pAinc = p->pNext; |
| 107439 | sqlite3DbFree(db, p); |
| @@ -109682,13 +109761,13 @@ | |
| 109761 | }else{ |
| 109762 | struct OpenMode { |
| 109763 | const char *z; |
| 109764 | int mode; |
| 109765 | } *aMode = 0; |
| 109766 | char *zModeType = 0; |
| 109767 | int mask = 0; |
| 109768 | int limit = 0; |
| 109769 | |
| 109770 | if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ |
| 109771 | static struct OpenMode aCacheMode[] = { |
| 109772 | { "shared", SQLITE_OPEN_SHAREDCACHE }, |
| 109773 | { "private", SQLITE_OPEN_PRIVATECACHE }, |
| @@ -111676,15 +111755,35 @@ | |
| 111755 | */ |
| 111756 | typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ |
| 111757 | typedef short int i16; /* 2-byte (or larger) signed integer */ |
| 111758 | typedef unsigned int u32; /* 4-byte unsigned integer */ |
| 111759 | typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ |
| 111760 | |
| 111761 | /* |
| 111762 | ** Macro used to suppress compiler warnings for unused parameters. |
| 111763 | */ |
| 111764 | #define UNUSED_PARAMETER(x) (void)(x) |
| 111765 | |
| 111766 | /* |
| 111767 | ** Activate assert() only if SQLITE_TEST is enabled. |
| 111768 | */ |
| 111769 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 111770 | # define NDEBUG 1 |
| 111771 | #endif |
| 111772 | |
| 111773 | /* |
| 111774 | ** The TESTONLY macro is used to enclose variable declarations or |
| 111775 | ** other bits of code that are needed to support the arguments |
| 111776 | ** within testcase() and assert() macros. |
| 111777 | */ |
| 111778 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) |
| 111779 | # define TESTONLY(X) X |
| 111780 | #else |
| 111781 | # define TESTONLY(X) |
| 111782 | #endif |
| 111783 | |
| 111784 | #endif /* SQLITE_AMALGAMATION */ |
| 111785 | |
| 111786 | typedef struct Fts3Table Fts3Table; |
| 111787 | typedef struct Fts3Cursor Fts3Cursor; |
| 111788 | typedef struct Fts3Expr Fts3Expr; |
| 111789 | typedef struct Fts3Phrase Fts3Phrase; |
| @@ -111735,10 +111834,20 @@ | |
| 111834 | */ |
| 111835 | int nMaxPendingData; |
| 111836 | int nPendingData; |
| 111837 | sqlite_int64 iPrevDocid; |
| 111838 | Fts3Hash pendingTerms; |
| 111839 | |
| 111840 | #if defined(SQLITE_DEBUG) |
| 111841 | /* State variables used for validating that the transaction control |
| 111842 | ** methods of the virtual table are called at appropriate times. These |
| 111843 | ** values do not contribution to the FTS computation; they are used for |
| 111844 | ** verifying the SQLite core. |
| 111845 | */ |
| 111846 | int inTransaction; /* True after xBegin but before xCommit/xRollback */ |
| 111847 | int mxSavepoint; /* Largest valid xSavepoint integer */ |
| 111848 | #endif |
| 111849 | }; |
| 111850 | |
| 111851 | /* |
| 111852 | ** When the core wants to read from the virtual table, it creates a |
| 111853 | ** virtual table cursor (an instance of the following structure) using |
| @@ -112645,10 +112754,12 @@ | |
| 112754 | p->pTokenizer = pTokenizer; |
| 112755 | p->nNodeSize = 1000; |
| 112756 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 112757 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 112758 | p->bHasStat = isFts4; |
| 112759 | TESTONLY( p->inTransaction = -1 ); |
| 112760 | TESTONLY( p->mxSavepoint = -1 ); |
| 112761 | fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); |
| 112762 | |
| 112763 | /* Fill in the zName and zDb fields of the vtab structure. */ |
| 112764 | zCsr = (char *)&p->azColumn[nCol]; |
| 112765 | p->zName = zCsr; |
| @@ -114942,11 +115053,15 @@ | |
| 115053 | /* |
| 115054 | ** Implementation of xBegin() method. This is a no-op. |
| 115055 | */ |
| 115056 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 115057 | UNUSED_PARAMETER(pVtab); |
| 115058 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 115059 | assert( p->nPendingData==0 ); |
| 115060 | assert( p->inTransaction!=1 ); |
| 115061 | TESTONLY( p->inTransaction = 1 ); |
| 115062 | TESTONLY( p->mxSavepoint = -1; ); |
| 115063 | return SQLITE_OK; |
| 115064 | } |
| 115065 | |
| 115066 | /* |
| 115067 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| @@ -114953,20 +115068,28 @@ | |
| 115068 | ** the pending-terms hash-table have already been flushed into the database |
| 115069 | ** by fts3SyncMethod(). |
| 115070 | */ |
| 115071 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 115072 | UNUSED_PARAMETER(pVtab); |
| 115073 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 115074 | assert( p->nPendingData==0 ); |
| 115075 | assert( p->inTransaction!=0 ); |
| 115076 | TESTONLY( p->inTransaction = 0 ); |
| 115077 | TESTONLY( p->mxSavepoint = -1; ); |
| 115078 | return SQLITE_OK; |
| 115079 | } |
| 115080 | |
| 115081 | /* |
| 115082 | ** Implementation of xRollback(). Discard the contents of the pending-terms |
| 115083 | ** hash-table. Any changes made to the database are reverted by SQLite. |
| 115084 | */ |
| 115085 | static int fts3RollbackMethod(sqlite3_vtab *pVtab){ |
| 115086 | Fts3Table *p = (Fts3Table*)pVtab; |
| 115087 | sqlite3Fts3PendingTermsClear(p); |
| 115088 | assert( p->inTransaction!=0 ); |
| 115089 | TESTONLY( p->inTransaction = 0 ); |
| 115090 | TESTONLY( p->mxSavepoint = -1; ); |
| 115091 | return SQLITE_OK; |
| 115092 | } |
| 115093 | |
| 115094 | /* |
| 115095 | ** Load the doclist associated with expression pExpr to pExpr->aDoclist. |
| @@ -115318,17 +115441,33 @@ | |
| 115441 | ); |
| 115442 | return rc; |
| 115443 | } |
| 115444 | |
| 115445 | static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115446 | Fts3Table *p = (Fts3Table*)pVtab; |
| 115447 | UNUSED_PARAMETER(iSavepoint); |
| 115448 | assert( p->inTransaction ); |
| 115449 | assert( p->mxSavepoint < iSavepoint ); |
| 115450 | TESTONLY( p->mxSavepoint = iSavepoint ); |
| 115451 | return sqlite3Fts3PendingTermsFlush(p); |
| 115452 | } |
| 115453 | static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115454 | TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 115455 | UNUSED_PARAMETER(iSavepoint); |
| 115456 | UNUSED_PARAMETER(pVtab); |
| 115457 | assert( p->inTransaction ); |
| 115458 | assert( p->mxSavepoint >= iSavepoint ); |
| 115459 | TESTONLY( p->mxSavepoint = iSavepoint-1 ); |
| 115460 | return SQLITE_OK; |
| 115461 | } |
| 115462 | static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115463 | Fts3Table *p = (Fts3Table*)pVtab; |
| 115464 | UNUSED_PARAMETER(iSavepoint); |
| 115465 | assert( p->inTransaction ); |
| 115466 | assert( p->mxSavepoint >= iSavepoint ); |
| 115467 | TESTONLY( p->mxSavepoint = iSavepoint ); |
| 115468 | sqlite3Fts3PendingTermsClear(p); |
| 115469 | return SQLITE_OK; |
| 115470 | } |
| 115471 | |
| 115472 | static const sqlite3_module fts3Module = { |
| 115473 | /* iVersion */ 2, |
| @@ -115823,10 +115962,11 @@ | |
| 115962 | Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; |
| 115963 | int rc; |
| 115964 | int isScan; |
| 115965 | |
| 115966 | UNUSED_PARAMETER(nVal); |
| 115967 | UNUSED_PARAMETER(idxStr); |
| 115968 | |
| 115969 | assert( idxStr==0 ); |
| 115970 | assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 |
| 115971 | || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT |
| 115972 | || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) |
| @@ -115940,11 +116080,14 @@ | |
| 116080 | 0, /* xBegin */ |
| 116081 | 0, /* xSync */ |
| 116082 | 0, /* xCommit */ |
| 116083 | 0, /* xRollback */ |
| 116084 | 0, /* xFindFunction */ |
| 116085 | 0, /* xRename */ |
| 116086 | 0, /* xSavepoint */ |
| 116087 | 0, /* xRelease */ |
| 116088 | 0 /* xRollbackTo */ |
| 116089 | }; |
| 116090 | int rc; /* Return code */ |
| 116091 | |
| 116092 | rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); |
| 116093 | return rc; |
| @@ -125919,11 +126062,11 @@ | |
| 126062 | } |
| 126063 | return rc; |
| 126064 | } |
| 126065 | |
| 126066 | static sqlite3_module rtreeModule = { |
| 126067 | 0, /* iVersion */ |
| 126068 | rtreeCreate, /* xCreate - create a table */ |
| 126069 | rtreeConnect, /* xConnect - connect to an existing table */ |
| 126070 | rtreeBestIndex, /* xBestIndex - Determine search strategy */ |
| 126071 | rtreeDisconnect, /* xDisconnect - Disconnect from a table */ |
| 126072 | rtreeDestroy, /* xDestroy - Drop a table */ |
| @@ -125938,11 +126081,14 @@ | |
| 126081 | 0, /* xBegin - begin transaction */ |
| 126082 | 0, /* xSync - sync transaction */ |
| 126083 | 0, /* xCommit - commit transaction */ |
| 126084 | 0, /* xRollback - rollback transaction */ |
| 126085 | 0, /* xFindFunction - function overloading */ |
| 126086 | rtreeRename, /* xRename - rename the table */ |
| 126087 | 0, /* xSavepoint */ |
| 126088 | 0, /* xRelease */ |
| 126089 | 0 /* xRollbackTo */ |
| 126090 | }; |
| 126091 | |
| 126092 | static int rtreeSqlInit( |
| 126093 | Rtree *pRtree, |
| 126094 | sqlite3 *db, |
| 126095 |
+5
-3
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.7.7" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007007 |
| 112 | -#define SQLITE_SOURCE_ID "2011-05-18 03:02:10 186d7ff1d9804d508e472e4939608bf2be67bdc2" | |
| 112 | +#define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -457,10 +457,12 @@ | ||
| 457 | 457 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 458 | 458 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 459 | 459 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 460 | 460 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 461 | 461 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 462 | +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) | |
| 463 | +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) | |
| 462 | 464 | |
| 463 | 465 | /* |
| 464 | 466 | ** CAPI3REF: Flags For File Open Operations |
| 465 | 467 | ** |
| 466 | 468 | ** These bit values are intended for use in the |
| @@ -762,15 +764,15 @@ | ||
| 762 | 764 | */ |
| 763 | 765 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 764 | 766 | |
| 765 | 767 | /* |
| 766 | 768 | ** CAPI3REF: OS Interface Object |
| 767 | -** KEYWORDS: VFS VFSes | |
| 768 | 769 | ** |
| 769 | 770 | ** An instance of the sqlite3_vfs object defines the interface between |
| 770 | 771 | ** the SQLite core and the underlying operating system. The "vfs" |
| 771 | -** in the name of the object stands for "virtual file system". | |
| 772 | +** in the name of the object stands for "virtual file system". See | |
| 773 | +** the [VFS | VFS documentation] for further information. | |
| 772 | 774 | ** |
| 773 | 775 | ** The value of the iVersion field is initially 1 but may be larger in |
| 774 | 776 | ** future versions of SQLite. Additional fields may be appended to this |
| 775 | 777 | ** object when the iVersion value is increased. Note that the structure |
| 776 | 778 | ** of the sqlite3_vfs object changes in the transaction between |
| 777 | 779 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.7" |
| 111 | #define SQLITE_VERSION_NUMBER 3007007 |
| 112 | #define SQLITE_SOURCE_ID "2011-05-18 03:02:10 186d7ff1d9804d508e472e4939608bf2be67bdc2" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -457,10 +457,12 @@ | |
| 457 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 458 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 459 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 460 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 461 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 462 | |
| 463 | /* |
| 464 | ** CAPI3REF: Flags For File Open Operations |
| 465 | ** |
| 466 | ** These bit values are intended for use in the |
| @@ -762,15 +764,15 @@ | |
| 762 | */ |
| 763 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 764 | |
| 765 | /* |
| 766 | ** CAPI3REF: OS Interface Object |
| 767 | ** KEYWORDS: VFS VFSes |
| 768 | ** |
| 769 | ** An instance of the sqlite3_vfs object defines the interface between |
| 770 | ** the SQLite core and the underlying operating system. The "vfs" |
| 771 | ** in the name of the object stands for "virtual file system". |
| 772 | ** |
| 773 | ** The value of the iVersion field is initially 1 but may be larger in |
| 774 | ** future versions of SQLite. Additional fields may be appended to this |
| 775 | ** object when the iVersion value is increased. Note that the structure |
| 776 | ** of the sqlite3_vfs object changes in the transaction between |
| 777 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.7" |
| 111 | #define SQLITE_VERSION_NUMBER 3007007 |
| 112 | #define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -457,10 +457,12 @@ | |
| 457 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 458 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 459 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 460 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 461 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 462 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 463 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 464 | |
| 465 | /* |
| 466 | ** CAPI3REF: Flags For File Open Operations |
| 467 | ** |
| 468 | ** These bit values are intended for use in the |
| @@ -762,15 +764,15 @@ | |
| 764 | */ |
| 765 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 766 | |
| 767 | /* |
| 768 | ** CAPI3REF: OS Interface Object |
| 769 | ** |
| 770 | ** An instance of the sqlite3_vfs object defines the interface between |
| 771 | ** the SQLite core and the underlying operating system. The "vfs" |
| 772 | ** in the name of the object stands for "virtual file system". See |
| 773 | ** the [VFS | VFS documentation] for further information. |
| 774 | ** |
| 775 | ** The value of the iVersion field is initially 1 but may be larger in |
| 776 | ** future versions of SQLite. Additional fields may be appended to this |
| 777 | ** object when the iVersion value is increased. Note that the structure |
| 778 | ** of the sqlite3_vfs object changes in the transaction between |
| 779 |
+14
-14
| --- src/stash.c | ||
| +++ src/stash.c | ||
| @@ -185,33 +185,33 @@ | ||
| 185 | 185 | blob_zero(&delta); |
| 186 | 186 | if( rid==0 ){ |
| 187 | 187 | db_ephemeral_blob(&q, 5, &delta); |
| 188 | 188 | blob_write_to_file(&delta, zNPath); |
| 189 | 189 | file_setexe(zNPath, isExec); |
| 190 | - printf("ADD %s\n", zNew); | |
| 190 | + fossil_print("ADD %s\n", zNew); | |
| 191 | 191 | }else if( isRemoved ){ |
| 192 | - printf("DELETE %s\n", zOrig); | |
| 193 | - unlink(zOPath); | |
| 192 | + fossil_print("DELETE %s\n", zOrig); | |
| 193 | + file_delete(zOPath); | |
| 194 | 194 | }else{ |
| 195 | 195 | Blob a, b, out, disk; |
| 196 | 196 | db_ephemeral_blob(&q, 5, &delta); |
| 197 | 197 | blob_read_from_file(&disk, zOPath); |
| 198 | 198 | content_get(rid, &a); |
| 199 | 199 | blob_delta_apply(&a, &delta, &b); |
| 200 | 200 | if( blob_compare(&disk, &a)==0 ){ |
| 201 | 201 | blob_write_to_file(&b, zNPath); |
| 202 | 202 | file_setexe(zNPath, isExec); |
| 203 | - printf("UPDATE %s\n", zNew); | |
| 203 | + fossil_print("UPDATE %s\n", zNew); | |
| 204 | 204 | }else{ |
| 205 | 205 | int rc = merge_3way(&a, zOPath, &b, &out); |
| 206 | 206 | blob_write_to_file(&out, zNPath); |
| 207 | 207 | file_setexe(zNPath, isExec); |
| 208 | 208 | if( rc ){ |
| 209 | - printf("CONFLICT %s\n", zNew); | |
| 209 | + fossil_print("CONFLICT %s\n", zNew); | |
| 210 | 210 | nConflict++; |
| 211 | 211 | }else{ |
| 212 | - printf("MERGE %s\n", zNew); | |
| 212 | + fossil_print("MERGE %s\n", zNew); | |
| 213 | 213 | } |
| 214 | 214 | blob_reset(&out); |
| 215 | 215 | } |
| 216 | 216 | blob_reset(&a); |
| 217 | 217 | blob_reset(&b); |
| @@ -218,16 +218,16 @@ | ||
| 218 | 218 | blob_reset(&disk); |
| 219 | 219 | } |
| 220 | 220 | blob_reset(&delta); |
| 221 | 221 | if( fossil_strcmp(zOrig,zNew)!=0 ){ |
| 222 | 222 | undo_save(zOrig); |
| 223 | - unlink(zOPath); | |
| 223 | + file_delete(zOPath); | |
| 224 | 224 | } |
| 225 | 225 | } |
| 226 | 226 | db_finalize(&q); |
| 227 | 227 | if( nConflict ){ |
| 228 | - printf("WARNING: merge conflicts - see messages above for details.\n"); | |
| 228 | + fossil_print("WARNING: merge conflicts - see messages above for details.\n"); | |
| 229 | 229 | } |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | /* |
| 233 | 233 | ** Show the diffs associate with a single stash. |
| @@ -248,25 +248,25 @@ | ||
| 248 | 248 | const char *zNew = db_column_text(&q, 4); |
| 249 | 249 | char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); |
| 250 | 250 | Blob delta; |
| 251 | 251 | if( rid==0 ){ |
| 252 | 252 | db_ephemeral_blob(&q, 5, &delta); |
| 253 | - printf("ADDED %s\n", zNew); | |
| 253 | + fossil_print("ADDED %s\n", zNew); | |
| 254 | 254 | diff_print_index(zNew); |
| 255 | 255 | diff_file_mem(&empty, &delta, zNew, zDiffCmd, 0); |
| 256 | 256 | }else if( isRemoved ){ |
| 257 | - printf("DELETE %s\n", zOrig); | |
| 257 | + fossil_print("DELETE %s\n", zOrig); | |
| 258 | 258 | blob_read_from_file(&delta, zOPath); |
| 259 | 259 | diff_print_index(zNew); |
| 260 | 260 | diff_file_mem(&delta, &empty, zOrig, zDiffCmd, 0); |
| 261 | 261 | }else{ |
| 262 | 262 | Blob a, b, disk; |
| 263 | 263 | db_ephemeral_blob(&q, 5, &delta); |
| 264 | 264 | blob_read_from_file(&disk, zOPath); |
| 265 | 265 | content_get(rid, &a); |
| 266 | 266 | blob_delta_apply(&a, &delta, &b); |
| 267 | - printf("CHANGED %s\n", zNew); | |
| 267 | + fossil_print("CHANGED %s\n", zNew); | |
| 268 | 268 | diff_file_mem(&disk, &b, zNew, zDiffCmd, 0); |
| 269 | 269 | blob_reset(&a); |
| 270 | 270 | blob_reset(&b); |
| 271 | 271 | blob_reset(&disk); |
| 272 | 272 | } |
| @@ -413,23 +413,23 @@ | ||
| 413 | 413 | " ORDER BY ctime DESC" |
| 414 | 414 | ); |
| 415 | 415 | while( db_step(&q)==SQLITE_ROW ){ |
| 416 | 416 | const char *zCom; |
| 417 | 417 | n++; |
| 418 | - printf("%5d: [%.14s] on %s\n", | |
| 418 | + fossil_print("%5d: [%.14s] on %s\n", | |
| 419 | 419 | db_column_int(&q, 0), |
| 420 | 420 | db_column_text(&q, 1), |
| 421 | 421 | db_column_text(&q, 3) |
| 422 | 422 | ); |
| 423 | 423 | zCom = db_column_text(&q, 2); |
| 424 | 424 | if( zCom && zCom[0] ){ |
| 425 | - printf(" "); | |
| 425 | + fossil_print(" "); | |
| 426 | 426 | comment_print(zCom, 7, 79); |
| 427 | 427 | } |
| 428 | 428 | } |
| 429 | 429 | db_finalize(&q); |
| 430 | - if( n==0 ) printf("empty stash\n"); | |
| 430 | + if( n==0 ) fossil_print("empty stash\n"); | |
| 431 | 431 | }else |
| 432 | 432 | if( memcmp(zCmd, "drop", nCmd)==0 ){ |
| 433 | 433 | int allFlag = find_option("all", 0, 0)!=0; |
| 434 | 434 | if( g.argc>4 ) usage("stash apply STASHID"); |
| 435 | 435 | if( allFlag ){ |
| 436 | 436 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -185,33 +185,33 @@ | |
| 185 | blob_zero(&delta); |
| 186 | if( rid==0 ){ |
| 187 | db_ephemeral_blob(&q, 5, &delta); |
| 188 | blob_write_to_file(&delta, zNPath); |
| 189 | file_setexe(zNPath, isExec); |
| 190 | printf("ADD %s\n", zNew); |
| 191 | }else if( isRemoved ){ |
| 192 | printf("DELETE %s\n", zOrig); |
| 193 | unlink(zOPath); |
| 194 | }else{ |
| 195 | Blob a, b, out, disk; |
| 196 | db_ephemeral_blob(&q, 5, &delta); |
| 197 | blob_read_from_file(&disk, zOPath); |
| 198 | content_get(rid, &a); |
| 199 | blob_delta_apply(&a, &delta, &b); |
| 200 | if( blob_compare(&disk, &a)==0 ){ |
| 201 | blob_write_to_file(&b, zNPath); |
| 202 | file_setexe(zNPath, isExec); |
| 203 | printf("UPDATE %s\n", zNew); |
| 204 | }else{ |
| 205 | int rc = merge_3way(&a, zOPath, &b, &out); |
| 206 | blob_write_to_file(&out, zNPath); |
| 207 | file_setexe(zNPath, isExec); |
| 208 | if( rc ){ |
| 209 | printf("CONFLICT %s\n", zNew); |
| 210 | nConflict++; |
| 211 | }else{ |
| 212 | printf("MERGE %s\n", zNew); |
| 213 | } |
| 214 | blob_reset(&out); |
| 215 | } |
| 216 | blob_reset(&a); |
| 217 | blob_reset(&b); |
| @@ -218,16 +218,16 @@ | |
| 218 | blob_reset(&disk); |
| 219 | } |
| 220 | blob_reset(&delta); |
| 221 | if( fossil_strcmp(zOrig,zNew)!=0 ){ |
| 222 | undo_save(zOrig); |
| 223 | unlink(zOPath); |
| 224 | } |
| 225 | } |
| 226 | db_finalize(&q); |
| 227 | if( nConflict ){ |
| 228 | printf("WARNING: merge conflicts - see messages above for details.\n"); |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | /* |
| 233 | ** Show the diffs associate with a single stash. |
| @@ -248,25 +248,25 @@ | |
| 248 | const char *zNew = db_column_text(&q, 4); |
| 249 | char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); |
| 250 | Blob delta; |
| 251 | if( rid==0 ){ |
| 252 | db_ephemeral_blob(&q, 5, &delta); |
| 253 | printf("ADDED %s\n", zNew); |
| 254 | diff_print_index(zNew); |
| 255 | diff_file_mem(&empty, &delta, zNew, zDiffCmd, 0); |
| 256 | }else if( isRemoved ){ |
| 257 | printf("DELETE %s\n", zOrig); |
| 258 | blob_read_from_file(&delta, zOPath); |
| 259 | diff_print_index(zNew); |
| 260 | diff_file_mem(&delta, &empty, zOrig, zDiffCmd, 0); |
| 261 | }else{ |
| 262 | Blob a, b, disk; |
| 263 | db_ephemeral_blob(&q, 5, &delta); |
| 264 | blob_read_from_file(&disk, zOPath); |
| 265 | content_get(rid, &a); |
| 266 | blob_delta_apply(&a, &delta, &b); |
| 267 | printf("CHANGED %s\n", zNew); |
| 268 | diff_file_mem(&disk, &b, zNew, zDiffCmd, 0); |
| 269 | blob_reset(&a); |
| 270 | blob_reset(&b); |
| 271 | blob_reset(&disk); |
| 272 | } |
| @@ -413,23 +413,23 @@ | |
| 413 | " ORDER BY ctime DESC" |
| 414 | ); |
| 415 | while( db_step(&q)==SQLITE_ROW ){ |
| 416 | const char *zCom; |
| 417 | n++; |
| 418 | printf("%5d: [%.14s] on %s\n", |
| 419 | db_column_int(&q, 0), |
| 420 | db_column_text(&q, 1), |
| 421 | db_column_text(&q, 3) |
| 422 | ); |
| 423 | zCom = db_column_text(&q, 2); |
| 424 | if( zCom && zCom[0] ){ |
| 425 | printf(" "); |
| 426 | comment_print(zCom, 7, 79); |
| 427 | } |
| 428 | } |
| 429 | db_finalize(&q); |
| 430 | if( n==0 ) printf("empty stash\n"); |
| 431 | }else |
| 432 | if( memcmp(zCmd, "drop", nCmd)==0 ){ |
| 433 | int allFlag = find_option("all", 0, 0)!=0; |
| 434 | if( g.argc>4 ) usage("stash apply STASHID"); |
| 435 | if( allFlag ){ |
| 436 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -185,33 +185,33 @@ | |
| 185 | blob_zero(&delta); |
| 186 | if( rid==0 ){ |
| 187 | db_ephemeral_blob(&q, 5, &delta); |
| 188 | blob_write_to_file(&delta, zNPath); |
| 189 | file_setexe(zNPath, isExec); |
| 190 | fossil_print("ADD %s\n", zNew); |
| 191 | }else if( isRemoved ){ |
| 192 | fossil_print("DELETE %s\n", zOrig); |
| 193 | file_delete(zOPath); |
| 194 | }else{ |
| 195 | Blob a, b, out, disk; |
| 196 | db_ephemeral_blob(&q, 5, &delta); |
| 197 | blob_read_from_file(&disk, zOPath); |
| 198 | content_get(rid, &a); |
| 199 | blob_delta_apply(&a, &delta, &b); |
| 200 | if( blob_compare(&disk, &a)==0 ){ |
| 201 | blob_write_to_file(&b, zNPath); |
| 202 | file_setexe(zNPath, isExec); |
| 203 | fossil_print("UPDATE %s\n", zNew); |
| 204 | }else{ |
| 205 | int rc = merge_3way(&a, zOPath, &b, &out); |
| 206 | blob_write_to_file(&out, zNPath); |
| 207 | file_setexe(zNPath, isExec); |
| 208 | if( rc ){ |
| 209 | fossil_print("CONFLICT %s\n", zNew); |
| 210 | nConflict++; |
| 211 | }else{ |
| 212 | fossil_print("MERGE %s\n", zNew); |
| 213 | } |
| 214 | blob_reset(&out); |
| 215 | } |
| 216 | blob_reset(&a); |
| 217 | blob_reset(&b); |
| @@ -218,16 +218,16 @@ | |
| 218 | blob_reset(&disk); |
| 219 | } |
| 220 | blob_reset(&delta); |
| 221 | if( fossil_strcmp(zOrig,zNew)!=0 ){ |
| 222 | undo_save(zOrig); |
| 223 | file_delete(zOPath); |
| 224 | } |
| 225 | } |
| 226 | db_finalize(&q); |
| 227 | if( nConflict ){ |
| 228 | fossil_print("WARNING: merge conflicts - see messages above for details.\n"); |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | /* |
| 233 | ** Show the diffs associate with a single stash. |
| @@ -248,25 +248,25 @@ | |
| 248 | const char *zNew = db_column_text(&q, 4); |
| 249 | char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); |
| 250 | Blob delta; |
| 251 | if( rid==0 ){ |
| 252 | db_ephemeral_blob(&q, 5, &delta); |
| 253 | fossil_print("ADDED %s\n", zNew); |
| 254 | diff_print_index(zNew); |
| 255 | diff_file_mem(&empty, &delta, zNew, zDiffCmd, 0); |
| 256 | }else if( isRemoved ){ |
| 257 | fossil_print("DELETE %s\n", zOrig); |
| 258 | blob_read_from_file(&delta, zOPath); |
| 259 | diff_print_index(zNew); |
| 260 | diff_file_mem(&delta, &empty, zOrig, zDiffCmd, 0); |
| 261 | }else{ |
| 262 | Blob a, b, disk; |
| 263 | db_ephemeral_blob(&q, 5, &delta); |
| 264 | blob_read_from_file(&disk, zOPath); |
| 265 | content_get(rid, &a); |
| 266 | blob_delta_apply(&a, &delta, &b); |
| 267 | fossil_print("CHANGED %s\n", zNew); |
| 268 | diff_file_mem(&disk, &b, zNew, zDiffCmd, 0); |
| 269 | blob_reset(&a); |
| 270 | blob_reset(&b); |
| 271 | blob_reset(&disk); |
| 272 | } |
| @@ -413,23 +413,23 @@ | |
| 413 | " ORDER BY ctime DESC" |
| 414 | ); |
| 415 | while( db_step(&q)==SQLITE_ROW ){ |
| 416 | const char *zCom; |
| 417 | n++; |
| 418 | fossil_print("%5d: [%.14s] on %s\n", |
| 419 | db_column_int(&q, 0), |
| 420 | db_column_text(&q, 1), |
| 421 | db_column_text(&q, 3) |
| 422 | ); |
| 423 | zCom = db_column_text(&q, 2); |
| 424 | if( zCom && zCom[0] ){ |
| 425 | fossil_print(" "); |
| 426 | comment_print(zCom, 7, 79); |
| 427 | } |
| 428 | } |
| 429 | db_finalize(&q); |
| 430 | if( n==0 ) fossil_print("empty stash\n"); |
| 431 | }else |
| 432 | if( memcmp(zCmd, "drop", nCmd)==0 ){ |
| 433 | int allFlag = find_option("all", 0, 0)!=0; |
| 434 | if( g.argc>4 ) usage("stash apply STASHID"); |
| 435 | if( allFlag ){ |
| 436 |
+16
-5
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -43,10 +43,13 @@ | ||
| 43 | 43 | const char *zPw; |
| 44 | 44 | int rc; |
| 45 | 45 | int configSync = 0; /* configuration changes transferred */ |
| 46 | 46 | if( g.fNoSync ){ |
| 47 | 47 | return 0; |
| 48 | + } | |
| 49 | + if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 50 | + return 0; | |
| 48 | 51 | } |
| 49 | 52 | zAutosync = db_get("autosync", 0); |
| 50 | 53 | if( zAutosync ){ |
| 51 | 54 | if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 52 | 55 | return 0; /* Do not auto-push when autosync=pullonly */ |
| @@ -76,11 +79,11 @@ | ||
| 76 | 79 | ** autosync, or something? |
| 77 | 80 | */ |
| 78 | 81 | configSync = CONFIGSET_SHUN; |
| 79 | 82 | } |
| 80 | 83 | #endif |
| 81 | - printf("Autosync: %s\n", g.urlCanonical); | |
| 84 | + fossil_print("Autosync: %s\n", g.urlCanonical); | |
| 82 | 85 | url_enable_proxy("via proxy: "); |
| 83 | 86 | rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); |
| 84 | 87 | if( rc ) fossil_warning("Autosync failed"); |
| 85 | 88 | return rc; |
| 86 | 89 | } |
| @@ -124,11 +127,11 @@ | ||
| 124 | 127 | db_set("last-sync-url", g.urlCanonical, 0); |
| 125 | 128 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 126 | 129 | } |
| 127 | 130 | user_select(); |
| 128 | 131 | if( g.argc==2 ){ |
| 129 | - printf("Server: %s\n", g.urlCanonical); | |
| 132 | + fossil_print("Server: %s\n", g.urlCanonical); | |
| 130 | 133 | } |
| 131 | 134 | url_enable_proxy("via proxy: "); |
| 132 | 135 | *pConfigSync = configSync; |
| 133 | 136 | } |
| 134 | 137 | |
| @@ -185,10 +188,13 @@ | ||
| 185 | 188 | */ |
| 186 | 189 | void push_cmd(void){ |
| 187 | 190 | int syncFlags; |
| 188 | 191 | int bPrivate; |
| 189 | 192 | process_sync_args(&syncFlags, &bPrivate); |
| 193 | + if( db_get_boolean("dont-push",0) ){ | |
| 194 | + fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); | |
| 195 | + } | |
| 190 | 196 | client_sync(1,0,0,bPrivate,0,0); |
| 191 | 197 | } |
| 192 | 198 | |
| 193 | 199 | |
| 194 | 200 | /* |
| @@ -219,12 +225,17 @@ | ||
| 219 | 225 | ** See also: clone, push, pull, remote-url |
| 220 | 226 | */ |
| 221 | 227 | void sync_cmd(void){ |
| 222 | 228 | int syncFlags; |
| 223 | 229 | int bPrivate; |
| 230 | + int pushFlag = 1; | |
| 224 | 231 | process_sync_args(&syncFlags, &bPrivate); |
| 225 | - client_sync(1,1,0,bPrivate,syncFlags,0); | |
| 232 | + if( db_get_boolean("dont-push",0) ) pushFlag = 0; | |
| 233 | + client_sync(pushFlag,1,0,bPrivate,syncFlags,0); | |
| 234 | + if( pushFlag==0 ){ | |
| 235 | + fossil_warning("pull only: the 'dont-push' option is set"); | |
| 236 | + } | |
| 226 | 237 | } |
| 227 | 238 | |
| 228 | 239 | /* |
| 229 | 240 | ** COMMAND: remote-url |
| 230 | 241 | ** |
| @@ -263,12 +274,12 @@ | ||
| 263 | 274 | } |
| 264 | 275 | } |
| 265 | 276 | } |
| 266 | 277 | zUrl = db_get("last-sync-url", 0); |
| 267 | 278 | if( zUrl==0 ){ |
| 268 | - printf("off\n"); | |
| 279 | + fossil_print("off\n"); | |
| 269 | 280 | return; |
| 270 | 281 | }else{ |
| 271 | 282 | url_parse(zUrl); |
| 272 | - printf("%s\n", g.urlCanonical); | |
| 283 | + fossil_print("%s\n", g.urlCanonical); | |
| 273 | 284 | } |
| 274 | 285 | } |
| 275 | 286 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -43,10 +43,13 @@ | |
| 43 | const char *zPw; |
| 44 | int rc; |
| 45 | int configSync = 0; /* configuration changes transferred */ |
| 46 | if( g.fNoSync ){ |
| 47 | return 0; |
| 48 | } |
| 49 | zAutosync = db_get("autosync", 0); |
| 50 | if( zAutosync ){ |
| 51 | if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 52 | return 0; /* Do not auto-push when autosync=pullonly */ |
| @@ -76,11 +79,11 @@ | |
| 76 | ** autosync, or something? |
| 77 | */ |
| 78 | configSync = CONFIGSET_SHUN; |
| 79 | } |
| 80 | #endif |
| 81 | printf("Autosync: %s\n", g.urlCanonical); |
| 82 | url_enable_proxy("via proxy: "); |
| 83 | rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); |
| 84 | if( rc ) fossil_warning("Autosync failed"); |
| 85 | return rc; |
| 86 | } |
| @@ -124,11 +127,11 @@ | |
| 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 126 | } |
| 127 | user_select(); |
| 128 | if( g.argc==2 ){ |
| 129 | printf("Server: %s\n", g.urlCanonical); |
| 130 | } |
| 131 | url_enable_proxy("via proxy: "); |
| 132 | *pConfigSync = configSync; |
| 133 | } |
| 134 | |
| @@ -185,10 +188,13 @@ | |
| 185 | */ |
| 186 | void push_cmd(void){ |
| 187 | int syncFlags; |
| 188 | int bPrivate; |
| 189 | process_sync_args(&syncFlags, &bPrivate); |
| 190 | client_sync(1,0,0,bPrivate,0,0); |
| 191 | } |
| 192 | |
| 193 | |
| 194 | /* |
| @@ -219,12 +225,17 @@ | |
| 219 | ** See also: clone, push, pull, remote-url |
| 220 | */ |
| 221 | void sync_cmd(void){ |
| 222 | int syncFlags; |
| 223 | int bPrivate; |
| 224 | process_sync_args(&syncFlags, &bPrivate); |
| 225 | client_sync(1,1,0,bPrivate,syncFlags,0); |
| 226 | } |
| 227 | |
| 228 | /* |
| 229 | ** COMMAND: remote-url |
| 230 | ** |
| @@ -263,12 +274,12 @@ | |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | zUrl = db_get("last-sync-url", 0); |
| 267 | if( zUrl==0 ){ |
| 268 | printf("off\n"); |
| 269 | return; |
| 270 | }else{ |
| 271 | url_parse(zUrl); |
| 272 | printf("%s\n", g.urlCanonical); |
| 273 | } |
| 274 | } |
| 275 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -43,10 +43,13 @@ | |
| 43 | const char *zPw; |
| 44 | int rc; |
| 45 | int configSync = 0; /* configuration changes transferred */ |
| 46 | if( g.fNoSync ){ |
| 47 | return 0; |
| 48 | } |
| 49 | if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 50 | return 0; |
| 51 | } |
| 52 | zAutosync = db_get("autosync", 0); |
| 53 | if( zAutosync ){ |
| 54 | if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 55 | return 0; /* Do not auto-push when autosync=pullonly */ |
| @@ -76,11 +79,11 @@ | |
| 79 | ** autosync, or something? |
| 80 | */ |
| 81 | configSync = CONFIGSET_SHUN; |
| 82 | } |
| 83 | #endif |
| 84 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | url_enable_proxy("via proxy: "); |
| 86 | rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); |
| 87 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | return rc; |
| 89 | } |
| @@ -124,11 +127,11 @@ | |
| 127 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | fossil_print("Server: %s\n", g.urlCanonical); |
| 133 | } |
| 134 | url_enable_proxy("via proxy: "); |
| 135 | *pConfigSync = configSync; |
| 136 | } |
| 137 | |
| @@ -185,10 +188,13 @@ | |
| 188 | */ |
| 189 | void push_cmd(void){ |
| 190 | int syncFlags; |
| 191 | int bPrivate; |
| 192 | process_sync_args(&syncFlags, &bPrivate); |
| 193 | if( db_get_boolean("dont-push",0) ){ |
| 194 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | } |
| 196 | client_sync(1,0,0,bPrivate,0,0); |
| 197 | } |
| 198 | |
| 199 | |
| 200 | /* |
| @@ -219,12 +225,17 @@ | |
| 225 | ** See also: clone, push, pull, remote-url |
| 226 | */ |
| 227 | void sync_cmd(void){ |
| 228 | int syncFlags; |
| 229 | int bPrivate; |
| 230 | int pushFlag = 1; |
| 231 | process_sync_args(&syncFlags, &bPrivate); |
| 232 | if( db_get_boolean("dont-push",0) ) pushFlag = 0; |
| 233 | client_sync(pushFlag,1,0,bPrivate,syncFlags,0); |
| 234 | if( pushFlag==0 ){ |
| 235 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | /* |
| 240 | ** COMMAND: remote-url |
| 241 | ** |
| @@ -263,12 +274,12 @@ | |
| 274 | } |
| 275 | } |
| 276 | } |
| 277 | zUrl = db_get("last-sync-url", 0); |
| 278 | if( zUrl==0 ){ |
| 279 | fossil_print("off\n"); |
| 280 | return; |
| 281 | }else{ |
| 282 | url_parse(zUrl); |
| 283 | fossil_print("%s\n", g.urlCanonical); |
| 284 | } |
| 285 | } |
| 286 |
+13
-9
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -296,11 +296,11 @@ | ||
| 296 | 296 | |
| 297 | 297 | assert( tagtype>=0 && tagtype<=2 ); |
| 298 | 298 | user_select(); |
| 299 | 299 | blob_zero(&uuid); |
| 300 | 300 | blob_append(&uuid, zObjName, -1); |
| 301 | - if( name_to_uuid(&uuid, 9) ){ | |
| 301 | + if( name_to_uuid(&uuid, 9, "*") ){ | |
| 302 | 302 | fossil_fatal("%s", g.zErrMsg); |
| 303 | 303 | return; |
| 304 | 304 | } |
| 305 | 305 | rid = name_to_rid(blob_str(&uuid)); |
| 306 | 306 | g.markPrivate = content_is_private(rid); |
| @@ -348,13 +348,14 @@ | ||
| 348 | 348 | ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN |
| 349 | 349 | ** |
| 350 | 350 | ** Remove the tag TAGNAME from CHECK-IN, and also remove |
| 351 | 351 | ** the propagation of the tag to any descendants. |
| 352 | 352 | ** |
| 353 | -** %fossil tag find ?--raw? TAGNAME | |
| 353 | +** %fossil tag find ?--raw? ?--type TYPE? TAGNAME | |
| 354 | 354 | ** |
| 355 | -** List all check-ins that use TAGNAME | |
| 355 | +** List all objects that use TAGNAME. TYPE can be "ci" for | |
| 356 | +** checkins or "e" for events. | |
| 356 | 357 | ** |
| 357 | 358 | ** %fossil tag list ?--raw? ?CHECK-IN? |
| 358 | 359 | ** |
| 359 | 360 | ** List all tags, or if CHECK-IN is supplied, list |
| 360 | 361 | ** all tags and their values for CHECK-IN. |
| @@ -426,10 +427,12 @@ | ||
| 426 | 427 | db_end_transaction(0); |
| 427 | 428 | }else |
| 428 | 429 | |
| 429 | 430 | if( strncmp(g.argv[2],"find",n)==0 ){ |
| 430 | 431 | Stmt q; |
| 432 | + const char *zType = find_option("type","t",1); | |
| 433 | + if( zType==0 || zType[0]==0 ) zType = "*"; | |
| 431 | 434 | if( g.argc!=4 ){ |
| 432 | 435 | usage("find ?--raw? TAGNAME"); |
| 433 | 436 | } |
| 434 | 437 | if( fRaw ){ |
| 435 | 438 | db_prepare(&q, |
| @@ -438,25 +441,26 @@ | ||
| 438 | 441 | " AND tagxref.tagtype>0" |
| 439 | 442 | " AND blob.rid=tagxref.rid", |
| 440 | 443 | g.argv[3] |
| 441 | 444 | ); |
| 442 | 445 | while( db_step(&q)==SQLITE_ROW ){ |
| 443 | - printf("%s\n", db_column_text(&q, 0)); | |
| 446 | + fossil_print("%s\n", db_column_text(&q, 0)); | |
| 444 | 447 | } |
| 445 | 448 | db_finalize(&q); |
| 446 | 449 | }else{ |
| 447 | 450 | int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", |
| 448 | 451 | g.argv[3]); |
| 449 | 452 | if( tagid>0 ){ |
| 450 | 453 | db_prepare(&q, |
| 451 | 454 | "%s" |
| 455 | + " AND event.type GLOB '%q'" | |
| 452 | 456 | " AND blob.rid IN (" |
| 453 | 457 | " SELECT rid FROM tagxref" |
| 454 | 458 | " WHERE tagtype>0 AND tagid=%d" |
| 455 | 459 | ")" |
| 456 | 460 | " ORDER BY event.mtime DESC", |
| 457 | - timeline_query_for_tty(), tagid | |
| 461 | + timeline_query_for_tty(), zType, tagid | |
| 458 | 462 | ); |
| 459 | 463 | print_timeline(&q, 2000); |
| 460 | 464 | db_finalize(&q); |
| 461 | 465 | } |
| 462 | 466 | } |
| @@ -473,13 +477,13 @@ | ||
| 473 | 477 | " ORDER BY tagname" |
| 474 | 478 | ); |
| 475 | 479 | while( db_step(&q)==SQLITE_ROW ){ |
| 476 | 480 | const char *zName = db_column_text(&q, 0); |
| 477 | 481 | if( fRaw ){ |
| 478 | - printf("%s\n", zName); | |
| 482 | + fossil_print("%s\n", zName); | |
| 479 | 483 | }else if( strncmp(zName, "sym-", 4)==0 ){ |
| 480 | - printf("%s\n", &zName[4]); | |
| 484 | + fossil_print("%s\n", &zName[4]); | |
| 481 | 485 | } |
| 482 | 486 | } |
| 483 | 487 | db_finalize(&q); |
| 484 | 488 | }else if( g.argc==4 ){ |
| 485 | 489 | int rid = name_to_rid(g.argv[3]); |
| @@ -497,13 +501,13 @@ | ||
| 497 | 501 | if( fRaw==0 ){ |
| 498 | 502 | if( strncmp(zName, "sym-", 4)!=0 ) continue; |
| 499 | 503 | zName += 4; |
| 500 | 504 | } |
| 501 | 505 | if( zValue && zValue[0] ){ |
| 502 | - printf("%s=%s\n", zName, zValue); | |
| 506 | + fossil_print("%s=%s\n", zName, zValue); | |
| 503 | 507 | }else{ |
| 504 | - printf("%s\n", zName); | |
| 508 | + fossil_print("%s\n", zName); | |
| 505 | 509 | } |
| 506 | 510 | } |
| 507 | 511 | db_finalize(&q); |
| 508 | 512 | }else{ |
| 509 | 513 | usage("tag list ?CHECK-IN?"); |
| 510 | 514 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -296,11 +296,11 @@ | |
| 296 | |
| 297 | assert( tagtype>=0 && tagtype<=2 ); |
| 298 | user_select(); |
| 299 | blob_zero(&uuid); |
| 300 | blob_append(&uuid, zObjName, -1); |
| 301 | if( name_to_uuid(&uuid, 9) ){ |
| 302 | fossil_fatal("%s", g.zErrMsg); |
| 303 | return; |
| 304 | } |
| 305 | rid = name_to_rid(blob_str(&uuid)); |
| 306 | g.markPrivate = content_is_private(rid); |
| @@ -348,13 +348,14 @@ | |
| 348 | ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN |
| 349 | ** |
| 350 | ** Remove the tag TAGNAME from CHECK-IN, and also remove |
| 351 | ** the propagation of the tag to any descendants. |
| 352 | ** |
| 353 | ** %fossil tag find ?--raw? TAGNAME |
| 354 | ** |
| 355 | ** List all check-ins that use TAGNAME |
| 356 | ** |
| 357 | ** %fossil tag list ?--raw? ?CHECK-IN? |
| 358 | ** |
| 359 | ** List all tags, or if CHECK-IN is supplied, list |
| 360 | ** all tags and their values for CHECK-IN. |
| @@ -426,10 +427,12 @@ | |
| 426 | db_end_transaction(0); |
| 427 | }else |
| 428 | |
| 429 | if( strncmp(g.argv[2],"find",n)==0 ){ |
| 430 | Stmt q; |
| 431 | if( g.argc!=4 ){ |
| 432 | usage("find ?--raw? TAGNAME"); |
| 433 | } |
| 434 | if( fRaw ){ |
| 435 | db_prepare(&q, |
| @@ -438,25 +441,26 @@ | |
| 438 | " AND tagxref.tagtype>0" |
| 439 | " AND blob.rid=tagxref.rid", |
| 440 | g.argv[3] |
| 441 | ); |
| 442 | while( db_step(&q)==SQLITE_ROW ){ |
| 443 | printf("%s\n", db_column_text(&q, 0)); |
| 444 | } |
| 445 | db_finalize(&q); |
| 446 | }else{ |
| 447 | int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", |
| 448 | g.argv[3]); |
| 449 | if( tagid>0 ){ |
| 450 | db_prepare(&q, |
| 451 | "%s" |
| 452 | " AND blob.rid IN (" |
| 453 | " SELECT rid FROM tagxref" |
| 454 | " WHERE tagtype>0 AND tagid=%d" |
| 455 | ")" |
| 456 | " ORDER BY event.mtime DESC", |
| 457 | timeline_query_for_tty(), tagid |
| 458 | ); |
| 459 | print_timeline(&q, 2000); |
| 460 | db_finalize(&q); |
| 461 | } |
| 462 | } |
| @@ -473,13 +477,13 @@ | |
| 473 | " ORDER BY tagname" |
| 474 | ); |
| 475 | while( db_step(&q)==SQLITE_ROW ){ |
| 476 | const char *zName = db_column_text(&q, 0); |
| 477 | if( fRaw ){ |
| 478 | printf("%s\n", zName); |
| 479 | }else if( strncmp(zName, "sym-", 4)==0 ){ |
| 480 | printf("%s\n", &zName[4]); |
| 481 | } |
| 482 | } |
| 483 | db_finalize(&q); |
| 484 | }else if( g.argc==4 ){ |
| 485 | int rid = name_to_rid(g.argv[3]); |
| @@ -497,13 +501,13 @@ | |
| 497 | if( fRaw==0 ){ |
| 498 | if( strncmp(zName, "sym-", 4)!=0 ) continue; |
| 499 | zName += 4; |
| 500 | } |
| 501 | if( zValue && zValue[0] ){ |
| 502 | printf("%s=%s\n", zName, zValue); |
| 503 | }else{ |
| 504 | printf("%s\n", zName); |
| 505 | } |
| 506 | } |
| 507 | db_finalize(&q); |
| 508 | }else{ |
| 509 | usage("tag list ?CHECK-IN?"); |
| 510 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -296,11 +296,11 @@ | |
| 296 | |
| 297 | assert( tagtype>=0 && tagtype<=2 ); |
| 298 | user_select(); |
| 299 | blob_zero(&uuid); |
| 300 | blob_append(&uuid, zObjName, -1); |
| 301 | if( name_to_uuid(&uuid, 9, "*") ){ |
| 302 | fossil_fatal("%s", g.zErrMsg); |
| 303 | return; |
| 304 | } |
| 305 | rid = name_to_rid(blob_str(&uuid)); |
| 306 | g.markPrivate = content_is_private(rid); |
| @@ -348,13 +348,14 @@ | |
| 348 | ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN |
| 349 | ** |
| 350 | ** Remove the tag TAGNAME from CHECK-IN, and also remove |
| 351 | ** the propagation of the tag to any descendants. |
| 352 | ** |
| 353 | ** %fossil tag find ?--raw? ?--type TYPE? TAGNAME |
| 354 | ** |
| 355 | ** List all objects that use TAGNAME. TYPE can be "ci" for |
| 356 | ** checkins or "e" for events. |
| 357 | ** |
| 358 | ** %fossil tag list ?--raw? ?CHECK-IN? |
| 359 | ** |
| 360 | ** List all tags, or if CHECK-IN is supplied, list |
| 361 | ** all tags and their values for CHECK-IN. |
| @@ -426,10 +427,12 @@ | |
| 427 | db_end_transaction(0); |
| 428 | }else |
| 429 | |
| 430 | if( strncmp(g.argv[2],"find",n)==0 ){ |
| 431 | Stmt q; |
| 432 | const char *zType = find_option("type","t",1); |
| 433 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 434 | if( g.argc!=4 ){ |
| 435 | usage("find ?--raw? TAGNAME"); |
| 436 | } |
| 437 | if( fRaw ){ |
| 438 | db_prepare(&q, |
| @@ -438,25 +441,26 @@ | |
| 441 | " AND tagxref.tagtype>0" |
| 442 | " AND blob.rid=tagxref.rid", |
| 443 | g.argv[3] |
| 444 | ); |
| 445 | while( db_step(&q)==SQLITE_ROW ){ |
| 446 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 447 | } |
| 448 | db_finalize(&q); |
| 449 | }else{ |
| 450 | int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", |
| 451 | g.argv[3]); |
| 452 | if( tagid>0 ){ |
| 453 | db_prepare(&q, |
| 454 | "%s" |
| 455 | " AND event.type GLOB '%q'" |
| 456 | " AND blob.rid IN (" |
| 457 | " SELECT rid FROM tagxref" |
| 458 | " WHERE tagtype>0 AND tagid=%d" |
| 459 | ")" |
| 460 | " ORDER BY event.mtime DESC", |
| 461 | timeline_query_for_tty(), zType, tagid |
| 462 | ); |
| 463 | print_timeline(&q, 2000); |
| 464 | db_finalize(&q); |
| 465 | } |
| 466 | } |
| @@ -473,13 +477,13 @@ | |
| 477 | " ORDER BY tagname" |
| 478 | ); |
| 479 | while( db_step(&q)==SQLITE_ROW ){ |
| 480 | const char *zName = db_column_text(&q, 0); |
| 481 | if( fRaw ){ |
| 482 | fossil_print("%s\n", zName); |
| 483 | }else if( strncmp(zName, "sym-", 4)==0 ){ |
| 484 | fossil_print("%s\n", &zName[4]); |
| 485 | } |
| 486 | } |
| 487 | db_finalize(&q); |
| 488 | }else if( g.argc==4 ){ |
| 489 | int rid = name_to_rid(g.argv[3]); |
| @@ -497,13 +501,13 @@ | |
| 501 | if( fRaw==0 ){ |
| 502 | if( strncmp(zName, "sym-", 4)!=0 ) continue; |
| 503 | zName += 4; |
| 504 | } |
| 505 | if( zValue && zValue[0] ){ |
| 506 | fossil_print("%s=%s\n", zName, zValue); |
| 507 | }else{ |
| 508 | fossil_print("%s\n", zName); |
| 509 | } |
| 510 | } |
| 511 | db_finalize(&q); |
| 512 | }else{ |
| 513 | usage("tag list ?CHECK-IN?"); |
| 514 |
+3
-3
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -96,11 +96,11 @@ | ||
| 96 | 96 | ){ |
| 97 | 97 | int i; |
| 98 | 98 | for(i=nName-1; i>0 && zName[i]!='/'; i--){} |
| 99 | 99 | if( i<=0 ) return; |
| 100 | 100 | if( tball.zPrevDir[i]==0 && memcmp(tball.zPrevDir, zName, i)==0 ) return; |
| 101 | - db_multi_exec("INSERT OR IGNORE INTO dir VALUES('%.*q')", i, zName); | |
| 101 | + db_multi_exec("INSERT OR IGNORE INTO dir VALUES('%#q')", i, zName); | |
| 102 | 102 | if( sqlite3_changes(g.db)==0 ) return; |
| 103 | 103 | tar_add_directory_of(zName, i-1, mTime); |
| 104 | 104 | tar_add_header(zName, i, 0755, mTime, 0, 5); |
| 105 | 105 | memcpy(tball.zPrevDir, zName, i); |
| 106 | 106 | tball.zPrevDir[i] = 0; |
| @@ -273,11 +273,11 @@ | ||
| 273 | 273 | zName = find_option("name", 0, 1); |
| 274 | 274 | db_find_and_open_repository(0, 0); |
| 275 | 275 | if( g.argc!=4 ){ |
| 276 | 276 | usage("VERSION OUTPUTFILE"); |
| 277 | 277 | } |
| 278 | - rid = name_to_rid(g.argv[2]); | |
| 278 | + rid = name_to_typed_rid(g.argv[2], "ci"); | |
| 279 | 279 | if( zName==0 ){ |
| 280 | 280 | zName = db_text("default-name", |
| 281 | 281 | "SELECT replace(%Q,' ','_') " |
| 282 | 282 | " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " |
| 283 | 283 | " || substr(blob.uuid, 1, 10)" |
| @@ -309,11 +309,11 @@ | ||
| 309 | 309 | if( !g.okZip ){ login_needed(); return; } |
| 310 | 310 | zName = mprintf("%s", PD("name","")); |
| 311 | 311 | nName = strlen(zName); |
| 312 | 312 | zRid = mprintf("%s", PD("uuid","")); |
| 313 | 313 | nRid = strlen(zRid); |
| 314 | - if( nName>7 && strcmp(&zName[nName-7], ".tar.gz")==0 ){ | |
| 314 | + if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){ | |
| 315 | 315 | /* Special case: Remove the ".tar.gz" suffix. */ |
| 316 | 316 | nName -= 7; |
| 317 | 317 | zName[nName] = 0; |
| 318 | 318 | }else{ |
| 319 | 319 | /* If the file suffix is not ".tar.gz" then just remove the |
| 320 | 320 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -96,11 +96,11 @@ | |
| 96 | ){ |
| 97 | int i; |
| 98 | for(i=nName-1; i>0 && zName[i]!='/'; i--){} |
| 99 | if( i<=0 ) return; |
| 100 | if( tball.zPrevDir[i]==0 && memcmp(tball.zPrevDir, zName, i)==0 ) return; |
| 101 | db_multi_exec("INSERT OR IGNORE INTO dir VALUES('%.*q')", i, zName); |
| 102 | if( sqlite3_changes(g.db)==0 ) return; |
| 103 | tar_add_directory_of(zName, i-1, mTime); |
| 104 | tar_add_header(zName, i, 0755, mTime, 0, 5); |
| 105 | memcpy(tball.zPrevDir, zName, i); |
| 106 | tball.zPrevDir[i] = 0; |
| @@ -273,11 +273,11 @@ | |
| 273 | zName = find_option("name", 0, 1); |
| 274 | db_find_and_open_repository(0, 0); |
| 275 | if( g.argc!=4 ){ |
| 276 | usage("VERSION OUTPUTFILE"); |
| 277 | } |
| 278 | rid = name_to_rid(g.argv[2]); |
| 279 | if( zName==0 ){ |
| 280 | zName = db_text("default-name", |
| 281 | "SELECT replace(%Q,' ','_') " |
| 282 | " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " |
| 283 | " || substr(blob.uuid, 1, 10)" |
| @@ -309,11 +309,11 @@ | |
| 309 | if( !g.okZip ){ login_needed(); return; } |
| 310 | zName = mprintf("%s", PD("name","")); |
| 311 | nName = strlen(zName); |
| 312 | zRid = mprintf("%s", PD("uuid","")); |
| 313 | nRid = strlen(zRid); |
| 314 | if( nName>7 && strcmp(&zName[nName-7], ".tar.gz")==0 ){ |
| 315 | /* Special case: Remove the ".tar.gz" suffix. */ |
| 316 | nName -= 7; |
| 317 | zName[nName] = 0; |
| 318 | }else{ |
| 319 | /* If the file suffix is not ".tar.gz" then just remove the |
| 320 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -96,11 +96,11 @@ | |
| 96 | ){ |
| 97 | int i; |
| 98 | for(i=nName-1; i>0 && zName[i]!='/'; i--){} |
| 99 | if( i<=0 ) return; |
| 100 | if( tball.zPrevDir[i]==0 && memcmp(tball.zPrevDir, zName, i)==0 ) return; |
| 101 | db_multi_exec("INSERT OR IGNORE INTO dir VALUES('%#q')", i, zName); |
| 102 | if( sqlite3_changes(g.db)==0 ) return; |
| 103 | tar_add_directory_of(zName, i-1, mTime); |
| 104 | tar_add_header(zName, i, 0755, mTime, 0, 5); |
| 105 | memcpy(tball.zPrevDir, zName, i); |
| 106 | tball.zPrevDir[i] = 0; |
| @@ -273,11 +273,11 @@ | |
| 273 | zName = find_option("name", 0, 1); |
| 274 | db_find_and_open_repository(0, 0); |
| 275 | if( g.argc!=4 ){ |
| 276 | usage("VERSION OUTPUTFILE"); |
| 277 | } |
| 278 | rid = name_to_typed_rid(g.argv[2], "ci"); |
| 279 | if( zName==0 ){ |
| 280 | zName = db_text("default-name", |
| 281 | "SELECT replace(%Q,' ','_') " |
| 282 | " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " |
| 283 | " || substr(blob.uuid, 1, 10)" |
| @@ -309,11 +309,11 @@ | |
| 309 | if( !g.okZip ){ login_needed(); return; } |
| 310 | zName = mprintf("%s", PD("name","")); |
| 311 | nName = strlen(zName); |
| 312 | zRid = mprintf("%s", PD("uuid","")); |
| 313 | nRid = strlen(zRid); |
| 314 | if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){ |
| 315 | /* Special case: Remove the ".tar.gz" suffix. */ |
| 316 | nName -= 7; |
| 317 | zName[nName] = 0; |
| 318 | }else{ |
| 319 | /* If the file suffix is not ".tar.gz" then just remove the |
| 320 |
+2
-2
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -208,11 +208,11 @@ | ||
| 208 | 208 | if( argc!=2 ){ |
| 209 | 209 | return Th_WrongNumArgs(interp, "hascap STRING"); |
| 210 | 210 | } |
| 211 | 211 | rc = login_has_capability((char*)argv[1],argl[1]); |
| 212 | 212 | if( g.thTrace ){ |
| 213 | - Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc); | |
| 213 | + Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); | |
| 214 | 214 | } |
| 215 | 215 | Th_SetResultInt(interp, rc); |
| 216 | 216 | return TH_OK; |
| 217 | 217 | } |
| 218 | 218 | |
| @@ -235,11 +235,11 @@ | ||
| 235 | 235 | } |
| 236 | 236 | for(i=0; rc==0 && i<argl[1]; i++){ |
| 237 | 237 | rc = login_has_capability((char*)&argv[1][i],1); |
| 238 | 238 | } |
| 239 | 239 | if( g.thTrace ){ |
| 240 | - Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc); | |
| 240 | + Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); | |
| 241 | 241 | } |
| 242 | 242 | Th_SetResultInt(interp, rc); |
| 243 | 243 | return TH_OK; |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -208,11 +208,11 @@ | |
| 208 | if( argc!=2 ){ |
| 209 | return Th_WrongNumArgs(interp, "hascap STRING"); |
| 210 | } |
| 211 | rc = login_has_capability((char*)argv[1],argl[1]); |
| 212 | if( g.thTrace ){ |
| 213 | Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc); |
| 214 | } |
| 215 | Th_SetResultInt(interp, rc); |
| 216 | return TH_OK; |
| 217 | } |
| 218 | |
| @@ -235,11 +235,11 @@ | |
| 235 | } |
| 236 | for(i=0; rc==0 && i<argl[1]; i++){ |
| 237 | rc = login_has_capability((char*)&argv[1][i],1); |
| 238 | } |
| 239 | if( g.thTrace ){ |
| 240 | Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc); |
| 241 | } |
| 242 | Th_SetResultInt(interp, rc); |
| 243 | return TH_OK; |
| 244 | } |
| 245 | |
| 246 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -208,11 +208,11 @@ | |
| 208 | if( argc!=2 ){ |
| 209 | return Th_WrongNumArgs(interp, "hascap STRING"); |
| 210 | } |
| 211 | rc = login_has_capability((char*)argv[1],argl[1]); |
| 212 | if( g.thTrace ){ |
| 213 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 214 | } |
| 215 | Th_SetResultInt(interp, rc); |
| 216 | return TH_OK; |
| 217 | } |
| 218 | |
| @@ -235,11 +235,11 @@ | |
| 235 | } |
| 236 | for(i=0; rc==0 && i<argl[1]; i++){ |
| 237 | rc = login_has_capability((char*)&argv[1][i],1); |
| 238 | } |
| 239 | if( g.thTrace ){ |
| 240 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 241 | } |
| 242 | Th_SetResultInt(interp, rc); |
| 243 | return TH_OK; |
| 244 | } |
| 245 | |
| 246 |
+15
-15
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -300,15 +300,15 @@ | ||
| 300 | 300 | blob_zero(&links); |
| 301 | 301 | while( z && z[0] ){ |
| 302 | 302 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 303 | 303 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 304 | 304 | blob_appendf(&links, |
| 305 | - "<a href=\"%s/timeline?r=%.*t&nd&c=%s\">%.*h</a>%.2s", | |
| 305 | + "<a href=\"%s/timeline?r=%#t&nd&c=%s\">%#h</a>%.2s", | |
| 306 | 306 | g.zTop, i, z, zDate, i, z, &z[i] |
| 307 | 307 | ); |
| 308 | 308 | }else{ |
| 309 | - blob_appendf(&links, "%.*h", i+2, z); | |
| 309 | + blob_appendf(&links, "%#h", i+2, z); | |
| 310 | 310 | } |
| 311 | 311 | if( z[i]==0 ) break; |
| 312 | 312 | z += i+2; |
| 313 | 313 | } |
| 314 | 314 | @ tags: %s(blob_str(&links))) |
| @@ -782,13 +782,13 @@ | ||
| 782 | 782 | void page_timeline(void){ |
| 783 | 783 | Stmt q; /* Query used to generate the timeline */ |
| 784 | 784 | Blob sql; /* text of SQL used to generate timeline */ |
| 785 | 785 | Blob desc; /* Description of the timeline */ |
| 786 | 786 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 787 | - int p_rid = name_to_rid(P("p")); /* artifact p and its parents */ | |
| 788 | - int d_rid = name_to_rid(P("d")); /* artifact d and its descendants */ | |
| 789 | - int f_rid = name_to_rid(P("f")); /* artifact f and immediate family */ | |
| 787 | + int p_rid = name_to_typed_rid(P("p"),"ci"); /* artifact p and its parents */ | |
| 788 | + int d_rid = name_to_typed_rid(P("d"),"ci"); /* artifact d and descendants */ | |
| 789 | + int f_rid = name_to_typed_rid(P("f"),"ci"); /* artifact f and close family */ | |
| 790 | 790 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 791 | 791 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 792 | 792 | const char *zAfter = P("a"); /* Events after this time */ |
| 793 | 793 | const char *zBefore = P("b"); /* Events before this time */ |
| 794 | 794 | const char *zCirca = P("c"); /* Events near this time */ |
| @@ -799,15 +799,15 @@ | ||
| 799 | 799 | int tagid; /* Tag ID */ |
| 800 | 800 | int tmFlags; /* Timeline flags */ |
| 801 | 801 | const char *zThisTag = 0; /* Suppress links to this tag */ |
| 802 | 802 | const char *zThisUser = 0; /* Suppress links to this user */ |
| 803 | 803 | HQuery url; /* URL for various branch links */ |
| 804 | - int from_rid = name_to_rid(P("from")); /* from= for path timelines */ | |
| 805 | - int to_rid = name_to_rid(P("to")); /* to= for path timelines */ | |
| 804 | + int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ | |
| 805 | + int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ | |
| 806 | 806 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 807 | - int me_rid = name_to_rid(P("me")); /* me= for common ancestory path */ | |
| 808 | - int you_rid = name_to_rid(P("you"));/* you= for common ancst path */ | |
| 807 | + int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ | |
| 808 | + int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ | |
| 809 | 809 | |
| 810 | 810 | /* To view the timeline, must have permission to read project data. |
| 811 | 811 | */ |
| 812 | 812 | login_check_credentials(); |
| 813 | 813 | if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ login_needed(); return; } |
| @@ -1203,16 +1203,16 @@ | ||
| 1203 | 1203 | char zPrefix[80]; |
| 1204 | 1204 | char zUuid[UUID_SIZE+1]; |
| 1205 | 1205 | |
| 1206 | 1206 | sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); |
| 1207 | 1207 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 1208 | - printf("=== %.10s ===\n", zDate); | |
| 1208 | + fossil_print("=== %.10s ===\n", zDate); | |
| 1209 | 1209 | memcpy(zPrevDate, zDate, 10); |
| 1210 | 1210 | nLine++; |
| 1211 | 1211 | } |
| 1212 | 1212 | if( zCom==0 ) zCom = ""; |
| 1213 | - printf("%.8s ", &zDate[11]); | |
| 1213 | + fossil_print("%.8s ", &zDate[11]); | |
| 1214 | 1214 | zPrefix[0] = 0; |
| 1215 | 1215 | if( nParent>1 ){ |
| 1216 | 1216 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* "); |
| 1217 | 1217 | n = strlen(zPrefix); |
| 1218 | 1218 | } |
| @@ -1350,11 +1350,11 @@ | ||
| 1350 | 1350 | zOrigin = "now"; |
| 1351 | 1351 | } |
| 1352 | 1352 | k = strlen(zOrigin); |
| 1353 | 1353 | blob_zero(&uuid); |
| 1354 | 1354 | blob_append(&uuid, zOrigin, -1); |
| 1355 | - if( strcmp(zOrigin, "now")==0 ){ | |
| 1355 | + if( fossil_strcmp(zOrigin, "now")==0 ){ | |
| 1356 | 1356 | if( mode==3 || mode==4 ){ |
| 1357 | 1357 | fossil_fatal("cannot compute descendants or ancestors of a date"); |
| 1358 | 1358 | } |
| 1359 | 1359 | zDate = mprintf("(SELECT datetime('now'))"); |
| 1360 | 1360 | }else if( strncmp(zOrigin, "current", k)==0 ){ |
| @@ -1361,11 +1361,11 @@ | ||
| 1361 | 1361 | if( !g.localOpen ){ |
| 1362 | 1362 | fossil_fatal("must be within a local checkout to use 'current'"); |
| 1363 | 1363 | } |
| 1364 | 1364 | objid = db_lget_int("checkout",0); |
| 1365 | 1365 | zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); |
| 1366 | - }else if( name_to_uuid(&uuid, 0)==0 ){ | |
| 1366 | + }else if( name_to_uuid(&uuid, 0, "*")==0 ){ | |
| 1367 | 1367 | objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 1368 | 1368 | zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); |
| 1369 | 1369 | }else{ |
| 1370 | 1370 | const char *zShift = ""; |
| 1371 | 1371 | if( mode==3 || mode==4 ){ |
| @@ -1453,13 +1453,13 @@ | ||
| 1453 | 1453 | " FROM plink p, plink c" |
| 1454 | 1454 | " WHERE p.cid=c.pid AND p.mtime>c.mtime" |
| 1455 | 1455 | ); |
| 1456 | 1456 | while( db_step(&q)==SQLITE_ROW ){ |
| 1457 | 1457 | if( !showDetail ){ |
| 1458 | - printf("%s\n", db_column_text(&q, 1)); | |
| 1458 | + fossil_print("%s\n", db_column_text(&q, 1)); | |
| 1459 | 1459 | }else{ |
| 1460 | - printf("%.14s -> %.14s %s -> %s\n", | |
| 1460 | + fossil_print("%.14s -> %.14s %s -> %s\n", | |
| 1461 | 1461 | db_column_text(&q, 0), |
| 1462 | 1462 | db_column_text(&q, 1), |
| 1463 | 1463 | db_column_text(&q, 2), |
| 1464 | 1464 | db_column_text(&q, 3)); |
| 1465 | 1465 | } |
| 1466 | 1466 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -300,15 +300,15 @@ | |
| 300 | blob_zero(&links); |
| 301 | while( z && z[0] ){ |
| 302 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 303 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 304 | blob_appendf(&links, |
| 305 | "<a href=\"%s/timeline?r=%.*t&nd&c=%s\">%.*h</a>%.2s", |
| 306 | g.zTop, i, z, zDate, i, z, &z[i] |
| 307 | ); |
| 308 | }else{ |
| 309 | blob_appendf(&links, "%.*h", i+2, z); |
| 310 | } |
| 311 | if( z[i]==0 ) break; |
| 312 | z += i+2; |
| 313 | } |
| 314 | @ tags: %s(blob_str(&links))) |
| @@ -782,13 +782,13 @@ | |
| 782 | void page_timeline(void){ |
| 783 | Stmt q; /* Query used to generate the timeline */ |
| 784 | Blob sql; /* text of SQL used to generate timeline */ |
| 785 | Blob desc; /* Description of the timeline */ |
| 786 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 787 | int p_rid = name_to_rid(P("p")); /* artifact p and its parents */ |
| 788 | int d_rid = name_to_rid(P("d")); /* artifact d and its descendants */ |
| 789 | int f_rid = name_to_rid(P("f")); /* artifact f and immediate family */ |
| 790 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 791 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 792 | const char *zAfter = P("a"); /* Events after this time */ |
| 793 | const char *zBefore = P("b"); /* Events before this time */ |
| 794 | const char *zCirca = P("c"); /* Events near this time */ |
| @@ -799,15 +799,15 @@ | |
| 799 | int tagid; /* Tag ID */ |
| 800 | int tmFlags; /* Timeline flags */ |
| 801 | const char *zThisTag = 0; /* Suppress links to this tag */ |
| 802 | const char *zThisUser = 0; /* Suppress links to this user */ |
| 803 | HQuery url; /* URL for various branch links */ |
| 804 | int from_rid = name_to_rid(P("from")); /* from= for path timelines */ |
| 805 | int to_rid = name_to_rid(P("to")); /* to= for path timelines */ |
| 806 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 807 | int me_rid = name_to_rid(P("me")); /* me= for common ancestory path */ |
| 808 | int you_rid = name_to_rid(P("you"));/* you= for common ancst path */ |
| 809 | |
| 810 | /* To view the timeline, must have permission to read project data. |
| 811 | */ |
| 812 | login_check_credentials(); |
| 813 | if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ login_needed(); return; } |
| @@ -1203,16 +1203,16 @@ | |
| 1203 | char zPrefix[80]; |
| 1204 | char zUuid[UUID_SIZE+1]; |
| 1205 | |
| 1206 | sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); |
| 1207 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 1208 | printf("=== %.10s ===\n", zDate); |
| 1209 | memcpy(zPrevDate, zDate, 10); |
| 1210 | nLine++; |
| 1211 | } |
| 1212 | if( zCom==0 ) zCom = ""; |
| 1213 | printf("%.8s ", &zDate[11]); |
| 1214 | zPrefix[0] = 0; |
| 1215 | if( nParent>1 ){ |
| 1216 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* "); |
| 1217 | n = strlen(zPrefix); |
| 1218 | } |
| @@ -1350,11 +1350,11 @@ | |
| 1350 | zOrigin = "now"; |
| 1351 | } |
| 1352 | k = strlen(zOrigin); |
| 1353 | blob_zero(&uuid); |
| 1354 | blob_append(&uuid, zOrigin, -1); |
| 1355 | if( strcmp(zOrigin, "now")==0 ){ |
| 1356 | if( mode==3 || mode==4 ){ |
| 1357 | fossil_fatal("cannot compute descendants or ancestors of a date"); |
| 1358 | } |
| 1359 | zDate = mprintf("(SELECT datetime('now'))"); |
| 1360 | }else if( strncmp(zOrigin, "current", k)==0 ){ |
| @@ -1361,11 +1361,11 @@ | |
| 1361 | if( !g.localOpen ){ |
| 1362 | fossil_fatal("must be within a local checkout to use 'current'"); |
| 1363 | } |
| 1364 | objid = db_lget_int("checkout",0); |
| 1365 | zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); |
| 1366 | }else if( name_to_uuid(&uuid, 0)==0 ){ |
| 1367 | objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 1368 | zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); |
| 1369 | }else{ |
| 1370 | const char *zShift = ""; |
| 1371 | if( mode==3 || mode==4 ){ |
| @@ -1453,13 +1453,13 @@ | |
| 1453 | " FROM plink p, plink c" |
| 1454 | " WHERE p.cid=c.pid AND p.mtime>c.mtime" |
| 1455 | ); |
| 1456 | while( db_step(&q)==SQLITE_ROW ){ |
| 1457 | if( !showDetail ){ |
| 1458 | printf("%s\n", db_column_text(&q, 1)); |
| 1459 | }else{ |
| 1460 | printf("%.14s -> %.14s %s -> %s\n", |
| 1461 | db_column_text(&q, 0), |
| 1462 | db_column_text(&q, 1), |
| 1463 | db_column_text(&q, 2), |
| 1464 | db_column_text(&q, 3)); |
| 1465 | } |
| 1466 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -300,15 +300,15 @@ | |
| 300 | blob_zero(&links); |
| 301 | while( z && z[0] ){ |
| 302 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 303 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 304 | blob_appendf(&links, |
| 305 | "<a href=\"%s/timeline?r=%#t&nd&c=%s\">%#h</a>%.2s", |
| 306 | g.zTop, i, z, zDate, i, z, &z[i] |
| 307 | ); |
| 308 | }else{ |
| 309 | blob_appendf(&links, "%#h", i+2, z); |
| 310 | } |
| 311 | if( z[i]==0 ) break; |
| 312 | z += i+2; |
| 313 | } |
| 314 | @ tags: %s(blob_str(&links))) |
| @@ -782,13 +782,13 @@ | |
| 782 | void page_timeline(void){ |
| 783 | Stmt q; /* Query used to generate the timeline */ |
| 784 | Blob sql; /* text of SQL used to generate timeline */ |
| 785 | Blob desc; /* Description of the timeline */ |
| 786 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 787 | int p_rid = name_to_typed_rid(P("p"),"ci"); /* artifact p and its parents */ |
| 788 | int d_rid = name_to_typed_rid(P("d"),"ci"); /* artifact d and descendants */ |
| 789 | int f_rid = name_to_typed_rid(P("f"),"ci"); /* artifact f and close family */ |
| 790 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 791 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 792 | const char *zAfter = P("a"); /* Events after this time */ |
| 793 | const char *zBefore = P("b"); /* Events before this time */ |
| 794 | const char *zCirca = P("c"); /* Events near this time */ |
| @@ -799,15 +799,15 @@ | |
| 799 | int tagid; /* Tag ID */ |
| 800 | int tmFlags; /* Timeline flags */ |
| 801 | const char *zThisTag = 0; /* Suppress links to this tag */ |
| 802 | const char *zThisUser = 0; /* Suppress links to this user */ |
| 803 | HQuery url; /* URL for various branch links */ |
| 804 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 805 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 806 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 807 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 808 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 809 | |
| 810 | /* To view the timeline, must have permission to read project data. |
| 811 | */ |
| 812 | login_check_credentials(); |
| 813 | if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ login_needed(); return; } |
| @@ -1203,16 +1203,16 @@ | |
| 1203 | char zPrefix[80]; |
| 1204 | char zUuid[UUID_SIZE+1]; |
| 1205 | |
| 1206 | sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); |
| 1207 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 1208 | fossil_print("=== %.10s ===\n", zDate); |
| 1209 | memcpy(zPrevDate, zDate, 10); |
| 1210 | nLine++; |
| 1211 | } |
| 1212 | if( zCom==0 ) zCom = ""; |
| 1213 | fossil_print("%.8s ", &zDate[11]); |
| 1214 | zPrefix[0] = 0; |
| 1215 | if( nParent>1 ){ |
| 1216 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* "); |
| 1217 | n = strlen(zPrefix); |
| 1218 | } |
| @@ -1350,11 +1350,11 @@ | |
| 1350 | zOrigin = "now"; |
| 1351 | } |
| 1352 | k = strlen(zOrigin); |
| 1353 | blob_zero(&uuid); |
| 1354 | blob_append(&uuid, zOrigin, -1); |
| 1355 | if( fossil_strcmp(zOrigin, "now")==0 ){ |
| 1356 | if( mode==3 || mode==4 ){ |
| 1357 | fossil_fatal("cannot compute descendants or ancestors of a date"); |
| 1358 | } |
| 1359 | zDate = mprintf("(SELECT datetime('now'))"); |
| 1360 | }else if( strncmp(zOrigin, "current", k)==0 ){ |
| @@ -1361,11 +1361,11 @@ | |
| 1361 | if( !g.localOpen ){ |
| 1362 | fossil_fatal("must be within a local checkout to use 'current'"); |
| 1363 | } |
| 1364 | objid = db_lget_int("checkout",0); |
| 1365 | zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); |
| 1366 | }else if( name_to_uuid(&uuid, 0, "*")==0 ){ |
| 1367 | objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); |
| 1368 | zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); |
| 1369 | }else{ |
| 1370 | const char *zShift = ""; |
| 1371 | if( mode==3 || mode==4 ){ |
| @@ -1453,13 +1453,13 @@ | |
| 1453 | " FROM plink p, plink c" |
| 1454 | " WHERE p.cid=c.pid AND p.mtime>c.mtime" |
| 1455 | ); |
| 1456 | while( db_step(&q)==SQLITE_ROW ){ |
| 1457 | if( !showDetail ){ |
| 1458 | fossil_print("%s\n", db_column_text(&q, 1)); |
| 1459 | }else{ |
| 1460 | fossil_print("%.14s -> %.14s %s -> %s\n", |
| 1461 | db_column_text(&q, 0), |
| 1462 | db_column_text(&q, 1), |
| 1463 | db_column_text(&q, 2), |
| 1464 | db_column_text(&q, 3)); |
| 1465 | } |
| 1466 |
+38
-20
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -34,11 +34,11 @@ | ||
| 34 | 34 | |
| 35 | 35 | /* |
| 36 | 36 | ** Compare two entries in azField for sorting purposes |
| 37 | 37 | */ |
| 38 | 38 | static int nameCmpr(const void *a, const void *b){ |
| 39 | - return strcmp(*(char**)a, *(char**)b); | |
| 39 | + return fossil_strcmp(*(char**)a, *(char**)b); | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | /* |
| 43 | 43 | ** Obtain a list of all fields of the TICKET table. Put them |
| 44 | 44 | ** in sorted order in azField[]. |
| @@ -75,11 +75,11 @@ | ||
| 75 | 75 | ** Return -1 if zField is not in azField[]. |
| 76 | 76 | */ |
| 77 | 77 | static int fieldId(const char *zField){ |
| 78 | 78 | int i; |
| 79 | 79 | for(i=0; i<nField; i++){ |
| 80 | - if( strcmp(azField[i], zField)==0 ) return i; | |
| 80 | + if( fossil_strcmp(azField[i], zField)==0 ) return i; | |
| 81 | 81 | } |
| 82 | 82 | return -1; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | /* |
| @@ -115,11 +115,11 @@ | ||
| 115 | 115 | zVal = ""; |
| 116 | 116 | }else if( strncmp(zName, "private_", 8)==0 ){ |
| 117 | 117 | zVal = zRevealed = db_reveal(zVal); |
| 118 | 118 | } |
| 119 | 119 | for(j=0; j<nField; j++){ |
| 120 | - if( strcmp(azField[j],zName)==0 ){ | |
| 120 | + if( fossil_strcmp(azField[j],zName)==0 ){ | |
| 121 | 121 | azValue[j] = mprintf("%s", zVal); |
| 122 | 122 | break; |
| 123 | 123 | } |
| 124 | 124 | } |
| 125 | 125 | if( Th_Fetch(zName, &size)==0 ){ |
| @@ -216,11 +216,12 @@ | ||
| 216 | 216 | char *zTag = mprintf("tkt-%s", zTktUuid); |
| 217 | 217 | int tagid = tag_findid(zTag, 1); |
| 218 | 218 | Stmt q; |
| 219 | 219 | Manifest *pTicket; |
| 220 | 220 | int createFlag = 1; |
| 221 | - | |
| 221 | + | |
| 222 | + fossil_free(zTag); | |
| 222 | 223 | db_multi_exec( |
| 223 | 224 | "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid |
| 224 | 225 | ); |
| 225 | 226 | db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); |
| 226 | 227 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -888,10 +889,11 @@ | ||
| 888 | 889 | ** status, type, severity, priority, resolution, |
| 889 | 890 | ** foundin, private_contact, resolution, title or comment |
| 890 | 891 | ** Field names given above are the ones, defined in a standard |
| 891 | 892 | ** fossil environment. If you have added, deleted columns, you |
| 892 | 893 | ** change the all your configured columns. |
| 894 | +** If you use +FIELD, the VLUE Is appended to the field FIELD. | |
| 893 | 895 | ** You can use more than one field/value pair on the commandline. |
| 894 | 896 | ** Using -q|--quote enables the special character decoding as |
| 895 | 897 | ** in "ticket show". So it's possible, to set multiline text or |
| 896 | 898 | ** text with special characters. |
| 897 | 899 | ** |
| @@ -1007,25 +1009,34 @@ | ||
| 1007 | 1009 | /* read commandline and assign fields in the azValue array */ |
| 1008 | 1010 | while( i<g.argc ){ |
| 1009 | 1011 | char *zFName; |
| 1010 | 1012 | char *zFValue; |
| 1011 | 1013 | int j; |
| 1014 | + int append = 0; | |
| 1012 | 1015 | |
| 1013 | 1016 | zFName = g.argv[i++]; |
| 1014 | 1017 | if( i==g.argc ){ |
| 1015 | 1018 | fossil_fatal("missing value for '%s'!",zFName); |
| 1016 | 1019 | } |
| 1017 | 1020 | zFValue = g.argv[i++]; |
| 1018 | - j = fieldId(zFName); | |
| 1019 | 1021 | if( tktEncoding == tktFossilize ){ |
| 1020 | 1022 | zFValue=mprintf("%s",zFValue); |
| 1021 | 1023 | defossilize(zFValue); |
| 1022 | 1024 | } |
| 1025 | + append = (zFName[0] == '+'); | |
| 1026 | + if (append){ | |
| 1027 | + zFName++; | |
| 1028 | + } | |
| 1029 | + j = fieldId(zFName); | |
| 1023 | 1030 | if( j == -1 ){ |
| 1024 | 1031 | fossil_fatal("unknown field name '%s'!",zFName); |
| 1025 | 1032 | }else{ |
| 1026 | - azValue[j] = zFValue; | |
| 1033 | + if (append) { | |
| 1034 | + azAppend[j] = zFValue; | |
| 1035 | + } else { | |
| 1036 | + azValue[j] = zFValue; | |
| 1037 | + } | |
| 1027 | 1038 | } |
| 1028 | 1039 | } |
| 1029 | 1040 | |
| 1030 | 1041 | /* now add the needed artifacts to the repository */ |
| 1031 | 1042 | blob_zero(&tktchng); |
| @@ -1036,24 +1047,31 @@ | ||
| 1036 | 1047 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 1037 | 1048 | free(zDate); |
| 1038 | 1049 | } |
| 1039 | 1050 | /* append defined elements */ |
| 1040 | 1051 | for(i=0; i<nField; i++){ |
| 1041 | - char *zValue; | |
| 1042 | - | |
| 1043 | - zValue = azValue[i]; | |
| 1044 | - if( azValue[i] && azValue[i][0] ){ | |
| 1045 | - if( strncmp(azField[i], "private_", 8)==0 ){ | |
| 1046 | - zValue = db_conceal(zValue, strlen(zValue)); | |
| 1047 | - blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue); | |
| 1048 | - }else{ | |
| 1049 | - blob_appendf(&tktchng, "J %s %#F\n", | |
| 1050 | - azField[i], strlen(zValue), zValue); | |
| 1051 | - } | |
| 1052 | - if( tktEncoding == tktFossilize ){ | |
| 1053 | - free(azValue[i]); | |
| 1054 | - } | |
| 1052 | + char *zValue = 0; | |
| 1053 | + char *zPfx; | |
| 1054 | + | |
| 1055 | + if (azAppend[i] && azAppend[i][0] ){ | |
| 1056 | + zPfx = " +"; | |
| 1057 | + zValue = azAppend[i]; | |
| 1058 | + } else if( azValue[i] && azValue[i][0] ){ | |
| 1059 | + zPfx = " "; | |
| 1060 | + zValue = azValue[i]; | |
| 1061 | + } else { | |
| 1062 | + continue; | |
| 1063 | + } | |
| 1064 | + if( strncmp(azField[i], "private_", 8)==0 ){ | |
| 1065 | + zValue = db_conceal(zValue, strlen(zValue)); | |
| 1066 | + blob_appendf(&tktchng, "J%s%s %s\n", zPfx, azField[i], zValue); | |
| 1067 | + }else{ | |
| 1068 | + blob_appendf(&tktchng, "J%s%s %#F\n", zPfx, | |
| 1069 | + azField[i], strlen(zValue), zValue); | |
| 1070 | + } | |
| 1071 | + if( tktEncoding == tktFossilize ){ | |
| 1072 | + free(azValue[i]); | |
| 1055 | 1073 | } |
| 1056 | 1074 | } |
| 1057 | 1075 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 1058 | 1076 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 1059 | 1077 | md5sum_blob(&tktchng, &cksum); |
| 1060 | 1078 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | |
| 35 | /* |
| 36 | ** Compare two entries in azField for sorting purposes |
| 37 | */ |
| 38 | static int nameCmpr(const void *a, const void *b){ |
| 39 | return strcmp(*(char**)a, *(char**)b); |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** Obtain a list of all fields of the TICKET table. Put them |
| 44 | ** in sorted order in azField[]. |
| @@ -75,11 +75,11 @@ | |
| 75 | ** Return -1 if zField is not in azField[]. |
| 76 | */ |
| 77 | static int fieldId(const char *zField){ |
| 78 | int i; |
| 79 | for(i=0; i<nField; i++){ |
| 80 | if( strcmp(azField[i], zField)==0 ) return i; |
| 81 | } |
| 82 | return -1; |
| 83 | } |
| 84 | |
| 85 | /* |
| @@ -115,11 +115,11 @@ | |
| 115 | zVal = ""; |
| 116 | }else if( strncmp(zName, "private_", 8)==0 ){ |
| 117 | zVal = zRevealed = db_reveal(zVal); |
| 118 | } |
| 119 | for(j=0; j<nField; j++){ |
| 120 | if( strcmp(azField[j],zName)==0 ){ |
| 121 | azValue[j] = mprintf("%s", zVal); |
| 122 | break; |
| 123 | } |
| 124 | } |
| 125 | if( Th_Fetch(zName, &size)==0 ){ |
| @@ -216,11 +216,12 @@ | |
| 216 | char *zTag = mprintf("tkt-%s", zTktUuid); |
| 217 | int tagid = tag_findid(zTag, 1); |
| 218 | Stmt q; |
| 219 | Manifest *pTicket; |
| 220 | int createFlag = 1; |
| 221 | |
| 222 | db_multi_exec( |
| 223 | "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid |
| 224 | ); |
| 225 | db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); |
| 226 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -888,10 +889,11 @@ | |
| 888 | ** status, type, severity, priority, resolution, |
| 889 | ** foundin, private_contact, resolution, title or comment |
| 890 | ** Field names given above are the ones, defined in a standard |
| 891 | ** fossil environment. If you have added, deleted columns, you |
| 892 | ** change the all your configured columns. |
| 893 | ** You can use more than one field/value pair on the commandline. |
| 894 | ** Using -q|--quote enables the special character decoding as |
| 895 | ** in "ticket show". So it's possible, to set multiline text or |
| 896 | ** text with special characters. |
| 897 | ** |
| @@ -1007,25 +1009,34 @@ | |
| 1007 | /* read commandline and assign fields in the azValue array */ |
| 1008 | while( i<g.argc ){ |
| 1009 | char *zFName; |
| 1010 | char *zFValue; |
| 1011 | int j; |
| 1012 | |
| 1013 | zFName = g.argv[i++]; |
| 1014 | if( i==g.argc ){ |
| 1015 | fossil_fatal("missing value for '%s'!",zFName); |
| 1016 | } |
| 1017 | zFValue = g.argv[i++]; |
| 1018 | j = fieldId(zFName); |
| 1019 | if( tktEncoding == tktFossilize ){ |
| 1020 | zFValue=mprintf("%s",zFValue); |
| 1021 | defossilize(zFValue); |
| 1022 | } |
| 1023 | if( j == -1 ){ |
| 1024 | fossil_fatal("unknown field name '%s'!",zFName); |
| 1025 | }else{ |
| 1026 | azValue[j] = zFValue; |
| 1027 | } |
| 1028 | } |
| 1029 | |
| 1030 | /* now add the needed artifacts to the repository */ |
| 1031 | blob_zero(&tktchng); |
| @@ -1036,24 +1047,31 @@ | |
| 1036 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 1037 | free(zDate); |
| 1038 | } |
| 1039 | /* append defined elements */ |
| 1040 | for(i=0; i<nField; i++){ |
| 1041 | char *zValue; |
| 1042 | |
| 1043 | zValue = azValue[i]; |
| 1044 | if( azValue[i] && azValue[i][0] ){ |
| 1045 | if( strncmp(azField[i], "private_", 8)==0 ){ |
| 1046 | zValue = db_conceal(zValue, strlen(zValue)); |
| 1047 | blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue); |
| 1048 | }else{ |
| 1049 | blob_appendf(&tktchng, "J %s %#F\n", |
| 1050 | azField[i], strlen(zValue), zValue); |
| 1051 | } |
| 1052 | if( tktEncoding == tktFossilize ){ |
| 1053 | free(azValue[i]); |
| 1054 | } |
| 1055 | } |
| 1056 | } |
| 1057 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 1058 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 1059 | md5sum_blob(&tktchng, &cksum); |
| 1060 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | |
| 35 | /* |
| 36 | ** Compare two entries in azField for sorting purposes |
| 37 | */ |
| 38 | static int nameCmpr(const void *a, const void *b){ |
| 39 | return fossil_strcmp(*(char**)a, *(char**)b); |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** Obtain a list of all fields of the TICKET table. Put them |
| 44 | ** in sorted order in azField[]. |
| @@ -75,11 +75,11 @@ | |
| 75 | ** Return -1 if zField is not in azField[]. |
| 76 | */ |
| 77 | static int fieldId(const char *zField){ |
| 78 | int i; |
| 79 | for(i=0; i<nField; i++){ |
| 80 | if( fossil_strcmp(azField[i], zField)==0 ) return i; |
| 81 | } |
| 82 | return -1; |
| 83 | } |
| 84 | |
| 85 | /* |
| @@ -115,11 +115,11 @@ | |
| 115 | zVal = ""; |
| 116 | }else if( strncmp(zName, "private_", 8)==0 ){ |
| 117 | zVal = zRevealed = db_reveal(zVal); |
| 118 | } |
| 119 | for(j=0; j<nField; j++){ |
| 120 | if( fossil_strcmp(azField[j],zName)==0 ){ |
| 121 | azValue[j] = mprintf("%s", zVal); |
| 122 | break; |
| 123 | } |
| 124 | } |
| 125 | if( Th_Fetch(zName, &size)==0 ){ |
| @@ -216,11 +216,12 @@ | |
| 216 | char *zTag = mprintf("tkt-%s", zTktUuid); |
| 217 | int tagid = tag_findid(zTag, 1); |
| 218 | Stmt q; |
| 219 | Manifest *pTicket; |
| 220 | int createFlag = 1; |
| 221 | |
| 222 | fossil_free(zTag); |
| 223 | db_multi_exec( |
| 224 | "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid |
| 225 | ); |
| 226 | db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); |
| 227 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -888,10 +889,11 @@ | |
| 889 | ** status, type, severity, priority, resolution, |
| 890 | ** foundin, private_contact, resolution, title or comment |
| 891 | ** Field names given above are the ones, defined in a standard |
| 892 | ** fossil environment. If you have added, deleted columns, you |
| 893 | ** change the all your configured columns. |
| 894 | ** If you use +FIELD, the VLUE Is appended to the field FIELD. |
| 895 | ** You can use more than one field/value pair on the commandline. |
| 896 | ** Using -q|--quote enables the special character decoding as |
| 897 | ** in "ticket show". So it's possible, to set multiline text or |
| 898 | ** text with special characters. |
| 899 | ** |
| @@ -1007,25 +1009,34 @@ | |
| 1009 | /* read commandline and assign fields in the azValue array */ |
| 1010 | while( i<g.argc ){ |
| 1011 | char *zFName; |
| 1012 | char *zFValue; |
| 1013 | int j; |
| 1014 | int append = 0; |
| 1015 | |
| 1016 | zFName = g.argv[i++]; |
| 1017 | if( i==g.argc ){ |
| 1018 | fossil_fatal("missing value for '%s'!",zFName); |
| 1019 | } |
| 1020 | zFValue = g.argv[i++]; |
| 1021 | if( tktEncoding == tktFossilize ){ |
| 1022 | zFValue=mprintf("%s",zFValue); |
| 1023 | defossilize(zFValue); |
| 1024 | } |
| 1025 | append = (zFName[0] == '+'); |
| 1026 | if (append){ |
| 1027 | zFName++; |
| 1028 | } |
| 1029 | j = fieldId(zFName); |
| 1030 | if( j == -1 ){ |
| 1031 | fossil_fatal("unknown field name '%s'!",zFName); |
| 1032 | }else{ |
| 1033 | if (append) { |
| 1034 | azAppend[j] = zFValue; |
| 1035 | } else { |
| 1036 | azValue[j] = zFValue; |
| 1037 | } |
| 1038 | } |
| 1039 | } |
| 1040 | |
| 1041 | /* now add the needed artifacts to the repository */ |
| 1042 | blob_zero(&tktchng); |
| @@ -1036,24 +1047,31 @@ | |
| 1047 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 1048 | free(zDate); |
| 1049 | } |
| 1050 | /* append defined elements */ |
| 1051 | for(i=0; i<nField; i++){ |
| 1052 | char *zValue = 0; |
| 1053 | char *zPfx; |
| 1054 | |
| 1055 | if (azAppend[i] && azAppend[i][0] ){ |
| 1056 | zPfx = " +"; |
| 1057 | zValue = azAppend[i]; |
| 1058 | } else if( azValue[i] && azValue[i][0] ){ |
| 1059 | zPfx = " "; |
| 1060 | zValue = azValue[i]; |
| 1061 | } else { |
| 1062 | continue; |
| 1063 | } |
| 1064 | if( strncmp(azField[i], "private_", 8)==0 ){ |
| 1065 | zValue = db_conceal(zValue, strlen(zValue)); |
| 1066 | blob_appendf(&tktchng, "J%s%s %s\n", zPfx, azField[i], zValue); |
| 1067 | }else{ |
| 1068 | blob_appendf(&tktchng, "J%s%s %#F\n", zPfx, |
| 1069 | azField[i], strlen(zValue), zValue); |
| 1070 | } |
| 1071 | if( tktEncoding == tktFossilize ){ |
| 1072 | free(azValue[i]); |
| 1073 | } |
| 1074 | } |
| 1075 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 1076 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 1077 | md5sum_blob(&tktchng, &cksum); |
| 1078 |
+38
-20
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -34,11 +34,11 @@ | ||
| 34 | 34 | |
| 35 | 35 | /* |
| 36 | 36 | ** Compare two entries in azField for sorting purposes |
| 37 | 37 | */ |
| 38 | 38 | static int nameCmpr(const void *a, const void *b){ |
| 39 | - return strcmp(*(char**)a, *(char**)b); | |
| 39 | + return fossil_strcmp(*(char**)a, *(char**)b); | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | /* |
| 43 | 43 | ** Obtain a list of all fields of the TICKET table. Put them |
| 44 | 44 | ** in sorted order in azField[]. |
| @@ -75,11 +75,11 @@ | ||
| 75 | 75 | ** Return -1 if zField is not in azField[]. |
| 76 | 76 | */ |
| 77 | 77 | static int fieldId(const char *zField){ |
| 78 | 78 | int i; |
| 79 | 79 | for(i=0; i<nField; i++){ |
| 80 | - if( strcmp(azField[i], zField)==0 ) return i; | |
| 80 | + if( fossil_strcmp(azField[i], zField)==0 ) return i; | |
| 81 | 81 | } |
| 82 | 82 | return -1; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | /* |
| @@ -115,11 +115,11 @@ | ||
| 115 | 115 | zVal = ""; |
| 116 | 116 | }else if( strncmp(zName, "private_", 8)==0 ){ |
| 117 | 117 | zVal = zRevealed = db_reveal(zVal); |
| 118 | 118 | } |
| 119 | 119 | for(j=0; j<nField; j++){ |
| 120 | - if( strcmp(azField[j],zName)==0 ){ | |
| 120 | + if( fossil_strcmp(azField[j],zName)==0 ){ | |
| 121 | 121 | azValue[j] = mprintf("%s", zVal); |
| 122 | 122 | break; |
| 123 | 123 | } |
| 124 | 124 | } |
| 125 | 125 | if( Th_Fetch(zName, &size)==0 ){ |
| @@ -216,11 +216,12 @@ | ||
| 216 | 216 | char *zTag = mprintf("tkt-%s", zTktUuid); |
| 217 | 217 | int tagid = tag_findid(zTag, 1); |
| 218 | 218 | Stmt q; |
| 219 | 219 | Manifest *pTicket; |
| 220 | 220 | int createFlag = 1; |
| 221 | - | |
| 221 | + | |
| 222 | + fossil_free(zTag); | |
| 222 | 223 | db_multi_exec( |
| 223 | 224 | "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid |
| 224 | 225 | ); |
| 225 | 226 | db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); |
| 226 | 227 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -888,10 +889,11 @@ | ||
| 888 | 889 | ** status, type, severity, priority, resolution, |
| 889 | 890 | ** foundin, private_contact, resolution, title or comment |
| 890 | 891 | ** Field names given above are the ones, defined in a standard |
| 891 | 892 | ** fossil environment. If you have added, deleted columns, you |
| 892 | 893 | ** change the all your configured columns. |
| 894 | +** If you use +FIELD, the VLUE Is appended to the field FIELD. | |
| 893 | 895 | ** You can use more than one field/value pair on the commandline. |
| 894 | 896 | ** Using -q|--quote enables the special character decoding as |
| 895 | 897 | ** in "ticket show". So it's possible, to set multiline text or |
| 896 | 898 | ** text with special characters. |
| 897 | 899 | ** |
| @@ -1007,25 +1009,34 @@ | ||
| 1007 | 1009 | /* read commandline and assign fields in the azValue array */ |
| 1008 | 1010 | while( i<g.argc ){ |
| 1009 | 1011 | char *zFName; |
| 1010 | 1012 | char *zFValue; |
| 1011 | 1013 | int j; |
| 1014 | + int append = 0; | |
| 1012 | 1015 | |
| 1013 | 1016 | zFName = g.argv[i++]; |
| 1014 | 1017 | if( i==g.argc ){ |
| 1015 | 1018 | fossil_fatal("missing value for '%s'!",zFName); |
| 1016 | 1019 | } |
| 1017 | 1020 | zFValue = g.argv[i++]; |
| 1018 | - j = fieldId(zFName); | |
| 1019 | 1021 | if( tktEncoding == tktFossilize ){ |
| 1020 | 1022 | zFValue=mprintf("%s",zFValue); |
| 1021 | 1023 | defossilize(zFValue); |
| 1022 | 1024 | } |
| 1025 | + append = (zFName[0] == '+'); | |
| 1026 | + if (append){ | |
| 1027 | + zFName++; | |
| 1028 | + } | |
| 1029 | + j = fieldId(zFName); | |
| 1023 | 1030 | if( j == -1 ){ |
| 1024 | 1031 | fossil_fatal("unknown field name '%s'!",zFName); |
| 1025 | 1032 | }else{ |
| 1026 | - azValue[j] = zFValue; | |
| 1033 | + if (append) { | |
| 1034 | + azAppend[j] = zFValue; | |
| 1035 | + } else { | |
| 1036 | + azValue[j] = zFValue; | |
| 1037 | + } | |
| 1027 | 1038 | } |
| 1028 | 1039 | } |
| 1029 | 1040 | |
| 1030 | 1041 | /* now add the needed artifacts to the repository */ |
| 1031 | 1042 | blob_zero(&tktchng); |
| @@ -1036,24 +1047,31 @@ | ||
| 1036 | 1047 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 1037 | 1048 | free(zDate); |
| 1038 | 1049 | } |
| 1039 | 1050 | /* append defined elements */ |
| 1040 | 1051 | for(i=0; i<nField; i++){ |
| 1041 | - char *zValue; | |
| 1042 | - | |
| 1043 | - zValue = azValue[i]; | |
| 1044 | - if( azValue[i] && azValue[i][0] ){ | |
| 1045 | - if( strncmp(azField[i], "private_", 8)==0 ){ | |
| 1046 | - zValue = db_conceal(zValue, strlen(zValue)); | |
| 1047 | - blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue); | |
| 1048 | - }else{ | |
| 1049 | - blob_appendf(&tktchng, "J %s %#F\n", | |
| 1050 | - azField[i], strlen(zValue), zValue); | |
| 1051 | - } | |
| 1052 | - if( tktEncoding == tktFossilize ){ | |
| 1053 | - free(azValue[i]); | |
| 1054 | - } | |
| 1052 | + char *zValue = 0; | |
| 1053 | + char *zPfx; | |
| 1054 | + | |
| 1055 | + if (azAppend[i] && azAppend[i][0] ){ | |
| 1056 | + zPfx = " +"; | |
| 1057 | + zValue = azAppend[i]; | |
| 1058 | + } else if( azValue[i] && azValue[i][0] ){ | |
| 1059 | + zPfx = " "; | |
| 1060 | + zValue = azValue[i]; | |
| 1061 | + } else { | |
| 1062 | + continue; | |
| 1063 | + } | |
| 1064 | + if( strncmp(azField[i], "private_", 8)==0 ){ | |
| 1065 | + zValue = db_conceal(zValue, strlen(zValue)); | |
| 1066 | + blob_appendf(&tktchng, "J%s%s %s\n", zPfx, azField[i], zValue); | |
| 1067 | + }else{ | |
| 1068 | + blob_appendf(&tktchng, "J%s%s %#F\n", zPfx, | |
| 1069 | + azField[i], strlen(zValue), zValue); | |
| 1070 | + } | |
| 1071 | + if( tktEncoding == tktFossilize ){ | |
| 1072 | + free(azValue[i]); | |
| 1055 | 1073 | } |
| 1056 | 1074 | } |
| 1057 | 1075 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 1058 | 1076 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 1059 | 1077 | md5sum_blob(&tktchng, &cksum); |
| 1060 | 1078 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | |
| 35 | /* |
| 36 | ** Compare two entries in azField for sorting purposes |
| 37 | */ |
| 38 | static int nameCmpr(const void *a, const void *b){ |
| 39 | return strcmp(*(char**)a, *(char**)b); |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** Obtain a list of all fields of the TICKET table. Put them |
| 44 | ** in sorted order in azField[]. |
| @@ -75,11 +75,11 @@ | |
| 75 | ** Return -1 if zField is not in azField[]. |
| 76 | */ |
| 77 | static int fieldId(const char *zField){ |
| 78 | int i; |
| 79 | for(i=0; i<nField; i++){ |
| 80 | if( strcmp(azField[i], zField)==0 ) return i; |
| 81 | } |
| 82 | return -1; |
| 83 | } |
| 84 | |
| 85 | /* |
| @@ -115,11 +115,11 @@ | |
| 115 | zVal = ""; |
| 116 | }else if( strncmp(zName, "private_", 8)==0 ){ |
| 117 | zVal = zRevealed = db_reveal(zVal); |
| 118 | } |
| 119 | for(j=0; j<nField; j++){ |
| 120 | if( strcmp(azField[j],zName)==0 ){ |
| 121 | azValue[j] = mprintf("%s", zVal); |
| 122 | break; |
| 123 | } |
| 124 | } |
| 125 | if( Th_Fetch(zName, &size)==0 ){ |
| @@ -216,11 +216,12 @@ | |
| 216 | char *zTag = mprintf("tkt-%s", zTktUuid); |
| 217 | int tagid = tag_findid(zTag, 1); |
| 218 | Stmt q; |
| 219 | Manifest *pTicket; |
| 220 | int createFlag = 1; |
| 221 | |
| 222 | db_multi_exec( |
| 223 | "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid |
| 224 | ); |
| 225 | db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); |
| 226 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -888,10 +889,11 @@ | |
| 888 | ** status, type, severity, priority, resolution, |
| 889 | ** foundin, private_contact, resolution, title or comment |
| 890 | ** Field names given above are the ones, defined in a standard |
| 891 | ** fossil environment. If you have added, deleted columns, you |
| 892 | ** change the all your configured columns. |
| 893 | ** You can use more than one field/value pair on the commandline. |
| 894 | ** Using -q|--quote enables the special character decoding as |
| 895 | ** in "ticket show". So it's possible, to set multiline text or |
| 896 | ** text with special characters. |
| 897 | ** |
| @@ -1007,25 +1009,34 @@ | |
| 1007 | /* read commandline and assign fields in the azValue array */ |
| 1008 | while( i<g.argc ){ |
| 1009 | char *zFName; |
| 1010 | char *zFValue; |
| 1011 | int j; |
| 1012 | |
| 1013 | zFName = g.argv[i++]; |
| 1014 | if( i==g.argc ){ |
| 1015 | fossil_fatal("missing value for '%s'!",zFName); |
| 1016 | } |
| 1017 | zFValue = g.argv[i++]; |
| 1018 | j = fieldId(zFName); |
| 1019 | if( tktEncoding == tktFossilize ){ |
| 1020 | zFValue=mprintf("%s",zFValue); |
| 1021 | defossilize(zFValue); |
| 1022 | } |
| 1023 | if( j == -1 ){ |
| 1024 | fossil_fatal("unknown field name '%s'!",zFName); |
| 1025 | }else{ |
| 1026 | azValue[j] = zFValue; |
| 1027 | } |
| 1028 | } |
| 1029 | |
| 1030 | /* now add the needed artifacts to the repository */ |
| 1031 | blob_zero(&tktchng); |
| @@ -1036,24 +1047,31 @@ | |
| 1036 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 1037 | free(zDate); |
| 1038 | } |
| 1039 | /* append defined elements */ |
| 1040 | for(i=0; i<nField; i++){ |
| 1041 | char *zValue; |
| 1042 | |
| 1043 | zValue = azValue[i]; |
| 1044 | if( azValue[i] && azValue[i][0] ){ |
| 1045 | if( strncmp(azField[i], "private_", 8)==0 ){ |
| 1046 | zValue = db_conceal(zValue, strlen(zValue)); |
| 1047 | blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue); |
| 1048 | }else{ |
| 1049 | blob_appendf(&tktchng, "J %s %#F\n", |
| 1050 | azField[i], strlen(zValue), zValue); |
| 1051 | } |
| 1052 | if( tktEncoding == tktFossilize ){ |
| 1053 | free(azValue[i]); |
| 1054 | } |
| 1055 | } |
| 1056 | } |
| 1057 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 1058 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 1059 | md5sum_blob(&tktchng, &cksum); |
| 1060 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | |
| 35 | /* |
| 36 | ** Compare two entries in azField for sorting purposes |
| 37 | */ |
| 38 | static int nameCmpr(const void *a, const void *b){ |
| 39 | return fossil_strcmp(*(char**)a, *(char**)b); |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** Obtain a list of all fields of the TICKET table. Put them |
| 44 | ** in sorted order in azField[]. |
| @@ -75,11 +75,11 @@ | |
| 75 | ** Return -1 if zField is not in azField[]. |
| 76 | */ |
| 77 | static int fieldId(const char *zField){ |
| 78 | int i; |
| 79 | for(i=0; i<nField; i++){ |
| 80 | if( fossil_strcmp(azField[i], zField)==0 ) return i; |
| 81 | } |
| 82 | return -1; |
| 83 | } |
| 84 | |
| 85 | /* |
| @@ -115,11 +115,11 @@ | |
| 115 | zVal = ""; |
| 116 | }else if( strncmp(zName, "private_", 8)==0 ){ |
| 117 | zVal = zRevealed = db_reveal(zVal); |
| 118 | } |
| 119 | for(j=0; j<nField; j++){ |
| 120 | if( fossil_strcmp(azField[j],zName)==0 ){ |
| 121 | azValue[j] = mprintf("%s", zVal); |
| 122 | break; |
| 123 | } |
| 124 | } |
| 125 | if( Th_Fetch(zName, &size)==0 ){ |
| @@ -216,11 +216,12 @@ | |
| 216 | char *zTag = mprintf("tkt-%s", zTktUuid); |
| 217 | int tagid = tag_findid(zTag, 1); |
| 218 | Stmt q; |
| 219 | Manifest *pTicket; |
| 220 | int createFlag = 1; |
| 221 | |
| 222 | fossil_free(zTag); |
| 223 | db_multi_exec( |
| 224 | "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid |
| 225 | ); |
| 226 | db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); |
| 227 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -888,10 +889,11 @@ | |
| 889 | ** status, type, severity, priority, resolution, |
| 890 | ** foundin, private_contact, resolution, title or comment |
| 891 | ** Field names given above are the ones, defined in a standard |
| 892 | ** fossil environment. If you have added, deleted columns, you |
| 893 | ** change the all your configured columns. |
| 894 | ** If you use +FIELD, the VLUE Is appended to the field FIELD. |
| 895 | ** You can use more than one field/value pair on the commandline. |
| 896 | ** Using -q|--quote enables the special character decoding as |
| 897 | ** in "ticket show". So it's possible, to set multiline text or |
| 898 | ** text with special characters. |
| 899 | ** |
| @@ -1007,25 +1009,34 @@ | |
| 1009 | /* read commandline and assign fields in the azValue array */ |
| 1010 | while( i<g.argc ){ |
| 1011 | char *zFName; |
| 1012 | char *zFValue; |
| 1013 | int j; |
| 1014 | int append = 0; |
| 1015 | |
| 1016 | zFName = g.argv[i++]; |
| 1017 | if( i==g.argc ){ |
| 1018 | fossil_fatal("missing value for '%s'!",zFName); |
| 1019 | } |
| 1020 | zFValue = g.argv[i++]; |
| 1021 | if( tktEncoding == tktFossilize ){ |
| 1022 | zFValue=mprintf("%s",zFValue); |
| 1023 | defossilize(zFValue); |
| 1024 | } |
| 1025 | append = (zFName[0] == '+'); |
| 1026 | if (append){ |
| 1027 | zFName++; |
| 1028 | } |
| 1029 | j = fieldId(zFName); |
| 1030 | if( j == -1 ){ |
| 1031 | fossil_fatal("unknown field name '%s'!",zFName); |
| 1032 | }else{ |
| 1033 | if (append) { |
| 1034 | azAppend[j] = zFValue; |
| 1035 | } else { |
| 1036 | azValue[j] = zFValue; |
| 1037 | } |
| 1038 | } |
| 1039 | } |
| 1040 | |
| 1041 | /* now add the needed artifacts to the repository */ |
| 1042 | blob_zero(&tktchng); |
| @@ -1036,24 +1047,31 @@ | |
| 1047 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 1048 | free(zDate); |
| 1049 | } |
| 1050 | /* append defined elements */ |
| 1051 | for(i=0; i<nField; i++){ |
| 1052 | char *zValue = 0; |
| 1053 | char *zPfx; |
| 1054 | |
| 1055 | if (azAppend[i] && azAppend[i][0] ){ |
| 1056 | zPfx = " +"; |
| 1057 | zValue = azAppend[i]; |
| 1058 | } else if( azValue[i] && azValue[i][0] ){ |
| 1059 | zPfx = " "; |
| 1060 | zValue = azValue[i]; |
| 1061 | } else { |
| 1062 | continue; |
| 1063 | } |
| 1064 | if( strncmp(azField[i], "private_", 8)==0 ){ |
| 1065 | zValue = db_conceal(zValue, strlen(zValue)); |
| 1066 | blob_appendf(&tktchng, "J%s%s %s\n", zPfx, azField[i], zValue); |
| 1067 | }else{ |
| 1068 | blob_appendf(&tktchng, "J%s%s %#F\n", zPfx, |
| 1069 | azField[i], strlen(zValue), zValue); |
| 1070 | } |
| 1071 | if( tktEncoding == tktFossilize ){ |
| 1072 | free(azValue[i]); |
| 1073 | } |
| 1074 | } |
| 1075 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 1076 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 1077 | md5sum_blob(&tktchng, &cksum); |
| 1078 |
+15
-14
| --- src/undo.c | ||
| +++ src/undo.c | ||
| @@ -58,19 +58,19 @@ | ||
| 58 | 58 | if( old_exists ){ |
| 59 | 59 | db_ephemeral_blob(&q, 0, &new); |
| 60 | 60 | } |
| 61 | 61 | if( old_exists ){ |
| 62 | 62 | if( new_exists ){ |
| 63 | - printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); | |
| 63 | + fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); | |
| 64 | 64 | }else{ |
| 65 | - printf("NEW %s\n", zPathname); | |
| 65 | + fossil_print("NEW %s\n", zPathname); | |
| 66 | 66 | } |
| 67 | 67 | blob_write_to_file(&new, zFullname); |
| 68 | 68 | file_setexe(zFullname, old_exe); |
| 69 | 69 | }else{ |
| 70 | - printf("DELETE %s\n", zPathname); | |
| 71 | - unlink(zFullname); | |
| 70 | + fossil_print("DELETE %s\n", zPathname); | |
| 71 | + file_delete(zFullname); | |
| 72 | 72 | } |
| 73 | 73 | blob_reset(&new); |
| 74 | 74 | free(zFullname); |
| 75 | 75 | db_finalize(&q); |
| 76 | 76 | db_prepare(&q, |
| @@ -297,11 +297,11 @@ | ||
| 297 | 297 | ** Complete the undo process is one is currently in process. |
| 298 | 298 | */ |
| 299 | 299 | void undo_finish(void){ |
| 300 | 300 | if( undoActive ){ |
| 301 | 301 | if( undoNeedRollback ){ |
| 302 | - printf("\"fossil undo\" is available to undo changes" | |
| 302 | + fossil_print("\"fossil undo\" is available to undo changes" | |
| 303 | 303 | " to the working checkout.\n"); |
| 304 | 304 | } |
| 305 | 305 | undoActive = 0; |
| 306 | 306 | undoNeedRollback = 0; |
| 307 | 307 | } |
| @@ -319,11 +319,11 @@ | ||
| 319 | 319 | void undo_rollback(void){ |
| 320 | 320 | if( !undoNeedRollback ) return; |
| 321 | 321 | assert( undoActive ); |
| 322 | 322 | undoNeedRollback = 0; |
| 323 | 323 | undoActive = 0; |
| 324 | - printf("Rolling back prior filesystem changes...\n"); | |
| 324 | + fossil_print("Rolling back prior filesystem changes...\n"); | |
| 325 | 325 | undo_all_filesystem(0); |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | 328 | /* |
| 329 | 329 | ** COMMAND: undo |
| @@ -360,34 +360,35 @@ | ||
| 360 | 360 | verify_all_options(); |
| 361 | 361 | db_begin_transaction(); |
| 362 | 362 | undo_available = db_lget_int("undo_available", 0); |
| 363 | 363 | if( explainFlag ){ |
| 364 | 364 | if( undo_available==0 ){ |
| 365 | - printf("No undo or redo is available\n"); | |
| 365 | + fossil_print("No undo or redo is available\n"); | |
| 366 | 366 | }else{ |
| 367 | 367 | Stmt q; |
| 368 | 368 | int nChng = 0; |
| 369 | 369 | zCmd = undo_available==1 ? "undo" : "redo"; |
| 370 | - printf("A %s is available for the following command:\n\n %s %s\n\n", | |
| 371 | - zCmd, g.argv[0], db_lget("undo_cmdline", "???")); | |
| 370 | + fossil_print("A %s is available for the following command:\n\n" | |
| 371 | + " %s %s\n\n", | |
| 372 | + zCmd, g.argv[0], db_lget("undo_cmdline", "???")); | |
| 372 | 373 | db_prepare(&q, |
| 373 | 374 | "SELECT existsflag, pathname FROM undo ORDER BY pathname" |
| 374 | 375 | ); |
| 375 | 376 | while( db_step(&q)==SQLITE_ROW ){ |
| 376 | 377 | if( nChng==0 ){ |
| 377 | - printf("The following file changes would occur if the " | |
| 378 | - "command above is %sne:\n\n", zCmd); | |
| 378 | + fossil_print("The following file changes would occur if the " | |
| 379 | + "command above is %sne:\n\n", zCmd); | |
| 379 | 380 | } |
| 380 | 381 | nChng++; |
| 381 | - printf("%s %s\n", | |
| 382 | + fossil_print("%s %s\n", | |
| 382 | 383 | db_column_int(&q,0) ? "UPDATE" : "DELETE", |
| 383 | 384 | db_column_text(&q, 1) |
| 384 | 385 | ); |
| 385 | 386 | } |
| 386 | 387 | db_finalize(&q); |
| 387 | 388 | if( nChng==0 ){ |
| 388 | - printf("No file changes would occur with this undo/redo.\n"); | |
| 389 | + fossil_print("No file changes would occur with this undo/redo.\n"); | |
| 389 | 390 | } |
| 390 | 391 | } |
| 391 | 392 | }else{ |
| 392 | 393 | int vid1 = db_lget_int("checkout", 0); |
| 393 | 394 | int vid2; |
| @@ -410,11 +411,11 @@ | ||
| 410 | 411 | blob_reset(&path); |
| 411 | 412 | } |
| 412 | 413 | } |
| 413 | 414 | vid2 = db_lget_int("checkout", 0); |
| 414 | 415 | if( vid1!=vid2 ){ |
| 415 | - printf("--------------------\n"); | |
| 416 | + fossil_print("--------------------\n"); | |
| 416 | 417 | show_common_info(vid2, "updated-to:", 1, 0); |
| 417 | 418 | } |
| 418 | 419 | } |
| 419 | 420 | db_end_transaction(0); |
| 420 | 421 | } |
| 421 | 422 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -58,19 +58,19 @@ | |
| 58 | if( old_exists ){ |
| 59 | db_ephemeral_blob(&q, 0, &new); |
| 60 | } |
| 61 | if( old_exists ){ |
| 62 | if( new_exists ){ |
| 63 | printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); |
| 64 | }else{ |
| 65 | printf("NEW %s\n", zPathname); |
| 66 | } |
| 67 | blob_write_to_file(&new, zFullname); |
| 68 | file_setexe(zFullname, old_exe); |
| 69 | }else{ |
| 70 | printf("DELETE %s\n", zPathname); |
| 71 | unlink(zFullname); |
| 72 | } |
| 73 | blob_reset(&new); |
| 74 | free(zFullname); |
| 75 | db_finalize(&q); |
| 76 | db_prepare(&q, |
| @@ -297,11 +297,11 @@ | |
| 297 | ** Complete the undo process is one is currently in process. |
| 298 | */ |
| 299 | void undo_finish(void){ |
| 300 | if( undoActive ){ |
| 301 | if( undoNeedRollback ){ |
| 302 | printf("\"fossil undo\" is available to undo changes" |
| 303 | " to the working checkout.\n"); |
| 304 | } |
| 305 | undoActive = 0; |
| 306 | undoNeedRollback = 0; |
| 307 | } |
| @@ -319,11 +319,11 @@ | |
| 319 | void undo_rollback(void){ |
| 320 | if( !undoNeedRollback ) return; |
| 321 | assert( undoActive ); |
| 322 | undoNeedRollback = 0; |
| 323 | undoActive = 0; |
| 324 | printf("Rolling back prior filesystem changes...\n"); |
| 325 | undo_all_filesystem(0); |
| 326 | } |
| 327 | |
| 328 | /* |
| 329 | ** COMMAND: undo |
| @@ -360,34 +360,35 @@ | |
| 360 | verify_all_options(); |
| 361 | db_begin_transaction(); |
| 362 | undo_available = db_lget_int("undo_available", 0); |
| 363 | if( explainFlag ){ |
| 364 | if( undo_available==0 ){ |
| 365 | printf("No undo or redo is available\n"); |
| 366 | }else{ |
| 367 | Stmt q; |
| 368 | int nChng = 0; |
| 369 | zCmd = undo_available==1 ? "undo" : "redo"; |
| 370 | printf("A %s is available for the following command:\n\n %s %s\n\n", |
| 371 | zCmd, g.argv[0], db_lget("undo_cmdline", "???")); |
| 372 | db_prepare(&q, |
| 373 | "SELECT existsflag, pathname FROM undo ORDER BY pathname" |
| 374 | ); |
| 375 | while( db_step(&q)==SQLITE_ROW ){ |
| 376 | if( nChng==0 ){ |
| 377 | printf("The following file changes would occur if the " |
| 378 | "command above is %sne:\n\n", zCmd); |
| 379 | } |
| 380 | nChng++; |
| 381 | printf("%s %s\n", |
| 382 | db_column_int(&q,0) ? "UPDATE" : "DELETE", |
| 383 | db_column_text(&q, 1) |
| 384 | ); |
| 385 | } |
| 386 | db_finalize(&q); |
| 387 | if( nChng==0 ){ |
| 388 | printf("No file changes would occur with this undo/redo.\n"); |
| 389 | } |
| 390 | } |
| 391 | }else{ |
| 392 | int vid1 = db_lget_int("checkout", 0); |
| 393 | int vid2; |
| @@ -410,11 +411,11 @@ | |
| 410 | blob_reset(&path); |
| 411 | } |
| 412 | } |
| 413 | vid2 = db_lget_int("checkout", 0); |
| 414 | if( vid1!=vid2 ){ |
| 415 | printf("--------------------\n"); |
| 416 | show_common_info(vid2, "updated-to:", 1, 0); |
| 417 | } |
| 418 | } |
| 419 | db_end_transaction(0); |
| 420 | } |
| 421 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -58,19 +58,19 @@ | |
| 58 | if( old_exists ){ |
| 59 | db_ephemeral_blob(&q, 0, &new); |
| 60 | } |
| 61 | if( old_exists ){ |
| 62 | if( new_exists ){ |
| 63 | fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); |
| 64 | }else{ |
| 65 | fossil_print("NEW %s\n", zPathname); |
| 66 | } |
| 67 | blob_write_to_file(&new, zFullname); |
| 68 | file_setexe(zFullname, old_exe); |
| 69 | }else{ |
| 70 | fossil_print("DELETE %s\n", zPathname); |
| 71 | file_delete(zFullname); |
| 72 | } |
| 73 | blob_reset(&new); |
| 74 | free(zFullname); |
| 75 | db_finalize(&q); |
| 76 | db_prepare(&q, |
| @@ -297,11 +297,11 @@ | |
| 297 | ** Complete the undo process is one is currently in process. |
| 298 | */ |
| 299 | void undo_finish(void){ |
| 300 | if( undoActive ){ |
| 301 | if( undoNeedRollback ){ |
| 302 | fossil_print("\"fossil undo\" is available to undo changes" |
| 303 | " to the working checkout.\n"); |
| 304 | } |
| 305 | undoActive = 0; |
| 306 | undoNeedRollback = 0; |
| 307 | } |
| @@ -319,11 +319,11 @@ | |
| 319 | void undo_rollback(void){ |
| 320 | if( !undoNeedRollback ) return; |
| 321 | assert( undoActive ); |
| 322 | undoNeedRollback = 0; |
| 323 | undoActive = 0; |
| 324 | fossil_print("Rolling back prior filesystem changes...\n"); |
| 325 | undo_all_filesystem(0); |
| 326 | } |
| 327 | |
| 328 | /* |
| 329 | ** COMMAND: undo |
| @@ -360,34 +360,35 @@ | |
| 360 | verify_all_options(); |
| 361 | db_begin_transaction(); |
| 362 | undo_available = db_lget_int("undo_available", 0); |
| 363 | if( explainFlag ){ |
| 364 | if( undo_available==0 ){ |
| 365 | fossil_print("No undo or redo is available\n"); |
| 366 | }else{ |
| 367 | Stmt q; |
| 368 | int nChng = 0; |
| 369 | zCmd = undo_available==1 ? "undo" : "redo"; |
| 370 | fossil_print("A %s is available for the following command:\n\n" |
| 371 | " %s %s\n\n", |
| 372 | zCmd, g.argv[0], db_lget("undo_cmdline", "???")); |
| 373 | db_prepare(&q, |
| 374 | "SELECT existsflag, pathname FROM undo ORDER BY pathname" |
| 375 | ); |
| 376 | while( db_step(&q)==SQLITE_ROW ){ |
| 377 | if( nChng==0 ){ |
| 378 | fossil_print("The following file changes would occur if the " |
| 379 | "command above is %sne:\n\n", zCmd); |
| 380 | } |
| 381 | nChng++; |
| 382 | fossil_print("%s %s\n", |
| 383 | db_column_int(&q,0) ? "UPDATE" : "DELETE", |
| 384 | db_column_text(&q, 1) |
| 385 | ); |
| 386 | } |
| 387 | db_finalize(&q); |
| 388 | if( nChng==0 ){ |
| 389 | fossil_print("No file changes would occur with this undo/redo.\n"); |
| 390 | } |
| 391 | } |
| 392 | }else{ |
| 393 | int vid1 = db_lget_int("checkout", 0); |
| 394 | int vid2; |
| @@ -410,11 +411,11 @@ | |
| 411 | blob_reset(&path); |
| 412 | } |
| 413 | } |
| 414 | vid2 = db_lget_int("checkout", 0); |
| 415 | if( vid1!=vid2 ){ |
| 416 | fossil_print("--------------------\n"); |
| 417 | show_common_info(vid2, "updated-to:", 1, 0); |
| 418 | } |
| 419 | } |
| 420 | db_end_transaction(0); |
| 421 | } |
| 422 |
+34
-28
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -119,20 +119,20 @@ | ||
| 119 | 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | 120 | |
| 121 | 121 | if( internalUpdate ){ |
| 122 | 122 | tid = internalUpdate; |
| 123 | 123 | }else if( g.argc>=3 ){ |
| 124 | - if( strcmp(g.argv[2], "current")==0 ){ | |
| 124 | + if( fossil_strcmp(g.argv[2], "current")==0 ){ | |
| 125 | 125 | /* If VERSION is "current", then use the same algorithm to find the |
| 126 | 126 | ** target as if VERSION were omitted. */ |
| 127 | - }else if( strcmp(g.argv[2], "latest")==0 ){ | |
| 127 | + }else if( fossil_strcmp(g.argv[2], "latest")==0 ){ | |
| 128 | 128 | /* If VERSION is "latest", then use the same algorithm to find the |
| 129 | 129 | ** target as if VERSION were omitted and the --latest flag is present. |
| 130 | 130 | */ |
| 131 | 131 | latestFlag = 1; |
| 132 | 132 | }else{ |
| 133 | - tid = name_to_rid(g.argv[2]); | |
| 133 | + tid = name_to_typed_rid(g.argv[2],"ci"); | |
| 134 | 134 | if( tid==0 ){ |
| 135 | 135 | fossil_fatal("no such version: %s", g.argv[2]); |
| 136 | 136 | }else if( !is_a_version(tid) ){ |
| 137 | 137 | fossil_fatal("no such version: %s", g.argv[2]); |
| 138 | 138 | } |
| @@ -175,13 +175,18 @@ | ||
| 175 | 175 | } |
| 176 | 176 | } |
| 177 | 177 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 178 | 178 | " WHERE event.objid=leaves.rid" |
| 179 | 179 | " ORDER BY event.mtime DESC"); |
| 180 | + if( tid==0 ) tid = vid; | |
| 181 | + } | |
| 182 | + | |
| 183 | + if( tid==0 ){ | |
| 184 | + fossil_panic("Internal Error: unable to find a version to update to."); | |
| 180 | 185 | } |
| 181 | 186 | |
| 182 | - if( !verboseFlag && (tid==vid)) return; /* Nothing to update */ | |
| 187 | + if( tid==vid && !verboseFlag ) return; /* Nothing to update */ | |
| 183 | 188 | db_begin_transaction(); |
| 184 | 189 | vfile_check_signature(vid, 1, 0); |
| 185 | 190 | if( !nochangeFlag && !internalUpdate ) undo_begin(); |
| 186 | 191 | load_vfile_from_rid(tid); |
| 187 | 192 | |
| @@ -253,18 +258,18 @@ | ||
| 253 | 258 | if( debugFlag ){ |
| 254 | 259 | db_prepare(&q, |
| 255 | 260 | "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv" |
| 256 | 261 | ); |
| 257 | 262 | while( db_step(&q)==SQLITE_ROW ){ |
| 258 | - printf("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n", | |
| 263 | + fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n", | |
| 259 | 264 | db_column_int(&q, 0), |
| 260 | 265 | db_column_int(&q, 4), |
| 261 | 266 | db_column_int(&q, 5), |
| 262 | 267 | db_column_int(&q, 3), |
| 263 | 268 | db_column_int(&q, 6)); |
| 264 | - printf(" fnv = [%s]\n", db_column_text(&q, 1)); | |
| 265 | - printf(" fnt = [%s]\n", db_column_text(&q, 2)); | |
| 269 | + fossil_print(" fnv = [%s]\n", db_column_text(&q, 1)); | |
| 270 | + fossil_print(" fnt = [%s]\n", db_column_text(&q, 2)); | |
| 266 | 271 | } |
| 267 | 272 | db_finalize(&q); |
| 268 | 273 | } |
| 269 | 274 | |
| 270 | 275 | /* If FILES appear on the command-line, remove from the "fv" table |
| @@ -331,26 +336,26 @@ | ||
| 331 | 336 | nameChng = fossil_strcmp(zName, zNewName); |
| 332 | 337 | if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ |
| 333 | 338 | /* Conflict. This file has been added to the current checkout |
| 334 | 339 | ** but also exists in the target checkout. Use the current version. |
| 335 | 340 | */ |
| 336 | - printf("CONFLICT %s\n", zName); | |
| 341 | + fossil_print("CONFLICT %s\n", zName); | |
| 337 | 342 | nConflict++; |
| 338 | 343 | }else if( idt>0 && idv==0 ){ |
| 339 | 344 | /* File added in the target. */ |
| 340 | - printf("ADD %s\n", zName); | |
| 345 | + fossil_print("ADD %s\n", zName); | |
| 341 | 346 | undo_save(zName); |
| 342 | 347 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 343 | 348 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ |
| 344 | 349 | /* The file is unedited. Change it to the target version */ |
| 345 | 350 | undo_save(zName); |
| 346 | - printf("UPDATE %s\n", zName); | |
| 351 | + fossil_print("UPDATE %s\n", zName); | |
| 347 | 352 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 348 | 353 | }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ |
| 349 | 354 | /* The file missing from the local check-out. Restore it to the |
| 350 | 355 | ** version that appears in the target. */ |
| 351 | - printf("UPDATE %s\n", zName); | |
| 356 | + fossil_print("UPDATE %s\n", zName); | |
| 352 | 357 | undo_save(zName); |
| 353 | 358 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 354 | 359 | }else if( idt==0 && idv>0 ){ |
| 355 | 360 | if( ridv==0 ){ |
| 356 | 361 | /* Added in current checkout. Continue to hold the file as |
| @@ -357,25 +362,26 @@ | ||
| 357 | 362 | ** as an addition */ |
| 358 | 363 | db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv); |
| 359 | 364 | }else if( chnged ){ |
| 360 | 365 | /* Edited locally but deleted from the target. Do not track the |
| 361 | 366 | ** file but keep the edited version around. */ |
| 362 | - printf("CONFLICT %s - edited locally but deleted by update\n", zName); | |
| 367 | + fossil_print("CONFLICT %s - edited locally but deleted by update\n", | |
| 368 | + zName); | |
| 363 | 369 | nConflict++; |
| 364 | 370 | }else{ |
| 365 | - printf("REMOVE %s\n", zName); | |
| 371 | + fossil_print("REMOVE %s\n", zName); | |
| 366 | 372 | undo_save(zName); |
| 367 | - if( !nochangeFlag ) unlink(zFullPath); | |
| 373 | + if( !nochangeFlag ) file_delete(zFullPath); | |
| 368 | 374 | } |
| 369 | 375 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){ |
| 370 | 376 | /* Merge the changes in the current tree into the target version */ |
| 371 | 377 | Blob r, t, v; |
| 372 | 378 | int rc; |
| 373 | 379 | if( nameChng ){ |
| 374 | - printf("MERGE %s -> %s\n", zName, zNewName); | |
| 380 | + fossil_print("MERGE %s -> %s\n", zName, zNewName); | |
| 375 | 381 | }else{ |
| 376 | - printf("MERGE %s\n", zName); | |
| 382 | + fossil_print("MERGE %s\n", zName); | |
| 377 | 383 | } |
| 378 | 384 | undo_save(zName); |
| 379 | 385 | content_get(ridt, &t); |
| 380 | 386 | content_get(ridv, &v); |
| 381 | 387 | rc = merge_3way(&v, zFullPath, &t, &r); |
| @@ -383,51 +389,51 @@ | ||
| 383 | 389 | if( !nochangeFlag ){ |
| 384 | 390 | blob_write_to_file(&r, zFullNewPath); |
| 385 | 391 | file_setexe(zFullNewPath, isexe); |
| 386 | 392 | } |
| 387 | 393 | if( rc>0 ){ |
| 388 | - printf("***** %d merge conflicts in %s\n", rc, zNewName); | |
| 394 | + fossil_print("***** %d merge conflicts in %s\n", rc, zNewName); | |
| 389 | 395 | nConflict++; |
| 390 | 396 | } |
| 391 | 397 | }else{ |
| 392 | 398 | if( !nochangeFlag ){ |
| 393 | 399 | blob_write_to_file(&t, zFullNewPath); |
| 394 | 400 | file_setexe(zFullNewPath, isexe); |
| 395 | 401 | } |
| 396 | - printf("***** Cannot merge binary file %s\n", zNewName); | |
| 402 | + fossil_print("***** Cannot merge binary file %s\n", zNewName); | |
| 397 | 403 | nConflict++; |
| 398 | 404 | } |
| 399 | - if( nameChng && !nochangeFlag ) unlink(zFullPath); | |
| 405 | + if( nameChng && !nochangeFlag ) file_delete(zFullPath); | |
| 400 | 406 | blob_reset(&v); |
| 401 | 407 | blob_reset(&t); |
| 402 | 408 | blob_reset(&r); |
| 403 | 409 | }else{ |
| 404 | 410 | if( chnged ){ |
| 405 | - if( verboseFlag ) printf("EDITED %s\n", zName); | |
| 411 | + if( verboseFlag ) fossil_print("EDITED %s\n", zName); | |
| 406 | 412 | }else{ |
| 407 | 413 | db_bind_int(&mtimeXfer, ":idv", idv); |
| 408 | 414 | db_bind_int(&mtimeXfer, ":idt", idt); |
| 409 | 415 | db_step(&mtimeXfer); |
| 410 | 416 | db_reset(&mtimeXfer); |
| 411 | - if( verboseFlag ) printf("UNCHANGED %s\n", zName); | |
| 417 | + if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName); | |
| 412 | 418 | } |
| 413 | 419 | } |
| 414 | 420 | free(zFullPath); |
| 415 | 421 | free(zFullNewPath); |
| 416 | 422 | } |
| 417 | 423 | db_finalize(&q); |
| 418 | 424 | db_finalize(&mtimeXfer); |
| 419 | - printf("--------------\n"); | |
| 425 | + fossil_print("--------------\n"); | |
| 420 | 426 | show_common_info(tid, "updated-to:", 1, 0); |
| 421 | 427 | |
| 422 | 428 | /* Report on conflicts |
| 423 | 429 | */ |
| 424 | 430 | if( nConflict && !nochangeFlag ){ |
| 425 | 431 | if( internalUpdate ){ |
| 426 | 432 | internalConflictCnt = nConflict; |
| 427 | 433 | }else{ |
| 428 | - printf("WARNING: %d merge conflicts - see messages above for details.\n", | |
| 434 | + fossil_print("WARNING: %d merge conflicts - see messages above for details.\n", | |
| 429 | 435 | nConflict); |
| 430 | 436 | } |
| 431 | 437 | } |
| 432 | 438 | |
| 433 | 439 | /* |
| @@ -467,11 +473,11 @@ | ||
| 467 | 473 | Manifest *pManifest; |
| 468 | 474 | ManifestFile *pFile; |
| 469 | 475 | int rid=0; |
| 470 | 476 | |
| 471 | 477 | if( revision ){ |
| 472 | - rid = name_to_rid(revision); | |
| 478 | + rid = name_to_typed_rid(revision,"ci"); | |
| 473 | 479 | }else{ |
| 474 | 480 | rid = db_lget_int("checkout", 0); |
| 475 | 481 | } |
| 476 | 482 | if( !is_a_version(rid) ){ |
| 477 | 483 | if( errCode>0 ) return errCode; |
| @@ -570,23 +576,23 @@ | ||
| 570 | 576 | zFile = db_column_text(&q, 0); |
| 571 | 577 | zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 572 | 578 | errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); |
| 573 | 579 | if( errCode==2 ){ |
| 574 | 580 | if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ |
| 575 | - printf("UNMANAGE: %s\n", zFile); | |
| 581 | + fossil_print("UNMANAGE: %s\n", zFile); | |
| 576 | 582 | }else{ |
| 577 | 583 | undo_save(zFile); |
| 578 | - unlink(zFull); | |
| 579 | - printf("DELETE: %s\n", zFile); | |
| 584 | + file_delete(zFull); | |
| 585 | + fossil_print("DELETE: %s\n", zFile); | |
| 580 | 586 | } |
| 581 | 587 | db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile); |
| 582 | 588 | }else{ |
| 583 | 589 | sqlite3_int64 mtime; |
| 584 | 590 | undo_save(zFile); |
| 585 | 591 | blob_write_to_file(&record, zFull); |
| 586 | 592 | file_setexe(zFull, isExe); |
| 587 | - printf("REVERTED: %s\n", zFile); | |
| 593 | + fossil_print("REVERTED: %s\n", zFile); | |
| 588 | 594 | mtime = file_mtime(zFull); |
| 589 | 595 | db_multi_exec( |
| 590 | 596 | "UPDATE vfile" |
| 591 | 597 | " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, mrid=rid," |
| 592 | 598 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 593 | 599 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -119,20 +119,20 @@ | |
| 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | |
| 121 | if( internalUpdate ){ |
| 122 | tid = internalUpdate; |
| 123 | }else if( g.argc>=3 ){ |
| 124 | if( strcmp(g.argv[2], "current")==0 ){ |
| 125 | /* If VERSION is "current", then use the same algorithm to find the |
| 126 | ** target as if VERSION were omitted. */ |
| 127 | }else if( strcmp(g.argv[2], "latest")==0 ){ |
| 128 | /* If VERSION is "latest", then use the same algorithm to find the |
| 129 | ** target as if VERSION were omitted and the --latest flag is present. |
| 130 | */ |
| 131 | latestFlag = 1; |
| 132 | }else{ |
| 133 | tid = name_to_rid(g.argv[2]); |
| 134 | if( tid==0 ){ |
| 135 | fossil_fatal("no such version: %s", g.argv[2]); |
| 136 | }else if( !is_a_version(tid) ){ |
| 137 | fossil_fatal("no such version: %s", g.argv[2]); |
| 138 | } |
| @@ -175,13 +175,18 @@ | |
| 175 | } |
| 176 | } |
| 177 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 178 | " WHERE event.objid=leaves.rid" |
| 179 | " ORDER BY event.mtime DESC"); |
| 180 | } |
| 181 | |
| 182 | if( !verboseFlag && (tid==vid)) return; /* Nothing to update */ |
| 183 | db_begin_transaction(); |
| 184 | vfile_check_signature(vid, 1, 0); |
| 185 | if( !nochangeFlag && !internalUpdate ) undo_begin(); |
| 186 | load_vfile_from_rid(tid); |
| 187 | |
| @@ -253,18 +258,18 @@ | |
| 253 | if( debugFlag ){ |
| 254 | db_prepare(&q, |
| 255 | "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv" |
| 256 | ); |
| 257 | while( db_step(&q)==SQLITE_ROW ){ |
| 258 | printf("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n", |
| 259 | db_column_int(&q, 0), |
| 260 | db_column_int(&q, 4), |
| 261 | db_column_int(&q, 5), |
| 262 | db_column_int(&q, 3), |
| 263 | db_column_int(&q, 6)); |
| 264 | printf(" fnv = [%s]\n", db_column_text(&q, 1)); |
| 265 | printf(" fnt = [%s]\n", db_column_text(&q, 2)); |
| 266 | } |
| 267 | db_finalize(&q); |
| 268 | } |
| 269 | |
| 270 | /* If FILES appear on the command-line, remove from the "fv" table |
| @@ -331,26 +336,26 @@ | |
| 331 | nameChng = fossil_strcmp(zName, zNewName); |
| 332 | if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ |
| 333 | /* Conflict. This file has been added to the current checkout |
| 334 | ** but also exists in the target checkout. Use the current version. |
| 335 | */ |
| 336 | printf("CONFLICT %s\n", zName); |
| 337 | nConflict++; |
| 338 | }else if( idt>0 && idv==0 ){ |
| 339 | /* File added in the target. */ |
| 340 | printf("ADD %s\n", zName); |
| 341 | undo_save(zName); |
| 342 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 343 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ |
| 344 | /* The file is unedited. Change it to the target version */ |
| 345 | undo_save(zName); |
| 346 | printf("UPDATE %s\n", zName); |
| 347 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 348 | }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ |
| 349 | /* The file missing from the local check-out. Restore it to the |
| 350 | ** version that appears in the target. */ |
| 351 | printf("UPDATE %s\n", zName); |
| 352 | undo_save(zName); |
| 353 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 354 | }else if( idt==0 && idv>0 ){ |
| 355 | if( ridv==0 ){ |
| 356 | /* Added in current checkout. Continue to hold the file as |
| @@ -357,25 +362,26 @@ | |
| 357 | ** as an addition */ |
| 358 | db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv); |
| 359 | }else if( chnged ){ |
| 360 | /* Edited locally but deleted from the target. Do not track the |
| 361 | ** file but keep the edited version around. */ |
| 362 | printf("CONFLICT %s - edited locally but deleted by update\n", zName); |
| 363 | nConflict++; |
| 364 | }else{ |
| 365 | printf("REMOVE %s\n", zName); |
| 366 | undo_save(zName); |
| 367 | if( !nochangeFlag ) unlink(zFullPath); |
| 368 | } |
| 369 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){ |
| 370 | /* Merge the changes in the current tree into the target version */ |
| 371 | Blob r, t, v; |
| 372 | int rc; |
| 373 | if( nameChng ){ |
| 374 | printf("MERGE %s -> %s\n", zName, zNewName); |
| 375 | }else{ |
| 376 | printf("MERGE %s\n", zName); |
| 377 | } |
| 378 | undo_save(zName); |
| 379 | content_get(ridt, &t); |
| 380 | content_get(ridv, &v); |
| 381 | rc = merge_3way(&v, zFullPath, &t, &r); |
| @@ -383,51 +389,51 @@ | |
| 383 | if( !nochangeFlag ){ |
| 384 | blob_write_to_file(&r, zFullNewPath); |
| 385 | file_setexe(zFullNewPath, isexe); |
| 386 | } |
| 387 | if( rc>0 ){ |
| 388 | printf("***** %d merge conflicts in %s\n", rc, zNewName); |
| 389 | nConflict++; |
| 390 | } |
| 391 | }else{ |
| 392 | if( !nochangeFlag ){ |
| 393 | blob_write_to_file(&t, zFullNewPath); |
| 394 | file_setexe(zFullNewPath, isexe); |
| 395 | } |
| 396 | printf("***** Cannot merge binary file %s\n", zNewName); |
| 397 | nConflict++; |
| 398 | } |
| 399 | if( nameChng && !nochangeFlag ) unlink(zFullPath); |
| 400 | blob_reset(&v); |
| 401 | blob_reset(&t); |
| 402 | blob_reset(&r); |
| 403 | }else{ |
| 404 | if( chnged ){ |
| 405 | if( verboseFlag ) printf("EDITED %s\n", zName); |
| 406 | }else{ |
| 407 | db_bind_int(&mtimeXfer, ":idv", idv); |
| 408 | db_bind_int(&mtimeXfer, ":idt", idt); |
| 409 | db_step(&mtimeXfer); |
| 410 | db_reset(&mtimeXfer); |
| 411 | if( verboseFlag ) printf("UNCHANGED %s\n", zName); |
| 412 | } |
| 413 | } |
| 414 | free(zFullPath); |
| 415 | free(zFullNewPath); |
| 416 | } |
| 417 | db_finalize(&q); |
| 418 | db_finalize(&mtimeXfer); |
| 419 | printf("--------------\n"); |
| 420 | show_common_info(tid, "updated-to:", 1, 0); |
| 421 | |
| 422 | /* Report on conflicts |
| 423 | */ |
| 424 | if( nConflict && !nochangeFlag ){ |
| 425 | if( internalUpdate ){ |
| 426 | internalConflictCnt = nConflict; |
| 427 | }else{ |
| 428 | printf("WARNING: %d merge conflicts - see messages above for details.\n", |
| 429 | nConflict); |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | /* |
| @@ -467,11 +473,11 @@ | |
| 467 | Manifest *pManifest; |
| 468 | ManifestFile *pFile; |
| 469 | int rid=0; |
| 470 | |
| 471 | if( revision ){ |
| 472 | rid = name_to_rid(revision); |
| 473 | }else{ |
| 474 | rid = db_lget_int("checkout", 0); |
| 475 | } |
| 476 | if( !is_a_version(rid) ){ |
| 477 | if( errCode>0 ) return errCode; |
| @@ -570,23 +576,23 @@ | |
| 570 | zFile = db_column_text(&q, 0); |
| 571 | zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 572 | errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); |
| 573 | if( errCode==2 ){ |
| 574 | if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ |
| 575 | printf("UNMANAGE: %s\n", zFile); |
| 576 | }else{ |
| 577 | undo_save(zFile); |
| 578 | unlink(zFull); |
| 579 | printf("DELETE: %s\n", zFile); |
| 580 | } |
| 581 | db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile); |
| 582 | }else{ |
| 583 | sqlite3_int64 mtime; |
| 584 | undo_save(zFile); |
| 585 | blob_write_to_file(&record, zFull); |
| 586 | file_setexe(zFull, isExe); |
| 587 | printf("REVERTED: %s\n", zFile); |
| 588 | mtime = file_mtime(zFull); |
| 589 | db_multi_exec( |
| 590 | "UPDATE vfile" |
| 591 | " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, mrid=rid," |
| 592 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 593 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -119,20 +119,20 @@ | |
| 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | |
| 121 | if( internalUpdate ){ |
| 122 | tid = internalUpdate; |
| 123 | }else if( g.argc>=3 ){ |
| 124 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| 125 | /* If VERSION is "current", then use the same algorithm to find the |
| 126 | ** target as if VERSION were omitted. */ |
| 127 | }else if( fossil_strcmp(g.argv[2], "latest")==0 ){ |
| 128 | /* If VERSION is "latest", then use the same algorithm to find the |
| 129 | ** target as if VERSION were omitted and the --latest flag is present. |
| 130 | */ |
| 131 | latestFlag = 1; |
| 132 | }else{ |
| 133 | tid = name_to_typed_rid(g.argv[2],"ci"); |
| 134 | if( tid==0 ){ |
| 135 | fossil_fatal("no such version: %s", g.argv[2]); |
| 136 | }else if( !is_a_version(tid) ){ |
| 137 | fossil_fatal("no such version: %s", g.argv[2]); |
| 138 | } |
| @@ -175,13 +175,18 @@ | |
| 175 | } |
| 176 | } |
| 177 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 178 | " WHERE event.objid=leaves.rid" |
| 179 | " ORDER BY event.mtime DESC"); |
| 180 | if( tid==0 ) tid = vid; |
| 181 | } |
| 182 | |
| 183 | if( tid==0 ){ |
| 184 | fossil_panic("Internal Error: unable to find a version to update to."); |
| 185 | } |
| 186 | |
| 187 | if( tid==vid && !verboseFlag ) return; /* Nothing to update */ |
| 188 | db_begin_transaction(); |
| 189 | vfile_check_signature(vid, 1, 0); |
| 190 | if( !nochangeFlag && !internalUpdate ) undo_begin(); |
| 191 | load_vfile_from_rid(tid); |
| 192 | |
| @@ -253,18 +258,18 @@ | |
| 258 | if( debugFlag ){ |
| 259 | db_prepare(&q, |
| 260 | "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv" |
| 261 | ); |
| 262 | while( db_step(&q)==SQLITE_ROW ){ |
| 263 | fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n", |
| 264 | db_column_int(&q, 0), |
| 265 | db_column_int(&q, 4), |
| 266 | db_column_int(&q, 5), |
| 267 | db_column_int(&q, 3), |
| 268 | db_column_int(&q, 6)); |
| 269 | fossil_print(" fnv = [%s]\n", db_column_text(&q, 1)); |
| 270 | fossil_print(" fnt = [%s]\n", db_column_text(&q, 2)); |
| 271 | } |
| 272 | db_finalize(&q); |
| 273 | } |
| 274 | |
| 275 | /* If FILES appear on the command-line, remove from the "fv" table |
| @@ -331,26 +336,26 @@ | |
| 336 | nameChng = fossil_strcmp(zName, zNewName); |
| 337 | if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ |
| 338 | /* Conflict. This file has been added to the current checkout |
| 339 | ** but also exists in the target checkout. Use the current version. |
| 340 | */ |
| 341 | fossil_print("CONFLICT %s\n", zName); |
| 342 | nConflict++; |
| 343 | }else if( idt>0 && idv==0 ){ |
| 344 | /* File added in the target. */ |
| 345 | fossil_print("ADD %s\n", zName); |
| 346 | undo_save(zName); |
| 347 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 348 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ |
| 349 | /* The file is unedited. Change it to the target version */ |
| 350 | undo_save(zName); |
| 351 | fossil_print("UPDATE %s\n", zName); |
| 352 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 353 | }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ |
| 354 | /* The file missing from the local check-out. Restore it to the |
| 355 | ** version that appears in the target. */ |
| 356 | fossil_print("UPDATE %s\n", zName); |
| 357 | undo_save(zName); |
| 358 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 359 | }else if( idt==0 && idv>0 ){ |
| 360 | if( ridv==0 ){ |
| 361 | /* Added in current checkout. Continue to hold the file as |
| @@ -357,25 +362,26 @@ | |
| 362 | ** as an addition */ |
| 363 | db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv); |
| 364 | }else if( chnged ){ |
| 365 | /* Edited locally but deleted from the target. Do not track the |
| 366 | ** file but keep the edited version around. */ |
| 367 | fossil_print("CONFLICT %s - edited locally but deleted by update\n", |
| 368 | zName); |
| 369 | nConflict++; |
| 370 | }else{ |
| 371 | fossil_print("REMOVE %s\n", zName); |
| 372 | undo_save(zName); |
| 373 | if( !nochangeFlag ) file_delete(zFullPath); |
| 374 | } |
| 375 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){ |
| 376 | /* Merge the changes in the current tree into the target version */ |
| 377 | Blob r, t, v; |
| 378 | int rc; |
| 379 | if( nameChng ){ |
| 380 | fossil_print("MERGE %s -> %s\n", zName, zNewName); |
| 381 | }else{ |
| 382 | fossil_print("MERGE %s\n", zName); |
| 383 | } |
| 384 | undo_save(zName); |
| 385 | content_get(ridt, &t); |
| 386 | content_get(ridv, &v); |
| 387 | rc = merge_3way(&v, zFullPath, &t, &r); |
| @@ -383,51 +389,51 @@ | |
| 389 | if( !nochangeFlag ){ |
| 390 | blob_write_to_file(&r, zFullNewPath); |
| 391 | file_setexe(zFullNewPath, isexe); |
| 392 | } |
| 393 | if( rc>0 ){ |
| 394 | fossil_print("***** %d merge conflicts in %s\n", rc, zNewName); |
| 395 | nConflict++; |
| 396 | } |
| 397 | }else{ |
| 398 | if( !nochangeFlag ){ |
| 399 | blob_write_to_file(&t, zFullNewPath); |
| 400 | file_setexe(zFullNewPath, isexe); |
| 401 | } |
| 402 | fossil_print("***** Cannot merge binary file %s\n", zNewName); |
| 403 | nConflict++; |
| 404 | } |
| 405 | if( nameChng && !nochangeFlag ) file_delete(zFullPath); |
| 406 | blob_reset(&v); |
| 407 | blob_reset(&t); |
| 408 | blob_reset(&r); |
| 409 | }else{ |
| 410 | if( chnged ){ |
| 411 | if( verboseFlag ) fossil_print("EDITED %s\n", zName); |
| 412 | }else{ |
| 413 | db_bind_int(&mtimeXfer, ":idv", idv); |
| 414 | db_bind_int(&mtimeXfer, ":idt", idt); |
| 415 | db_step(&mtimeXfer); |
| 416 | db_reset(&mtimeXfer); |
| 417 | if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName); |
| 418 | } |
| 419 | } |
| 420 | free(zFullPath); |
| 421 | free(zFullNewPath); |
| 422 | } |
| 423 | db_finalize(&q); |
| 424 | db_finalize(&mtimeXfer); |
| 425 | fossil_print("--------------\n"); |
| 426 | show_common_info(tid, "updated-to:", 1, 0); |
| 427 | |
| 428 | /* Report on conflicts |
| 429 | */ |
| 430 | if( nConflict && !nochangeFlag ){ |
| 431 | if( internalUpdate ){ |
| 432 | internalConflictCnt = nConflict; |
| 433 | }else{ |
| 434 | fossil_print("WARNING: %d merge conflicts - see messages above for details.\n", |
| 435 | nConflict); |
| 436 | } |
| 437 | } |
| 438 | |
| 439 | /* |
| @@ -467,11 +473,11 @@ | |
| 473 | Manifest *pManifest; |
| 474 | ManifestFile *pFile; |
| 475 | int rid=0; |
| 476 | |
| 477 | if( revision ){ |
| 478 | rid = name_to_typed_rid(revision,"ci"); |
| 479 | }else{ |
| 480 | rid = db_lget_int("checkout", 0); |
| 481 | } |
| 482 | if( !is_a_version(rid) ){ |
| 483 | if( errCode>0 ) return errCode; |
| @@ -570,23 +576,23 @@ | |
| 576 | zFile = db_column_text(&q, 0); |
| 577 | zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 578 | errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); |
| 579 | if( errCode==2 ){ |
| 580 | if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ |
| 581 | fossil_print("UNMANAGE: %s\n", zFile); |
| 582 | }else{ |
| 583 | undo_save(zFile); |
| 584 | file_delete(zFull); |
| 585 | fossil_print("DELETE: %s\n", zFile); |
| 586 | } |
| 587 | db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile); |
| 588 | }else{ |
| 589 | sqlite3_int64 mtime; |
| 590 | undo_save(zFile); |
| 591 | blob_write_to_file(&record, zFull); |
| 592 | file_setexe(zFull, isExe); |
| 593 | fossil_print("REVERTED: %s\n", zFile); |
| 594 | mtime = file_mtime(zFull); |
| 595 | db_multi_exec( |
| 596 | "UPDATE vfile" |
| 597 | " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, mrid=rid," |
| 598 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 599 |
+17
-17
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -208,26 +208,26 @@ | ||
| 208 | 208 | if( g.argc!=3 && g.argc!=4 ){ |
| 209 | 209 | usage("URL"); |
| 210 | 210 | } |
| 211 | 211 | url_parse(g.argv[2]); |
| 212 | 212 | for(i=0; i<2; i++){ |
| 213 | - printf("g.urlIsFile = %d\n", g.urlIsFile); | |
| 214 | - printf("g.urlIsHttps = %d\n", g.urlIsHttps); | |
| 215 | - printf("g.urlIsSsh = %d\n", g.urlIsSsh); | |
| 216 | - printf("g.urlProtocol = %s\n", g.urlProtocol); | |
| 217 | - printf("g.urlName = %s\n", g.urlName); | |
| 218 | - printf("g.urlPort = %d\n", g.urlPort); | |
| 219 | - printf("g.urlDfltPort = %d\n", g.urlDfltPort); | |
| 220 | - printf("g.urlHostname = %s\n", g.urlHostname); | |
| 221 | - printf("g.urlPath = %s\n", g.urlPath); | |
| 222 | - printf("g.urlUser = %s\n", g.urlUser); | |
| 223 | - printf("g.urlPasswd = %s\n", g.urlPasswd); | |
| 224 | - printf("g.urlCanonical = %s\n", g.urlCanonical); | |
| 225 | - printf("g.urlFossil = %s\n", g.urlFossil); | |
| 213 | + fossil_print("g.urlIsFile = %d\n", g.urlIsFile); | |
| 214 | + fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); | |
| 215 | + fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); | |
| 216 | + fossil_print("g.urlProtocol = %s\n", g.urlProtocol); | |
| 217 | + fossil_print("g.urlName = %s\n", g.urlName); | |
| 218 | + fossil_print("g.urlPort = %d\n", g.urlPort); | |
| 219 | + fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); | |
| 220 | + fossil_print("g.urlHostname = %s\n", g.urlHostname); | |
| 221 | + fossil_print("g.urlPath = %s\n", g.urlPath); | |
| 222 | + fossil_print("g.urlUser = %s\n", g.urlUser); | |
| 223 | + fossil_print("g.urlPasswd = %s\n", g.urlPasswd); | |
| 224 | + fossil_print("g.urlCanonical = %s\n", g.urlCanonical); | |
| 225 | + fossil_print("g.urlFossil = %s\n", g.urlFossil); | |
| 226 | 226 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 227 | 227 | if( i==0 ){ |
| 228 | - printf("********\n"); | |
| 228 | + fossil_print("********\n"); | |
| 229 | 229 | url_enable_proxy("Using proxy: "); |
| 230 | 230 | } |
| 231 | 231 | } |
| 232 | 232 | } |
| 233 | 233 | |
| @@ -276,11 +276,11 @@ | ||
| 276 | 276 | char *zOriginalUser = g.urlUser; |
| 277 | 277 | char *zOriginalPasswd = g.urlPasswd; |
| 278 | 278 | g.urlUser = 0; |
| 279 | 279 | g.urlPasswd = ""; |
| 280 | 280 | url_parse(zProxy); |
| 281 | - if( zMsg ) printf("%s%s\n", zMsg, g.urlCanonical); | |
| 281 | + if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); | |
| 282 | 282 | g.urlPath = zOriginalUrl; |
| 283 | 283 | g.urlHostname = zOriginalHost; |
| 284 | 284 | if( g.urlUser ){ |
| 285 | 285 | char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 286 | 286 | char *zCredentials2 = encode64(zCredentials1, -1); |
| @@ -340,16 +340,16 @@ | ||
| 340 | 340 | |
| 341 | 341 | blob_reset(&p->url); |
| 342 | 342 | blob_appendf(&p->url, "%s/%s", g.zTop, p->zBase); |
| 343 | 343 | for(i=0; i<p->nParam; i++){ |
| 344 | 344 | const char *z = p->azValue[i]; |
| 345 | - if( zName1 && strcmp(zName1,p->azName[i])==0 ){ | |
| 345 | + if( zName1 && fossil_strcmp(zName1,p->azName[i])==0 ){ | |
| 346 | 346 | zName1 = 0; |
| 347 | 347 | z = zValue1; |
| 348 | 348 | if( z==0 ) continue; |
| 349 | 349 | } |
| 350 | - if( zName2 && strcmp(zName2,p->azName[i])==0 ){ | |
| 350 | + if( zName2 && fossil_strcmp(zName2,p->azName[i])==0 ){ | |
| 351 | 351 | zName2 = 0; |
| 352 | 352 | z = zValue2; |
| 353 | 353 | if( z==0 ) continue; |
| 354 | 354 | } |
| 355 | 355 | blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); |
| 356 | 356 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -208,26 +208,26 @@ | |
| 208 | if( g.argc!=3 && g.argc!=4 ){ |
| 209 | usage("URL"); |
| 210 | } |
| 211 | url_parse(g.argv[2]); |
| 212 | for(i=0; i<2; i++){ |
| 213 | printf("g.urlIsFile = %d\n", g.urlIsFile); |
| 214 | printf("g.urlIsHttps = %d\n", g.urlIsHttps); |
| 215 | printf("g.urlIsSsh = %d\n", g.urlIsSsh); |
| 216 | printf("g.urlProtocol = %s\n", g.urlProtocol); |
| 217 | printf("g.urlName = %s\n", g.urlName); |
| 218 | printf("g.urlPort = %d\n", g.urlPort); |
| 219 | printf("g.urlDfltPort = %d\n", g.urlDfltPort); |
| 220 | printf("g.urlHostname = %s\n", g.urlHostname); |
| 221 | printf("g.urlPath = %s\n", g.urlPath); |
| 222 | printf("g.urlUser = %s\n", g.urlUser); |
| 223 | printf("g.urlPasswd = %s\n", g.urlPasswd); |
| 224 | printf("g.urlCanonical = %s\n", g.urlCanonical); |
| 225 | printf("g.urlFossil = %s\n", g.urlFossil); |
| 226 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 227 | if( i==0 ){ |
| 228 | printf("********\n"); |
| 229 | url_enable_proxy("Using proxy: "); |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | |
| @@ -276,11 +276,11 @@ | |
| 276 | char *zOriginalUser = g.urlUser; |
| 277 | char *zOriginalPasswd = g.urlPasswd; |
| 278 | g.urlUser = 0; |
| 279 | g.urlPasswd = ""; |
| 280 | url_parse(zProxy); |
| 281 | if( zMsg ) printf("%s%s\n", zMsg, g.urlCanonical); |
| 282 | g.urlPath = zOriginalUrl; |
| 283 | g.urlHostname = zOriginalHost; |
| 284 | if( g.urlUser ){ |
| 285 | char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 286 | char *zCredentials2 = encode64(zCredentials1, -1); |
| @@ -340,16 +340,16 @@ | |
| 340 | |
| 341 | blob_reset(&p->url); |
| 342 | blob_appendf(&p->url, "%s/%s", g.zTop, p->zBase); |
| 343 | for(i=0; i<p->nParam; i++){ |
| 344 | const char *z = p->azValue[i]; |
| 345 | if( zName1 && strcmp(zName1,p->azName[i])==0 ){ |
| 346 | zName1 = 0; |
| 347 | z = zValue1; |
| 348 | if( z==0 ) continue; |
| 349 | } |
| 350 | if( zName2 && strcmp(zName2,p->azName[i])==0 ){ |
| 351 | zName2 = 0; |
| 352 | z = zValue2; |
| 353 | if( z==0 ) continue; |
| 354 | } |
| 355 | blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); |
| 356 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -208,26 +208,26 @@ | |
| 208 | if( g.argc!=3 && g.argc!=4 ){ |
| 209 | usage("URL"); |
| 210 | } |
| 211 | url_parse(g.argv[2]); |
| 212 | for(i=0; i<2; i++){ |
| 213 | fossil_print("g.urlIsFile = %d\n", g.urlIsFile); |
| 214 | fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); |
| 215 | fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); |
| 216 | fossil_print("g.urlProtocol = %s\n", g.urlProtocol); |
| 217 | fossil_print("g.urlName = %s\n", g.urlName); |
| 218 | fossil_print("g.urlPort = %d\n", g.urlPort); |
| 219 | fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); |
| 220 | fossil_print("g.urlHostname = %s\n", g.urlHostname); |
| 221 | fossil_print("g.urlPath = %s\n", g.urlPath); |
| 222 | fossil_print("g.urlUser = %s\n", g.urlUser); |
| 223 | fossil_print("g.urlPasswd = %s\n", g.urlPasswd); |
| 224 | fossil_print("g.urlCanonical = %s\n", g.urlCanonical); |
| 225 | fossil_print("g.urlFossil = %s\n", g.urlFossil); |
| 226 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 227 | if( i==0 ){ |
| 228 | fossil_print("********\n"); |
| 229 | url_enable_proxy("Using proxy: "); |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | |
| @@ -276,11 +276,11 @@ | |
| 276 | char *zOriginalUser = g.urlUser; |
| 277 | char *zOriginalPasswd = g.urlPasswd; |
| 278 | g.urlUser = 0; |
| 279 | g.urlPasswd = ""; |
| 280 | url_parse(zProxy); |
| 281 | if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); |
| 282 | g.urlPath = zOriginalUrl; |
| 283 | g.urlHostname = zOriginalHost; |
| 284 | if( g.urlUser ){ |
| 285 | char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 286 | char *zCredentials2 = encode64(zCredentials1, -1); |
| @@ -340,16 +340,16 @@ | |
| 340 | |
| 341 | blob_reset(&p->url); |
| 342 | blob_appendf(&p->url, "%s/%s", g.zTop, p->zBase); |
| 343 | for(i=0; i<p->nParam; i++){ |
| 344 | const char *z = p->azValue[i]; |
| 345 | if( zName1 && fossil_strcmp(zName1,p->azName[i])==0 ){ |
| 346 | zName1 = 0; |
| 347 | z = zValue1; |
| 348 | if( z==0 ) continue; |
| 349 | } |
| 350 | if( zName2 && fossil_strcmp(zName2,p->azName[i])==0 ){ |
| 351 | zName2 = 0; |
| 352 | z = zValue2; |
| 353 | if( z==0 ) continue; |
| 354 | } |
| 355 | blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); |
| 356 |
+6
-6
| --- src/user.c | ||
| +++ src/user.c | ||
| @@ -117,11 +117,11 @@ | ||
| 117 | 117 | prompt_for_passphrase(zPrompt, pPassphrase); |
| 118 | 118 | if( verify==0 ) break; |
| 119 | 119 | if( verify==1 && blob_size(pPassphrase)==0 ) break; |
| 120 | 120 | prompt_for_passphrase("Retype new password: ", &secondTry); |
| 121 | 121 | if( blob_compare(pPassphrase, &secondTry) ){ |
| 122 | - printf("Passphrases do not match. Try again...\n"); | |
| 122 | + fossil_print("Passphrases do not match. Try again...\n"); | |
| 123 | 123 | }else{ |
| 124 | 124 | break; |
| 125 | 125 | } |
| 126 | 126 | } |
| 127 | 127 | blob_reset(&secondTry); |
| @@ -132,11 +132,11 @@ | ||
| 132 | 132 | */ |
| 133 | 133 | void prompt_user(const char *zPrompt, Blob *pIn){ |
| 134 | 134 | char *z; |
| 135 | 135 | char zLine[1000]; |
| 136 | 136 | blob_zero(pIn); |
| 137 | - printf("%s", zPrompt); | |
| 137 | + fossil_print("%s", zPrompt); | |
| 138 | 138 | fflush(stdout); |
| 139 | 139 | z = fgets(zLine, sizeof(zLine), stdin); |
| 140 | 140 | if( z ){ |
| 141 | 141 | strip_string(pIn, z); |
| 142 | 142 | } |
| @@ -212,11 +212,11 @@ | ||
| 212 | 212 | ); |
| 213 | 213 | free(zPw); |
| 214 | 214 | }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){ |
| 215 | 215 | user_select(); |
| 216 | 216 | if( g.argc==3 ){ |
| 217 | - printf("%s\n", g.zLogin); | |
| 217 | + fossil_print("%s\n", g.zLogin); | |
| 218 | 218 | }else{ |
| 219 | 219 | if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.argv[3]) ){ |
| 220 | 220 | fossil_fatal("no such user: %s", g.argv[3]); |
| 221 | 221 | } |
| 222 | 222 | if( g.localOpen ){ |
| @@ -227,11 +227,11 @@ | ||
| 227 | 227 | } |
| 228 | 228 | }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ |
| 229 | 229 | Stmt q; |
| 230 | 230 | db_prepare(&q, "SELECT login, info FROM user ORDER BY login"); |
| 231 | 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | - printf("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1)); | |
| 232 | + fossil_print("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1)); | |
| 233 | 233 | } |
| 234 | 234 | db_finalize(&q); |
| 235 | 235 | }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){ |
| 236 | 236 | char *zPrompt; |
| 237 | 237 | int uid; |
| @@ -246,11 +246,11 @@ | ||
| 246 | 246 | }else{ |
| 247 | 247 | zPrompt = mprintf("New password for %s: ", g.argv[3]); |
| 248 | 248 | prompt_for_password(zPrompt, &pw, 1); |
| 249 | 249 | } |
| 250 | 250 | if( blob_size(&pw)==0 ){ |
| 251 | - printf("password unchanged\n"); | |
| 251 | + fossil_print("password unchanged\n"); | |
| 252 | 252 | }else{ |
| 253 | 253 | char *zSecret = sha1_shared_secret(blob_str(&pw), g.argv[3], 0); |
| 254 | 254 | db_multi_exec("UPDATE user SET pw=%Q, mtime=now() WHERE uid=%d", |
| 255 | 255 | zSecret, uid); |
| 256 | 256 | free(zSecret); |
| @@ -268,11 +268,11 @@ | ||
| 268 | 268 | db_multi_exec( |
| 269 | 269 | "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d", |
| 270 | 270 | g.argv[4], uid |
| 271 | 271 | ); |
| 272 | 272 | } |
| 273 | - printf("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid)); | |
| 273 | + fossil_print("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid)); | |
| 274 | 274 | }else{ |
| 275 | 275 | fossil_panic("user subcommand should be one of: " |
| 276 | 276 | "capabilities default list new password"); |
| 277 | 277 | } |
| 278 | 278 | } |
| 279 | 279 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -117,11 +117,11 @@ | |
| 117 | prompt_for_passphrase(zPrompt, pPassphrase); |
| 118 | if( verify==0 ) break; |
| 119 | if( verify==1 && blob_size(pPassphrase)==0 ) break; |
| 120 | prompt_for_passphrase("Retype new password: ", &secondTry); |
| 121 | if( blob_compare(pPassphrase, &secondTry) ){ |
| 122 | printf("Passphrases do not match. Try again...\n"); |
| 123 | }else{ |
| 124 | break; |
| 125 | } |
| 126 | } |
| 127 | blob_reset(&secondTry); |
| @@ -132,11 +132,11 @@ | |
| 132 | */ |
| 133 | void prompt_user(const char *zPrompt, Blob *pIn){ |
| 134 | char *z; |
| 135 | char zLine[1000]; |
| 136 | blob_zero(pIn); |
| 137 | printf("%s", zPrompt); |
| 138 | fflush(stdout); |
| 139 | z = fgets(zLine, sizeof(zLine), stdin); |
| 140 | if( z ){ |
| 141 | strip_string(pIn, z); |
| 142 | } |
| @@ -212,11 +212,11 @@ | |
| 212 | ); |
| 213 | free(zPw); |
| 214 | }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){ |
| 215 | user_select(); |
| 216 | if( g.argc==3 ){ |
| 217 | printf("%s\n", g.zLogin); |
| 218 | }else{ |
| 219 | if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.argv[3]) ){ |
| 220 | fossil_fatal("no such user: %s", g.argv[3]); |
| 221 | } |
| 222 | if( g.localOpen ){ |
| @@ -227,11 +227,11 @@ | |
| 227 | } |
| 228 | }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ |
| 229 | Stmt q; |
| 230 | db_prepare(&q, "SELECT login, info FROM user ORDER BY login"); |
| 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | printf("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1)); |
| 233 | } |
| 234 | db_finalize(&q); |
| 235 | }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){ |
| 236 | char *zPrompt; |
| 237 | int uid; |
| @@ -246,11 +246,11 @@ | |
| 246 | }else{ |
| 247 | zPrompt = mprintf("New password for %s: ", g.argv[3]); |
| 248 | prompt_for_password(zPrompt, &pw, 1); |
| 249 | } |
| 250 | if( blob_size(&pw)==0 ){ |
| 251 | printf("password unchanged\n"); |
| 252 | }else{ |
| 253 | char *zSecret = sha1_shared_secret(blob_str(&pw), g.argv[3], 0); |
| 254 | db_multi_exec("UPDATE user SET pw=%Q, mtime=now() WHERE uid=%d", |
| 255 | zSecret, uid); |
| 256 | free(zSecret); |
| @@ -268,11 +268,11 @@ | |
| 268 | db_multi_exec( |
| 269 | "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d", |
| 270 | g.argv[4], uid |
| 271 | ); |
| 272 | } |
| 273 | printf("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid)); |
| 274 | }else{ |
| 275 | fossil_panic("user subcommand should be one of: " |
| 276 | "capabilities default list new password"); |
| 277 | } |
| 278 | } |
| 279 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -117,11 +117,11 @@ | |
| 117 | prompt_for_passphrase(zPrompt, pPassphrase); |
| 118 | if( verify==0 ) break; |
| 119 | if( verify==1 && blob_size(pPassphrase)==0 ) break; |
| 120 | prompt_for_passphrase("Retype new password: ", &secondTry); |
| 121 | if( blob_compare(pPassphrase, &secondTry) ){ |
| 122 | fossil_print("Passphrases do not match. Try again...\n"); |
| 123 | }else{ |
| 124 | break; |
| 125 | } |
| 126 | } |
| 127 | blob_reset(&secondTry); |
| @@ -132,11 +132,11 @@ | |
| 132 | */ |
| 133 | void prompt_user(const char *zPrompt, Blob *pIn){ |
| 134 | char *z; |
| 135 | char zLine[1000]; |
| 136 | blob_zero(pIn); |
| 137 | fossil_print("%s", zPrompt); |
| 138 | fflush(stdout); |
| 139 | z = fgets(zLine, sizeof(zLine), stdin); |
| 140 | if( z ){ |
| 141 | strip_string(pIn, z); |
| 142 | } |
| @@ -212,11 +212,11 @@ | |
| 212 | ); |
| 213 | free(zPw); |
| 214 | }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){ |
| 215 | user_select(); |
| 216 | if( g.argc==3 ){ |
| 217 | fossil_print("%s\n", g.zLogin); |
| 218 | }else{ |
| 219 | if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.argv[3]) ){ |
| 220 | fossil_fatal("no such user: %s", g.argv[3]); |
| 221 | } |
| 222 | if( g.localOpen ){ |
| @@ -227,11 +227,11 @@ | |
| 227 | } |
| 228 | }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ |
| 229 | Stmt q; |
| 230 | db_prepare(&q, "SELECT login, info FROM user ORDER BY login"); |
| 231 | while( db_step(&q)==SQLITE_ROW ){ |
| 232 | fossil_print("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1)); |
| 233 | } |
| 234 | db_finalize(&q); |
| 235 | }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){ |
| 236 | char *zPrompt; |
| 237 | int uid; |
| @@ -246,11 +246,11 @@ | |
| 246 | }else{ |
| 247 | zPrompt = mprintf("New password for %s: ", g.argv[3]); |
| 248 | prompt_for_password(zPrompt, &pw, 1); |
| 249 | } |
| 250 | if( blob_size(&pw)==0 ){ |
| 251 | fossil_print("password unchanged\n"); |
| 252 | }else{ |
| 253 | char *zSecret = sha1_shared_secret(blob_str(&pw), g.argv[3], 0); |
| 254 | db_multi_exec("UPDATE user SET pw=%Q, mtime=now() WHERE uid=%d", |
| 255 | zSecret, uid); |
| 256 | free(zSecret); |
| @@ -268,11 +268,11 @@ | |
| 268 | db_multi_exec( |
| 269 | "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d", |
| 270 | g.argv[4], uid |
| 271 | ); |
| 272 | } |
| 273 | fossil_print("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid)); |
| 274 | }else{ |
| 275 | fossil_panic("user subcommand should be one of: " |
| 276 | "capabilities default list new password"); |
| 277 | } |
| 278 | } |
| 279 |
+16
-9
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -264,11 +264,11 @@ | ||
| 264 | 264 | if( cReply=='n' || cReply=='N' ){ |
| 265 | 265 | blob_reset(&content); |
| 266 | 266 | continue; |
| 267 | 267 | } |
| 268 | 268 | } |
| 269 | - if( verbose ) printf("%s\n", &zName[nRepos]); | |
| 269 | + if( verbose ) fossil_print("%s\n", &zName[nRepos]); | |
| 270 | 270 | blob_write_to_file(&content, zName); |
| 271 | 271 | file_setexe(zName, isExe); |
| 272 | 272 | blob_reset(&content); |
| 273 | 273 | db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", |
| 274 | 274 | file_mtime(zName), id); |
| @@ -286,11 +286,11 @@ | ||
| 286 | 286 | " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); |
| 287 | 287 | while( db_step(&q)==SQLITE_ROW ){ |
| 288 | 288 | const char *zName; |
| 289 | 289 | |
| 290 | 290 | zName = db_column_text(&q, 0); |
| 291 | - unlink(zName); | |
| 291 | + file_delete(zName); | |
| 292 | 292 | } |
| 293 | 293 | db_finalize(&q); |
| 294 | 294 | db_multi_exec("UPDATE vfile SET mtime=NULL WHERE vid=%d AND mrid>0", vid); |
| 295 | 295 | } |
| 296 | 296 | |
| @@ -335,10 +335,11 @@ | ||
| 335 | 335 | const char *zDir; |
| 336 | 336 | struct dirent *pEntry; |
| 337 | 337 | int skipAll = 0; |
| 338 | 338 | static Stmt ins; |
| 339 | 339 | static int depth = 0; |
| 340 | + char *zMbcs; | |
| 340 | 341 | |
| 341 | 342 | origSize = blob_size(pPath); |
| 342 | 343 | if( pIgnore ){ |
| 343 | 344 | blob_appendf(pPath, "/"); |
| 344 | 345 | if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1; |
| @@ -353,20 +354,24 @@ | ||
| 353 | 354 | ); |
| 354 | 355 | } |
| 355 | 356 | depth++; |
| 356 | 357 | |
| 357 | 358 | zDir = blob_str(pPath); |
| 358 | - d = opendir(zDir); | |
| 359 | + zMbcs = fossil_utf8_to_mbcs(zDir); | |
| 360 | + d = opendir(zMbcs); | |
| 359 | 361 | if( d ){ |
| 360 | 362 | while( (pEntry=readdir(d))!=0 ){ |
| 361 | 363 | char *zPath; |
| 364 | + char *zUtf8; | |
| 362 | 365 | if( pEntry->d_name[0]=='.' ){ |
| 363 | 366 | if( !allFlag ) continue; |
| 364 | 367 | if( pEntry->d_name[1]==0 ) continue; |
| 365 | 368 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 366 | 369 | } |
| 367 | - blob_appendf(pPath, "/%s", pEntry->d_name); | |
| 370 | + zUtf8 = fossil_mbcs_to_utf8(pEntry->d_name); | |
| 371 | + blob_appendf(pPath, "/%s", zUtf8); | |
| 372 | + fossil_mbcs_free(zUtf8); | |
| 368 | 373 | zPath = blob_str(pPath); |
| 369 | 374 | if( glob_match(pIgnore, &zPath[nPrefix+1]) ){ |
| 370 | 375 | /* do nothing */ |
| 371 | 376 | }else if( file_isdir(zPath)==1 ){ |
| 372 | 377 | if( !vfile_top_of_checkout(zPath) ){ |
| @@ -379,10 +384,11 @@ | ||
| 379 | 384 | } |
| 380 | 385 | blob_resize(pPath, origSize); |
| 381 | 386 | } |
| 382 | 387 | closedir(d); |
| 383 | 388 | } |
| 389 | + fossil_mbcs_free(zMbcs); | |
| 384 | 390 | |
| 385 | 391 | depth--; |
| 386 | 392 | if( depth==0 ){ |
| 387 | 393 | db_finalize(&ins); |
| 388 | 394 | } |
| @@ -428,11 +434,11 @@ | ||
| 428 | 434 | const char *zName = db_column_text(&q, 1); |
| 429 | 435 | int isSelected = db_column_int(&q, 3); |
| 430 | 436 | |
| 431 | 437 | if( isSelected ){ |
| 432 | 438 | md5sum_step_text(zName, -1); |
| 433 | - in = fopen(zFullpath,"rb"); | |
| 439 | + in = fossil_fopen(zFullpath,"rb"); | |
| 434 | 440 | if( in==0 ){ |
| 435 | 441 | md5sum_step_text(" 0\n", -1); |
| 436 | 442 | continue; |
| 437 | 443 | } |
| 438 | 444 | fseek(in, 0L, SEEK_END); |
| @@ -491,26 +497,27 @@ | ||
| 491 | 497 | int rid = db_column_int(&q, 2); |
| 492 | 498 | |
| 493 | 499 | blob_zero(&disk); |
| 494 | 500 | rc = blob_read_from_file(&disk, zFullpath); |
| 495 | 501 | if( rc<0 ){ |
| 496 | - printf("ERROR: cannot read file [%s]\n", zFullpath); | |
| 502 | + fossil_print("ERROR: cannot read file [%s]\n", zFullpath); | |
| 497 | 503 | blob_reset(&disk); |
| 498 | 504 | continue; |
| 499 | 505 | } |
| 500 | 506 | blob_zero(&repo); |
| 501 | 507 | content_get(rid, &repo); |
| 502 | 508 | if( blob_size(&repo)!=blob_size(&disk) ){ |
| 503 | - printf("ERROR: [%s] is %d bytes on disk but %d in the repository\n", | |
| 509 | + fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n", | |
| 504 | 510 | zName, blob_size(&disk), blob_size(&repo)); |
| 505 | 511 | blob_reset(&disk); |
| 506 | 512 | blob_reset(&repo); |
| 507 | 513 | continue; |
| 508 | 514 | } |
| 509 | 515 | if( blob_compare(&repo, &disk) ){ |
| 510 | - printf("ERROR: [%s] is different on disk compared to the repository\n", | |
| 511 | - zName); | |
| 516 | + fossil_print( | |
| 517 | + "ERROR: [%s] is different on disk compared to the repository\n", | |
| 518 | + zName); | |
| 512 | 519 | } |
| 513 | 520 | blob_reset(&disk); |
| 514 | 521 | blob_reset(&repo); |
| 515 | 522 | } |
| 516 | 523 | db_finalize(&q); |
| 517 | 524 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -264,11 +264,11 @@ | |
| 264 | if( cReply=='n' || cReply=='N' ){ |
| 265 | blob_reset(&content); |
| 266 | continue; |
| 267 | } |
| 268 | } |
| 269 | if( verbose ) printf("%s\n", &zName[nRepos]); |
| 270 | blob_write_to_file(&content, zName); |
| 271 | file_setexe(zName, isExe); |
| 272 | blob_reset(&content); |
| 273 | db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", |
| 274 | file_mtime(zName), id); |
| @@ -286,11 +286,11 @@ | |
| 286 | " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); |
| 287 | while( db_step(&q)==SQLITE_ROW ){ |
| 288 | const char *zName; |
| 289 | |
| 290 | zName = db_column_text(&q, 0); |
| 291 | unlink(zName); |
| 292 | } |
| 293 | db_finalize(&q); |
| 294 | db_multi_exec("UPDATE vfile SET mtime=NULL WHERE vid=%d AND mrid>0", vid); |
| 295 | } |
| 296 | |
| @@ -335,10 +335,11 @@ | |
| 335 | const char *zDir; |
| 336 | struct dirent *pEntry; |
| 337 | int skipAll = 0; |
| 338 | static Stmt ins; |
| 339 | static int depth = 0; |
| 340 | |
| 341 | origSize = blob_size(pPath); |
| 342 | if( pIgnore ){ |
| 343 | blob_appendf(pPath, "/"); |
| 344 | if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1; |
| @@ -353,20 +354,24 @@ | |
| 353 | ); |
| 354 | } |
| 355 | depth++; |
| 356 | |
| 357 | zDir = blob_str(pPath); |
| 358 | d = opendir(zDir); |
| 359 | if( d ){ |
| 360 | while( (pEntry=readdir(d))!=0 ){ |
| 361 | char *zPath; |
| 362 | if( pEntry->d_name[0]=='.' ){ |
| 363 | if( !allFlag ) continue; |
| 364 | if( pEntry->d_name[1]==0 ) continue; |
| 365 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 366 | } |
| 367 | blob_appendf(pPath, "/%s", pEntry->d_name); |
| 368 | zPath = blob_str(pPath); |
| 369 | if( glob_match(pIgnore, &zPath[nPrefix+1]) ){ |
| 370 | /* do nothing */ |
| 371 | }else if( file_isdir(zPath)==1 ){ |
| 372 | if( !vfile_top_of_checkout(zPath) ){ |
| @@ -379,10 +384,11 @@ | |
| 379 | } |
| 380 | blob_resize(pPath, origSize); |
| 381 | } |
| 382 | closedir(d); |
| 383 | } |
| 384 | |
| 385 | depth--; |
| 386 | if( depth==0 ){ |
| 387 | db_finalize(&ins); |
| 388 | } |
| @@ -428,11 +434,11 @@ | |
| 428 | const char *zName = db_column_text(&q, 1); |
| 429 | int isSelected = db_column_int(&q, 3); |
| 430 | |
| 431 | if( isSelected ){ |
| 432 | md5sum_step_text(zName, -1); |
| 433 | in = fopen(zFullpath,"rb"); |
| 434 | if( in==0 ){ |
| 435 | md5sum_step_text(" 0\n", -1); |
| 436 | continue; |
| 437 | } |
| 438 | fseek(in, 0L, SEEK_END); |
| @@ -491,26 +497,27 @@ | |
| 491 | int rid = db_column_int(&q, 2); |
| 492 | |
| 493 | blob_zero(&disk); |
| 494 | rc = blob_read_from_file(&disk, zFullpath); |
| 495 | if( rc<0 ){ |
| 496 | printf("ERROR: cannot read file [%s]\n", zFullpath); |
| 497 | blob_reset(&disk); |
| 498 | continue; |
| 499 | } |
| 500 | blob_zero(&repo); |
| 501 | content_get(rid, &repo); |
| 502 | if( blob_size(&repo)!=blob_size(&disk) ){ |
| 503 | printf("ERROR: [%s] is %d bytes on disk but %d in the repository\n", |
| 504 | zName, blob_size(&disk), blob_size(&repo)); |
| 505 | blob_reset(&disk); |
| 506 | blob_reset(&repo); |
| 507 | continue; |
| 508 | } |
| 509 | if( blob_compare(&repo, &disk) ){ |
| 510 | printf("ERROR: [%s] is different on disk compared to the repository\n", |
| 511 | zName); |
| 512 | } |
| 513 | blob_reset(&disk); |
| 514 | blob_reset(&repo); |
| 515 | } |
| 516 | db_finalize(&q); |
| 517 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -264,11 +264,11 @@ | |
| 264 | if( cReply=='n' || cReply=='N' ){ |
| 265 | blob_reset(&content); |
| 266 | continue; |
| 267 | } |
| 268 | } |
| 269 | if( verbose ) fossil_print("%s\n", &zName[nRepos]); |
| 270 | blob_write_to_file(&content, zName); |
| 271 | file_setexe(zName, isExe); |
| 272 | blob_reset(&content); |
| 273 | db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", |
| 274 | file_mtime(zName), id); |
| @@ -286,11 +286,11 @@ | |
| 286 | " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); |
| 287 | while( db_step(&q)==SQLITE_ROW ){ |
| 288 | const char *zName; |
| 289 | |
| 290 | zName = db_column_text(&q, 0); |
| 291 | file_delete(zName); |
| 292 | } |
| 293 | db_finalize(&q); |
| 294 | db_multi_exec("UPDATE vfile SET mtime=NULL WHERE vid=%d AND mrid>0", vid); |
| 295 | } |
| 296 | |
| @@ -335,10 +335,11 @@ | |
| 335 | const char *zDir; |
| 336 | struct dirent *pEntry; |
| 337 | int skipAll = 0; |
| 338 | static Stmt ins; |
| 339 | static int depth = 0; |
| 340 | char *zMbcs; |
| 341 | |
| 342 | origSize = blob_size(pPath); |
| 343 | if( pIgnore ){ |
| 344 | blob_appendf(pPath, "/"); |
| 345 | if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1; |
| @@ -353,20 +354,24 @@ | |
| 354 | ); |
| 355 | } |
| 356 | depth++; |
| 357 | |
| 358 | zDir = blob_str(pPath); |
| 359 | zMbcs = fossil_utf8_to_mbcs(zDir); |
| 360 | d = opendir(zMbcs); |
| 361 | if( d ){ |
| 362 | while( (pEntry=readdir(d))!=0 ){ |
| 363 | char *zPath; |
| 364 | char *zUtf8; |
| 365 | if( pEntry->d_name[0]=='.' ){ |
| 366 | if( !allFlag ) continue; |
| 367 | if( pEntry->d_name[1]==0 ) continue; |
| 368 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 369 | } |
| 370 | zUtf8 = fossil_mbcs_to_utf8(pEntry->d_name); |
| 371 | blob_appendf(pPath, "/%s", zUtf8); |
| 372 | fossil_mbcs_free(zUtf8); |
| 373 | zPath = blob_str(pPath); |
| 374 | if( glob_match(pIgnore, &zPath[nPrefix+1]) ){ |
| 375 | /* do nothing */ |
| 376 | }else if( file_isdir(zPath)==1 ){ |
| 377 | if( !vfile_top_of_checkout(zPath) ){ |
| @@ -379,10 +384,11 @@ | |
| 384 | } |
| 385 | blob_resize(pPath, origSize); |
| 386 | } |
| 387 | closedir(d); |
| 388 | } |
| 389 | fossil_mbcs_free(zMbcs); |
| 390 | |
| 391 | depth--; |
| 392 | if( depth==0 ){ |
| 393 | db_finalize(&ins); |
| 394 | } |
| @@ -428,11 +434,11 @@ | |
| 434 | const char *zName = db_column_text(&q, 1); |
| 435 | int isSelected = db_column_int(&q, 3); |
| 436 | |
| 437 | if( isSelected ){ |
| 438 | md5sum_step_text(zName, -1); |
| 439 | in = fossil_fopen(zFullpath,"rb"); |
| 440 | if( in==0 ){ |
| 441 | md5sum_step_text(" 0\n", -1); |
| 442 | continue; |
| 443 | } |
| 444 | fseek(in, 0L, SEEK_END); |
| @@ -491,26 +497,27 @@ | |
| 497 | int rid = db_column_int(&q, 2); |
| 498 | |
| 499 | blob_zero(&disk); |
| 500 | rc = blob_read_from_file(&disk, zFullpath); |
| 501 | if( rc<0 ){ |
| 502 | fossil_print("ERROR: cannot read file [%s]\n", zFullpath); |
| 503 | blob_reset(&disk); |
| 504 | continue; |
| 505 | } |
| 506 | blob_zero(&repo); |
| 507 | content_get(rid, &repo); |
| 508 | if( blob_size(&repo)!=blob_size(&disk) ){ |
| 509 | fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n", |
| 510 | zName, blob_size(&disk), blob_size(&repo)); |
| 511 | blob_reset(&disk); |
| 512 | blob_reset(&repo); |
| 513 | continue; |
| 514 | } |
| 515 | if( blob_compare(&repo, &disk) ){ |
| 516 | fossil_print( |
| 517 | "ERROR: [%s] is different on disk compared to the repository\n", |
| 518 | zName); |
| 519 | } |
| 520 | blob_reset(&disk); |
| 521 | blob_reset(&repo); |
| 522 | } |
| 523 | db_finalize(&q); |
| 524 |
+7
-7
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -85,11 +85,11 @@ | ||
| 85 | 85 | login_check_credentials(); |
| 86 | 86 | if( zIndexPage ){ |
| 87 | 87 | const char *zPathInfo = P("PATH_INFO"); |
| 88 | 88 | while( zIndexPage[0]=='/' ) zIndexPage++; |
| 89 | 89 | while( zPathInfo[0]=='/' ) zPathInfo++; |
| 90 | - if( strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0; | |
| 90 | + if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0; | |
| 91 | 91 | } |
| 92 | 92 | if( zIndexPage ){ |
| 93 | 93 | cgi_redirectf("%s/%s", g.zTop, zIndexPage); |
| 94 | 94 | } |
| 95 | 95 | if( !g.okRdWiki ){ |
| @@ -415,11 +415,11 @@ | ||
| 415 | 415 | zId = db_text(0, "SELECT lower(hex(randomblob(8)))"); |
| 416 | 416 | blob_appendf(p, "\n\n<hr><div id=\"%s\"><i>On %s UTC %h", |
| 417 | 417 | zId, zDate, g.zLogin); |
| 418 | 418 | free(zDate); |
| 419 | 419 | zUser = PD("u",g.zLogin); |
| 420 | - if( zUser[0] && strcmp(zUser,g.zLogin) ){ | |
| 420 | + if( zUser[0] && fossil_strcmp(zUser,g.zLogin) ){ | |
| 421 | 421 | blob_appendf(p, " (claiming to be %h)", zUser); |
| 422 | 422 | } |
| 423 | 423 | zRemark = PD("r",""); |
| 424 | 424 | blob_appendf(p, " added:</i><br />\n%s</div id=\"%s\">", zRemark, zId); |
| 425 | 425 | } |
| @@ -916,20 +916,20 @@ | ||
| 916 | 916 | FILE * zF; |
| 917 | 917 | short doClose = 0; |
| 918 | 918 | if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ |
| 919 | 919 | zF = stdout; |
| 920 | 920 | }else{ |
| 921 | - zF = fopen( zFile, "w" ); | |
| 921 | + zF = fossil_fopen( zFile, "w" ); | |
| 922 | 922 | doClose = zF ? 1 : 0; |
| 923 | 923 | } |
| 924 | 924 | if( ! zF ){ |
| 925 | 925 | fossil_fatal("wiki export could not open output file for writing."); |
| 926 | 926 | } |
| 927 | 927 | fprintf(zF,"%.*s\n", i, zBody); |
| 928 | 928 | if( doClose ) fclose(zF); |
| 929 | 929 | }else{ |
| 930 | - printf("%.*s\n", i, zBody); | |
| 930 | + fossil_print("%.*s\n", i, zBody); | |
| 931 | 931 | } |
| 932 | 932 | manifest_destroy(pWiki); |
| 933 | 933 | return; |
| 934 | 934 | }else |
| 935 | 935 | if( strncmp(g.argv[2],"commit",n)==0 |
| @@ -945,14 +945,14 @@ | ||
| 945 | 945 | }else{ |
| 946 | 946 | blob_read_from_file(&content, g.argv[4]); |
| 947 | 947 | } |
| 948 | 948 | if( g.argv[2][1]=='r' ){ |
| 949 | 949 | wiki_cmd_commit(zPageName, 1, &content); |
| 950 | - printf("Created new wiki page %s.\n", zPageName); | |
| 950 | + fossil_print("Created new wiki page %s.\n", zPageName); | |
| 951 | 951 | }else{ |
| 952 | 952 | wiki_cmd_commit(zPageName, 0, &content); |
| 953 | - printf("Updated wiki page %s.\n", zPageName); | |
| 953 | + fossil_print("Updated wiki page %s.\n", zPageName); | |
| 954 | 954 | } |
| 955 | 955 | blob_reset(&content); |
| 956 | 956 | }else |
| 957 | 957 | if( strncmp(g.argv[2],"delete",n)==0 ){ |
| 958 | 958 | if( g.argc!=5 ){ |
| @@ -966,11 +966,11 @@ | ||
| 966 | 966 | "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'" |
| 967 | 967 | " ORDER BY lower(tagname) /*sort*/" |
| 968 | 968 | ); |
| 969 | 969 | while( db_step(&q)==SQLITE_ROW ){ |
| 970 | 970 | const char *zName = db_column_text(&q, 0); |
| 971 | - printf( "%s\n",zName); | |
| 971 | + fossil_print( "%s\n",zName); | |
| 972 | 972 | } |
| 973 | 973 | db_finalize(&q); |
| 974 | 974 | }else |
| 975 | 975 | { |
| 976 | 976 | goto wiki_cmd_usage; |
| 977 | 977 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -85,11 +85,11 @@ | |
| 85 | login_check_credentials(); |
| 86 | if( zIndexPage ){ |
| 87 | const char *zPathInfo = P("PATH_INFO"); |
| 88 | while( zIndexPage[0]=='/' ) zIndexPage++; |
| 89 | while( zPathInfo[0]=='/' ) zPathInfo++; |
| 90 | if( strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0; |
| 91 | } |
| 92 | if( zIndexPage ){ |
| 93 | cgi_redirectf("%s/%s", g.zTop, zIndexPage); |
| 94 | } |
| 95 | if( !g.okRdWiki ){ |
| @@ -415,11 +415,11 @@ | |
| 415 | zId = db_text(0, "SELECT lower(hex(randomblob(8)))"); |
| 416 | blob_appendf(p, "\n\n<hr><div id=\"%s\"><i>On %s UTC %h", |
| 417 | zId, zDate, g.zLogin); |
| 418 | free(zDate); |
| 419 | zUser = PD("u",g.zLogin); |
| 420 | if( zUser[0] && strcmp(zUser,g.zLogin) ){ |
| 421 | blob_appendf(p, " (claiming to be %h)", zUser); |
| 422 | } |
| 423 | zRemark = PD("r",""); |
| 424 | blob_appendf(p, " added:</i><br />\n%s</div id=\"%s\">", zRemark, zId); |
| 425 | } |
| @@ -916,20 +916,20 @@ | |
| 916 | FILE * zF; |
| 917 | short doClose = 0; |
| 918 | if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ |
| 919 | zF = stdout; |
| 920 | }else{ |
| 921 | zF = fopen( zFile, "w" ); |
| 922 | doClose = zF ? 1 : 0; |
| 923 | } |
| 924 | if( ! zF ){ |
| 925 | fossil_fatal("wiki export could not open output file for writing."); |
| 926 | } |
| 927 | fprintf(zF,"%.*s\n", i, zBody); |
| 928 | if( doClose ) fclose(zF); |
| 929 | }else{ |
| 930 | printf("%.*s\n", i, zBody); |
| 931 | } |
| 932 | manifest_destroy(pWiki); |
| 933 | return; |
| 934 | }else |
| 935 | if( strncmp(g.argv[2],"commit",n)==0 |
| @@ -945,14 +945,14 @@ | |
| 945 | }else{ |
| 946 | blob_read_from_file(&content, g.argv[4]); |
| 947 | } |
| 948 | if( g.argv[2][1]=='r' ){ |
| 949 | wiki_cmd_commit(zPageName, 1, &content); |
| 950 | printf("Created new wiki page %s.\n", zPageName); |
| 951 | }else{ |
| 952 | wiki_cmd_commit(zPageName, 0, &content); |
| 953 | printf("Updated wiki page %s.\n", zPageName); |
| 954 | } |
| 955 | blob_reset(&content); |
| 956 | }else |
| 957 | if( strncmp(g.argv[2],"delete",n)==0 ){ |
| 958 | if( g.argc!=5 ){ |
| @@ -966,11 +966,11 @@ | |
| 966 | "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'" |
| 967 | " ORDER BY lower(tagname) /*sort*/" |
| 968 | ); |
| 969 | while( db_step(&q)==SQLITE_ROW ){ |
| 970 | const char *zName = db_column_text(&q, 0); |
| 971 | printf( "%s\n",zName); |
| 972 | } |
| 973 | db_finalize(&q); |
| 974 | }else |
| 975 | { |
| 976 | goto wiki_cmd_usage; |
| 977 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -85,11 +85,11 @@ | |
| 85 | login_check_credentials(); |
| 86 | if( zIndexPage ){ |
| 87 | const char *zPathInfo = P("PATH_INFO"); |
| 88 | while( zIndexPage[0]=='/' ) zIndexPage++; |
| 89 | while( zPathInfo[0]=='/' ) zPathInfo++; |
| 90 | if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0; |
| 91 | } |
| 92 | if( zIndexPage ){ |
| 93 | cgi_redirectf("%s/%s", g.zTop, zIndexPage); |
| 94 | } |
| 95 | if( !g.okRdWiki ){ |
| @@ -415,11 +415,11 @@ | |
| 415 | zId = db_text(0, "SELECT lower(hex(randomblob(8)))"); |
| 416 | blob_appendf(p, "\n\n<hr><div id=\"%s\"><i>On %s UTC %h", |
| 417 | zId, zDate, g.zLogin); |
| 418 | free(zDate); |
| 419 | zUser = PD("u",g.zLogin); |
| 420 | if( zUser[0] && fossil_strcmp(zUser,g.zLogin) ){ |
| 421 | blob_appendf(p, " (claiming to be %h)", zUser); |
| 422 | } |
| 423 | zRemark = PD("r",""); |
| 424 | blob_appendf(p, " added:</i><br />\n%s</div id=\"%s\">", zRemark, zId); |
| 425 | } |
| @@ -916,20 +916,20 @@ | |
| 916 | FILE * zF; |
| 917 | short doClose = 0; |
| 918 | if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ |
| 919 | zF = stdout; |
| 920 | }else{ |
| 921 | zF = fossil_fopen( zFile, "w" ); |
| 922 | doClose = zF ? 1 : 0; |
| 923 | } |
| 924 | if( ! zF ){ |
| 925 | fossil_fatal("wiki export could not open output file for writing."); |
| 926 | } |
| 927 | fprintf(zF,"%.*s\n", i, zBody); |
| 928 | if( doClose ) fclose(zF); |
| 929 | }else{ |
| 930 | fossil_print("%.*s\n", i, zBody); |
| 931 | } |
| 932 | manifest_destroy(pWiki); |
| 933 | return; |
| 934 | }else |
| 935 | if( strncmp(g.argv[2],"commit",n)==0 |
| @@ -945,14 +945,14 @@ | |
| 945 | }else{ |
| 946 | blob_read_from_file(&content, g.argv[4]); |
| 947 | } |
| 948 | if( g.argv[2][1]=='r' ){ |
| 949 | wiki_cmd_commit(zPageName, 1, &content); |
| 950 | fossil_print("Created new wiki page %s.\n", zPageName); |
| 951 | }else{ |
| 952 | wiki_cmd_commit(zPageName, 0, &content); |
| 953 | fossil_print("Updated wiki page %s.\n", zPageName); |
| 954 | } |
| 955 | blob_reset(&content); |
| 956 | }else |
| 957 | if( strncmp(g.argv[2],"delete",n)==0 ){ |
| 958 | if( g.argc!=5 ){ |
| @@ -966,11 +966,11 @@ | |
| 966 | "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'" |
| 967 | " ORDER BY lower(tagname) /*sort*/" |
| 968 | ); |
| 969 | while( db_step(&q)==SQLITE_ROW ){ |
| 970 | const char *zName = db_column_text(&q, 0); |
| 971 | fossil_print( "%s\n",zName); |
| 972 | } |
| 973 | db_finalize(&q); |
| 974 | }else |
| 975 | { |
| 976 | goto wiki_cmd_usage; |
| 977 |
+6
-5
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -131,11 +131,11 @@ | ||
| 131 | 131 | int i, c, first, last; |
| 132 | 132 | first = 1; |
| 133 | 133 | last = sizeof(aAttribute)/sizeof(aAttribute[0]) - 1; |
| 134 | 134 | while( first<=last ){ |
| 135 | 135 | i = (first+last)/2; |
| 136 | - c = strcmp(aAttribute[i].zName, z); | |
| 136 | + c = fossil_strcmp(aAttribute[i].zName, z); | |
| 137 | 137 | if( c==0 ){ |
| 138 | 138 | return i; |
| 139 | 139 | }else if( c<0 ){ |
| 140 | 140 | first = i+1; |
| 141 | 141 | }else{ |
| @@ -330,11 +330,11 @@ | ||
| 330 | 330 | int i, c, first, last; |
| 331 | 331 | first = 1; |
| 332 | 332 | last = sizeof(aMarkup)/sizeof(aMarkup[0]) - 1; |
| 333 | 333 | while( first<=last ){ |
| 334 | 334 | i = (first+last)/2; |
| 335 | - c = strcmp(aMarkup[i].zName, z); | |
| 335 | + c = fossil_strcmp(aMarkup[i].zName, z); | |
| 336 | 336 | if( c==0 ){ |
| 337 | 337 | assert( aMarkup[i].iCode==i ); |
| 338 | 338 | return i; |
| 339 | 339 | }else if( c<0 ){ |
| 340 | 340 | first = i+1; |
| @@ -880,11 +880,11 @@ | ||
| 880 | 880 | int i; |
| 881 | 881 | assert( zId!=0 ); |
| 882 | 882 | for(i=p->nStack-1; i>=0; i--){ |
| 883 | 883 | if( p->aStack[i].iCode!=iTag ) continue; |
| 884 | 884 | if( p->aStack[i].zId==0 ) continue; |
| 885 | - if( strcmp(zId, p->aStack[i].zId)!=0 ) continue; | |
| 885 | + if( fossil_strcmp(zId, p->aStack[i].zId)!=0 ) continue; | |
| 886 | 886 | break; |
| 887 | 887 | } |
| 888 | 888 | return i; |
| 889 | 889 | } |
| 890 | 890 | |
| @@ -1118,11 +1118,11 @@ | ||
| 1118 | 1118 | if( pMarkup->iCode!=MARKUP_VERBATIM ) return 0; |
| 1119 | 1119 | if( !pMarkup->endTag ) return 0; |
| 1120 | 1120 | if( p->zVerbatimId==0 ) return 1; |
| 1121 | 1121 | if( pMarkup->nAttr!=1 ) return 0; |
| 1122 | 1122 | z = pMarkup->aAttr[0].zValue; |
| 1123 | - return strcmp(z, p->zVerbatimId)==0; | |
| 1123 | + return fossil_strcmp(z, p->zVerbatimId)==0; | |
| 1124 | 1124 | } |
| 1125 | 1125 | |
| 1126 | 1126 | /* |
| 1127 | 1127 | ** Return the MUTYPE for the top of the stack. |
| 1128 | 1128 | */ |
| @@ -1144,11 +1144,11 @@ | ||
| 1144 | 1144 | int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; |
| 1145 | 1145 | int wikiUseHtml = (p->state & WIKI_USE_HTML)!=0; |
| 1146 | 1146 | |
| 1147 | 1147 | /* Make sure the attribute constants and names still align |
| 1148 | 1148 | ** following changes in the attribute list. */ |
| 1149 | - assert( strcmp(aAttribute[ATTR_WIDTH].zName, "width")==0 ); | |
| 1149 | + assert( fossil_strcmp(aAttribute[ATTR_WIDTH].zName, "width")==0 ); | |
| 1150 | 1150 | |
| 1151 | 1151 | while( z[0] ){ |
| 1152 | 1152 | if( wikiUseHtml ){ |
| 1153 | 1153 | n = nextRawToken(z, p, &tokenType); |
| 1154 | 1154 | }else{ |
| @@ -1734,6 +1734,7 @@ | ||
| 1734 | 1734 | break; |
| 1735 | 1735 | } |
| 1736 | 1736 | } |
| 1737 | 1737 | z += n; |
| 1738 | 1738 | } |
| 1739 | + free(renderer.aStack); | |
| 1739 | 1740 | } |
| 1740 | 1741 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -131,11 +131,11 @@ | |
| 131 | int i, c, first, last; |
| 132 | first = 1; |
| 133 | last = sizeof(aAttribute)/sizeof(aAttribute[0]) - 1; |
| 134 | while( first<=last ){ |
| 135 | i = (first+last)/2; |
| 136 | c = strcmp(aAttribute[i].zName, z); |
| 137 | if( c==0 ){ |
| 138 | return i; |
| 139 | }else if( c<0 ){ |
| 140 | first = i+1; |
| 141 | }else{ |
| @@ -330,11 +330,11 @@ | |
| 330 | int i, c, first, last; |
| 331 | first = 1; |
| 332 | last = sizeof(aMarkup)/sizeof(aMarkup[0]) - 1; |
| 333 | while( first<=last ){ |
| 334 | i = (first+last)/2; |
| 335 | c = strcmp(aMarkup[i].zName, z); |
| 336 | if( c==0 ){ |
| 337 | assert( aMarkup[i].iCode==i ); |
| 338 | return i; |
| 339 | }else if( c<0 ){ |
| 340 | first = i+1; |
| @@ -880,11 +880,11 @@ | |
| 880 | int i; |
| 881 | assert( zId!=0 ); |
| 882 | for(i=p->nStack-1; i>=0; i--){ |
| 883 | if( p->aStack[i].iCode!=iTag ) continue; |
| 884 | if( p->aStack[i].zId==0 ) continue; |
| 885 | if( strcmp(zId, p->aStack[i].zId)!=0 ) continue; |
| 886 | break; |
| 887 | } |
| 888 | return i; |
| 889 | } |
| 890 | |
| @@ -1118,11 +1118,11 @@ | |
| 1118 | if( pMarkup->iCode!=MARKUP_VERBATIM ) return 0; |
| 1119 | if( !pMarkup->endTag ) return 0; |
| 1120 | if( p->zVerbatimId==0 ) return 1; |
| 1121 | if( pMarkup->nAttr!=1 ) return 0; |
| 1122 | z = pMarkup->aAttr[0].zValue; |
| 1123 | return strcmp(z, p->zVerbatimId)==0; |
| 1124 | } |
| 1125 | |
| 1126 | /* |
| 1127 | ** Return the MUTYPE for the top of the stack. |
| 1128 | */ |
| @@ -1144,11 +1144,11 @@ | |
| 1144 | int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; |
| 1145 | int wikiUseHtml = (p->state & WIKI_USE_HTML)!=0; |
| 1146 | |
| 1147 | /* Make sure the attribute constants and names still align |
| 1148 | ** following changes in the attribute list. */ |
| 1149 | assert( strcmp(aAttribute[ATTR_WIDTH].zName, "width")==0 ); |
| 1150 | |
| 1151 | while( z[0] ){ |
| 1152 | if( wikiUseHtml ){ |
| 1153 | n = nextRawToken(z, p, &tokenType); |
| 1154 | }else{ |
| @@ -1734,6 +1734,7 @@ | |
| 1734 | break; |
| 1735 | } |
| 1736 | } |
| 1737 | z += n; |
| 1738 | } |
| 1739 | } |
| 1740 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -131,11 +131,11 @@ | |
| 131 | int i, c, first, last; |
| 132 | first = 1; |
| 133 | last = sizeof(aAttribute)/sizeof(aAttribute[0]) - 1; |
| 134 | while( first<=last ){ |
| 135 | i = (first+last)/2; |
| 136 | c = fossil_strcmp(aAttribute[i].zName, z); |
| 137 | if( c==0 ){ |
| 138 | return i; |
| 139 | }else if( c<0 ){ |
| 140 | first = i+1; |
| 141 | }else{ |
| @@ -330,11 +330,11 @@ | |
| 330 | int i, c, first, last; |
| 331 | first = 1; |
| 332 | last = sizeof(aMarkup)/sizeof(aMarkup[0]) - 1; |
| 333 | while( first<=last ){ |
| 334 | i = (first+last)/2; |
| 335 | c = fossil_strcmp(aMarkup[i].zName, z); |
| 336 | if( c==0 ){ |
| 337 | assert( aMarkup[i].iCode==i ); |
| 338 | return i; |
| 339 | }else if( c<0 ){ |
| 340 | first = i+1; |
| @@ -880,11 +880,11 @@ | |
| 880 | int i; |
| 881 | assert( zId!=0 ); |
| 882 | for(i=p->nStack-1; i>=0; i--){ |
| 883 | if( p->aStack[i].iCode!=iTag ) continue; |
| 884 | if( p->aStack[i].zId==0 ) continue; |
| 885 | if( fossil_strcmp(zId, p->aStack[i].zId)!=0 ) continue; |
| 886 | break; |
| 887 | } |
| 888 | return i; |
| 889 | } |
| 890 | |
| @@ -1118,11 +1118,11 @@ | |
| 1118 | if( pMarkup->iCode!=MARKUP_VERBATIM ) return 0; |
| 1119 | if( !pMarkup->endTag ) return 0; |
| 1120 | if( p->zVerbatimId==0 ) return 1; |
| 1121 | if( pMarkup->nAttr!=1 ) return 0; |
| 1122 | z = pMarkup->aAttr[0].zValue; |
| 1123 | return fossil_strcmp(z, p->zVerbatimId)==0; |
| 1124 | } |
| 1125 | |
| 1126 | /* |
| 1127 | ** Return the MUTYPE for the top of the stack. |
| 1128 | */ |
| @@ -1144,11 +1144,11 @@ | |
| 1144 | int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; |
| 1145 | int wikiUseHtml = (p->state & WIKI_USE_HTML)!=0; |
| 1146 | |
| 1147 | /* Make sure the attribute constants and names still align |
| 1148 | ** following changes in the attribute list. */ |
| 1149 | assert( fossil_strcmp(aAttribute[ATTR_WIDTH].zName, "width")==0 ); |
| 1150 | |
| 1151 | while( z[0] ){ |
| 1152 | if( wikiUseHtml ){ |
| 1153 | n = nextRawToken(z, p, &tokenType); |
| 1154 | }else{ |
| @@ -1734,6 +1734,7 @@ | |
| 1734 | break; |
| 1735 | } |
| 1736 | } |
| 1737 | z += n; |
| 1738 | } |
| 1739 | free(renderer.aStack); |
| 1740 | } |
| 1741 |
+8
-8
| --- src/winhttp.c | ||
| +++ src/winhttp.c | ||
| @@ -92,11 +92,11 @@ | ||
| 92 | 92 | wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt; |
| 93 | 93 | break; |
| 94 | 94 | } |
| 95 | 95 | } |
| 96 | 96 | if( amt>=sizeof(zHdr) ) goto end_request; |
| 97 | - out = fopen(zRequestFName, "wb"); | |
| 97 | + out = fossil_fopen(zRequestFName, "wb"); | |
| 98 | 98 | if( out==0 ) goto end_request; |
| 99 | 99 | fwrite(zHdr, 1, amt, out); |
| 100 | 100 | while( wanted>0 ){ |
| 101 | 101 | got = recv(p->s, zHdr, sizeof(zHdr), 0); |
| 102 | 102 | if( got==SOCKET_ERROR ) goto end_request; |
| @@ -112,11 +112,11 @@ | ||
| 112 | 112 | sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http \"%s\" %s %s %s --nossl%s", |
| 113 | 113 | fossil_nameofexe(), g.zRepositoryName, zRequestFName, zReplyFName, |
| 114 | 114 | inet_ntoa(p->addr.sin_addr), p->zOptions |
| 115 | 115 | ); |
| 116 | 116 | fossil_system(zCmd); |
| 117 | - in = fopen(zReplyFName, "rb"); | |
| 117 | + in = fossil_fopen(zReplyFName, "rb"); | |
| 118 | 118 | if( in ){ |
| 119 | 119 | while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){ |
| 120 | 120 | send(p->s, zHdr, got, 0); |
| 121 | 121 | } |
| 122 | 122 | } |
| @@ -123,12 +123,12 @@ | ||
| 123 | 123 | |
| 124 | 124 | end_request: |
| 125 | 125 | if( out ) fclose(out); |
| 126 | 126 | if( in ) fclose(in); |
| 127 | 127 | closesocket(p->s); |
| 128 | - unlink(zRequestFName); | |
| 129 | - unlink(zReplyFName); | |
| 128 | + file_delete(zRequestFName); | |
| 129 | + file_delete(zReplyFName); | |
| 130 | 130 | free(p); |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | 133 | /* |
| 134 | 134 | ** Start a listening socket and process incoming HTTP requests on |
| @@ -146,11 +146,11 @@ | ||
| 146 | 146 | SOCKADDR_IN addr; |
| 147 | 147 | int idCnt = 0; |
| 148 | 148 | int iPort = mnPort; |
| 149 | 149 | Blob options; |
| 150 | 150 | |
| 151 | - if( zStopper ) unlink(zStopper); | |
| 151 | + if( zStopper ) file_delete(zStopper); | |
| 152 | 152 | blob_zero(&options); |
| 153 | 153 | if( zNotFound ){ |
| 154 | 154 | blob_appendf(&options, " --notfound %s", zNotFound); |
| 155 | 155 | } |
| 156 | 156 | if( g.useLocalauth ){ |
| @@ -190,17 +190,17 @@ | ||
| 190 | 190 | fossil_fatal("unable to open listening socket on any" |
| 191 | 191 | " port in the range %d..%d", mnPort, mxPort); |
| 192 | 192 | } |
| 193 | 193 | } |
| 194 | 194 | zTempPrefix = mprintf("fossil_server_P%d_", iPort); |
| 195 | - printf("Listening for HTTP requests on TCP port %d\n", iPort); | |
| 195 | + fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); | |
| 196 | 196 | if( zBrowser ){ |
| 197 | 197 | zBrowser = mprintf(zBrowser, iPort); |
| 198 | - printf("Launch webbrowser: %s\n", zBrowser); | |
| 198 | + fossil_print("Launch webbrowser: %s\n", zBrowser); | |
| 199 | 199 | fossil_system(zBrowser); |
| 200 | 200 | } |
| 201 | - printf("Type Ctrl-C to stop the HTTP server\n"); | |
| 201 | + fossil_print("Type Ctrl-C to stop the HTTP server\n"); | |
| 202 | 202 | for(;;){ |
| 203 | 203 | SOCKET client; |
| 204 | 204 | SOCKADDR_IN client_addr; |
| 205 | 205 | HttpRequest *p; |
| 206 | 206 | int len = sizeof(client_addr); |
| 207 | 207 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -92,11 +92,11 @@ | |
| 92 | wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt; |
| 93 | break; |
| 94 | } |
| 95 | } |
| 96 | if( amt>=sizeof(zHdr) ) goto end_request; |
| 97 | out = fopen(zRequestFName, "wb"); |
| 98 | if( out==0 ) goto end_request; |
| 99 | fwrite(zHdr, 1, amt, out); |
| 100 | while( wanted>0 ){ |
| 101 | got = recv(p->s, zHdr, sizeof(zHdr), 0); |
| 102 | if( got==SOCKET_ERROR ) goto end_request; |
| @@ -112,11 +112,11 @@ | |
| 112 | sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http \"%s\" %s %s %s --nossl%s", |
| 113 | fossil_nameofexe(), g.zRepositoryName, zRequestFName, zReplyFName, |
| 114 | inet_ntoa(p->addr.sin_addr), p->zOptions |
| 115 | ); |
| 116 | fossil_system(zCmd); |
| 117 | in = fopen(zReplyFName, "rb"); |
| 118 | if( in ){ |
| 119 | while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){ |
| 120 | send(p->s, zHdr, got, 0); |
| 121 | } |
| 122 | } |
| @@ -123,12 +123,12 @@ | |
| 123 | |
| 124 | end_request: |
| 125 | if( out ) fclose(out); |
| 126 | if( in ) fclose(in); |
| 127 | closesocket(p->s); |
| 128 | unlink(zRequestFName); |
| 129 | unlink(zReplyFName); |
| 130 | free(p); |
| 131 | } |
| 132 | |
| 133 | /* |
| 134 | ** Start a listening socket and process incoming HTTP requests on |
| @@ -146,11 +146,11 @@ | |
| 146 | SOCKADDR_IN addr; |
| 147 | int idCnt = 0; |
| 148 | int iPort = mnPort; |
| 149 | Blob options; |
| 150 | |
| 151 | if( zStopper ) unlink(zStopper); |
| 152 | blob_zero(&options); |
| 153 | if( zNotFound ){ |
| 154 | blob_appendf(&options, " --notfound %s", zNotFound); |
| 155 | } |
| 156 | if( g.useLocalauth ){ |
| @@ -190,17 +190,17 @@ | |
| 190 | fossil_fatal("unable to open listening socket on any" |
| 191 | " port in the range %d..%d", mnPort, mxPort); |
| 192 | } |
| 193 | } |
| 194 | zTempPrefix = mprintf("fossil_server_P%d_", iPort); |
| 195 | printf("Listening for HTTP requests on TCP port %d\n", iPort); |
| 196 | if( zBrowser ){ |
| 197 | zBrowser = mprintf(zBrowser, iPort); |
| 198 | printf("Launch webbrowser: %s\n", zBrowser); |
| 199 | fossil_system(zBrowser); |
| 200 | } |
| 201 | printf("Type Ctrl-C to stop the HTTP server\n"); |
| 202 | for(;;){ |
| 203 | SOCKET client; |
| 204 | SOCKADDR_IN client_addr; |
| 205 | HttpRequest *p; |
| 206 | int len = sizeof(client_addr); |
| 207 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -92,11 +92,11 @@ | |
| 92 | wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt; |
| 93 | break; |
| 94 | } |
| 95 | } |
| 96 | if( amt>=sizeof(zHdr) ) goto end_request; |
| 97 | out = fossil_fopen(zRequestFName, "wb"); |
| 98 | if( out==0 ) goto end_request; |
| 99 | fwrite(zHdr, 1, amt, out); |
| 100 | while( wanted>0 ){ |
| 101 | got = recv(p->s, zHdr, sizeof(zHdr), 0); |
| 102 | if( got==SOCKET_ERROR ) goto end_request; |
| @@ -112,11 +112,11 @@ | |
| 112 | sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http \"%s\" %s %s %s --nossl%s", |
| 113 | fossil_nameofexe(), g.zRepositoryName, zRequestFName, zReplyFName, |
| 114 | inet_ntoa(p->addr.sin_addr), p->zOptions |
| 115 | ); |
| 116 | fossil_system(zCmd); |
| 117 | in = fossil_fopen(zReplyFName, "rb"); |
| 118 | if( in ){ |
| 119 | while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){ |
| 120 | send(p->s, zHdr, got, 0); |
| 121 | } |
| 122 | } |
| @@ -123,12 +123,12 @@ | |
| 123 | |
| 124 | end_request: |
| 125 | if( out ) fclose(out); |
| 126 | if( in ) fclose(in); |
| 127 | closesocket(p->s); |
| 128 | file_delete(zRequestFName); |
| 129 | file_delete(zReplyFName); |
| 130 | free(p); |
| 131 | } |
| 132 | |
| 133 | /* |
| 134 | ** Start a listening socket and process incoming HTTP requests on |
| @@ -146,11 +146,11 @@ | |
| 146 | SOCKADDR_IN addr; |
| 147 | int idCnt = 0; |
| 148 | int iPort = mnPort; |
| 149 | Blob options; |
| 150 | |
| 151 | if( zStopper ) file_delete(zStopper); |
| 152 | blob_zero(&options); |
| 153 | if( zNotFound ){ |
| 154 | blob_appendf(&options, " --notfound %s", zNotFound); |
| 155 | } |
| 156 | if( g.useLocalauth ){ |
| @@ -190,17 +190,17 @@ | |
| 190 | fossil_fatal("unable to open listening socket on any" |
| 191 | " port in the range %d..%d", mnPort, mxPort); |
| 192 | } |
| 193 | } |
| 194 | zTempPrefix = mprintf("fossil_server_P%d_", iPort); |
| 195 | fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); |
| 196 | if( zBrowser ){ |
| 197 | zBrowser = mprintf(zBrowser, iPort); |
| 198 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 199 | fossil_system(zBrowser); |
| 200 | } |
| 201 | fossil_print("Type Ctrl-C to stop the HTTP server\n"); |
| 202 | for(;;){ |
| 203 | SOCKET client; |
| 204 | SOCKADDR_IN client_addr; |
| 205 | HttpRequest *p; |
| 206 | int len = sizeof(client_addr); |
| 207 |
+6
-6
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -549,11 +549,11 @@ | ||
| 549 | 549 | Stmt q; |
| 550 | 550 | int rc = -1; |
| 551 | 551 | char *zLogin = blob_terminate(pLogin); |
| 552 | 552 | defossilize(zLogin); |
| 553 | 553 | |
| 554 | - if( strcmp(zLogin, "nobody")==0 || strcmp(zLogin,"anonymous")==0 ){ | |
| 554 | + if( fossil_strcmp(zLogin, "nobody")==0 || fossil_strcmp(zLogin,"anonymous")==0 ){ | |
| 555 | 555 | return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ |
| 556 | 556 | } |
| 557 | 557 | if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){ |
| 558 | 558 | return 0; /* Accept Basic Authorization */ |
| 559 | 559 | } |
| @@ -807,11 +807,11 @@ | ||
| 807 | 807 | int nGimme = 0; |
| 808 | 808 | int size; |
| 809 | 809 | int recvConfig = 0; |
| 810 | 810 | char *zNow; |
| 811 | 811 | |
| 812 | - if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ | |
| 812 | + if( fossil_strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ | |
| 813 | 813 | fossil_redirect_home(); |
| 814 | 814 | } |
| 815 | 815 | g.zLogin = "anonymous"; |
| 816 | 816 | login_set_anon_nobody_capabilities(); |
| 817 | 817 | login_check_credentials(); |
| @@ -1206,11 +1206,11 @@ | ||
| 1206 | 1206 | } |
| 1207 | 1207 | blob_zero(&g.cgiIn); |
| 1208 | 1208 | blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); |
| 1209 | 1209 | disableLogin = 1; |
| 1210 | 1210 | page_xfer(); |
| 1211 | - printf("%s\n", cgi_extract_content(¬Used)); | |
| 1211 | + fossil_print("%s\n", cgi_extract_content(¬Used)); | |
| 1212 | 1212 | } |
| 1213 | 1213 | |
| 1214 | 1214 | /* |
| 1215 | 1215 | ** Format strings for progress reporting. |
| 1216 | 1216 | */ |
| @@ -1390,11 +1390,11 @@ | ||
| 1390 | 1390 | xfer.nFileSent = 0; |
| 1391 | 1391 | xfer.nDeltaSent = 0; |
| 1392 | 1392 | xfer.nGimmeSent = 0; |
| 1393 | 1393 | xfer.nIGotSent = 0; |
| 1394 | 1394 | if( !g.cgiOutput && !g.fQuiet ){ |
| 1395 | - printf("waiting for server..."); | |
| 1395 | + fossil_print("waiting for server..."); | |
| 1396 | 1396 | } |
| 1397 | 1397 | fflush(stdout); |
| 1398 | 1398 | if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ |
| 1399 | 1399 | nErr++; |
| 1400 | 1400 | break; |
| @@ -1446,11 +1446,11 @@ | ||
| 1446 | 1446 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1447 | 1447 | nCardRcvd++; |
| 1448 | 1448 | if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ |
| 1449 | 1449 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1450 | 1450 | if( pctDone!=lastPctDone ){ |
| 1451 | - printf("\rprocessed: %d%% ", pctDone); | |
| 1451 | + fossil_print("\rprocessed: %d%% ", pctDone); | |
| 1452 | 1452 | lastPctDone = pctDone; |
| 1453 | 1453 | fflush(stdout); |
| 1454 | 1454 | } |
| 1455 | 1455 | } |
| 1456 | 1456 | |
| @@ -1632,11 +1632,11 @@ | ||
| 1632 | 1632 | */ |
| 1633 | 1633 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1634 | 1634 | if( !cloneFlag || nCycle>0 ){ |
| 1635 | 1635 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1636 | 1636 | defossilize(zMsg); |
| 1637 | - if( strcmp(zMsg, "login failed")==0 ){ | |
| 1637 | + if( fossil_strcmp(zMsg, "login failed")==0 ){ | |
| 1638 | 1638 | if( nCycle<2 ){ |
| 1639 | 1639 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| 1640 | 1640 | go = 1; |
| 1641 | 1641 | } |
| 1642 | 1642 | }else{ |
| 1643 | 1643 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -549,11 +549,11 @@ | |
| 549 | Stmt q; |
| 550 | int rc = -1; |
| 551 | char *zLogin = blob_terminate(pLogin); |
| 552 | defossilize(zLogin); |
| 553 | |
| 554 | if( strcmp(zLogin, "nobody")==0 || strcmp(zLogin,"anonymous")==0 ){ |
| 555 | return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ |
| 556 | } |
| 557 | if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){ |
| 558 | return 0; /* Accept Basic Authorization */ |
| 559 | } |
| @@ -807,11 +807,11 @@ | |
| 807 | int nGimme = 0; |
| 808 | int size; |
| 809 | int recvConfig = 0; |
| 810 | char *zNow; |
| 811 | |
| 812 | if( strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ |
| 813 | fossil_redirect_home(); |
| 814 | } |
| 815 | g.zLogin = "anonymous"; |
| 816 | login_set_anon_nobody_capabilities(); |
| 817 | login_check_credentials(); |
| @@ -1206,11 +1206,11 @@ | |
| 1206 | } |
| 1207 | blob_zero(&g.cgiIn); |
| 1208 | blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); |
| 1209 | disableLogin = 1; |
| 1210 | page_xfer(); |
| 1211 | printf("%s\n", cgi_extract_content(¬Used)); |
| 1212 | } |
| 1213 | |
| 1214 | /* |
| 1215 | ** Format strings for progress reporting. |
| 1216 | */ |
| @@ -1390,11 +1390,11 @@ | |
| 1390 | xfer.nFileSent = 0; |
| 1391 | xfer.nDeltaSent = 0; |
| 1392 | xfer.nGimmeSent = 0; |
| 1393 | xfer.nIGotSent = 0; |
| 1394 | if( !g.cgiOutput && !g.fQuiet ){ |
| 1395 | printf("waiting for server..."); |
| 1396 | } |
| 1397 | fflush(stdout); |
| 1398 | if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ |
| 1399 | nErr++; |
| 1400 | break; |
| @@ -1446,11 +1446,11 @@ | |
| 1446 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1447 | nCardRcvd++; |
| 1448 | if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ |
| 1449 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1450 | if( pctDone!=lastPctDone ){ |
| 1451 | printf("\rprocessed: %d%% ", pctDone); |
| 1452 | lastPctDone = pctDone; |
| 1453 | fflush(stdout); |
| 1454 | } |
| 1455 | } |
| 1456 | |
| @@ -1632,11 +1632,11 @@ | |
| 1632 | */ |
| 1633 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1634 | if( !cloneFlag || nCycle>0 ){ |
| 1635 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1636 | defossilize(zMsg); |
| 1637 | if( strcmp(zMsg, "login failed")==0 ){ |
| 1638 | if( nCycle<2 ){ |
| 1639 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| 1640 | go = 1; |
| 1641 | } |
| 1642 | }else{ |
| 1643 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -549,11 +549,11 @@ | |
| 549 | Stmt q; |
| 550 | int rc = -1; |
| 551 | char *zLogin = blob_terminate(pLogin); |
| 552 | defossilize(zLogin); |
| 553 | |
| 554 | if( fossil_strcmp(zLogin, "nobody")==0 || fossil_strcmp(zLogin,"anonymous")==0 ){ |
| 555 | return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ |
| 556 | } |
| 557 | if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){ |
| 558 | return 0; /* Accept Basic Authorization */ |
| 559 | } |
| @@ -807,11 +807,11 @@ | |
| 807 | int nGimme = 0; |
| 808 | int size; |
| 809 | int recvConfig = 0; |
| 810 | char *zNow; |
| 811 | |
| 812 | if( fossil_strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ |
| 813 | fossil_redirect_home(); |
| 814 | } |
| 815 | g.zLogin = "anonymous"; |
| 816 | login_set_anon_nobody_capabilities(); |
| 817 | login_check_credentials(); |
| @@ -1206,11 +1206,11 @@ | |
| 1206 | } |
| 1207 | blob_zero(&g.cgiIn); |
| 1208 | blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); |
| 1209 | disableLogin = 1; |
| 1210 | page_xfer(); |
| 1211 | fossil_print("%s\n", cgi_extract_content(¬Used)); |
| 1212 | } |
| 1213 | |
| 1214 | /* |
| 1215 | ** Format strings for progress reporting. |
| 1216 | */ |
| @@ -1390,11 +1390,11 @@ | |
| 1390 | xfer.nFileSent = 0; |
| 1391 | xfer.nDeltaSent = 0; |
| 1392 | xfer.nGimmeSent = 0; |
| 1393 | xfer.nIGotSent = 0; |
| 1394 | if( !g.cgiOutput && !g.fQuiet ){ |
| 1395 | fossil_print("waiting for server..."); |
| 1396 | } |
| 1397 | fflush(stdout); |
| 1398 | if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ |
| 1399 | nErr++; |
| 1400 | break; |
| @@ -1446,11 +1446,11 @@ | |
| 1446 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1447 | nCardRcvd++; |
| 1448 | if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ |
| 1449 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1450 | if( pctDone!=lastPctDone ){ |
| 1451 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1452 | lastPctDone = pctDone; |
| 1453 | fflush(stdout); |
| 1454 | } |
| 1455 | } |
| 1456 | |
| @@ -1632,11 +1632,11 @@ | |
| 1632 | */ |
| 1633 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1634 | if( !cloneFlag || nCycle>0 ){ |
| 1635 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1636 | defossilize(zMsg); |
| 1637 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1638 | if( nCycle<2 ){ |
| 1639 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| 1640 | go = 1; |
| 1641 | } |
| 1642 | }else{ |
| 1643 |
+3
-3
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -98,11 +98,11 @@ | ||
| 98 | 98 | for(i=0; zName[i]; i++){ |
| 99 | 99 | if( zName[i]=='/' ){ |
| 100 | 100 | c = zName[i+1]; |
| 101 | 101 | zName[i+1] = 0; |
| 102 | 102 | for(j=0; j<nDir; j++){ |
| 103 | - if( strcmp(zName, azDir[j])==0 ) break; | |
| 103 | + if( fossil_strcmp(zName, azDir[j])==0 ) break; | |
| 104 | 104 | } |
| 105 | 105 | if( j>=nDir ){ |
| 106 | 106 | nDir++; |
| 107 | 107 | azDir = fossil_realloc(azDir, sizeof(azDir[0])*nDir); |
| 108 | 108 | azDir[j] = mprintf("%s", zName); |
| @@ -392,11 +392,11 @@ | ||
| 392 | 392 | zName = find_option("name", 0, 1); |
| 393 | 393 | db_find_and_open_repository(0, 0); |
| 394 | 394 | if( g.argc!=4 ){ |
| 395 | 395 | usage("VERSION OUTPUTFILE"); |
| 396 | 396 | } |
| 397 | - rid = name_to_rid(g.argv[2]); | |
| 397 | + rid = name_to_typed_rid(g.argv[2],"ci"); | |
| 398 | 398 | if( zName==0 ){ |
| 399 | 399 | zName = db_text("default-name", |
| 400 | 400 | "SELECT replace(%Q,' ','_') " |
| 401 | 401 | " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " |
| 402 | 402 | " || substr(blob.uuid, 1, 10)" |
| @@ -433,11 +433,11 @@ | ||
| 433 | 433 | if( zName[nName]=='.' ){ |
| 434 | 434 | zName[nName] = 0; |
| 435 | 435 | break; |
| 436 | 436 | } |
| 437 | 437 | } |
| 438 | - rid = name_to_rid(nRid?zRid:zName); | |
| 438 | + rid = name_to_typed_rid(nRid?zRid:zName,"ci"); | |
| 439 | 439 | if( rid==0 ){ |
| 440 | 440 | @ Not found |
| 441 | 441 | return; |
| 442 | 442 | } |
| 443 | 443 | if( nRid==0 && nName>10 ) zName[10] = 0; |
| 444 | 444 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -98,11 +98,11 @@ | |
| 98 | for(i=0; zName[i]; i++){ |
| 99 | if( zName[i]=='/' ){ |
| 100 | c = zName[i+1]; |
| 101 | zName[i+1] = 0; |
| 102 | for(j=0; j<nDir; j++){ |
| 103 | if( strcmp(zName, azDir[j])==0 ) break; |
| 104 | } |
| 105 | if( j>=nDir ){ |
| 106 | nDir++; |
| 107 | azDir = fossil_realloc(azDir, sizeof(azDir[0])*nDir); |
| 108 | azDir[j] = mprintf("%s", zName); |
| @@ -392,11 +392,11 @@ | |
| 392 | zName = find_option("name", 0, 1); |
| 393 | db_find_and_open_repository(0, 0); |
| 394 | if( g.argc!=4 ){ |
| 395 | usage("VERSION OUTPUTFILE"); |
| 396 | } |
| 397 | rid = name_to_rid(g.argv[2]); |
| 398 | if( zName==0 ){ |
| 399 | zName = db_text("default-name", |
| 400 | "SELECT replace(%Q,' ','_') " |
| 401 | " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " |
| 402 | " || substr(blob.uuid, 1, 10)" |
| @@ -433,11 +433,11 @@ | |
| 433 | if( zName[nName]=='.' ){ |
| 434 | zName[nName] = 0; |
| 435 | break; |
| 436 | } |
| 437 | } |
| 438 | rid = name_to_rid(nRid?zRid:zName); |
| 439 | if( rid==0 ){ |
| 440 | @ Not found |
| 441 | return; |
| 442 | } |
| 443 | if( nRid==0 && nName>10 ) zName[10] = 0; |
| 444 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -98,11 +98,11 @@ | |
| 98 | for(i=0; zName[i]; i++){ |
| 99 | if( zName[i]=='/' ){ |
| 100 | c = zName[i+1]; |
| 101 | zName[i+1] = 0; |
| 102 | for(j=0; j<nDir; j++){ |
| 103 | if( fossil_strcmp(zName, azDir[j])==0 ) break; |
| 104 | } |
| 105 | if( j>=nDir ){ |
| 106 | nDir++; |
| 107 | azDir = fossil_realloc(azDir, sizeof(azDir[0])*nDir); |
| 108 | azDir[j] = mprintf("%s", zName); |
| @@ -392,11 +392,11 @@ | |
| 392 | zName = find_option("name", 0, 1); |
| 393 | db_find_and_open_repository(0, 0); |
| 394 | if( g.argc!=4 ){ |
| 395 | usage("VERSION OUTPUTFILE"); |
| 396 | } |
| 397 | rid = name_to_typed_rid(g.argv[2],"ci"); |
| 398 | if( zName==0 ){ |
| 399 | zName = db_text("default-name", |
| 400 | "SELECT replace(%Q,' ','_') " |
| 401 | " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " |
| 402 | " || substr(blob.uuid, 1, 10)" |
| @@ -433,11 +433,11 @@ | |
| 433 | if( zName[nName]=='.' ){ |
| 434 | zName[nName] = 0; |
| 435 | break; |
| 436 | } |
| 437 | } |
| 438 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 439 | if( rid==0 ){ |
| 440 | @ Not found |
| 441 | return; |
| 442 | } |
| 443 | if( nRid==0 && nName>10 ) zName[10] = 0; |
| 444 |
| --- www/build-icons/mac.gif | ||
| +++ www/build-icons/mac.gif | ||
| cannot compute difference between binary files | ||
| 1 | 1 |
| --- www/build-icons/mac.gif | |
| +++ www/build-icons/mac.gif | |
| 0 | annot compute difference between binary files |
| 1 |
| --- www/build-icons/mac.gif | |
| +++ www/build-icons/mac.gif | |
| 0 | annot compute difference between binary files |
| 1 |
| --- www/fossil_logo_small.gif | ||
| +++ www/fossil_logo_small.gif | ||
| cannot compute difference between binary files | ||
| 1 | 1 |
| --- www/fossil_logo_small.gif | |
| +++ www/fossil_logo_small.gif | |
| 0 | annot compute difference between binary files |
| 1 |
| --- www/fossil_logo_small.gif | |
| +++ www/fossil_logo_small.gif | |
| 0 | annot compute difference between binary files |
| 1 |