Fossil SCM
merge trunk. Add support for extended UNC paths as well.
Commit
9d4a73cb408e66e39d5c3ae6f973ec225b447ea6
Parent
d88d1bc0f69b4bb…
65 files changed
+4
-5
-3
+5
+2
-2
+16
-7
+4
-4
+8
-11
+1
-1
+28
-17
+6
-6
+1
+1
-1
+1
-5
+1
-1
+100
-44
+37
-6
+7
-1
+6
-10
+31
-31
+7
-6
+8
-6
+4
-4
+34
-36
+14
-14
+1
-1
+5
-12
+1
-8
+9
-29
+54
-59
+176
-70
+1
-2
+3
-13
+1
+2
-1
+19
-12
+19
-12
+2
-2
+10
-10
+9
+90
-10
+4
+80
-20
+12
-19
+2
+61
-61
+1
-1
+10
+1
-1
+118
-96
+6
-6
+3
-3
+9
+20
+20
+7
+7
+7
+7
+113
+113
+4
-9
+3
-9
+4
-10
+3
+23
~
Makefile.Cygwin.in
~
Makefile.in
~
auto.def
~
src/add.c
~
src/allrepo.c
~
src/attach.c
~
src/browse.c
~
src/cgi.c
~
src/checkin.c
~
src/clone.c
~
src/comformat.c
~
src/configure.c
~
src/db.c
~
src/delta.c
~
src/diff.c
~
src/diffcmd.c
~
src/file.c
~
src/finfo.c
~
src/http.c
~
src/http_socket.c
~
src/http_ssl.c
~
src/http_transport.c
~
src/info.c
~
src/json.c
~
src/json_wiki.c
~
src/main.c
~
src/main.mk
~
src/makemake.tcl
~
src/manifest.c
~
src/name.c
~
src/popen.c
~
src/report.c
~
src/setup.c
~
src/shell.c
~
src/sqlite3.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/sync.c
~
src/tar.c
~
src/th.c
~
src/th.h
~
src/timeline.c
~
src/tkt.c
~
src/update.c
~
src/url.c
~
src/user.c
~
src/util.c
~
src/wiki.c
~
src/wikiformat.c
~
src/xfer.c
~
src/xfersetup.c
~
src/zip.c
~
test/file1.test
~
test/file1.test
~
test/merge_renames.test
~
test/merge_renames.test
~
test/revert.test
~
test/revert.test
~
test/th1.test
~
test/th1.test
~
win/Makefile.mingw
~
win/Makefile.mingw.mistachkin
~
win/Makefile.msc
~
www/changes.wiki
~
www/quickstart.wiki
+4
-5
| --- Makefile.Cygwin.in | ||
| +++ Makefile.Cygwin.in | ||
| @@ -36,17 +36,16 @@ | ||
| 36 | 36 | # care about testing the end result, this can be blank. |
| 37 | 37 | # |
| 38 | 38 | TCLSH = tclsh |
| 39 | 39 | |
| 40 | 40 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 41 | -TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H -DFOSSIL_OMIT_LOAD_AVERAGE | |
| 41 | +TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H | |
| 42 | 42 | INSTALLDIR =$(DESTDIR)@prefix@/bin |
| 43 | 43 | USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
| 44 | -FOSSIL_ENABLE_TCL = @FOSSIL_ENABLE_TCL@ | |
| 45 | -FOSSIL_ENABLE_TCL_STUBS = @FOSSIL_ENABLE_TCL_STUBS@ | |
| 46 | -FOSSIL_ENABLE_TCL_PRIVATE_STUBS = @FOSSIL_ENABLE_TCL_PRIVATE_STUBS@ | |
| 47 | -SQLITE_CFLAGS += -DSQLITE_WIN32_NO_ANSI -DSQLITE_WINNT_MAX_PATH_CHARS=4096 | |
| 44 | +SQLITE_CFLAGS += -DSQLITE_WIN32_NO_ANSI | |
| 45 | +SQLITE_CFLAGS += -DSQLITE_WIN32_MAX_PATH_BYTES=4096 | |
| 46 | +SQLITE_CFLAGS += -DSQLITE_MAX_MMAP_SIZE=0x7fff0000 | |
| 48 | 47 | |
| 49 | 48 | include $(SRCDIR)/main.mk |
| 50 | 49 | |
| 51 | 50 | distclean: clean |
| 52 | 51 | rm -f autoconfig.h config.log Makefile |
| 53 | 52 |
| --- Makefile.Cygwin.in | |
| +++ Makefile.Cygwin.in | |
| @@ -36,17 +36,16 @@ | |
| 36 | # care about testing the end result, this can be blank. |
| 37 | # |
| 38 | TCLSH = tclsh |
| 39 | |
| 40 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 41 | TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H -DFOSSIL_OMIT_LOAD_AVERAGE |
| 42 | INSTALLDIR =$(DESTDIR)@prefix@/bin |
| 43 | USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
| 44 | FOSSIL_ENABLE_TCL = @FOSSIL_ENABLE_TCL@ |
| 45 | FOSSIL_ENABLE_TCL_STUBS = @FOSSIL_ENABLE_TCL_STUBS@ |
| 46 | FOSSIL_ENABLE_TCL_PRIVATE_STUBS = @FOSSIL_ENABLE_TCL_PRIVATE_STUBS@ |
| 47 | SQLITE_CFLAGS += -DSQLITE_WIN32_NO_ANSI -DSQLITE_WINNT_MAX_PATH_CHARS=4096 |
| 48 | |
| 49 | include $(SRCDIR)/main.mk |
| 50 | |
| 51 | distclean: clean |
| 52 | rm -f autoconfig.h config.log Makefile |
| 53 |
| --- Makefile.Cygwin.in | |
| +++ Makefile.Cygwin.in | |
| @@ -36,17 +36,16 @@ | |
| 36 | # care about testing the end result, this can be blank. |
| 37 | # |
| 38 | TCLSH = tclsh |
| 39 | |
| 40 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 41 | TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H |
| 42 | INSTALLDIR =$(DESTDIR)@prefix@/bin |
| 43 | USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
| 44 | SQLITE_CFLAGS += -DSQLITE_WIN32_NO_ANSI |
| 45 | SQLITE_CFLAGS += -DSQLITE_WIN32_MAX_PATH_BYTES=4096 |
| 46 | SQLITE_CFLAGS += -DSQLITE_MAX_MMAP_SIZE=0x7fff0000 |
| 47 | |
| 48 | include $(SRCDIR)/main.mk |
| 49 | |
| 50 | distclean: clean |
| 51 | rm -f autoconfig.h config.log Makefile |
| 52 |
-3
| --- Makefile.in | ||
| +++ Makefile.in | ||
| @@ -40,13 +40,10 @@ | ||
| 40 | 40 | |
| 41 | 41 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 42 | 42 | TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H |
| 43 | 43 | INSTALLDIR = $(DESTDIR)@prefix@/bin |
| 44 | 44 | USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
| 45 | -FOSSIL_ENABLE_TCL = @FOSSIL_ENABLE_TCL@ | |
| 46 | -FOSSIL_ENABLE_TCL_STUBS = @FOSSIL_ENABLE_TCL_STUBS@ | |
| 47 | -FOSSIL_ENABLE_TCL_PRIVATE_STUBS = @FOSSIL_ENABLE_TCL_PRIVATE_STUBS@ | |
| 48 | 45 | |
| 49 | 46 | include $(SRCDIR)/main.mk |
| 50 | 47 | |
| 51 | 48 | distclean: clean |
| 52 | 49 | rm -f autoconfig.h config.log Makefile |
| 53 | 50 |
| --- Makefile.in | |
| +++ Makefile.in | |
| @@ -40,13 +40,10 @@ | |
| 40 | |
| 41 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 42 | TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H |
| 43 | INSTALLDIR = $(DESTDIR)@prefix@/bin |
| 44 | USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
| 45 | FOSSIL_ENABLE_TCL = @FOSSIL_ENABLE_TCL@ |
| 46 | FOSSIL_ENABLE_TCL_STUBS = @FOSSIL_ENABLE_TCL_STUBS@ |
| 47 | FOSSIL_ENABLE_TCL_PRIVATE_STUBS = @FOSSIL_ENABLE_TCL_PRIVATE_STUBS@ |
| 48 | |
| 49 | include $(SRCDIR)/main.mk |
| 50 | |
| 51 | distclean: clean |
| 52 | rm -f autoconfig.h config.log Makefile |
| 53 |
| --- Makefile.in | |
| +++ Makefile.in | |
| @@ -40,13 +40,10 @@ | |
| 40 | |
| 41 | LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ |
| 42 | TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H |
| 43 | INSTALLDIR = $(DESTDIR)@prefix@/bin |
| 44 | USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
| 45 | |
| 46 | include $(SRCDIR)/main.mk |
| 47 | |
| 48 | distclean: clean |
| 49 | rm -f autoconfig.h config.log Makefile |
| 50 |
M
auto.def
+5
| --- auto.def | ||
| +++ auto.def | ||
| @@ -248,10 +248,15 @@ | ||
| 248 | 248 | if {[string match *mingw* [get-define host]]} { |
| 249 | 249 | define-append LIBS -lwsock32 |
| 250 | 250 | } |
| 251 | 251 | } |
| 252 | 252 | cc-check-function-in-lib iconv iconv |
| 253 | + | |
| 254 | +# Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE | |
| 255 | +if {![cc-check-functions getloadavg]} { | |
| 256 | + define FOSSIL_OMIT_LOAD_AVERAGE 1 | |
| 257 | +} | |
| 253 | 258 | |
| 254 | 259 | # Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars |
| 255 | 260 | if {![cc-check-functions getpassphrase]} { |
| 256 | 261 | # Haiku needs this |
| 257 | 262 | cc-check-function-in-lib getpass bsd |
| 258 | 263 |
| --- auto.def | |
| +++ auto.def | |
| @@ -248,10 +248,15 @@ | |
| 248 | if {[string match *mingw* [get-define host]]} { |
| 249 | define-append LIBS -lwsock32 |
| 250 | } |
| 251 | } |
| 252 | cc-check-function-in-lib iconv iconv |
| 253 | |
| 254 | # Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars |
| 255 | if {![cc-check-functions getpassphrase]} { |
| 256 | # Haiku needs this |
| 257 | cc-check-function-in-lib getpass bsd |
| 258 |
| --- auto.def | |
| +++ auto.def | |
| @@ -248,10 +248,15 @@ | |
| 248 | if {[string match *mingw* [get-define host]]} { |
| 249 | define-append LIBS -lwsock32 |
| 250 | } |
| 251 | } |
| 252 | cc-check-function-in-lib iconv iconv |
| 253 | |
| 254 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 255 | if {![cc-check-functions getloadavg]} { |
| 256 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 257 | } |
| 258 | |
| 259 | # Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars |
| 260 | if {![cc-check-functions getpassphrase]} { |
| 261 | # Haiku needs this |
| 262 | cc-check-function-in-lib getpass bsd |
| 263 |
+2
-2
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -25,11 +25,11 @@ | ||
| 25 | 25 | #include "cygsup.h" |
| 26 | 26 | |
| 27 | 27 | /* |
| 28 | 28 | ** This routine returns the names of files in a working checkout that |
| 29 | 29 | ** are created by Fossil itself, and hence should not be added, deleted, |
| 30 | -** or merge, and should be omitted from "clean" and "extra" lists. | |
| 30 | +** or merge, and should be omitted from "clean" and "extras" lists. | |
| 31 | 31 | ** |
| 32 | 32 | ** Return the N-th name. The first name has N==0. When all names have |
| 33 | 33 | ** been used, return 0. |
| 34 | 34 | */ |
| 35 | 35 | const char *fossil_reserved_name(int N, int omitRepo){ |
| @@ -461,11 +461,11 @@ | ||
| 461 | 461 | ** |
| 462 | 462 | ** Do all necessary "add" and "rm" commands to synchronize the repository |
| 463 | 463 | ** with the content of the working checkout: |
| 464 | 464 | ** |
| 465 | 465 | ** * All files in the checkout but not in the repository (that is, |
| 466 | -** all files displayed using the "extra" command) are added as | |
| 466 | +** all files displayed using the "extras" command) are added as | |
| 467 | 467 | ** if by the "add" command. |
| 468 | 468 | ** |
| 469 | 469 | ** * All files in the repository but missing from the checkout (that is, |
| 470 | 470 | ** all files that show as MISSING with the "status" command) are |
| 471 | 471 | ** removed as if by the "rm" command. |
| 472 | 472 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -25,11 +25,11 @@ | |
| 25 | #include "cygsup.h" |
| 26 | |
| 27 | /* |
| 28 | ** This routine returns the names of files in a working checkout that |
| 29 | ** are created by Fossil itself, and hence should not be added, deleted, |
| 30 | ** or merge, and should be omitted from "clean" and "extra" lists. |
| 31 | ** |
| 32 | ** Return the N-th name. The first name has N==0. When all names have |
| 33 | ** been used, return 0. |
| 34 | */ |
| 35 | const char *fossil_reserved_name(int N, int omitRepo){ |
| @@ -461,11 +461,11 @@ | |
| 461 | ** |
| 462 | ** Do all necessary "add" and "rm" commands to synchronize the repository |
| 463 | ** with the content of the working checkout: |
| 464 | ** |
| 465 | ** * All files in the checkout but not in the repository (that is, |
| 466 | ** all files displayed using the "extra" command) are added as |
| 467 | ** if by the "add" command. |
| 468 | ** |
| 469 | ** * All files in the repository but missing from the checkout (that is, |
| 470 | ** all files that show as MISSING with the "status" command) are |
| 471 | ** removed as if by the "rm" command. |
| 472 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -25,11 +25,11 @@ | |
| 25 | #include "cygsup.h" |
| 26 | |
| 27 | /* |
| 28 | ** This routine returns the names of files in a working checkout that |
| 29 | ** are created by Fossil itself, and hence should not be added, deleted, |
| 30 | ** or merge, and should be omitted from "clean" and "extras" lists. |
| 31 | ** |
| 32 | ** Return the N-th name. The first name has N==0. When all names have |
| 33 | ** been used, return 0. |
| 34 | */ |
| 35 | const char *fossil_reserved_name(int N, int omitRepo){ |
| @@ -461,11 +461,11 @@ | |
| 461 | ** |
| 462 | ** Do all necessary "add" and "rm" commands to synchronize the repository |
| 463 | ** with the content of the working checkout: |
| 464 | ** |
| 465 | ** * All files in the checkout but not in the repository (that is, |
| 466 | ** all files displayed using the "extras" command) are added as |
| 467 | ** if by the "add" command. |
| 468 | ** |
| 469 | ** * All files in the repository but missing from the checkout (that is, |
| 470 | ** all files that show as MISSING with the "status" command) are |
| 471 | ** removed as if by the "rm" command. |
| 472 |
+16
-7
| --- src/allrepo.c | ||
| +++ src/allrepo.c | ||
| @@ -76,11 +76,11 @@ | ||
| 76 | 76 | |
| 77 | 77 | |
| 78 | 78 | /* |
| 79 | 79 | ** COMMAND: all |
| 80 | 80 | ** |
| 81 | -** Usage: %fossil all (changes|clean|extra|ignore|list|ls|pull|push|rebuild|sync) | |
| 81 | +** Usage: %fossil all (changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync) | |
| 82 | 82 | ** |
| 83 | 83 | ** The ~/.fossil file records the location of all repositories for a |
| 84 | 84 | ** user. This command performs certain operations on all repositories |
| 85 | 85 | ** that can be useful before or after a period of disconnected operation. |
| 86 | 86 | ** |
| @@ -99,16 +99,16 @@ | ||
| 99 | 99 | ** and the --whatif option to carefully review the files to |
| 100 | 100 | ** be deleted beforehand is highly recommended. The command |
| 101 | 101 | ** line options supported by the clean command itself, if any |
| 102 | 102 | ** are present, are passed along verbatim. |
| 103 | 103 | ** |
| 104 | -** extra Shows extra files from all local checkouts. The command | |
| 104 | +** extras Shows "extra" files from all local checkouts. The command | |
| 105 | 105 | ** line options supported by the extra command itself, if any |
| 106 | 106 | ** are present, are passed along verbatim. |
| 107 | 107 | ** |
| 108 | 108 | ** ignore Arguments are repositories that should be ignored by |
| 109 | -** subsequent clean, extra, list, pull, push, rebuild, and | |
| 109 | +** subsequent clean, extras, list, pull, push, rebuild, and | |
| 110 | 110 | ** sync operations. The -c|--ckout option causes the listed |
| 111 | 111 | ** local checkouts to be ignored instead. |
| 112 | 112 | ** |
| 113 | 113 | ** list | ls Display the location of all repositories. The -c|--ckout |
| 114 | 114 | ** option causes all local checkouts to be listed instead. |
| @@ -136,10 +136,11 @@ | ||
| 136 | 136 | ** when one of the following commands are run against the repository: |
| 137 | 137 | ** clone, info, pull, push, or sync. Even previously ignored repositories |
| 138 | 138 | ** are added back to the list of repositories by these commands. |
| 139 | 139 | ** |
| 140 | 140 | ** Options: |
| 141 | +** --showfile Show the repository or checkout being operated upon. | |
| 141 | 142 | ** --dontstop Continue with other repositories even after an error. |
| 142 | 143 | ** --dry-run If given, display instead of run actions. |
| 143 | 144 | */ |
| 144 | 145 | void all_cmd(void){ |
| 145 | 146 | int n; |
| @@ -150,10 +151,11 @@ | ||
| 150 | 151 | char *zQFilename; |
| 151 | 152 | Blob extra; |
| 152 | 153 | int useCheckouts = 0; |
| 153 | 154 | int quiet = 0; |
| 154 | 155 | int dryRunFlag = 0; |
| 156 | + int showFile = find_option("showfile",0,0)!=0; | |
| 155 | 157 | int stopOnError = find_option("dontstop",0,0)==0; |
| 156 | 158 | int rc; |
| 157 | 159 | int nToDel = 0; |
| 158 | 160 | |
| 159 | 161 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| @@ -160,11 +162,11 @@ | ||
| 160 | 162 | if( !dryRunFlag ){ |
| 161 | 163 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 162 | 164 | } |
| 163 | 165 | |
| 164 | 166 | if( g.argc<3 ){ |
| 165 | - usage("changes|clean|extra|ignore|list|ls|pull|push|rebuild|sync"); | |
| 167 | + usage("changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync"); | |
| 166 | 168 | } |
| 167 | 169 | n = strlen(g.argv[2]); |
| 168 | 170 | db_open_config(1); |
| 169 | 171 | blob_zero(&extra); |
| 170 | 172 | zCmd = g.argv[2]; |
| @@ -185,12 +187,16 @@ | ||
| 185 | 187 | collect_argument_value(&extra, "keep"); |
| 186 | 188 | collect_argument(&extra, "temp",0); |
| 187 | 189 | collect_argument(&extra, "verbose","v"); |
| 188 | 190 | collect_argument(&extra, "whatif",0); |
| 189 | 191 | useCheckouts = 1; |
| 190 | - }else if( strncmp(zCmd, "extra", n)==0 ){ | |
| 191 | - zCmd = "extra --chdir"; | |
| 192 | + }else if( strncmp(zCmd, "extras", n)==0 ){ | |
| 193 | + if( showFile ){ | |
| 194 | + zCmd = "extras --chdir"; | |
| 195 | + }else{ | |
| 196 | + zCmd = "extras --header --chdir"; | |
| 197 | + } | |
| 192 | 198 | collect_argument(&extra, "abs-paths",0); |
| 193 | 199 | collect_argument_value(&extra, "case-sensitive"); |
| 194 | 200 | collect_argument(&extra, "dotfiles",0); |
| 195 | 201 | collect_argument_value(&extra, "ignore"); |
| 196 | 202 | collect_argument(&extra, "rel-paths",0); |
| @@ -254,11 +260,11 @@ | ||
| 254 | 260 | } |
| 255 | 261 | db_end_transaction(0); |
| 256 | 262 | return; |
| 257 | 263 | }else{ |
| 258 | 264 | fossil_fatal("\"all\" subcommand should be one of: " |
| 259 | - "changes clean extra ignore list ls push pull rebuild sync"); | |
| 265 | + "changes clean extras ignore list ls push pull rebuild sync"); | |
| 260 | 266 | } |
| 261 | 267 | verify_all_options(); |
| 262 | 268 | zFossil = quoteFilename(g.nameOfExe); |
| 263 | 269 | if( useCheckouts ){ |
| 264 | 270 | db_prepare(&q, |
| @@ -287,10 +293,13 @@ | ||
| 287 | 293 | continue; |
| 288 | 294 | } |
| 289 | 295 | if( zCmd[0]=='l' ){ |
| 290 | 296 | fossil_print("%s\n", zFilename); |
| 291 | 297 | continue; |
| 298 | + }else if( showFile ){ | |
| 299 | + fossil_print("%s: %s\n", useCheckouts ? "checkout" : "repository", | |
| 300 | + zFilename); | |
| 292 | 301 | } |
| 293 | 302 | zQFilename = quoteFilename(zFilename); |
| 294 | 303 | zSyscmd = mprintf("%s %s %s%s", |
| 295 | 304 | zFossil, zCmd, zQFilename, blob_str(&extra)); |
| 296 | 305 | if( !quiet || dryRunFlag ){ |
| 297 | 306 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -76,11 +76,11 @@ | |
| 76 | |
| 77 | |
| 78 | /* |
| 79 | ** COMMAND: all |
| 80 | ** |
| 81 | ** Usage: %fossil all (changes|clean|extra|ignore|list|ls|pull|push|rebuild|sync) |
| 82 | ** |
| 83 | ** The ~/.fossil file records the location of all repositories for a |
| 84 | ** user. This command performs certain operations on all repositories |
| 85 | ** that can be useful before or after a period of disconnected operation. |
| 86 | ** |
| @@ -99,16 +99,16 @@ | |
| 99 | ** and the --whatif option to carefully review the files to |
| 100 | ** be deleted beforehand is highly recommended. The command |
| 101 | ** line options supported by the clean command itself, if any |
| 102 | ** are present, are passed along verbatim. |
| 103 | ** |
| 104 | ** extra Shows extra files from all local checkouts. The command |
| 105 | ** line options supported by the extra command itself, if any |
| 106 | ** are present, are passed along verbatim. |
| 107 | ** |
| 108 | ** ignore Arguments are repositories that should be ignored by |
| 109 | ** subsequent clean, extra, list, pull, push, rebuild, and |
| 110 | ** sync operations. The -c|--ckout option causes the listed |
| 111 | ** local checkouts to be ignored instead. |
| 112 | ** |
| 113 | ** list | ls Display the location of all repositories. The -c|--ckout |
| 114 | ** option causes all local checkouts to be listed instead. |
| @@ -136,10 +136,11 @@ | |
| 136 | ** when one of the following commands are run against the repository: |
| 137 | ** clone, info, pull, push, or sync. Even previously ignored repositories |
| 138 | ** are added back to the list of repositories by these commands. |
| 139 | ** |
| 140 | ** Options: |
| 141 | ** --dontstop Continue with other repositories even after an error. |
| 142 | ** --dry-run If given, display instead of run actions. |
| 143 | */ |
| 144 | void all_cmd(void){ |
| 145 | int n; |
| @@ -150,10 +151,11 @@ | |
| 150 | char *zQFilename; |
| 151 | Blob extra; |
| 152 | int useCheckouts = 0; |
| 153 | int quiet = 0; |
| 154 | int dryRunFlag = 0; |
| 155 | int stopOnError = find_option("dontstop",0,0)==0; |
| 156 | int rc; |
| 157 | int nToDel = 0; |
| 158 | |
| 159 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| @@ -160,11 +162,11 @@ | |
| 160 | if( !dryRunFlag ){ |
| 161 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 162 | } |
| 163 | |
| 164 | if( g.argc<3 ){ |
| 165 | usage("changes|clean|extra|ignore|list|ls|pull|push|rebuild|sync"); |
| 166 | } |
| 167 | n = strlen(g.argv[2]); |
| 168 | db_open_config(1); |
| 169 | blob_zero(&extra); |
| 170 | zCmd = g.argv[2]; |
| @@ -185,12 +187,16 @@ | |
| 185 | collect_argument_value(&extra, "keep"); |
| 186 | collect_argument(&extra, "temp",0); |
| 187 | collect_argument(&extra, "verbose","v"); |
| 188 | collect_argument(&extra, "whatif",0); |
| 189 | useCheckouts = 1; |
| 190 | }else if( strncmp(zCmd, "extra", n)==0 ){ |
| 191 | zCmd = "extra --chdir"; |
| 192 | collect_argument(&extra, "abs-paths",0); |
| 193 | collect_argument_value(&extra, "case-sensitive"); |
| 194 | collect_argument(&extra, "dotfiles",0); |
| 195 | collect_argument_value(&extra, "ignore"); |
| 196 | collect_argument(&extra, "rel-paths",0); |
| @@ -254,11 +260,11 @@ | |
| 254 | } |
| 255 | db_end_transaction(0); |
| 256 | return; |
| 257 | }else{ |
| 258 | fossil_fatal("\"all\" subcommand should be one of: " |
| 259 | "changes clean extra ignore list ls push pull rebuild sync"); |
| 260 | } |
| 261 | verify_all_options(); |
| 262 | zFossil = quoteFilename(g.nameOfExe); |
| 263 | if( useCheckouts ){ |
| 264 | db_prepare(&q, |
| @@ -287,10 +293,13 @@ | |
| 287 | continue; |
| 288 | } |
| 289 | if( zCmd[0]=='l' ){ |
| 290 | fossil_print("%s\n", zFilename); |
| 291 | continue; |
| 292 | } |
| 293 | zQFilename = quoteFilename(zFilename); |
| 294 | zSyscmd = mprintf("%s %s %s%s", |
| 295 | zFossil, zCmd, zQFilename, blob_str(&extra)); |
| 296 | if( !quiet || dryRunFlag ){ |
| 297 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -76,11 +76,11 @@ | |
| 76 | |
| 77 | |
| 78 | /* |
| 79 | ** COMMAND: all |
| 80 | ** |
| 81 | ** Usage: %fossil all (changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync) |
| 82 | ** |
| 83 | ** The ~/.fossil file records the location of all repositories for a |
| 84 | ** user. This command performs certain operations on all repositories |
| 85 | ** that can be useful before or after a period of disconnected operation. |
| 86 | ** |
| @@ -99,16 +99,16 @@ | |
| 99 | ** and the --whatif option to carefully review the files to |
| 100 | ** be deleted beforehand is highly recommended. The command |
| 101 | ** line options supported by the clean command itself, if any |
| 102 | ** are present, are passed along verbatim. |
| 103 | ** |
| 104 | ** extras Shows "extra" files from all local checkouts. The command |
| 105 | ** line options supported by the extra command itself, if any |
| 106 | ** are present, are passed along verbatim. |
| 107 | ** |
| 108 | ** ignore Arguments are repositories that should be ignored by |
| 109 | ** subsequent clean, extras, list, pull, push, rebuild, and |
| 110 | ** sync operations. The -c|--ckout option causes the listed |
| 111 | ** local checkouts to be ignored instead. |
| 112 | ** |
| 113 | ** list | ls Display the location of all repositories. The -c|--ckout |
| 114 | ** option causes all local checkouts to be listed instead. |
| @@ -136,10 +136,11 @@ | |
| 136 | ** when one of the following commands are run against the repository: |
| 137 | ** clone, info, pull, push, or sync. Even previously ignored repositories |
| 138 | ** are added back to the list of repositories by these commands. |
| 139 | ** |
| 140 | ** Options: |
| 141 | ** --showfile Show the repository or checkout being operated upon. |
| 142 | ** --dontstop Continue with other repositories even after an error. |
| 143 | ** --dry-run If given, display instead of run actions. |
| 144 | */ |
| 145 | void all_cmd(void){ |
| 146 | int n; |
| @@ -150,10 +151,11 @@ | |
| 151 | char *zQFilename; |
| 152 | Blob extra; |
| 153 | int useCheckouts = 0; |
| 154 | int quiet = 0; |
| 155 | int dryRunFlag = 0; |
| 156 | int showFile = find_option("showfile",0,0)!=0; |
| 157 | int stopOnError = find_option("dontstop",0,0)==0; |
| 158 | int rc; |
| 159 | int nToDel = 0; |
| 160 | |
| 161 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| @@ -160,11 +162,11 @@ | |
| 162 | if( !dryRunFlag ){ |
| 163 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 164 | } |
| 165 | |
| 166 | if( g.argc<3 ){ |
| 167 | usage("changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync"); |
| 168 | } |
| 169 | n = strlen(g.argv[2]); |
| 170 | db_open_config(1); |
| 171 | blob_zero(&extra); |
| 172 | zCmd = g.argv[2]; |
| @@ -185,12 +187,16 @@ | |
| 187 | collect_argument_value(&extra, "keep"); |
| 188 | collect_argument(&extra, "temp",0); |
| 189 | collect_argument(&extra, "verbose","v"); |
| 190 | collect_argument(&extra, "whatif",0); |
| 191 | useCheckouts = 1; |
| 192 | }else if( strncmp(zCmd, "extras", n)==0 ){ |
| 193 | if( showFile ){ |
| 194 | zCmd = "extras --chdir"; |
| 195 | }else{ |
| 196 | zCmd = "extras --header --chdir"; |
| 197 | } |
| 198 | collect_argument(&extra, "abs-paths",0); |
| 199 | collect_argument_value(&extra, "case-sensitive"); |
| 200 | collect_argument(&extra, "dotfiles",0); |
| 201 | collect_argument_value(&extra, "ignore"); |
| 202 | collect_argument(&extra, "rel-paths",0); |
| @@ -254,11 +260,11 @@ | |
| 260 | } |
| 261 | db_end_transaction(0); |
| 262 | return; |
| 263 | }else{ |
| 264 | fossil_fatal("\"all\" subcommand should be one of: " |
| 265 | "changes clean extras ignore list ls push pull rebuild sync"); |
| 266 | } |
| 267 | verify_all_options(); |
| 268 | zFossil = quoteFilename(g.nameOfExe); |
| 269 | if( useCheckouts ){ |
| 270 | db_prepare(&q, |
| @@ -287,10 +293,13 @@ | |
| 293 | continue; |
| 294 | } |
| 295 | if( zCmd[0]=='l' ){ |
| 296 | fossil_print("%s\n", zFilename); |
| 297 | continue; |
| 298 | }else if( showFile ){ |
| 299 | fossil_print("%s: %s\n", useCheckouts ? "checkout" : "repository", |
| 300 | zFilename); |
| 301 | } |
| 302 | zQFilename = quoteFilename(zFilename); |
| 303 | zSyscmd = mprintf("%s %s %s%s", |
| 304 | zFossil, zCmd, zQFilename, blob_str(&extra)); |
| 305 | if( !quiet || dryRunFlag ){ |
| 306 |
+4
-4
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -258,11 +258,11 @@ | ||
| 258 | 258 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | 261 | } |
| 262 | 262 | zTarget = zTkt; |
| 263 | - zTargetType = mprintf("Ticket <a href=\"%s/tktview/%S\">%S</a>", | |
| 263 | + zTargetType = mprintf("Ticket <a href=\"%s/tktview/%s\">%S</a>", | |
| 264 | 264 | g.zTop, zTkt, zTkt); |
| 265 | 265 | } |
| 266 | 266 | if( zFrom==0 ) zFrom = mprintf("%s/home", g.zTop); |
| 267 | 267 | if( P("cancel") ){ |
| 268 | 268 | cgi_redirect(zFrom); |
| @@ -463,11 +463,11 @@ | ||
| 463 | 463 | if( strcmp(zModAction,"approve")==0 ){ |
| 464 | 464 | moderation_approve(rid); |
| 465 | 465 | } |
| 466 | 466 | } |
| 467 | 467 | style_header("Attachment Details"); |
| 468 | - style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid); | |
| 468 | + style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid); | |
| 469 | 469 | |
| 470 | 470 | @ <div class="section">Overview</div> |
| 471 | 471 | @ <p><table class="label-value"> |
| 472 | 472 | @ <tr><th>Artifact ID:</th> |
| 473 | 473 | @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a> |
| @@ -531,12 +531,12 @@ | ||
| 531 | 531 | @ <pre> |
| 532 | 532 | @ %h(z) |
| 533 | 533 | @ </pre> |
| 534 | 534 | } |
| 535 | 535 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 536 | - @ <img src="%R/raw/%S(zSrc)?m=%s(zMime)"></img> | |
| 537 | - style_submenu_element("Image", "Image", "%R/raw/%S?m=%s", zSrc, zMime); | |
| 536 | + @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img> | |
| 537 | + style_submenu_element("Image", "Image", "%R/raw/%s?m=%s", zSrc, zMime); | |
| 538 | 538 | }else{ |
| 539 | 539 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 540 | 540 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 541 | 541 | } |
| 542 | 542 | @ </blockquote> |
| 543 | 543 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -258,11 +258,11 @@ | |
| 258 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | } |
| 262 | zTarget = zTkt; |
| 263 | zTargetType = mprintf("Ticket <a href=\"%s/tktview/%S\">%S</a>", |
| 264 | g.zTop, zTkt, zTkt); |
| 265 | } |
| 266 | if( zFrom==0 ) zFrom = mprintf("%s/home", g.zTop); |
| 267 | if( P("cancel") ){ |
| 268 | cgi_redirect(zFrom); |
| @@ -463,11 +463,11 @@ | |
| 463 | if( strcmp(zModAction,"approve")==0 ){ |
| 464 | moderation_approve(rid); |
| 465 | } |
| 466 | } |
| 467 | style_header("Attachment Details"); |
| 468 | style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid); |
| 469 | |
| 470 | @ <div class="section">Overview</div> |
| 471 | @ <p><table class="label-value"> |
| 472 | @ <tr><th>Artifact ID:</th> |
| 473 | @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a> |
| @@ -531,12 +531,12 @@ | |
| 531 | @ <pre> |
| 532 | @ %h(z) |
| 533 | @ </pre> |
| 534 | } |
| 535 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 536 | @ <img src="%R/raw/%S(zSrc)?m=%s(zMime)"></img> |
| 537 | style_submenu_element("Image", "Image", "%R/raw/%S?m=%s", zSrc, zMime); |
| 538 | }else{ |
| 539 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 540 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 541 | } |
| 542 | @ </blockquote> |
| 543 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -258,11 +258,11 @@ | |
| 258 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | } |
| 262 | zTarget = zTkt; |
| 263 | zTargetType = mprintf("Ticket <a href=\"%s/tktview/%s\">%S</a>", |
| 264 | g.zTop, zTkt, zTkt); |
| 265 | } |
| 266 | if( zFrom==0 ) zFrom = mprintf("%s/home", g.zTop); |
| 267 | if( P("cancel") ){ |
| 268 | cgi_redirect(zFrom); |
| @@ -463,11 +463,11 @@ | |
| 463 | if( strcmp(zModAction,"approve")==0 ){ |
| 464 | moderation_approve(rid); |
| 465 | } |
| 466 | } |
| 467 | style_header("Attachment Details"); |
| 468 | style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid); |
| 469 | |
| 470 | @ <div class="section">Overview</div> |
| 471 | @ <p><table class="label-value"> |
| 472 | @ <tr><th>Artifact ID:</th> |
| 473 | @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a> |
| @@ -531,12 +531,12 @@ | |
| 531 | @ <pre> |
| 532 | @ %h(z) |
| 533 | @ </pre> |
| 534 | } |
| 535 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 536 | @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img> |
| 537 | style_submenu_element("Image", "Image", "%R/raw/%s?m=%s", zSrc, zMime); |
| 538 | }else{ |
| 539 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 540 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 541 | } |
| 542 | @ </blockquote> |
| 543 |
+8
-11
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -85,11 +85,11 @@ | ||
| 85 | 85 | |
| 86 | 86 | for(i=0; zPath[i]; i=j){ |
| 87 | 87 | for(j=i; zPath[j] && zPath[j]!='/'; j++){} |
| 88 | 88 | if( zPath[j] && g.perm.Hyperlink ){ |
| 89 | 89 | if( zCI ){ |
| 90 | - char *zLink = href("%R/%s?ci=%S&name=%#T%s", zURI, zCI, j, zPath,zREx); | |
| 90 | + char *zLink = href("%R/%s?name=%#T%s&ci=%s", zURI, j, zPath, zREx, zCI); | |
| 91 | 91 | blob_appendf(pOut, "%s%z%#h</a>", |
| 92 | 92 | zSep, zLink, j-i, &zPath[i]); |
| 93 | 93 | }else{ |
| 94 | 94 | char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx); |
| 95 | 95 | blob_appendf(pOut, "%s%z%#h</a>", |
| @@ -179,18 +179,15 @@ | ||
| 179 | 179 | if( linkTip ){ |
| 180 | 180 | style_submenu_element("Tip", "Tip", "%s", |
| 181 | 181 | url_render(&sURI, "ci", "tip", 0, 0)); |
| 182 | 182 | } |
| 183 | 183 | if( zCI ){ |
| 184 | - char zShort[20]; | |
| 185 | - memcpy(zShort, zUuid, 10); | |
| 186 | - zShort[10] = 0; | |
| 187 | - @ <h2>Files of check-in [%z(href("vinfo?name=%T",zUuid))%s(zShort)</a>] | |
| 184 | + @ <h2>Files of check-in [%z(href("vinfo?name=%s",zUuid))%.10s(zUuid)</a>] | |
| 188 | 185 | @ %s(blob_str(&dirname))</h2> |
| 189 | - zSubdirLink = mprintf("%R/dir?ci=%S&name=%T", zUuid, zPrefix); | |
| 186 | + zSubdirLink = mprintf("%R/dir?ci=%s&name=%T", zUuid, zPrefix); | |
| 190 | 187 | if( nD==0 ){ |
| 191 | - style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%S", | |
| 188 | + style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", | |
| 192 | 189 | zUuid); |
| 193 | 190 | } |
| 194 | 191 | }else{ |
| 195 | 192 | @ <h2>The union of all files from all check-ins |
| 196 | 193 | @ %s(blob_str(&dirname))</h2> |
| @@ -490,11 +487,11 @@ | ||
| 490 | 487 | } |
| 491 | 488 | if( zCI ){ |
| 492 | 489 | style_submenu_element("All", "All", "%s", |
| 493 | 490 | url_render(&sURI, "ci", 0, 0, 0)); |
| 494 | 491 | if( nD==0 && !showDirOnly ){ |
| 495 | - style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%S", | |
| 492 | + style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", | |
| 496 | 493 | zUuid); |
| 497 | 494 | } |
| 498 | 495 | } |
| 499 | 496 | if( linkTrunk ){ |
| 500 | 497 | style_submenu_element("Trunk", "Trunk", "%s", |
| @@ -574,11 +571,11 @@ | ||
| 574 | 571 | if( zCI ){ |
| 575 | 572 | @ <h2>%d(nFile) %s(zObjType) of check-in |
| 576 | 573 | if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){ |
| 577 | 574 | @ "%h(zCI)" |
| 578 | 575 | } |
| 579 | - @ [%z(href("vinfo?name=%T",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2> | |
| 576 | + @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2> | |
| 580 | 577 | }else{ |
| 581 | 578 | int n = db_int(0, "SELECT count(*) FROM plink"); |
| 582 | 579 | @ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins |
| 583 | 580 | @ %s(blob_str(&dirname))</h2> |
| 584 | 581 | } |
| @@ -617,11 +614,11 @@ | ||
| 617 | 614 | nDir++; |
| 618 | 615 | }else if( !showDirOnly ){ |
| 619 | 616 | const char *zFileClass = fileext_class(p->zName); |
| 620 | 617 | char *zLink; |
| 621 | 618 | if( zCI ){ |
| 622 | - zLink = href("%R/artifact/%S",p->zUuid); | |
| 619 | + zLink = href("%R/artifact/%s",p->zUuid); | |
| 623 | 620 | }else{ |
| 624 | 621 | zLink = href("%R/finfo?name=%T",p->zFullName); |
| 625 | 622 | } |
| 626 | 623 | @ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a> |
| 627 | 624 | } |
| @@ -875,14 +872,14 @@ | ||
| 875 | 872 | zAge[0] = 0; |
| 876 | 873 | } |
| 877 | 874 | @ <tr> |
| 878 | 875 | @ <td>%s(zAge) |
| 879 | 876 | @ <td width="25"> |
| 880 | - @ <td>%z(href("%R/artifact/%S?ln", zFUuid))%h(db_column_text(&q, 3))</a> | |
| 877 | + @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a> | |
| 881 | 878 | @ </tr> |
| 882 | 879 | @ |
| 883 | 880 | } |
| 884 | 881 | @ <tr><td colspan=3><hr></tr> |
| 885 | 882 | @ </table> |
| 886 | 883 | db_finalize(&q); |
| 887 | 884 | style_footer(); |
| 888 | 885 | } |
| 889 | 886 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -85,11 +85,11 @@ | |
| 85 | |
| 86 | for(i=0; zPath[i]; i=j){ |
| 87 | for(j=i; zPath[j] && zPath[j]!='/'; j++){} |
| 88 | if( zPath[j] && g.perm.Hyperlink ){ |
| 89 | if( zCI ){ |
| 90 | char *zLink = href("%R/%s?ci=%S&name=%#T%s", zURI, zCI, j, zPath,zREx); |
| 91 | blob_appendf(pOut, "%s%z%#h</a>", |
| 92 | zSep, zLink, j-i, &zPath[i]); |
| 93 | }else{ |
| 94 | char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx); |
| 95 | blob_appendf(pOut, "%s%z%#h</a>", |
| @@ -179,18 +179,15 @@ | |
| 179 | if( linkTip ){ |
| 180 | style_submenu_element("Tip", "Tip", "%s", |
| 181 | url_render(&sURI, "ci", "tip", 0, 0)); |
| 182 | } |
| 183 | if( zCI ){ |
| 184 | char zShort[20]; |
| 185 | memcpy(zShort, zUuid, 10); |
| 186 | zShort[10] = 0; |
| 187 | @ <h2>Files of check-in [%z(href("vinfo?name=%T",zUuid))%s(zShort)</a>] |
| 188 | @ %s(blob_str(&dirname))</h2> |
| 189 | zSubdirLink = mprintf("%R/dir?ci=%S&name=%T", zUuid, zPrefix); |
| 190 | if( nD==0 ){ |
| 191 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%S", |
| 192 | zUuid); |
| 193 | } |
| 194 | }else{ |
| 195 | @ <h2>The union of all files from all check-ins |
| 196 | @ %s(blob_str(&dirname))</h2> |
| @@ -490,11 +487,11 @@ | |
| 490 | } |
| 491 | if( zCI ){ |
| 492 | style_submenu_element("All", "All", "%s", |
| 493 | url_render(&sURI, "ci", 0, 0, 0)); |
| 494 | if( nD==0 && !showDirOnly ){ |
| 495 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%S", |
| 496 | zUuid); |
| 497 | } |
| 498 | } |
| 499 | if( linkTrunk ){ |
| 500 | style_submenu_element("Trunk", "Trunk", "%s", |
| @@ -574,11 +571,11 @@ | |
| 574 | if( zCI ){ |
| 575 | @ <h2>%d(nFile) %s(zObjType) of check-in |
| 576 | if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){ |
| 577 | @ "%h(zCI)" |
| 578 | } |
| 579 | @ [%z(href("vinfo?name=%T",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2> |
| 580 | }else{ |
| 581 | int n = db_int(0, "SELECT count(*) FROM plink"); |
| 582 | @ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins |
| 583 | @ %s(blob_str(&dirname))</h2> |
| 584 | } |
| @@ -617,11 +614,11 @@ | |
| 617 | nDir++; |
| 618 | }else if( !showDirOnly ){ |
| 619 | const char *zFileClass = fileext_class(p->zName); |
| 620 | char *zLink; |
| 621 | if( zCI ){ |
| 622 | zLink = href("%R/artifact/%S",p->zUuid); |
| 623 | }else{ |
| 624 | zLink = href("%R/finfo?name=%T",p->zFullName); |
| 625 | } |
| 626 | @ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a> |
| 627 | } |
| @@ -875,14 +872,14 @@ | |
| 875 | zAge[0] = 0; |
| 876 | } |
| 877 | @ <tr> |
| 878 | @ <td>%s(zAge) |
| 879 | @ <td width="25"> |
| 880 | @ <td>%z(href("%R/artifact/%S?ln", zFUuid))%h(db_column_text(&q, 3))</a> |
| 881 | @ </tr> |
| 882 | @ |
| 883 | } |
| 884 | @ <tr><td colspan=3><hr></tr> |
| 885 | @ </table> |
| 886 | db_finalize(&q); |
| 887 | style_footer(); |
| 888 | } |
| 889 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -85,11 +85,11 @@ | |
| 85 | |
| 86 | for(i=0; zPath[i]; i=j){ |
| 87 | for(j=i; zPath[j] && zPath[j]!='/'; j++){} |
| 88 | if( zPath[j] && g.perm.Hyperlink ){ |
| 89 | if( zCI ){ |
| 90 | char *zLink = href("%R/%s?name=%#T%s&ci=%s", zURI, j, zPath, zREx, zCI); |
| 91 | blob_appendf(pOut, "%s%z%#h</a>", |
| 92 | zSep, zLink, j-i, &zPath[i]); |
| 93 | }else{ |
| 94 | char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx); |
| 95 | blob_appendf(pOut, "%s%z%#h</a>", |
| @@ -179,18 +179,15 @@ | |
| 179 | if( linkTip ){ |
| 180 | style_submenu_element("Tip", "Tip", "%s", |
| 181 | url_render(&sURI, "ci", "tip", 0, 0)); |
| 182 | } |
| 183 | if( zCI ){ |
| 184 | @ <h2>Files of check-in [%z(href("vinfo?name=%s",zUuid))%.10s(zUuid)</a>] |
| 185 | @ %s(blob_str(&dirname))</h2> |
| 186 | zSubdirLink = mprintf("%R/dir?ci=%s&name=%T", zUuid, zPrefix); |
| 187 | if( nD==0 ){ |
| 188 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", |
| 189 | zUuid); |
| 190 | } |
| 191 | }else{ |
| 192 | @ <h2>The union of all files from all check-ins |
| 193 | @ %s(blob_str(&dirname))</h2> |
| @@ -490,11 +487,11 @@ | |
| 487 | } |
| 488 | if( zCI ){ |
| 489 | style_submenu_element("All", "All", "%s", |
| 490 | url_render(&sURI, "ci", 0, 0, 0)); |
| 491 | if( nD==0 && !showDirOnly ){ |
| 492 | style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s", |
| 493 | zUuid); |
| 494 | } |
| 495 | } |
| 496 | if( linkTrunk ){ |
| 497 | style_submenu_element("Trunk", "Trunk", "%s", |
| @@ -574,11 +571,11 @@ | |
| 571 | if( zCI ){ |
| 572 | @ <h2>%d(nFile) %s(zObjType) of check-in |
| 573 | if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){ |
| 574 | @ "%h(zCI)" |
| 575 | } |
| 576 | @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2> |
| 577 | }else{ |
| 578 | int n = db_int(0, "SELECT count(*) FROM plink"); |
| 579 | @ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins |
| 580 | @ %s(blob_str(&dirname))</h2> |
| 581 | } |
| @@ -617,11 +614,11 @@ | |
| 614 | nDir++; |
| 615 | }else if( !showDirOnly ){ |
| 616 | const char *zFileClass = fileext_class(p->zName); |
| 617 | char *zLink; |
| 618 | if( zCI ){ |
| 619 | zLink = href("%R/artifact/%s",p->zUuid); |
| 620 | }else{ |
| 621 | zLink = href("%R/finfo?name=%T",p->zFullName); |
| 622 | } |
| 623 | @ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a> |
| 624 | } |
| @@ -875,14 +872,14 @@ | |
| 872 | zAge[0] = 0; |
| 873 | } |
| 874 | @ <tr> |
| 875 | @ <td>%s(zAge) |
| 876 | @ <td width="25"> |
| 877 | @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a> |
| 878 | @ </tr> |
| 879 | @ |
| 880 | } |
| 881 | @ <tr><td colspan=3><hr></tr> |
| 882 | @ </table> |
| 883 | db_finalize(&q); |
| 884 | style_footer(); |
| 885 | } |
| 886 |
+1
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -874,11 +874,11 @@ | ||
| 874 | 874 | char *z; |
| 875 | 875 | const char *zType; |
| 876 | 876 | int len; |
| 877 | 877 | const char *zRequestUri = cgi_parameter("REQUEST_URI",0); |
| 878 | 878 | const char *zScriptName = cgi_parameter("SCRIPT_NAME",0); |
| 879 | - const char *zPathInfo = cgi_parameter("PATH_INFO",""); | |
| 879 | + const char *zPathInfo = cgi_parameter("PATH_INFO",0); | |
| 880 | 880 | |
| 881 | 881 | #ifdef FOSSIL_ENABLE_JSON |
| 882 | 882 | json_main_bootstrap(); |
| 883 | 883 | #endif |
| 884 | 884 | g.isHTTP = 1; |
| 885 | 885 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -874,11 +874,11 @@ | |
| 874 | char *z; |
| 875 | const char *zType; |
| 876 | int len; |
| 877 | const char *zRequestUri = cgi_parameter("REQUEST_URI",0); |
| 878 | const char *zScriptName = cgi_parameter("SCRIPT_NAME",0); |
| 879 | const char *zPathInfo = cgi_parameter("PATH_INFO",""); |
| 880 | |
| 881 | #ifdef FOSSIL_ENABLE_JSON |
| 882 | json_main_bootstrap(); |
| 883 | #endif |
| 884 | g.isHTTP = 1; |
| 885 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -874,11 +874,11 @@ | |
| 874 | char *z; |
| 875 | const char *zType; |
| 876 | int len; |
| 877 | const char *zRequestUri = cgi_parameter("REQUEST_URI",0); |
| 878 | const char *zScriptName = cgi_parameter("SCRIPT_NAME",0); |
| 879 | const char *zPathInfo = cgi_parameter("PATH_INFO",0); |
| 880 | |
| 881 | #ifdef FOSSIL_ENABLE_JSON |
| 882 | json_main_bootstrap(); |
| 883 | #endif |
| 884 | g.isHTTP = 1; |
| 885 |
+28
-17
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -179,11 +179,11 @@ | ||
| 179 | 179 | ** --sha1sum Verify file status using SHA1 hashing rather |
| 180 | 180 | ** than relying on file mtimes. |
| 181 | 181 | ** --header Identify the repository if there are changes |
| 182 | 182 | ** -v|--verbose Say "(none)" if there are no changes |
| 183 | 183 | ** |
| 184 | -** See also: extra, ls, status | |
| 184 | +** See also: extras, ls, status | |
| 185 | 185 | */ |
| 186 | 186 | void changes_cmd(void){ |
| 187 | 187 | Blob report; |
| 188 | 188 | int vid; |
| 189 | 189 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| @@ -223,11 +223,11 @@ | ||
| 223 | 223 | ** --rel-paths Display pathnames relative to the current working |
| 224 | 224 | ** directory. |
| 225 | 225 | ** --sha1sum Verify file status using SHA1 hashing rather |
| 226 | 226 | ** than relying on file mtimes. |
| 227 | 227 | ** |
| 228 | -** See also: changes, extra, ls | |
| 228 | +** See also: changes, extras, ls | |
| 229 | 229 | */ |
| 230 | 230 | void status_cmd(void){ |
| 231 | 231 | int vid; |
| 232 | 232 | db_must_be_within_tree(); |
| 233 | 233 | /* 012345678901234 */ |
| @@ -255,11 +255,11 @@ | ||
| 255 | 255 | ** |
| 256 | 256 | ** Options: |
| 257 | 257 | ** --age Show when each file was committed |
| 258 | 258 | ** -v|--verbose Provide extra information about each file. |
| 259 | 259 | ** |
| 260 | -** See also: changes, extra, status | |
| 260 | +** See also: changes, extras, status | |
| 261 | 261 | */ |
| 262 | 262 | void ls_cmd(void){ |
| 263 | 263 | int vid; |
| 264 | 264 | Stmt q; |
| 265 | 265 | int verboseFlag; |
| @@ -433,20 +433,22 @@ | ||
| 433 | 433 | ** |
| 434 | 434 | ** Options: |
| 435 | 435 | ** --abs-paths Display absolute pathnames. |
| 436 | 436 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 437 | 437 | ** --dotfiles include files beginning with a dot (".") |
| 438 | +** --header Identify the repository if there are extras | |
| 438 | 439 | ** --ignore <CSG> ignore files matching patterns from the argument |
| 439 | 440 | ** --rel-paths Display pathnames relative to the current working |
| 440 | 441 | ** directory. |
| 441 | 442 | ** |
| 442 | 443 | ** See also: changes, clean, status |
| 443 | 444 | */ |
| 444 | -void extra_cmd(void){ | |
| 445 | +void extras_cmd(void){ | |
| 445 | 446 | Stmt q; |
| 446 | 447 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 447 | 448 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 449 | + int showHdr = find_option("header",0,0)!=0; | |
| 448 | 450 | int cwdRelative = 0; |
| 449 | 451 | Glob *pIgnore; |
| 450 | 452 | Blob rewrittenPathname; |
| 451 | 453 | const char *zPathname, *zDisplayName; |
| 452 | 454 | |
| @@ -477,10 +479,15 @@ | ||
| 477 | 479 | zDisplayName = blob_str(&rewrittenPathname); |
| 478 | 480 | if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){ |
| 479 | 481 | zDisplayName += 2; /* no unnecessary ./ prefix */ |
| 480 | 482 | } |
| 481 | 483 | } |
| 484 | + if( showHdr ){ | |
| 485 | + showHdr = 0; | |
| 486 | + fossil_print("Extras for %s at %s:\n", db_get("project-name","???"), | |
| 487 | + g.zLocalRoot); | |
| 488 | + } | |
| 482 | 489 | fossil_print("%s\n", zDisplayName); |
| 483 | 490 | } |
| 484 | 491 | blob_reset(&rewrittenPathname); |
| 485 | 492 | db_finalize(&q); |
| 486 | 493 | } |
| @@ -536,11 +543,11 @@ | ||
| 536 | 543 | ** list of glob patterns. |
| 537 | 544 | ** -n|--dry-run If given, display instead of run actions. |
| 538 | 545 | ** --temp Remove only Fossil-generated temporary files. |
| 539 | 546 | ** -v|--verbose Show all files as they are removed. |
| 540 | 547 | ** |
| 541 | -** See also: addremove, extra, status | |
| 548 | +** See also: addremove, extras, status | |
| 542 | 549 | */ |
| 543 | 550 | void clean_cmd(void){ |
| 544 | 551 | int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; |
| 545 | 552 | int emptyDirsFlag, dirsOnlyFlag; |
| 546 | 553 | unsigned scanFlags = 0; |
| @@ -1301,21 +1308,25 @@ | ||
| 1301 | 1308 | char *zOrig = file_newname(zFilename, "original", 1); |
| 1302 | 1309 | FILE *f; |
| 1303 | 1310 | blob_write_to_file(p, zOrig); |
| 1304 | 1311 | fossil_free(zOrig); |
| 1305 | 1312 | f = fossil_fopen(zFilename, "wb"); |
| 1306 | - if( fUnicode ) { | |
| 1307 | - int bomSize; | |
| 1308 | - const unsigned char *bom = get_utf8_bom(&bomSize); | |
| 1309 | - fwrite(bom, 1, bomSize, f); | |
| 1310 | - blob_to_utf8_no_bom(p, 0); | |
| 1311 | - } | |
| 1312 | - if( fHasAnyCr ){ | |
| 1313 | - blob_to_lf_only(p); | |
| 1314 | - } | |
| 1315 | - fwrite(blob_buffer(p), 1, blob_size(p), f); | |
| 1316 | - fclose(f); | |
| 1313 | + if( f==0 ){ | |
| 1314 | + fossil_warning("cannot open %s for writing", zFilename); | |
| 1315 | + }else{ | |
| 1316 | + if( fUnicode ) { | |
| 1317 | + int bomSize; | |
| 1318 | + const unsigned char *bom = get_utf8_bom(&bomSize); | |
| 1319 | + fwrite(bom, 1, bomSize, f); | |
| 1320 | + blob_to_utf8_no_bom(p, 0); | |
| 1321 | + } | |
| 1322 | + if( fHasAnyCr ){ | |
| 1323 | + blob_to_lf_only(p); | |
| 1324 | + } | |
| 1325 | + fwrite(blob_buffer(p), 1, blob_size(p), f); | |
| 1326 | + fclose(f); | |
| 1327 | + } | |
| 1317 | 1328 | return 1; |
| 1318 | 1329 | }else if( cReply!='y' && cReply!='Y' ){ |
| 1319 | 1330 | fossil_fatal("Abandoning commit due to %s in %s", |
| 1320 | 1331 | zWarning, blob_str(&fname)); |
| 1321 | 1332 | } |
| @@ -1408,11 +1419,11 @@ | ||
| 1408 | 1419 | ** --private do not sync changes and their descendants |
| 1409 | 1420 | ** --sha1sum verify file status using SHA1 hashing rather |
| 1410 | 1421 | ** than relying on file mtimes |
| 1411 | 1422 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1412 | 1423 | ** |
| 1413 | -** See also: branch, changes, checkout, extra, sync | |
| 1424 | +** See also: branch, changes, checkout, extras, sync | |
| 1414 | 1425 | */ |
| 1415 | 1426 | void commit_cmd(void){ |
| 1416 | 1427 | int hasChanges; /* True if unsaved changes exist */ |
| 1417 | 1428 | int vid; /* blob-id of parent version */ |
| 1418 | 1429 | int nrid; /* blob-id of a modified file */ |
| 1419 | 1430 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -179,11 +179,11 @@ | |
| 179 | ** --sha1sum Verify file status using SHA1 hashing rather |
| 180 | ** than relying on file mtimes. |
| 181 | ** --header Identify the repository if there are changes |
| 182 | ** -v|--verbose Say "(none)" if there are no changes |
| 183 | ** |
| 184 | ** See also: extra, ls, status |
| 185 | */ |
| 186 | void changes_cmd(void){ |
| 187 | Blob report; |
| 188 | int vid; |
| 189 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| @@ -223,11 +223,11 @@ | |
| 223 | ** --rel-paths Display pathnames relative to the current working |
| 224 | ** directory. |
| 225 | ** --sha1sum Verify file status using SHA1 hashing rather |
| 226 | ** than relying on file mtimes. |
| 227 | ** |
| 228 | ** See also: changes, extra, ls |
| 229 | */ |
| 230 | void status_cmd(void){ |
| 231 | int vid; |
| 232 | db_must_be_within_tree(); |
| 233 | /* 012345678901234 */ |
| @@ -255,11 +255,11 @@ | |
| 255 | ** |
| 256 | ** Options: |
| 257 | ** --age Show when each file was committed |
| 258 | ** -v|--verbose Provide extra information about each file. |
| 259 | ** |
| 260 | ** See also: changes, extra, status |
| 261 | */ |
| 262 | void ls_cmd(void){ |
| 263 | int vid; |
| 264 | Stmt q; |
| 265 | int verboseFlag; |
| @@ -433,20 +433,22 @@ | |
| 433 | ** |
| 434 | ** Options: |
| 435 | ** --abs-paths Display absolute pathnames. |
| 436 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 437 | ** --dotfiles include files beginning with a dot (".") |
| 438 | ** --ignore <CSG> ignore files matching patterns from the argument |
| 439 | ** --rel-paths Display pathnames relative to the current working |
| 440 | ** directory. |
| 441 | ** |
| 442 | ** See also: changes, clean, status |
| 443 | */ |
| 444 | void extra_cmd(void){ |
| 445 | Stmt q; |
| 446 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 447 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 448 | int cwdRelative = 0; |
| 449 | Glob *pIgnore; |
| 450 | Blob rewrittenPathname; |
| 451 | const char *zPathname, *zDisplayName; |
| 452 | |
| @@ -477,10 +479,15 @@ | |
| 477 | zDisplayName = blob_str(&rewrittenPathname); |
| 478 | if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){ |
| 479 | zDisplayName += 2; /* no unnecessary ./ prefix */ |
| 480 | } |
| 481 | } |
| 482 | fossil_print("%s\n", zDisplayName); |
| 483 | } |
| 484 | blob_reset(&rewrittenPathname); |
| 485 | db_finalize(&q); |
| 486 | } |
| @@ -536,11 +543,11 @@ | |
| 536 | ** list of glob patterns. |
| 537 | ** -n|--dry-run If given, display instead of run actions. |
| 538 | ** --temp Remove only Fossil-generated temporary files. |
| 539 | ** -v|--verbose Show all files as they are removed. |
| 540 | ** |
| 541 | ** See also: addremove, extra, status |
| 542 | */ |
| 543 | void clean_cmd(void){ |
| 544 | int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; |
| 545 | int emptyDirsFlag, dirsOnlyFlag; |
| 546 | unsigned scanFlags = 0; |
| @@ -1301,21 +1308,25 @@ | |
| 1301 | char *zOrig = file_newname(zFilename, "original", 1); |
| 1302 | FILE *f; |
| 1303 | blob_write_to_file(p, zOrig); |
| 1304 | fossil_free(zOrig); |
| 1305 | f = fossil_fopen(zFilename, "wb"); |
| 1306 | if( fUnicode ) { |
| 1307 | int bomSize; |
| 1308 | const unsigned char *bom = get_utf8_bom(&bomSize); |
| 1309 | fwrite(bom, 1, bomSize, f); |
| 1310 | blob_to_utf8_no_bom(p, 0); |
| 1311 | } |
| 1312 | if( fHasAnyCr ){ |
| 1313 | blob_to_lf_only(p); |
| 1314 | } |
| 1315 | fwrite(blob_buffer(p), 1, blob_size(p), f); |
| 1316 | fclose(f); |
| 1317 | return 1; |
| 1318 | }else if( cReply!='y' && cReply!='Y' ){ |
| 1319 | fossil_fatal("Abandoning commit due to %s in %s", |
| 1320 | zWarning, blob_str(&fname)); |
| 1321 | } |
| @@ -1408,11 +1419,11 @@ | |
| 1408 | ** --private do not sync changes and their descendants |
| 1409 | ** --sha1sum verify file status using SHA1 hashing rather |
| 1410 | ** than relying on file mtimes |
| 1411 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1412 | ** |
| 1413 | ** See also: branch, changes, checkout, extra, sync |
| 1414 | */ |
| 1415 | void commit_cmd(void){ |
| 1416 | int hasChanges; /* True if unsaved changes exist */ |
| 1417 | int vid; /* blob-id of parent version */ |
| 1418 | int nrid; /* blob-id of a modified file */ |
| 1419 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -179,11 +179,11 @@ | |
| 179 | ** --sha1sum Verify file status using SHA1 hashing rather |
| 180 | ** than relying on file mtimes. |
| 181 | ** --header Identify the repository if there are changes |
| 182 | ** -v|--verbose Say "(none)" if there are no changes |
| 183 | ** |
| 184 | ** See also: extras, ls, status |
| 185 | */ |
| 186 | void changes_cmd(void){ |
| 187 | Blob report; |
| 188 | int vid; |
| 189 | int useSha1sum = find_option("sha1sum", 0, 0)!=0; |
| @@ -223,11 +223,11 @@ | |
| 223 | ** --rel-paths Display pathnames relative to the current working |
| 224 | ** directory. |
| 225 | ** --sha1sum Verify file status using SHA1 hashing rather |
| 226 | ** than relying on file mtimes. |
| 227 | ** |
| 228 | ** See also: changes, extras, ls |
| 229 | */ |
| 230 | void status_cmd(void){ |
| 231 | int vid; |
| 232 | db_must_be_within_tree(); |
| 233 | /* 012345678901234 */ |
| @@ -255,11 +255,11 @@ | |
| 255 | ** |
| 256 | ** Options: |
| 257 | ** --age Show when each file was committed |
| 258 | ** -v|--verbose Provide extra information about each file. |
| 259 | ** |
| 260 | ** See also: changes, extras, status |
| 261 | */ |
| 262 | void ls_cmd(void){ |
| 263 | int vid; |
| 264 | Stmt q; |
| 265 | int verboseFlag; |
| @@ -433,20 +433,22 @@ | |
| 433 | ** |
| 434 | ** Options: |
| 435 | ** --abs-paths Display absolute pathnames. |
| 436 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 437 | ** --dotfiles include files beginning with a dot (".") |
| 438 | ** --header Identify the repository if there are extras |
| 439 | ** --ignore <CSG> ignore files matching patterns from the argument |
| 440 | ** --rel-paths Display pathnames relative to the current working |
| 441 | ** directory. |
| 442 | ** |
| 443 | ** See also: changes, clean, status |
| 444 | */ |
| 445 | void extras_cmd(void){ |
| 446 | Stmt q; |
| 447 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 448 | unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0; |
| 449 | int showHdr = find_option("header",0,0)!=0; |
| 450 | int cwdRelative = 0; |
| 451 | Glob *pIgnore; |
| 452 | Blob rewrittenPathname; |
| 453 | const char *zPathname, *zDisplayName; |
| 454 | |
| @@ -477,10 +479,15 @@ | |
| 479 | zDisplayName = blob_str(&rewrittenPathname); |
| 480 | if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){ |
| 481 | zDisplayName += 2; /* no unnecessary ./ prefix */ |
| 482 | } |
| 483 | } |
| 484 | if( showHdr ){ |
| 485 | showHdr = 0; |
| 486 | fossil_print("Extras for %s at %s:\n", db_get("project-name","???"), |
| 487 | g.zLocalRoot); |
| 488 | } |
| 489 | fossil_print("%s\n", zDisplayName); |
| 490 | } |
| 491 | blob_reset(&rewrittenPathname); |
| 492 | db_finalize(&q); |
| 493 | } |
| @@ -536,11 +543,11 @@ | |
| 543 | ** list of glob patterns. |
| 544 | ** -n|--dry-run If given, display instead of run actions. |
| 545 | ** --temp Remove only Fossil-generated temporary files. |
| 546 | ** -v|--verbose Show all files as they are removed. |
| 547 | ** |
| 548 | ** See also: addremove, extras, status |
| 549 | */ |
| 550 | void clean_cmd(void){ |
| 551 | int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; |
| 552 | int emptyDirsFlag, dirsOnlyFlag; |
| 553 | unsigned scanFlags = 0; |
| @@ -1301,21 +1308,25 @@ | |
| 1308 | char *zOrig = file_newname(zFilename, "original", 1); |
| 1309 | FILE *f; |
| 1310 | blob_write_to_file(p, zOrig); |
| 1311 | fossil_free(zOrig); |
| 1312 | f = fossil_fopen(zFilename, "wb"); |
| 1313 | if( f==0 ){ |
| 1314 | fossil_warning("cannot open %s for writing", zFilename); |
| 1315 | }else{ |
| 1316 | if( fUnicode ) { |
| 1317 | int bomSize; |
| 1318 | const unsigned char *bom = get_utf8_bom(&bomSize); |
| 1319 | fwrite(bom, 1, bomSize, f); |
| 1320 | blob_to_utf8_no_bom(p, 0); |
| 1321 | } |
| 1322 | if( fHasAnyCr ){ |
| 1323 | blob_to_lf_only(p); |
| 1324 | } |
| 1325 | fwrite(blob_buffer(p), 1, blob_size(p), f); |
| 1326 | fclose(f); |
| 1327 | } |
| 1328 | return 1; |
| 1329 | }else if( cReply!='y' && cReply!='Y' ){ |
| 1330 | fossil_fatal("Abandoning commit due to %s in %s", |
| 1331 | zWarning, blob_str(&fname)); |
| 1332 | } |
| @@ -1408,11 +1419,11 @@ | |
| 1419 | ** --private do not sync changes and their descendants |
| 1420 | ** --sha1sum verify file status using SHA1 hashing rather |
| 1421 | ** than relying on file mtimes |
| 1422 | ** --tag TAG-NAME assign given tag TAG-NAME to the checkin |
| 1423 | ** |
| 1424 | ** See also: branch, changes, checkout, extras, sync |
| 1425 | */ |
| 1426 | void commit_cmd(void){ |
| 1427 | int hasChanges; /* True if unsaved changes exist */ |
| 1428 | int vid; /* blob-id of parent version */ |
| 1429 | int nrid; /* blob-id of a modified file */ |
| 1430 |
+6
-6
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -136,13 +136,13 @@ | ||
| 136 | 136 | if( file_size(g.argv[3])>0 ){ |
| 137 | 137 | fossil_fatal("file already exists: %s", g.argv[3]); |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | url_parse(g.argv[2], urlFlags); |
| 141 | - if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser; | |
| 142 | - if( g.urlIsFile ){ | |
| 143 | - file_copy(g.urlName, g.argv[3]); | |
| 141 | + if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user; | |
| 142 | + if( g.url.isFile ){ | |
| 143 | + file_copy(g.url.name, g.argv[3]); | |
| 144 | 144 | db_close(1); |
| 145 | 145 | db_open_repository(g.argv[3]); |
| 146 | 146 | db_record_repository_filename(g.argv[3]); |
| 147 | 147 | url_remember(); |
| 148 | 148 | if( !bPrivate ) delete_private_content(); |
| @@ -211,11 +211,11 @@ | ||
| 211 | 211 | void remember_or_get_http_auth( |
| 212 | 212 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| 213 | 213 | int fRemember, /* True to remember credentials for later reuse */ |
| 214 | 214 | const char *zUrl /* URL for which these credentials apply */ |
| 215 | 215 | ){ |
| 216 | - char *zKey = mprintf("http-auth:%s", g.urlCanonical); | |
| 216 | + char *zKey = mprintf("http-auth:%s", g.url.canonical); | |
| 217 | 217 | if( zHttpAuth && zHttpAuth[0] ){ |
| 218 | 218 | g.zHttpAuth = mprintf("%s", zHttpAuth); |
| 219 | 219 | } |
| 220 | 220 | if( fRemember ){ |
| 221 | 221 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| @@ -233,20 +233,20 @@ | ||
| 233 | 233 | |
| 234 | 234 | /* |
| 235 | 235 | ** Get the HTTP Authorization preference from db. |
| 236 | 236 | */ |
| 237 | 237 | char *get_httpauth(void){ |
| 238 | - char *zKey = mprintf("http-auth:%s", g.urlCanonical); | |
| 238 | + char *zKey = mprintf("http-auth:%s", g.url.canonical); | |
| 239 | 239 | return unobscure(db_get(zKey, 0)); |
| 240 | 240 | free(zKey); |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | 243 | /* |
| 244 | 244 | ** Set the HTTP Authorization preference in db. |
| 245 | 245 | */ |
| 246 | 246 | void set_httpauth(const char *zHttpAuth){ |
| 247 | - char *zKey = mprintf("http-auth:%s", g.urlCanonical); | |
| 247 | + char *zKey = mprintf("http-auth:%s", g.url.canonical); | |
| 248 | 248 | db_set(zKey, obscure(zHttpAuth), 0); |
| 249 | 249 | free(zKey); |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | /* |
| 253 | 253 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -136,13 +136,13 @@ | |
| 136 | if( file_size(g.argv[3])>0 ){ |
| 137 | fossil_fatal("file already exists: %s", g.argv[3]); |
| 138 | } |
| 139 | |
| 140 | url_parse(g.argv[2], urlFlags); |
| 141 | if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser; |
| 142 | if( g.urlIsFile ){ |
| 143 | file_copy(g.urlName, g.argv[3]); |
| 144 | db_close(1); |
| 145 | db_open_repository(g.argv[3]); |
| 146 | db_record_repository_filename(g.argv[3]); |
| 147 | url_remember(); |
| 148 | if( !bPrivate ) delete_private_content(); |
| @@ -211,11 +211,11 @@ | |
| 211 | void remember_or_get_http_auth( |
| 212 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| 213 | int fRemember, /* True to remember credentials for later reuse */ |
| 214 | const char *zUrl /* URL for which these credentials apply */ |
| 215 | ){ |
| 216 | char *zKey = mprintf("http-auth:%s", g.urlCanonical); |
| 217 | if( zHttpAuth && zHttpAuth[0] ){ |
| 218 | g.zHttpAuth = mprintf("%s", zHttpAuth); |
| 219 | } |
| 220 | if( fRemember ){ |
| 221 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| @@ -233,20 +233,20 @@ | |
| 233 | |
| 234 | /* |
| 235 | ** Get the HTTP Authorization preference from db. |
| 236 | */ |
| 237 | char *get_httpauth(void){ |
| 238 | char *zKey = mprintf("http-auth:%s", g.urlCanonical); |
| 239 | return unobscure(db_get(zKey, 0)); |
| 240 | free(zKey); |
| 241 | } |
| 242 | |
| 243 | /* |
| 244 | ** Set the HTTP Authorization preference in db. |
| 245 | */ |
| 246 | void set_httpauth(const char *zHttpAuth){ |
| 247 | char *zKey = mprintf("http-auth:%s", g.urlCanonical); |
| 248 | db_set(zKey, obscure(zHttpAuth), 0); |
| 249 | free(zKey); |
| 250 | } |
| 251 | |
| 252 | /* |
| 253 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -136,13 +136,13 @@ | |
| 136 | if( file_size(g.argv[3])>0 ){ |
| 137 | fossil_fatal("file already exists: %s", g.argv[3]); |
| 138 | } |
| 139 | |
| 140 | url_parse(g.argv[2], urlFlags); |
| 141 | if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user; |
| 142 | if( g.url.isFile ){ |
| 143 | file_copy(g.url.name, g.argv[3]); |
| 144 | db_close(1); |
| 145 | db_open_repository(g.argv[3]); |
| 146 | db_record_repository_filename(g.argv[3]); |
| 147 | url_remember(); |
| 148 | if( !bPrivate ) delete_private_content(); |
| @@ -211,11 +211,11 @@ | |
| 211 | void remember_or_get_http_auth( |
| 212 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| 213 | int fRemember, /* True to remember credentials for later reuse */ |
| 214 | const char *zUrl /* URL for which these credentials apply */ |
| 215 | ){ |
| 216 | char *zKey = mprintf("http-auth:%s", g.url.canonical); |
| 217 | if( zHttpAuth && zHttpAuth[0] ){ |
| 218 | g.zHttpAuth = mprintf("%s", zHttpAuth); |
| 219 | } |
| 220 | if( fRemember ){ |
| 221 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| @@ -233,20 +233,20 @@ | |
| 233 | |
| 234 | /* |
| 235 | ** Get the HTTP Authorization preference from db. |
| 236 | */ |
| 237 | char *get_httpauth(void){ |
| 238 | char *zKey = mprintf("http-auth:%s", g.url.canonical); |
| 239 | return unobscure(db_get(zKey, 0)); |
| 240 | free(zKey); |
| 241 | } |
| 242 | |
| 243 | /* |
| 244 | ** Set the HTTP Authorization preference in db. |
| 245 | */ |
| 246 | void set_httpauth(const char *zHttpAuth){ |
| 247 | char *zKey = mprintf("http-auth:%s", g.url.canonical); |
| 248 | db_set(zKey, obscure(zHttpAuth), 0); |
| 249 | free(zKey); |
| 250 | } |
| 251 | |
| 252 | /* |
| 253 |
+1
| --- src/comformat.c | ||
| +++ src/comformat.c | ||
| @@ -36,10 +36,11 @@ | ||
| 36 | 36 | int doIndent = 0; |
| 37 | 37 | char *zBuf; |
| 38 | 38 | char zBuffer[400]; |
| 39 | 39 | int lineCnt = 0; |
| 40 | 40 | |
| 41 | + if( zText==0 ) zText = "(NULL)"; | |
| 41 | 42 | if( tlen<=0 ){ |
| 42 | 43 | tlen = strlen(zText); |
| 43 | 44 | } |
| 44 | 45 | if( tlen >= (sizeof(zBuffer)) ){ |
| 45 | 46 | zBuf = fossil_malloc(tlen+1); |
| 46 | 47 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -36,10 +36,11 @@ | |
| 36 | int doIndent = 0; |
| 37 | char *zBuf; |
| 38 | char zBuffer[400]; |
| 39 | int lineCnt = 0; |
| 40 | |
| 41 | if( tlen<=0 ){ |
| 42 | tlen = strlen(zText); |
| 43 | } |
| 44 | if( tlen >= (sizeof(zBuffer)) ){ |
| 45 | zBuf = fossil_malloc(tlen+1); |
| 46 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -36,10 +36,11 @@ | |
| 36 | int doIndent = 0; |
| 37 | char *zBuf; |
| 38 | char zBuffer[400]; |
| 39 | int lineCnt = 0; |
| 40 | |
| 41 | if( zText==0 ) zText = "(NULL)"; |
| 42 | if( tlen<=0 ){ |
| 43 | tlen = strlen(zText); |
| 44 | } |
| 45 | if( tlen >= (sizeof(zBuffer)) ){ |
| 46 | zBuf = fossil_malloc(tlen+1); |
| 47 |
+1
-1
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -924,11 +924,11 @@ | ||
| 924 | 924 | mask = configure_name_to_mask(g.argv[3], 1); |
| 925 | 925 | if( g.argc==5 ){ |
| 926 | 926 | zServer = g.argv[4]; |
| 927 | 927 | } |
| 928 | 928 | url_parse(zServer, URL_PROMPT_PW); |
| 929 | - if( g.urlProtocol==0 ) fossil_fatal("no server URL specified"); | |
| 929 | + if( g.url.protocol==0 ) fossil_fatal("no server URL specified"); | |
| 930 | 930 | user_select(); |
| 931 | 931 | url_enable_proxy("via proxy: "); |
| 932 | 932 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 933 | 933 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 934 | 934 | if( strncmp(zMethod, "push", n)==0 ){ |
| 935 | 935 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -924,11 +924,11 @@ | |
| 924 | mask = configure_name_to_mask(g.argv[3], 1); |
| 925 | if( g.argc==5 ){ |
| 926 | zServer = g.argv[4]; |
| 927 | } |
| 928 | url_parse(zServer, URL_PROMPT_PW); |
| 929 | if( g.urlProtocol==0 ) fossil_fatal("no server URL specified"); |
| 930 | user_select(); |
| 931 | url_enable_proxy("via proxy: "); |
| 932 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 933 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 934 | if( strncmp(zMethod, "push", n)==0 ){ |
| 935 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -924,11 +924,11 @@ | |
| 924 | mask = configure_name_to_mask(g.argv[3], 1); |
| 925 | if( g.argc==5 ){ |
| 926 | zServer = g.argv[4]; |
| 927 | } |
| 928 | url_parse(zServer, URL_PROMPT_PW); |
| 929 | if( g.url.protocol==0 ) fossil_fatal("no server URL specified"); |
| 930 | user_select(); |
| 931 | url_enable_proxy("via proxy: "); |
| 932 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 933 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 934 | if( strncmp(zMethod, "push", n)==0 ){ |
| 935 |
M
src/db.c
+1
-5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -715,11 +715,11 @@ | ||
| 715 | 715 | */ |
| 716 | 716 | LOCAL sqlite3 *db_open(const char *zDbName){ |
| 717 | 717 | int rc; |
| 718 | 718 | sqlite3 *db; |
| 719 | 719 | |
| 720 | -#if defined(__CYGWIN__) && !defined(USE_SYSTEM_SQLITE) | |
| 720 | +#if defined(__CYGWIN__) && USE_SYSTEM_SQLITE+0!=1 | |
| 721 | 721 | zDbName = fossil_utf8_to_filename(zDbName); |
| 722 | 722 | #endif |
| 723 | 723 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 724 | 724 | rc = sqlite3_open_v2( |
| 725 | 725 | zDbName, &db, |
| @@ -1022,15 +1022,11 @@ | ||
| 1022 | 1022 | g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; |
| 1023 | 1023 | #endif |
| 1024 | 1024 | fossil_panic("not a valid repository: %s", zDbName); |
| 1025 | 1025 | } |
| 1026 | 1026 | } |
| 1027 | -#if defined(__CYGWIN__) | |
| 1028 | - g.zRepositoryName = fossil_utf8_to_filename(zDbName); | |
| 1029 | -#else | |
| 1030 | 1027 | g.zRepositoryName = mprintf("%s", zDbName); |
| 1031 | -#endif | |
| 1032 | 1028 | db_open_or_attach(g.zRepositoryName, "repository", 0); |
| 1033 | 1029 | g.repositoryOpen = 1; |
| 1034 | 1030 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1035 | 1031 | g.allowSymlinks = db_get_boolean("allow-symlinks", 0); |
| 1036 | 1032 | } |
| 1037 | 1033 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -715,11 +715,11 @@ | |
| 715 | */ |
| 716 | LOCAL sqlite3 *db_open(const char *zDbName){ |
| 717 | int rc; |
| 718 | sqlite3 *db; |
| 719 | |
| 720 | #if defined(__CYGWIN__) && !defined(USE_SYSTEM_SQLITE) |
| 721 | zDbName = fossil_utf8_to_filename(zDbName); |
| 722 | #endif |
| 723 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 724 | rc = sqlite3_open_v2( |
| 725 | zDbName, &db, |
| @@ -1022,15 +1022,11 @@ | |
| 1022 | g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; |
| 1023 | #endif |
| 1024 | fossil_panic("not a valid repository: %s", zDbName); |
| 1025 | } |
| 1026 | } |
| 1027 | #if defined(__CYGWIN__) |
| 1028 | g.zRepositoryName = fossil_utf8_to_filename(zDbName); |
| 1029 | #else |
| 1030 | g.zRepositoryName = mprintf("%s", zDbName); |
| 1031 | #endif |
| 1032 | db_open_or_attach(g.zRepositoryName, "repository", 0); |
| 1033 | g.repositoryOpen = 1; |
| 1034 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1035 | g.allowSymlinks = db_get_boolean("allow-symlinks", 0); |
| 1036 | } |
| 1037 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -715,11 +715,11 @@ | |
| 715 | */ |
| 716 | LOCAL sqlite3 *db_open(const char *zDbName){ |
| 717 | int rc; |
| 718 | sqlite3 *db; |
| 719 | |
| 720 | #if defined(__CYGWIN__) && USE_SYSTEM_SQLITE+0!=1 |
| 721 | zDbName = fossil_utf8_to_filename(zDbName); |
| 722 | #endif |
| 723 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 724 | rc = sqlite3_open_v2( |
| 725 | zDbName, &db, |
| @@ -1022,15 +1022,11 @@ | |
| 1022 | g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; |
| 1023 | #endif |
| 1024 | fossil_panic("not a valid repository: %s", zDbName); |
| 1025 | } |
| 1026 | } |
| 1027 | g.zRepositoryName = mprintf("%s", zDbName); |
| 1028 | db_open_or_attach(g.zRepositoryName, "repository", 0); |
| 1029 | g.repositoryOpen = 1; |
| 1030 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1031 | g.allowSymlinks = db_get_boolean("allow-symlinks", 0); |
| 1032 | } |
| 1033 |
+1
-1
| --- src/delta.c | ||
| +++ src/delta.c | ||
| @@ -467,11 +467,11 @@ | ||
| 467 | 467 | zDelta += lenOut-base; |
| 468 | 468 | } |
| 469 | 469 | /* Output the final checksum record. */ |
| 470 | 470 | putInt(checksum(zOut, lenOut), &zDelta); |
| 471 | 471 | *(zDelta++) = ';'; |
| 472 | - free(collide); | |
| 472 | + fossil_free(collide); | |
| 473 | 473 | return zDelta - zOrigDelta; |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | /* |
| 477 | 477 | ** Return the size (in bytes) of the output from applying |
| 478 | 478 |
| --- src/delta.c | |
| +++ src/delta.c | |
| @@ -467,11 +467,11 @@ | |
| 467 | zDelta += lenOut-base; |
| 468 | } |
| 469 | /* Output the final checksum record. */ |
| 470 | putInt(checksum(zOut, lenOut), &zDelta); |
| 471 | *(zDelta++) = ';'; |
| 472 | free(collide); |
| 473 | return zDelta - zOrigDelta; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | ** Return the size (in bytes) of the output from applying |
| 478 |
| --- src/delta.c | |
| +++ src/delta.c | |
| @@ -467,11 +467,11 @@ | |
| 467 | zDelta += lenOut-base; |
| 468 | } |
| 469 | /* Output the final checksum record. */ |
| 470 | putInt(checksum(zOut, lenOut), &zDelta); |
| 471 | *(zDelta++) = ';'; |
| 472 | fossil_free(collide); |
| 473 | return zDelta - zOrigDelta; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | ** Return the size (in bytes) of the output from applying |
| 478 |
+100
-44
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -32,18 +32,18 @@ | ||
| 32 | 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 35 | 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 36 | 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 37 | -#define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ | |
| 38 | 37 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| 39 | 38 | #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */ |
| 40 | 39 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 41 | 40 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 42 | 41 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 43 | 42 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 44 | 43 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 44 | +#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ | |
| 45 | 45 | |
| 46 | 46 | /* |
| 47 | 47 | ** These error messages are shared in multiple locations. They are defined |
| 48 | 48 | ** here for consistency. |
| 49 | 49 | */ |
| @@ -89,11 +89,11 @@ | ||
| 89 | 89 | }; |
| 90 | 90 | |
| 91 | 91 | /* |
| 92 | 92 | ** Length of a dline |
| 93 | 93 | */ |
| 94 | -#define LENGTH(X) ((X)->h & LENGTH_MASK) | |
| 94 | +#define LENGTH(X) ((X)->n) | |
| 95 | 95 | |
| 96 | 96 | /* |
| 97 | 97 | ** A context for running a raw diff. |
| 98 | 98 | ** |
| 99 | 99 | ** The aEdit[] array describes the raw diff. Each triple of integers in |
| @@ -113,10 +113,11 @@ | ||
| 113 | 113 | int nEditAlloc; /* Space allocated for aEdit[] */ |
| 114 | 114 | DLine *aFrom; /* File on left side of the diff */ |
| 115 | 115 | int nFrom; /* Number of lines in aFrom[] */ |
| 116 | 116 | DLine *aTo; /* File on right side of the diff */ |
| 117 | 117 | int nTo; /* Number of lines in aTo[] */ |
| 118 | + int (*same_fn)(const DLine *, const DLine *); /* Function to be used for comparing */ | |
| 118 | 119 | }; |
| 119 | 120 | |
| 120 | 121 | /* |
| 121 | 122 | ** Return an array of DLine objects containing a pointer to the |
| 122 | 123 | ** start of each line and a hash of that line. The lower |
| @@ -165,22 +166,36 @@ | ||
| 165 | 166 | |
| 166 | 167 | /* Fill in the array */ |
| 167 | 168 | for(i=0; i<nLine; i++){ |
| 168 | 169 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | 170 | a[i].z = z; |
| 170 | - a[i].n = k = j; | |
| 171 | + k = j; | |
| 172 | + if( diffFlags & DIFF_STRIP_EOLCR ){ | |
| 173 | + if( k>0 && z[k-1]=='\r' ){ k--; } | |
| 174 | + } | |
| 175 | + a[i].n = k; | |
| 171 | 176 | s = 0; |
| 172 | 177 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 173 | 178 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 174 | 179 | } |
| 175 | 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 181 | + int numws = 0; | |
| 176 | 182 | while( s<k && fossil_isspace(z[s]) ){ s++; } |
| 183 | + for(h=0, x=s; x<k; x++){ | |
| 184 | + if( fossil_isspace(z[x]) ){ | |
| 185 | + ++numws; | |
| 186 | + }else{ | |
| 187 | + h = h ^ (h<<2) ^ z[x]; | |
| 188 | + } | |
| 189 | + } | |
| 190 | + k -= numws; | |
| 191 | + }else{ | |
| 192 | + for(h=0, x=s; x<k; x++){ | |
| 193 | + h = h ^ (h<<2) ^ z[x]; | |
| 194 | + } | |
| 177 | 195 | } |
| 178 | 196 | a[i].indent = s; |
| 179 | - for(h=0, x=s; x<k; x++){ | |
| 180 | - h = h ^ (h<<2) ^ z[x]; | |
| 181 | - } | |
| 182 | 197 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 183 | 198 | h2 = h % nLine; |
| 184 | 199 | a[i].iNext = a[h2].iHash; |
| 185 | 200 | a[h2].iHash = i+1; |
| 186 | 201 | z += j+1; |
| @@ -192,13 +207,31 @@ | ||
| 192 | 207 | } |
| 193 | 208 | |
| 194 | 209 | /* |
| 195 | 210 | ** Return true if two DLine elements are identical. |
| 196 | 211 | */ |
| 197 | -static int same_dline(DLine *pA, DLine *pB){ | |
| 198 | - return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent, | |
| 199 | - pA->h & LENGTH_MASK)==0; | |
| 212 | +static int same_dline(const DLine *pA, const DLine *pB){ | |
| 213 | + return pA->h==pB->h && memcmp(pA->z,pB->z, pA->h&LENGTH_MASK)==0; | |
| 214 | +} | |
| 215 | + | |
| 216 | +/* | |
| 217 | +** Return true if two DLine elements are identical, ignoring | |
| 218 | +** all whitespace. The indent field of pA/pB already points | |
| 219 | +** to the first non-space character in the string. | |
| 220 | +*/ | |
| 221 | + | |
| 222 | +static int same_dline_ignore_allws(const DLine *pA, const DLine *pB){ | |
| 223 | + int a = pA->indent, b = pB->indent; | |
| 224 | + if( pA->h==pB->h ){ | |
| 225 | + while( a<pA->n && b<pB->n ){ | |
| 226 | + if( pA->z[a++] != pB->z[b++] ) return 0; | |
| 227 | + while( a<pA->n && fossil_isspace(pA->z[a])) ++a; | |
| 228 | + while( b<pB->n && fossil_isspace(pB->z[b])) ++b; | |
| 229 | + } | |
| 230 | + return pA->n-a == pB->n-b; | |
| 231 | + } | |
| 232 | + return 0; | |
| 200 | 233 | } |
| 201 | 234 | |
| 202 | 235 | /* |
| 203 | 236 | ** Return true if the regular expression *pRe matches any of the |
| 204 | 237 | ** N dlines |
| @@ -733,13 +766,13 @@ | ||
| 733 | 766 | int aLCS[4]; /* Bounds of common middle segment */ |
| 734 | 767 | static const char zClassRm[] = "<span class=\"diffrm\">"; |
| 735 | 768 | static const char zClassAdd[] = "<span class=\"diffadd\">"; |
| 736 | 769 | static const char zClassChng[] = "<span class=\"diffchng\">"; |
| 737 | 770 | |
| 738 | - nLeft = pLeft->h & LENGTH_MASK; | |
| 771 | + nLeft = pLeft->n; | |
| 739 | 772 | zLeft = pLeft->z; |
| 740 | - nRight = pRight->h & LENGTH_MASK; | |
| 773 | + nRight = pRight->n; | |
| 741 | 774 | zRight = pRight->z; |
| 742 | 775 | nShort = nLeft<nRight ? nLeft : nRight; |
| 743 | 776 | |
| 744 | 777 | nPrefix = 0; |
| 745 | 778 | while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){ |
| @@ -881,12 +914,12 @@ | ||
| 881 | 914 | unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */ |
| 882 | 915 | unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */ |
| 883 | 916 | |
| 884 | 917 | zA = pA->z; |
| 885 | 918 | zB = pB->z; |
| 886 | - nA = pA->h & LENGTH_MASK; | |
| 887 | - nB = pB->h & LENGTH_MASK; | |
| 919 | + nA = pA->n; | |
| 920 | + nB = pB->n; | |
| 888 | 921 | while( nA>0 && fossil_isspace(zA[0]) ){ nA--; zA++; } |
| 889 | 922 | while( nA>0 && fossil_isspace(zA[nA-1]) ){ nA--; } |
| 890 | 923 | while( nB>0 && fossil_isspace(zB[0]) ){ nB--; zB++; } |
| 891 | 924 | while( nB>0 && fossil_isspace(zB[nB-1]) ){ nB--; } |
| 892 | 925 | if( nA>250 ) nA = 250; |
| @@ -1350,16 +1383,16 @@ | ||
| 1350 | 1383 | int iSXb = iS1; /* Best match so far */ |
| 1351 | 1384 | int iSYb = iS2; /* Best match so far */ |
| 1352 | 1385 | |
| 1353 | 1386 | for(i=iS1; i<iE1-mxLength; i++){ |
| 1354 | 1387 | for(j=iS2; j<iE2-mxLength; j++){ |
| 1355 | - if( !same_dline(&p->aFrom[i], &p->aTo[j]) ) continue; | |
| 1356 | - if( mxLength && !same_dline(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ | |
| 1388 | + if( !p->same_fn(&p->aFrom[i], &p->aTo[j]) ) continue; | |
| 1389 | + if( mxLength && !p->same_fn(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ | |
| 1357 | 1390 | continue; |
| 1358 | 1391 | } |
| 1359 | 1392 | k = 1; |
| 1360 | - while( i+k<iE1 && j+k<iE2 && same_dline(&p->aFrom[i+k],&p->aTo[j+k]) ){ | |
| 1393 | + while( i+k<iE1 && j+k<iE2 && p->same_fn(&p->aFrom[i+k],&p->aTo[j+k]) ){ | |
| 1361 | 1394 | k++; |
| 1362 | 1395 | } |
| 1363 | 1396 | if( k>mxLength ){ |
| 1364 | 1397 | iSXb = i; |
| 1365 | 1398 | iSYb = j; |
| @@ -1421,11 +1454,11 @@ | ||
| 1421 | 1454 | mid = (iE1 + iS1)/2; |
| 1422 | 1455 | for(i=iS1; i<iE1; i++){ |
| 1423 | 1456 | int limit = 0; |
| 1424 | 1457 | j = p->aTo[p->aFrom[i].h % p->nTo].iHash; |
| 1425 | 1458 | while( j>0 |
| 1426 | - && (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1])) | |
| 1459 | + && (j-1<iS2 || j>=iE2 || !p->same_fn(&p->aFrom[i], &p->aTo[j-1])) | |
| 1427 | 1460 | ){ |
| 1428 | 1461 | if( limit++ > 10 ){ |
| 1429 | 1462 | j = 0; |
| 1430 | 1463 | break; |
| 1431 | 1464 | } |
| @@ -1438,19 +1471,19 @@ | ||
| 1438 | 1471 | iSX = i; |
| 1439 | 1472 | iSY = j-1; |
| 1440 | 1473 | pA = &p->aFrom[iSX-1]; |
| 1441 | 1474 | pB = &p->aTo[iSY-1]; |
| 1442 | 1475 | n = minInt(iSX-iS1, iSY-iS2); |
| 1443 | - for(k=0; k<n && same_dline(pA,pB); k++, pA--, pB--){} | |
| 1476 | + for(k=0; k<n && p->same_fn(pA,pB); k++, pA--, pB--){} | |
| 1444 | 1477 | iSX -= k; |
| 1445 | 1478 | iSY -= k; |
| 1446 | 1479 | iEX = i+1; |
| 1447 | 1480 | iEY = j; |
| 1448 | 1481 | pA = &p->aFrom[iEX]; |
| 1449 | 1482 | pB = &p->aTo[iEY]; |
| 1450 | 1483 | n = minInt(iE1-iEX, iE2-iEY); |
| 1451 | - for(k=0; k<n && same_dline(pA,pB); k++, pA++, pB++){} | |
| 1484 | + for(k=0; k<n && p->same_fn(pA,pB); k++, pA++, pB++){} | |
| 1452 | 1485 | iEX += k; |
| 1453 | 1486 | iEY += k; |
| 1454 | 1487 | skew = (iSX-iS1) - (iSY-iS2); |
| 1455 | 1488 | if( skew<0 ) skew = -skew; |
| 1456 | 1489 | dist = (iSX+iEX)/2 - mid; |
| @@ -1587,16 +1620,16 @@ | ||
| 1587 | 1620 | int mnE, iS, iE1, iE2; |
| 1588 | 1621 | |
| 1589 | 1622 | /* Carve off the common header and footer */ |
| 1590 | 1623 | iE1 = p->nFrom; |
| 1591 | 1624 | iE2 = p->nTo; |
| 1592 | - while( iE1>0 && iE2>0 && same_dline(&p->aFrom[iE1-1], &p->aTo[iE2-1]) ){ | |
| 1625 | + while( iE1>0 && iE2>0 && p->same_fn(&p->aFrom[iE1-1], &p->aTo[iE2-1]) ){ | |
| 1593 | 1626 | iE1--; |
| 1594 | 1627 | iE2--; |
| 1595 | 1628 | } |
| 1596 | 1629 | mnE = iE1<iE2 ? iE1 : iE2; |
| 1597 | - for(iS=0; iS<mnE && same_dline(&p->aFrom[iS],&p->aTo[iS]); iS++){} | |
| 1630 | + for(iS=0; iS<mnE && p->same_fn(&p->aFrom[iS],&p->aTo[iS]); iS++){} | |
| 1598 | 1631 | |
| 1599 | 1632 | /* do the difference */ |
| 1600 | 1633 | if( iS>0 ){ |
| 1601 | 1634 | appendTriple(p, iS, 0, 0); |
| 1602 | 1635 | } |
| @@ -1661,11 +1694,11 @@ | ||
| 1661 | 1694 | |
| 1662 | 1695 | /* Shift insertions toward the beginning of the file */ |
| 1663 | 1696 | while( cpy>0 && del==0 && ins>0 ){ |
| 1664 | 1697 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */ |
| 1665 | 1698 | DLine *pBtm = &p->aTo[lnTo+ins-1]; /* Last line inserted */ |
| 1666 | - if( same_dline(pTop, pBtm)==0 ) break; | |
| 1699 | + if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1667 | 1700 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1668 | 1701 | lnFrom--; |
| 1669 | 1702 | lnTo--; |
| 1670 | 1703 | p->aEdit[r]--; |
| 1671 | 1704 | p->aEdit[r+3]++; |
| @@ -1674,11 +1707,11 @@ | ||
| 1674 | 1707 | |
| 1675 | 1708 | /* Shift insertions toward the end of the file */ |
| 1676 | 1709 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){ |
| 1677 | 1710 | DLine *pTop = &p->aTo[lnTo]; /* First line inserted */ |
| 1678 | 1711 | DLine *pBtm = &p->aTo[lnTo+ins]; /* First line past end of insert */ |
| 1679 | - if( same_dline(pTop, pBtm)==0 ) break; | |
| 1712 | + if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1680 | 1713 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break; |
| 1681 | 1714 | lnFrom++; |
| 1682 | 1715 | lnTo++; |
| 1683 | 1716 | p->aEdit[r]++; |
| 1684 | 1717 | p->aEdit[r+3]--; |
| @@ -1687,11 +1720,11 @@ | ||
| 1687 | 1720 | |
| 1688 | 1721 | /* Shift deletions toward the beginning of the file */ |
| 1689 | 1722 | while( cpy>0 && del>0 && ins==0 ){ |
| 1690 | 1723 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */ |
| 1691 | 1724 | DLine *pBtm = &p->aFrom[lnFrom+del-1]; /* Last line deleted */ |
| 1692 | - if( same_dline(pTop, pBtm)==0 ) break; | |
| 1725 | + if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1693 | 1726 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1694 | 1727 | lnFrom--; |
| 1695 | 1728 | lnTo--; |
| 1696 | 1729 | p->aEdit[r]--; |
| 1697 | 1730 | p->aEdit[r+3]++; |
| @@ -1700,11 +1733,11 @@ | ||
| 1700 | 1733 | |
| 1701 | 1734 | /* Shift deletions toward the end of the file */ |
| 1702 | 1735 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){ |
| 1703 | 1736 | DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */ |
| 1704 | 1737 | DLine *pBtm = &p->aFrom[lnFrom+del]; /* First line past end of delete */ |
| 1705 | - if( same_dline(pTop, pBtm)==0 ) break; | |
| 1738 | + if( p->same_fn(pTop, pBtm)==0 ) break; | |
| 1706 | 1739 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break; |
| 1707 | 1740 | lnFrom++; |
| 1708 | 1741 | lnTo++; |
| 1709 | 1742 | p->aEdit[r]++; |
| 1710 | 1743 | p->aEdit[r+3]--; |
| @@ -1780,10 +1813,15 @@ | ||
| 1780 | 1813 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1781 | 1814 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1782 | 1815 | |
| 1783 | 1816 | /* Prepare the input files */ |
| 1784 | 1817 | memset(&c, 0, sizeof(c)); |
| 1818 | + if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ | |
| 1819 | + c.same_fn = same_dline_ignore_allws; | |
| 1820 | + }else{ | |
| 1821 | + c.same_fn = same_dline; | |
| 1822 | + } | |
| 1785 | 1823 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1786 | 1824 | &c.nFrom, diffFlags); |
| 1787 | 1825 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 1788 | 1826 | &c.nTo, diffFlags); |
| 1789 | 1827 | if( c.aFrom==0 || c.aTo==0 ){ |
| @@ -1850,20 +1888,30 @@ | ||
| 1850 | 1888 | ** -c|--context N N lines of context. DIFF_CONTEXT_MASK |
| 1851 | 1889 | ** --html Format for HTML DIFF_HTML |
| 1852 | 1890 | ** --invert Invert the diff DIFF_INVERT |
| 1853 | 1891 | ** -n|--linenum Show line numbers DIFF_LINENO |
| 1854 | 1892 | ** --noopt Disable optimization DIFF_NOOPT |
| 1893 | +** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR | |
| 1855 | 1894 | ** --unified Unified diff. ~DIFF_SIDEBYSIDE |
| 1856 | 1895 | ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS |
| 1857 | -** --width|-W N N character lines. DIFF_WIDTH_MASK | |
| 1896 | +** -W|--width N N character lines. DIFF_WIDTH_MASK | |
| 1858 | 1897 | ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE |
| 1859 | 1898 | ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS |
| 1860 | 1899 | */ |
| 1861 | 1900 | u64 diff_options(void){ |
| 1862 | 1901 | u64 diffFlags = 0; |
| 1863 | 1902 | const char *z; |
| 1864 | 1903 | int f; |
| 1904 | + if( find_option("ignore-trailing-space","Z",0)!=0 ){ | |
| 1905 | + diffFlags = DIFF_IGNORE_EOLWS; | |
| 1906 | + } | |
| 1907 | + if( find_option("ignore-all-space","w",0)!=0 ){ | |
| 1908 | + diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ | |
| 1909 | + } | |
| 1910 | + if( find_option("strip-trailing-cr",0,0)!=0 ){ | |
| 1911 | + diffFlags |= DIFF_STRIP_EOLCR; | |
| 1912 | + } | |
| 1865 | 1913 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1866 | 1914 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1867 | 1915 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1868 | 1916 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| 1869 | 1917 | diffFlags |= f + DIFF_CONTEXT_EX; |
| @@ -1872,12 +1920,10 @@ | ||
| 1872 | 1920 | f *= DIFF_CONTEXT_MASK+1; |
| 1873 | 1921 | if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK; |
| 1874 | 1922 | diffFlags |= f; |
| 1875 | 1923 | } |
| 1876 | 1924 | if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML; |
| 1877 | - if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags |= DIFF_IGNORE_EOLWS; | |
| 1878 | - if( find_option("ignore-all-space","w",0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS; | |
| 1879 | 1925 | if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO; |
| 1880 | 1926 | if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 1881 | 1927 | if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT; |
| 1882 | 1928 | if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF; |
| 1883 | 1929 | return diffFlags; |
| @@ -1954,11 +2000,11 @@ | ||
| 1954 | 2000 | typedef struct Annotator Annotator; |
| 1955 | 2001 | struct Annotator { |
| 1956 | 2002 | DContext c; /* The diff-engine context */ |
| 1957 | 2003 | struct AnnLine { /* Lines of the original files... */ |
| 1958 | 2004 | const char *z; /* The text of the line */ |
| 1959 | - short int n; /* Number of bytes (omitting trailing space and \n) */ | |
| 2005 | + short int n; /* Number of bytes (omitting trailing \n) */ | |
| 1960 | 2006 | short int iVers; /* Level at which tag was set */ |
| 1961 | 2007 | } *aOrig; |
| 1962 | 2008 | int nOrig; /* Number of elements in aOrig[] */ |
| 1963 | 2009 | int nVers; /* Number of versions analyzed */ |
| 1964 | 2010 | int bLimit; /* True if the iLimit was reached */ |
| @@ -1980,10 +2026,15 @@ | ||
| 1980 | 2026 | */ |
| 1981 | 2027 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 1982 | 2028 | int i; |
| 1983 | 2029 | |
| 1984 | 2030 | memset(p, 0, sizeof(*p)); |
| 2031 | + if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ | |
| 2032 | + p->c.same_fn = same_dline_ignore_allws; | |
| 2033 | + }else{ | |
| 2034 | + p->c.same_fn = same_dline; | |
| 2035 | + } | |
| 1985 | 2036 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 1986 | 2037 | diffFlags); |
| 1987 | 2038 | if( p->c.aTo==0 ){ |
| 1988 | 2039 | return 1; |
| 1989 | 2040 | } |
| @@ -2138,10 +2189,11 @@ | ||
| 2138 | 2189 | */ |
| 2139 | 2190 | unsigned gradient_color(unsigned c1, unsigned c2, int n, int i){ |
| 2140 | 2191 | unsigned c; /* Result color */ |
| 2141 | 2192 | unsigned x1, x2; |
| 2142 | 2193 | if( i==0 || n==0 ) return c1; |
| 2194 | + else if(i>=n) return c2; | |
| 2143 | 2195 | x1 = (c1>>16)&0xff; |
| 2144 | 2196 | x2 = (c2>>16)&0xff; |
| 2145 | 2197 | c = (x1*(n-i) + x2*i)/n<<16 & 0xff0000; |
| 2146 | 2198 | x1 = (c1>>8)&0xff; |
| 2147 | 2199 | x2 = (c2>>8)&0xff; |
| @@ -2168,11 +2220,11 @@ | ||
| 2168 | 2220 | void annotation_page(void){ |
| 2169 | 2221 | int mid; |
| 2170 | 2222 | int fnid; |
| 2171 | 2223 | int i; |
| 2172 | 2224 | int iLimit; /* Depth limit */ |
| 2173 | - u64 annFlags = ANN_FILE_ANCEST; | |
| 2225 | + u64 annFlags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); | |
| 2174 | 2226 | int showLog = 0; /* True to display the log */ |
| 2175 | 2227 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2176 | 2228 | const char *zFilename; /* Name of file to annotate */ |
| 2177 | 2229 | const char *zCI; /* The check-in containing zFilename */ |
| 2178 | 2230 | Annotator ann; |
| @@ -2255,17 +2307,17 @@ | ||
| 2255 | 2307 | clr = gradient_color(clr1, clr2, ann.nVers-1, i); |
| 2256 | 2308 | ann.aVers[i].zBgColor = mprintf("#%06x", clr); |
| 2257 | 2309 | } |
| 2258 | 2310 | |
| 2259 | 2311 | if( showLog ){ |
| 2260 | - char *zLink = href("%R/finfo?name=%t&ci=%S",zFilename,zCI); | |
| 2312 | + char *zLink = href("%R/finfo?name=%t&ci=%s",zFilename,zCI); | |
| 2261 | 2313 | @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> |
| 2262 | 2314 | @ <ol> |
| 2263 | 2315 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2264 | 2316 | @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) |
| 2265 | - @ check-in %z(href("%R/info/%S",p->zMUuid))%.10s(p->zMUuid)</a> | |
| 2266 | - @ artifact %z(href("%R/artifact/%S",p->zFUuid))%.10s(p->zFUuid)</a> | |
| 2317 | + @ check-in %z(href("%R/info/%s",p->zMUuid))%.10s(p->zMUuid)</a> | |
| 2318 | + @ artifact %z(href("%R/artifact/%s",p->zFUuid))%.10s(p->zFUuid)</a> | |
| 2267 | 2319 | @ </span> |
| 2268 | 2320 | #if 0 |
| 2269 | 2321 | if( i>0 ){ |
| 2270 | 2322 | char *zLink = xhref("target='infowindow'", |
| 2271 | 2323 | "%R/fdiff?v1=%S&v2=%S&sbs=1", |
| @@ -2283,17 +2335,17 @@ | ||
| 2283 | 2335 | @ </ol> |
| 2284 | 2336 | @ <hr> |
| 2285 | 2337 | } |
| 2286 | 2338 | if( !ann.bLimit ){ |
| 2287 | 2339 | @ <h2>Origin for each line in |
| 2288 | - @ %z(href("%R/finfo?name=%h&ci=%S", zFilename, zCI))%h(zFilename)</a> | |
| 2289 | - @ from check-in %z(href("%R/info/%S",zCI))%S(zCI)</a>:</h2> | |
| 2340 | + @ %z(href("%R/finfo?name=%h&ci=%s", zFilename, zCI))%h(zFilename)</a> | |
| 2341 | + @ from check-in %z(href("%R/info/%s",zCI))%S(zCI)</a>:</h2> | |
| 2290 | 2342 | iLimit = ann.nVers+10; |
| 2291 | 2343 | }else{ |
| 2292 | 2344 | @ <h2>Lines added by the %d(iLimit) most recent ancestors of |
| 2293 | - @ %z(href("%R/finfo?name=%h&ci=%S", zFilename, zCI))%h(zFilename)</a> | |
| 2294 | - @ from check-in %z(href("%R/info/%S",zCI))%S(zCI)</a>:</h2> | |
| 2345 | + @ %z(href("%R/finfo?name=%h&ci=%s", zFilename, zCI))%h(zFilename)</a> | |
| 2346 | + @ from check-in %z(href("%R/info/%s",zCI))%S(zCI)</a>:</h2> | |
| 2295 | 2347 | } |
| 2296 | 2348 | @ <pre> |
| 2297 | 2349 | for(i=0; i<ann.nOrig; i++){ |
| 2298 | 2350 | int iVers = ann.aOrig[i].iVers; |
| 2299 | 2351 | char *z = (char*)ann.aOrig[i].z; |
| @@ -2303,11 +2355,11 @@ | ||
| 2303 | 2355 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2304 | 2356 | |
| 2305 | 2357 | if( bBlame ){ |
| 2306 | 2358 | if( iVers>=0 ){ |
| 2307 | 2359 | struct AnnVers *p = ann.aVers+iVers; |
| 2308 | - char *zLink = xhref("target='infowindow'", "%R/info/%S", p->zMUuid); | |
| 2360 | + char *zLink = xhref("target='infowindow'", "%R/info/%s", p->zMUuid); | |
| 2309 | 2361 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 2310 | 2362 | "<span style='background-color:%s'>" |
| 2311 | 2363 | "%s%.10s</a> %s</span> %13.13s:", |
| 2312 | 2364 | p->zBgColor, zLink, p->zMUuid, p->zDate, p->zUser); |
| 2313 | 2365 | fossil_free(zLink); |
| @@ -2315,11 +2367,11 @@ | ||
| 2315 | 2367 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%36s", ""); |
| 2316 | 2368 | } |
| 2317 | 2369 | }else{ |
| 2318 | 2370 | if( iVers>=0 ){ |
| 2319 | 2371 | struct AnnVers *p = ann.aVers+iVers; |
| 2320 | - char *zLink = xhref("target='infowindow'", "%R/info/%S", p->zMUuid); | |
| 2372 | + char *zLink = xhref("target='infowindow'", "%R/info/%s", p->zMUuid); | |
| 2321 | 2373 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 2322 | 2374 | "<span style='background-color:%s'>" |
| 2323 | 2375 | "%s%.10s</a> %s</span> %4d:", |
| 2324 | 2376 | p->zBgColor, zLink, p->zMUuid, p->zDate, i+1); |
| 2325 | 2377 | fossil_free(zLink); |
| @@ -2348,12 +2400,12 @@ | ||
| 2348 | 2400 | ** |
| 2349 | 2401 | ** Options: |
| 2350 | 2402 | ** --filevers Show file version numbers rather than check-in versions |
| 2351 | 2403 | ** -l|--log List all versions analyzed |
| 2352 | 2404 | ** -n|--limit N Only look backwards in time by N versions |
| 2353 | -** -Z|--ignore-trailing-space Ignore eol-whitespaces | |
| 2354 | -** -w|--ignore-all-space Ignore all whitespaces | |
| 2405 | +** -w|--ignore-all-space Ignore white space when comparing lines | |
| 2406 | +** -Z|--ignore-trailing-space Ignore whitespace at line end | |
| 2355 | 2407 | ** |
| 2356 | 2408 | ** See also: info, finfo, timeline |
| 2357 | 2409 | */ |
| 2358 | 2410 | void annotate_cmd(void){ |
| 2359 | 2411 | int fnid; /* Filename ID */ |
| @@ -2374,12 +2426,16 @@ | ||
| 2374 | 2426 | bBlame = g.argv[1][0]!='a'; |
| 2375 | 2427 | zLimit = find_option("limit","n",1); |
| 2376 | 2428 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2377 | 2429 | iLimit = atoi(zLimit); |
| 2378 | 2430 | showLog = find_option("log","l",0)!=0; |
| 2379 | - if( find_option("ignore-trailing-space","Z",0)!=0 ) annFlags |= DIFF_IGNORE_EOLWS; | |
| 2380 | - if( find_option("ignore-all-space","w",0)!=0 ) annFlags |= DIFF_IGNORE_ALLWS; | |
| 2431 | + if( find_option("ignore-trailing-space","Z",0)!=0 ){ | |
| 2432 | + annFlags = DIFF_IGNORE_EOLWS; | |
| 2433 | + } | |
| 2434 | + if( find_option("ignore-all-space","w",0)!=0 ){ | |
| 2435 | + annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ | |
| 2436 | + } | |
| 2381 | 2437 | fileVers = find_option("filevers",0,0)!=0; |
| 2382 | 2438 | db_must_be_within_tree(); |
| 2383 | 2439 | if( g.argc<3 ) { |
| 2384 | 2440 | usage("FILENAME"); |
| 2385 | 2441 | } |
| @@ -2404,11 +2460,11 @@ | ||
| 2404 | 2460 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2405 | 2461 | fid, fnid); |
| 2406 | 2462 | if( mid==0 ){ |
| 2407 | 2463 | fossil_fatal("unable to find manifest"); |
| 2408 | 2464 | } |
| 2409 | - annFlags |= ANN_FILE_ANCEST; | |
| 2465 | + annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); | |
| 2410 | 2466 | annotate_file(&ann, fnid, mid, iLimit, annFlags); |
| 2411 | 2467 | if( showLog ){ |
| 2412 | 2468 | struct AnnVers *p; |
| 2413 | 2469 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2414 | 2470 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2415 | 2471 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -32,18 +32,18 @@ | |
| 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| 39 | #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */ |
| 40 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 41 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 42 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 43 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 44 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 45 | |
| 46 | /* |
| 47 | ** These error messages are shared in multiple locations. They are defined |
| 48 | ** here for consistency. |
| 49 | */ |
| @@ -89,11 +89,11 @@ | |
| 89 | }; |
| 90 | |
| 91 | /* |
| 92 | ** Length of a dline |
| 93 | */ |
| 94 | #define LENGTH(X) ((X)->h & LENGTH_MASK) |
| 95 | |
| 96 | /* |
| 97 | ** A context for running a raw diff. |
| 98 | ** |
| 99 | ** The aEdit[] array describes the raw diff. Each triple of integers in |
| @@ -113,10 +113,11 @@ | |
| 113 | int nEditAlloc; /* Space allocated for aEdit[] */ |
| 114 | DLine *aFrom; /* File on left side of the diff */ |
| 115 | int nFrom; /* Number of lines in aFrom[] */ |
| 116 | DLine *aTo; /* File on right side of the diff */ |
| 117 | int nTo; /* Number of lines in aTo[] */ |
| 118 | }; |
| 119 | |
| 120 | /* |
| 121 | ** Return an array of DLine objects containing a pointer to the |
| 122 | ** start of each line and a hash of that line. The lower |
| @@ -165,22 +166,36 @@ | |
| 165 | |
| 166 | /* Fill in the array */ |
| 167 | for(i=0; i<nLine; i++){ |
| 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | a[i].z = z; |
| 170 | a[i].n = k = j; |
| 171 | s = 0; |
| 172 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 173 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 174 | } |
| 175 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 176 | while( s<k && fossil_isspace(z[s]) ){ s++; } |
| 177 | } |
| 178 | a[i].indent = s; |
| 179 | for(h=0, x=s; x<k; x++){ |
| 180 | h = h ^ (h<<2) ^ z[x]; |
| 181 | } |
| 182 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 183 | h2 = h % nLine; |
| 184 | a[i].iNext = a[h2].iHash; |
| 185 | a[h2].iHash = i+1; |
| 186 | z += j+1; |
| @@ -192,13 +207,31 @@ | |
| 192 | } |
| 193 | |
| 194 | /* |
| 195 | ** Return true if two DLine elements are identical. |
| 196 | */ |
| 197 | static int same_dline(DLine *pA, DLine *pB){ |
| 198 | return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent, |
| 199 | pA->h & LENGTH_MASK)==0; |
| 200 | } |
| 201 | |
| 202 | /* |
| 203 | ** Return true if the regular expression *pRe matches any of the |
| 204 | ** N dlines |
| @@ -733,13 +766,13 @@ | |
| 733 | int aLCS[4]; /* Bounds of common middle segment */ |
| 734 | static const char zClassRm[] = "<span class=\"diffrm\">"; |
| 735 | static const char zClassAdd[] = "<span class=\"diffadd\">"; |
| 736 | static const char zClassChng[] = "<span class=\"diffchng\">"; |
| 737 | |
| 738 | nLeft = pLeft->h & LENGTH_MASK; |
| 739 | zLeft = pLeft->z; |
| 740 | nRight = pRight->h & LENGTH_MASK; |
| 741 | zRight = pRight->z; |
| 742 | nShort = nLeft<nRight ? nLeft : nRight; |
| 743 | |
| 744 | nPrefix = 0; |
| 745 | while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){ |
| @@ -881,12 +914,12 @@ | |
| 881 | unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */ |
| 882 | unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */ |
| 883 | |
| 884 | zA = pA->z; |
| 885 | zB = pB->z; |
| 886 | nA = pA->h & LENGTH_MASK; |
| 887 | nB = pB->h & LENGTH_MASK; |
| 888 | while( nA>0 && fossil_isspace(zA[0]) ){ nA--; zA++; } |
| 889 | while( nA>0 && fossil_isspace(zA[nA-1]) ){ nA--; } |
| 890 | while( nB>0 && fossil_isspace(zB[0]) ){ nB--; zB++; } |
| 891 | while( nB>0 && fossil_isspace(zB[nB-1]) ){ nB--; } |
| 892 | if( nA>250 ) nA = 250; |
| @@ -1350,16 +1383,16 @@ | |
| 1350 | int iSXb = iS1; /* Best match so far */ |
| 1351 | int iSYb = iS2; /* Best match so far */ |
| 1352 | |
| 1353 | for(i=iS1; i<iE1-mxLength; i++){ |
| 1354 | for(j=iS2; j<iE2-mxLength; j++){ |
| 1355 | if( !same_dline(&p->aFrom[i], &p->aTo[j]) ) continue; |
| 1356 | if( mxLength && !same_dline(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ |
| 1357 | continue; |
| 1358 | } |
| 1359 | k = 1; |
| 1360 | while( i+k<iE1 && j+k<iE2 && same_dline(&p->aFrom[i+k],&p->aTo[j+k]) ){ |
| 1361 | k++; |
| 1362 | } |
| 1363 | if( k>mxLength ){ |
| 1364 | iSXb = i; |
| 1365 | iSYb = j; |
| @@ -1421,11 +1454,11 @@ | |
| 1421 | mid = (iE1 + iS1)/2; |
| 1422 | for(i=iS1; i<iE1; i++){ |
| 1423 | int limit = 0; |
| 1424 | j = p->aTo[p->aFrom[i].h % p->nTo].iHash; |
| 1425 | while( j>0 |
| 1426 | && (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1])) |
| 1427 | ){ |
| 1428 | if( limit++ > 10 ){ |
| 1429 | j = 0; |
| 1430 | break; |
| 1431 | } |
| @@ -1438,19 +1471,19 @@ | |
| 1438 | iSX = i; |
| 1439 | iSY = j-1; |
| 1440 | pA = &p->aFrom[iSX-1]; |
| 1441 | pB = &p->aTo[iSY-1]; |
| 1442 | n = minInt(iSX-iS1, iSY-iS2); |
| 1443 | for(k=0; k<n && same_dline(pA,pB); k++, pA--, pB--){} |
| 1444 | iSX -= k; |
| 1445 | iSY -= k; |
| 1446 | iEX = i+1; |
| 1447 | iEY = j; |
| 1448 | pA = &p->aFrom[iEX]; |
| 1449 | pB = &p->aTo[iEY]; |
| 1450 | n = minInt(iE1-iEX, iE2-iEY); |
| 1451 | for(k=0; k<n && same_dline(pA,pB); k++, pA++, pB++){} |
| 1452 | iEX += k; |
| 1453 | iEY += k; |
| 1454 | skew = (iSX-iS1) - (iSY-iS2); |
| 1455 | if( skew<0 ) skew = -skew; |
| 1456 | dist = (iSX+iEX)/2 - mid; |
| @@ -1587,16 +1620,16 @@ | |
| 1587 | int mnE, iS, iE1, iE2; |
| 1588 | |
| 1589 | /* Carve off the common header and footer */ |
| 1590 | iE1 = p->nFrom; |
| 1591 | iE2 = p->nTo; |
| 1592 | while( iE1>0 && iE2>0 && same_dline(&p->aFrom[iE1-1], &p->aTo[iE2-1]) ){ |
| 1593 | iE1--; |
| 1594 | iE2--; |
| 1595 | } |
| 1596 | mnE = iE1<iE2 ? iE1 : iE2; |
| 1597 | for(iS=0; iS<mnE && same_dline(&p->aFrom[iS],&p->aTo[iS]); iS++){} |
| 1598 | |
| 1599 | /* do the difference */ |
| 1600 | if( iS>0 ){ |
| 1601 | appendTriple(p, iS, 0, 0); |
| 1602 | } |
| @@ -1661,11 +1694,11 @@ | |
| 1661 | |
| 1662 | /* Shift insertions toward the beginning of the file */ |
| 1663 | while( cpy>0 && del==0 && ins>0 ){ |
| 1664 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */ |
| 1665 | DLine *pBtm = &p->aTo[lnTo+ins-1]; /* Last line inserted */ |
| 1666 | if( same_dline(pTop, pBtm)==0 ) break; |
| 1667 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1668 | lnFrom--; |
| 1669 | lnTo--; |
| 1670 | p->aEdit[r]--; |
| 1671 | p->aEdit[r+3]++; |
| @@ -1674,11 +1707,11 @@ | |
| 1674 | |
| 1675 | /* Shift insertions toward the end of the file */ |
| 1676 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){ |
| 1677 | DLine *pTop = &p->aTo[lnTo]; /* First line inserted */ |
| 1678 | DLine *pBtm = &p->aTo[lnTo+ins]; /* First line past end of insert */ |
| 1679 | if( same_dline(pTop, pBtm)==0 ) break; |
| 1680 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break; |
| 1681 | lnFrom++; |
| 1682 | lnTo++; |
| 1683 | p->aEdit[r]++; |
| 1684 | p->aEdit[r+3]--; |
| @@ -1687,11 +1720,11 @@ | |
| 1687 | |
| 1688 | /* Shift deletions toward the beginning of the file */ |
| 1689 | while( cpy>0 && del>0 && ins==0 ){ |
| 1690 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */ |
| 1691 | DLine *pBtm = &p->aFrom[lnFrom+del-1]; /* Last line deleted */ |
| 1692 | if( same_dline(pTop, pBtm)==0 ) break; |
| 1693 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1694 | lnFrom--; |
| 1695 | lnTo--; |
| 1696 | p->aEdit[r]--; |
| 1697 | p->aEdit[r+3]++; |
| @@ -1700,11 +1733,11 @@ | |
| 1700 | |
| 1701 | /* Shift deletions toward the end of the file */ |
| 1702 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){ |
| 1703 | DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */ |
| 1704 | DLine *pBtm = &p->aFrom[lnFrom+del]; /* First line past end of delete */ |
| 1705 | if( same_dline(pTop, pBtm)==0 ) break; |
| 1706 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break; |
| 1707 | lnFrom++; |
| 1708 | lnTo++; |
| 1709 | p->aEdit[r]++; |
| 1710 | p->aEdit[r+3]--; |
| @@ -1780,10 +1813,15 @@ | |
| 1780 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1781 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1782 | |
| 1783 | /* Prepare the input files */ |
| 1784 | memset(&c, 0, sizeof(c)); |
| 1785 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1786 | &c.nFrom, diffFlags); |
| 1787 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 1788 | &c.nTo, diffFlags); |
| 1789 | if( c.aFrom==0 || c.aTo==0 ){ |
| @@ -1850,20 +1888,30 @@ | |
| 1850 | ** -c|--context N N lines of context. DIFF_CONTEXT_MASK |
| 1851 | ** --html Format for HTML DIFF_HTML |
| 1852 | ** --invert Invert the diff DIFF_INVERT |
| 1853 | ** -n|--linenum Show line numbers DIFF_LINENO |
| 1854 | ** --noopt Disable optimization DIFF_NOOPT |
| 1855 | ** --unified Unified diff. ~DIFF_SIDEBYSIDE |
| 1856 | ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS |
| 1857 | ** --width|-W N N character lines. DIFF_WIDTH_MASK |
| 1858 | ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE |
| 1859 | ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS |
| 1860 | */ |
| 1861 | u64 diff_options(void){ |
| 1862 | u64 diffFlags = 0; |
| 1863 | const char *z; |
| 1864 | int f; |
| 1865 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1866 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1867 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1868 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| 1869 | diffFlags |= f + DIFF_CONTEXT_EX; |
| @@ -1872,12 +1920,10 @@ | |
| 1872 | f *= DIFF_CONTEXT_MASK+1; |
| 1873 | if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK; |
| 1874 | diffFlags |= f; |
| 1875 | } |
| 1876 | if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML; |
| 1877 | if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags |= DIFF_IGNORE_EOLWS; |
| 1878 | if( find_option("ignore-all-space","w",0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS; |
| 1879 | if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO; |
| 1880 | if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 1881 | if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT; |
| 1882 | if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF; |
| 1883 | return diffFlags; |
| @@ -1954,11 +2000,11 @@ | |
| 1954 | typedef struct Annotator Annotator; |
| 1955 | struct Annotator { |
| 1956 | DContext c; /* The diff-engine context */ |
| 1957 | struct AnnLine { /* Lines of the original files... */ |
| 1958 | const char *z; /* The text of the line */ |
| 1959 | short int n; /* Number of bytes (omitting trailing space and \n) */ |
| 1960 | short int iVers; /* Level at which tag was set */ |
| 1961 | } *aOrig; |
| 1962 | int nOrig; /* Number of elements in aOrig[] */ |
| 1963 | int nVers; /* Number of versions analyzed */ |
| 1964 | int bLimit; /* True if the iLimit was reached */ |
| @@ -1980,10 +2026,15 @@ | |
| 1980 | */ |
| 1981 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 1982 | int i; |
| 1983 | |
| 1984 | memset(p, 0, sizeof(*p)); |
| 1985 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 1986 | diffFlags); |
| 1987 | if( p->c.aTo==0 ){ |
| 1988 | return 1; |
| 1989 | } |
| @@ -2138,10 +2189,11 @@ | |
| 2138 | */ |
| 2139 | unsigned gradient_color(unsigned c1, unsigned c2, int n, int i){ |
| 2140 | unsigned c; /* Result color */ |
| 2141 | unsigned x1, x2; |
| 2142 | if( i==0 || n==0 ) return c1; |
| 2143 | x1 = (c1>>16)&0xff; |
| 2144 | x2 = (c2>>16)&0xff; |
| 2145 | c = (x1*(n-i) + x2*i)/n<<16 & 0xff0000; |
| 2146 | x1 = (c1>>8)&0xff; |
| 2147 | x2 = (c2>>8)&0xff; |
| @@ -2168,11 +2220,11 @@ | |
| 2168 | void annotation_page(void){ |
| 2169 | int mid; |
| 2170 | int fnid; |
| 2171 | int i; |
| 2172 | int iLimit; /* Depth limit */ |
| 2173 | u64 annFlags = ANN_FILE_ANCEST; |
| 2174 | int showLog = 0; /* True to display the log */ |
| 2175 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2176 | const char *zFilename; /* Name of file to annotate */ |
| 2177 | const char *zCI; /* The check-in containing zFilename */ |
| 2178 | Annotator ann; |
| @@ -2255,17 +2307,17 @@ | |
| 2255 | clr = gradient_color(clr1, clr2, ann.nVers-1, i); |
| 2256 | ann.aVers[i].zBgColor = mprintf("#%06x", clr); |
| 2257 | } |
| 2258 | |
| 2259 | if( showLog ){ |
| 2260 | char *zLink = href("%R/finfo?name=%t&ci=%S",zFilename,zCI); |
| 2261 | @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> |
| 2262 | @ <ol> |
| 2263 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2264 | @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) |
| 2265 | @ check-in %z(href("%R/info/%S",p->zMUuid))%.10s(p->zMUuid)</a> |
| 2266 | @ artifact %z(href("%R/artifact/%S",p->zFUuid))%.10s(p->zFUuid)</a> |
| 2267 | @ </span> |
| 2268 | #if 0 |
| 2269 | if( i>0 ){ |
| 2270 | char *zLink = xhref("target='infowindow'", |
| 2271 | "%R/fdiff?v1=%S&v2=%S&sbs=1", |
| @@ -2283,17 +2335,17 @@ | |
| 2283 | @ </ol> |
| 2284 | @ <hr> |
| 2285 | } |
| 2286 | if( !ann.bLimit ){ |
| 2287 | @ <h2>Origin for each line in |
| 2288 | @ %z(href("%R/finfo?name=%h&ci=%S", zFilename, zCI))%h(zFilename)</a> |
| 2289 | @ from check-in %z(href("%R/info/%S",zCI))%S(zCI)</a>:</h2> |
| 2290 | iLimit = ann.nVers+10; |
| 2291 | }else{ |
| 2292 | @ <h2>Lines added by the %d(iLimit) most recent ancestors of |
| 2293 | @ %z(href("%R/finfo?name=%h&ci=%S", zFilename, zCI))%h(zFilename)</a> |
| 2294 | @ from check-in %z(href("%R/info/%S",zCI))%S(zCI)</a>:</h2> |
| 2295 | } |
| 2296 | @ <pre> |
| 2297 | for(i=0; i<ann.nOrig; i++){ |
| 2298 | int iVers = ann.aOrig[i].iVers; |
| 2299 | char *z = (char*)ann.aOrig[i].z; |
| @@ -2303,11 +2355,11 @@ | |
| 2303 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2304 | |
| 2305 | if( bBlame ){ |
| 2306 | if( iVers>=0 ){ |
| 2307 | struct AnnVers *p = ann.aVers+iVers; |
| 2308 | char *zLink = xhref("target='infowindow'", "%R/info/%S", p->zMUuid); |
| 2309 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 2310 | "<span style='background-color:%s'>" |
| 2311 | "%s%.10s</a> %s</span> %13.13s:", |
| 2312 | p->zBgColor, zLink, p->zMUuid, p->zDate, p->zUser); |
| 2313 | fossil_free(zLink); |
| @@ -2315,11 +2367,11 @@ | |
| 2315 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%36s", ""); |
| 2316 | } |
| 2317 | }else{ |
| 2318 | if( iVers>=0 ){ |
| 2319 | struct AnnVers *p = ann.aVers+iVers; |
| 2320 | char *zLink = xhref("target='infowindow'", "%R/info/%S", p->zMUuid); |
| 2321 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 2322 | "<span style='background-color:%s'>" |
| 2323 | "%s%.10s</a> %s</span> %4d:", |
| 2324 | p->zBgColor, zLink, p->zMUuid, p->zDate, i+1); |
| 2325 | fossil_free(zLink); |
| @@ -2348,12 +2400,12 @@ | |
| 2348 | ** |
| 2349 | ** Options: |
| 2350 | ** --filevers Show file version numbers rather than check-in versions |
| 2351 | ** -l|--log List all versions analyzed |
| 2352 | ** -n|--limit N Only look backwards in time by N versions |
| 2353 | ** -Z|--ignore-trailing-space Ignore eol-whitespaces |
| 2354 | ** -w|--ignore-all-space Ignore all whitespaces |
| 2355 | ** |
| 2356 | ** See also: info, finfo, timeline |
| 2357 | */ |
| 2358 | void annotate_cmd(void){ |
| 2359 | int fnid; /* Filename ID */ |
| @@ -2374,12 +2426,16 @@ | |
| 2374 | bBlame = g.argv[1][0]!='a'; |
| 2375 | zLimit = find_option("limit","n",1); |
| 2376 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2377 | iLimit = atoi(zLimit); |
| 2378 | showLog = find_option("log","l",0)!=0; |
| 2379 | if( find_option("ignore-trailing-space","Z",0)!=0 ) annFlags |= DIFF_IGNORE_EOLWS; |
| 2380 | if( find_option("ignore-all-space","w",0)!=0 ) annFlags |= DIFF_IGNORE_ALLWS; |
| 2381 | fileVers = find_option("filevers",0,0)!=0; |
| 2382 | db_must_be_within_tree(); |
| 2383 | if( g.argc<3 ) { |
| 2384 | usage("FILENAME"); |
| 2385 | } |
| @@ -2404,11 +2460,11 @@ | |
| 2404 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2405 | fid, fnid); |
| 2406 | if( mid==0 ){ |
| 2407 | fossil_fatal("unable to find manifest"); |
| 2408 | } |
| 2409 | annFlags |= ANN_FILE_ANCEST; |
| 2410 | annotate_file(&ann, fnid, mid, iLimit, annFlags); |
| 2411 | if( showLog ){ |
| 2412 | struct AnnVers *p; |
| 2413 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2414 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2415 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -32,18 +32,18 @@ | |
| 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 37 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| 38 | #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */ |
| 39 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 40 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 41 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 42 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 43 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 44 | #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ |
| 45 | |
| 46 | /* |
| 47 | ** These error messages are shared in multiple locations. They are defined |
| 48 | ** here for consistency. |
| 49 | */ |
| @@ -89,11 +89,11 @@ | |
| 89 | }; |
| 90 | |
| 91 | /* |
| 92 | ** Length of a dline |
| 93 | */ |
| 94 | #define LENGTH(X) ((X)->n) |
| 95 | |
| 96 | /* |
| 97 | ** A context for running a raw diff. |
| 98 | ** |
| 99 | ** The aEdit[] array describes the raw diff. Each triple of integers in |
| @@ -113,10 +113,11 @@ | |
| 113 | int nEditAlloc; /* Space allocated for aEdit[] */ |
| 114 | DLine *aFrom; /* File on left side of the diff */ |
| 115 | int nFrom; /* Number of lines in aFrom[] */ |
| 116 | DLine *aTo; /* File on right side of the diff */ |
| 117 | int nTo; /* Number of lines in aTo[] */ |
| 118 | int (*same_fn)(const DLine *, const DLine *); /* Function to be used for comparing */ |
| 119 | }; |
| 120 | |
| 121 | /* |
| 122 | ** Return an array of DLine objects containing a pointer to the |
| 123 | ** start of each line and a hash of that line. The lower |
| @@ -165,22 +166,36 @@ | |
| 166 | |
| 167 | /* Fill in the array */ |
| 168 | for(i=0; i<nLine; i++){ |
| 169 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 170 | a[i].z = z; |
| 171 | k = j; |
| 172 | if( diffFlags & DIFF_STRIP_EOLCR ){ |
| 173 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 174 | } |
| 175 | a[i].n = k; |
| 176 | s = 0; |
| 177 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 178 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 179 | } |
| 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 181 | int numws = 0; |
| 182 | while( s<k && fossil_isspace(z[s]) ){ s++; } |
| 183 | for(h=0, x=s; x<k; x++){ |
| 184 | if( fossil_isspace(z[x]) ){ |
| 185 | ++numws; |
| 186 | }else{ |
| 187 | h = h ^ (h<<2) ^ z[x]; |
| 188 | } |
| 189 | } |
| 190 | k -= numws; |
| 191 | }else{ |
| 192 | for(h=0, x=s; x<k; x++){ |
| 193 | h = h ^ (h<<2) ^ z[x]; |
| 194 | } |
| 195 | } |
| 196 | a[i].indent = s; |
| 197 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 198 | h2 = h % nLine; |
| 199 | a[i].iNext = a[h2].iHash; |
| 200 | a[h2].iHash = i+1; |
| 201 | z += j+1; |
| @@ -192,13 +207,31 @@ | |
| 207 | } |
| 208 | |
| 209 | /* |
| 210 | ** Return true if two DLine elements are identical. |
| 211 | */ |
| 212 | static int same_dline(const DLine *pA, const DLine *pB){ |
| 213 | return pA->h==pB->h && memcmp(pA->z,pB->z, pA->h&LENGTH_MASK)==0; |
| 214 | } |
| 215 | |
| 216 | /* |
| 217 | ** Return true if two DLine elements are identical, ignoring |
| 218 | ** all whitespace. The indent field of pA/pB already points |
| 219 | ** to the first non-space character in the string. |
| 220 | */ |
| 221 | |
| 222 | static int same_dline_ignore_allws(const DLine *pA, const DLine *pB){ |
| 223 | int a = pA->indent, b = pB->indent; |
| 224 | if( pA->h==pB->h ){ |
| 225 | while( a<pA->n && b<pB->n ){ |
| 226 | if( pA->z[a++] != pB->z[b++] ) return 0; |
| 227 | while( a<pA->n && fossil_isspace(pA->z[a])) ++a; |
| 228 | while( b<pB->n && fossil_isspace(pB->z[b])) ++b; |
| 229 | } |
| 230 | return pA->n-a == pB->n-b; |
| 231 | } |
| 232 | return 0; |
| 233 | } |
| 234 | |
| 235 | /* |
| 236 | ** Return true if the regular expression *pRe matches any of the |
| 237 | ** N dlines |
| @@ -733,13 +766,13 @@ | |
| 766 | int aLCS[4]; /* Bounds of common middle segment */ |
| 767 | static const char zClassRm[] = "<span class=\"diffrm\">"; |
| 768 | static const char zClassAdd[] = "<span class=\"diffadd\">"; |
| 769 | static const char zClassChng[] = "<span class=\"diffchng\">"; |
| 770 | |
| 771 | nLeft = pLeft->n; |
| 772 | zLeft = pLeft->z; |
| 773 | nRight = pRight->n; |
| 774 | zRight = pRight->z; |
| 775 | nShort = nLeft<nRight ? nLeft : nRight; |
| 776 | |
| 777 | nPrefix = 0; |
| 778 | while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){ |
| @@ -881,12 +914,12 @@ | |
| 914 | unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */ |
| 915 | unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */ |
| 916 | |
| 917 | zA = pA->z; |
| 918 | zB = pB->z; |
| 919 | nA = pA->n; |
| 920 | nB = pB->n; |
| 921 | while( nA>0 && fossil_isspace(zA[0]) ){ nA--; zA++; } |
| 922 | while( nA>0 && fossil_isspace(zA[nA-1]) ){ nA--; } |
| 923 | while( nB>0 && fossil_isspace(zB[0]) ){ nB--; zB++; } |
| 924 | while( nB>0 && fossil_isspace(zB[nB-1]) ){ nB--; } |
| 925 | if( nA>250 ) nA = 250; |
| @@ -1350,16 +1383,16 @@ | |
| 1383 | int iSXb = iS1; /* Best match so far */ |
| 1384 | int iSYb = iS2; /* Best match so far */ |
| 1385 | |
| 1386 | for(i=iS1; i<iE1-mxLength; i++){ |
| 1387 | for(j=iS2; j<iE2-mxLength; j++){ |
| 1388 | if( !p->same_fn(&p->aFrom[i], &p->aTo[j]) ) continue; |
| 1389 | if( mxLength && !p->same_fn(&p->aFrom[i+mxLength], &p->aTo[j+mxLength]) ){ |
| 1390 | continue; |
| 1391 | } |
| 1392 | k = 1; |
| 1393 | while( i+k<iE1 && j+k<iE2 && p->same_fn(&p->aFrom[i+k],&p->aTo[j+k]) ){ |
| 1394 | k++; |
| 1395 | } |
| 1396 | if( k>mxLength ){ |
| 1397 | iSXb = i; |
| 1398 | iSYb = j; |
| @@ -1421,11 +1454,11 @@ | |
| 1454 | mid = (iE1 + iS1)/2; |
| 1455 | for(i=iS1; i<iE1; i++){ |
| 1456 | int limit = 0; |
| 1457 | j = p->aTo[p->aFrom[i].h % p->nTo].iHash; |
| 1458 | while( j>0 |
| 1459 | && (j-1<iS2 || j>=iE2 || !p->same_fn(&p->aFrom[i], &p->aTo[j-1])) |
| 1460 | ){ |
| 1461 | if( limit++ > 10 ){ |
| 1462 | j = 0; |
| 1463 | break; |
| 1464 | } |
| @@ -1438,19 +1471,19 @@ | |
| 1471 | iSX = i; |
| 1472 | iSY = j-1; |
| 1473 | pA = &p->aFrom[iSX-1]; |
| 1474 | pB = &p->aTo[iSY-1]; |
| 1475 | n = minInt(iSX-iS1, iSY-iS2); |
| 1476 | for(k=0; k<n && p->same_fn(pA,pB); k++, pA--, pB--){} |
| 1477 | iSX -= k; |
| 1478 | iSY -= k; |
| 1479 | iEX = i+1; |
| 1480 | iEY = j; |
| 1481 | pA = &p->aFrom[iEX]; |
| 1482 | pB = &p->aTo[iEY]; |
| 1483 | n = minInt(iE1-iEX, iE2-iEY); |
| 1484 | for(k=0; k<n && p->same_fn(pA,pB); k++, pA++, pB++){} |
| 1485 | iEX += k; |
| 1486 | iEY += k; |
| 1487 | skew = (iSX-iS1) - (iSY-iS2); |
| 1488 | if( skew<0 ) skew = -skew; |
| 1489 | dist = (iSX+iEX)/2 - mid; |
| @@ -1587,16 +1620,16 @@ | |
| 1620 | int mnE, iS, iE1, iE2; |
| 1621 | |
| 1622 | /* Carve off the common header and footer */ |
| 1623 | iE1 = p->nFrom; |
| 1624 | iE2 = p->nTo; |
| 1625 | while( iE1>0 && iE2>0 && p->same_fn(&p->aFrom[iE1-1], &p->aTo[iE2-1]) ){ |
| 1626 | iE1--; |
| 1627 | iE2--; |
| 1628 | } |
| 1629 | mnE = iE1<iE2 ? iE1 : iE2; |
| 1630 | for(iS=0; iS<mnE && p->same_fn(&p->aFrom[iS],&p->aTo[iS]); iS++){} |
| 1631 | |
| 1632 | /* do the difference */ |
| 1633 | if( iS>0 ){ |
| 1634 | appendTriple(p, iS, 0, 0); |
| 1635 | } |
| @@ -1661,11 +1694,11 @@ | |
| 1694 | |
| 1695 | /* Shift insertions toward the beginning of the file */ |
| 1696 | while( cpy>0 && del==0 && ins>0 ){ |
| 1697 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */ |
| 1698 | DLine *pBtm = &p->aTo[lnTo+ins-1]; /* Last line inserted */ |
| 1699 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1700 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1701 | lnFrom--; |
| 1702 | lnTo--; |
| 1703 | p->aEdit[r]--; |
| 1704 | p->aEdit[r+3]++; |
| @@ -1674,11 +1707,11 @@ | |
| 1707 | |
| 1708 | /* Shift insertions toward the end of the file */ |
| 1709 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){ |
| 1710 | DLine *pTop = &p->aTo[lnTo]; /* First line inserted */ |
| 1711 | DLine *pBtm = &p->aTo[lnTo+ins]; /* First line past end of insert */ |
| 1712 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1713 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break; |
| 1714 | lnFrom++; |
| 1715 | lnTo++; |
| 1716 | p->aEdit[r]++; |
| 1717 | p->aEdit[r+3]--; |
| @@ -1687,11 +1720,11 @@ | |
| 1720 | |
| 1721 | /* Shift deletions toward the beginning of the file */ |
| 1722 | while( cpy>0 && del>0 && ins==0 ){ |
| 1723 | DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */ |
| 1724 | DLine *pBtm = &p->aFrom[lnFrom+del-1]; /* Last line deleted */ |
| 1725 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1726 | if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break; |
| 1727 | lnFrom--; |
| 1728 | lnTo--; |
| 1729 | p->aEdit[r]--; |
| 1730 | p->aEdit[r+3]++; |
| @@ -1700,11 +1733,11 @@ | |
| 1733 | |
| 1734 | /* Shift deletions toward the end of the file */ |
| 1735 | while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){ |
| 1736 | DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */ |
| 1737 | DLine *pBtm = &p->aFrom[lnFrom+del]; /* First line past end of delete */ |
| 1738 | if( p->same_fn(pTop, pBtm)==0 ) break; |
| 1739 | if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break; |
| 1740 | lnFrom++; |
| 1741 | lnTo++; |
| 1742 | p->aEdit[r]++; |
| 1743 | p->aEdit[r+3]--; |
| @@ -1780,10 +1813,15 @@ | |
| 1813 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1814 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1815 | |
| 1816 | /* Prepare the input files */ |
| 1817 | memset(&c, 0, sizeof(c)); |
| 1818 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 1819 | c.same_fn = same_dline_ignore_allws; |
| 1820 | }else{ |
| 1821 | c.same_fn = same_dline; |
| 1822 | } |
| 1823 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1824 | &c.nFrom, diffFlags); |
| 1825 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 1826 | &c.nTo, diffFlags); |
| 1827 | if( c.aFrom==0 || c.aTo==0 ){ |
| @@ -1850,20 +1888,30 @@ | |
| 1888 | ** -c|--context N N lines of context. DIFF_CONTEXT_MASK |
| 1889 | ** --html Format for HTML DIFF_HTML |
| 1890 | ** --invert Invert the diff DIFF_INVERT |
| 1891 | ** -n|--linenum Show line numbers DIFF_LINENO |
| 1892 | ** --noopt Disable optimization DIFF_NOOPT |
| 1893 | ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR |
| 1894 | ** --unified Unified diff. ~DIFF_SIDEBYSIDE |
| 1895 | ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS |
| 1896 | ** -W|--width N N character lines. DIFF_WIDTH_MASK |
| 1897 | ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE |
| 1898 | ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS |
| 1899 | */ |
| 1900 | u64 diff_options(void){ |
| 1901 | u64 diffFlags = 0; |
| 1902 | const char *z; |
| 1903 | int f; |
| 1904 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1905 | diffFlags = DIFF_IGNORE_EOLWS; |
| 1906 | } |
| 1907 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1908 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1909 | } |
| 1910 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1911 | diffFlags |= DIFF_STRIP_EOLCR; |
| 1912 | } |
| 1913 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1914 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1915 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1916 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| 1917 | diffFlags |= f + DIFF_CONTEXT_EX; |
| @@ -1872,12 +1920,10 @@ | |
| 1920 | f *= DIFF_CONTEXT_MASK+1; |
| 1921 | if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK; |
| 1922 | diffFlags |= f; |
| 1923 | } |
| 1924 | if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML; |
| 1925 | if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO; |
| 1926 | if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 1927 | if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT; |
| 1928 | if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF; |
| 1929 | return diffFlags; |
| @@ -1954,11 +2000,11 @@ | |
| 2000 | typedef struct Annotator Annotator; |
| 2001 | struct Annotator { |
| 2002 | DContext c; /* The diff-engine context */ |
| 2003 | struct AnnLine { /* Lines of the original files... */ |
| 2004 | const char *z; /* The text of the line */ |
| 2005 | short int n; /* Number of bytes (omitting trailing \n) */ |
| 2006 | short int iVers; /* Level at which tag was set */ |
| 2007 | } *aOrig; |
| 2008 | int nOrig; /* Number of elements in aOrig[] */ |
| 2009 | int nVers; /* Number of versions analyzed */ |
| 2010 | int bLimit; /* True if the iLimit was reached */ |
| @@ -1980,10 +2026,15 @@ | |
| 2026 | */ |
| 2027 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 2028 | int i; |
| 2029 | |
| 2030 | memset(p, 0, sizeof(*p)); |
| 2031 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 2032 | p->c.same_fn = same_dline_ignore_allws; |
| 2033 | }else{ |
| 2034 | p->c.same_fn = same_dline; |
| 2035 | } |
| 2036 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 2037 | diffFlags); |
| 2038 | if( p->c.aTo==0 ){ |
| 2039 | return 1; |
| 2040 | } |
| @@ -2138,10 +2189,11 @@ | |
| 2189 | */ |
| 2190 | unsigned gradient_color(unsigned c1, unsigned c2, int n, int i){ |
| 2191 | unsigned c; /* Result color */ |
| 2192 | unsigned x1, x2; |
| 2193 | if( i==0 || n==0 ) return c1; |
| 2194 | else if(i>=n) return c2; |
| 2195 | x1 = (c1>>16)&0xff; |
| 2196 | x2 = (c2>>16)&0xff; |
| 2197 | c = (x1*(n-i) + x2*i)/n<<16 & 0xff0000; |
| 2198 | x1 = (c1>>8)&0xff; |
| 2199 | x2 = (c2>>8)&0xff; |
| @@ -2168,11 +2220,11 @@ | |
| 2220 | void annotation_page(void){ |
| 2221 | int mid; |
| 2222 | int fnid; |
| 2223 | int i; |
| 2224 | int iLimit; /* Depth limit */ |
| 2225 | u64 annFlags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2226 | int showLog = 0; /* True to display the log */ |
| 2227 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2228 | const char *zFilename; /* Name of file to annotate */ |
| 2229 | const char *zCI; /* The check-in containing zFilename */ |
| 2230 | Annotator ann; |
| @@ -2255,17 +2307,17 @@ | |
| 2307 | clr = gradient_color(clr1, clr2, ann.nVers-1, i); |
| 2308 | ann.aVers[i].zBgColor = mprintf("#%06x", clr); |
| 2309 | } |
| 2310 | |
| 2311 | if( showLog ){ |
| 2312 | char *zLink = href("%R/finfo?name=%t&ci=%s",zFilename,zCI); |
| 2313 | @ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2> |
| 2314 | @ <ol> |
| 2315 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2316 | @ <li><span style='background-color:%s(p->zBgColor);'>%s(p->zDate) |
| 2317 | @ check-in %z(href("%R/info/%s",p->zMUuid))%.10s(p->zMUuid)</a> |
| 2318 | @ artifact %z(href("%R/artifact/%s",p->zFUuid))%.10s(p->zFUuid)</a> |
| 2319 | @ </span> |
| 2320 | #if 0 |
| 2321 | if( i>0 ){ |
| 2322 | char *zLink = xhref("target='infowindow'", |
| 2323 | "%R/fdiff?v1=%S&v2=%S&sbs=1", |
| @@ -2283,17 +2335,17 @@ | |
| 2335 | @ </ol> |
| 2336 | @ <hr> |
| 2337 | } |
| 2338 | if( !ann.bLimit ){ |
| 2339 | @ <h2>Origin for each line in |
| 2340 | @ %z(href("%R/finfo?name=%h&ci=%s", zFilename, zCI))%h(zFilename)</a> |
| 2341 | @ from check-in %z(href("%R/info/%s",zCI))%S(zCI)</a>:</h2> |
| 2342 | iLimit = ann.nVers+10; |
| 2343 | }else{ |
| 2344 | @ <h2>Lines added by the %d(iLimit) most recent ancestors of |
| 2345 | @ %z(href("%R/finfo?name=%h&ci=%s", zFilename, zCI))%h(zFilename)</a> |
| 2346 | @ from check-in %z(href("%R/info/%s",zCI))%S(zCI)</a>:</h2> |
| 2347 | } |
| 2348 | @ <pre> |
| 2349 | for(i=0; i<ann.nOrig; i++){ |
| 2350 | int iVers = ann.aOrig[i].iVers; |
| 2351 | char *z = (char*)ann.aOrig[i].z; |
| @@ -2303,11 +2355,11 @@ | |
| 2355 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2356 | |
| 2357 | if( bBlame ){ |
| 2358 | if( iVers>=0 ){ |
| 2359 | struct AnnVers *p = ann.aVers+iVers; |
| 2360 | char *zLink = xhref("target='infowindow'", "%R/info/%s", p->zMUuid); |
| 2361 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 2362 | "<span style='background-color:%s'>" |
| 2363 | "%s%.10s</a> %s</span> %13.13s:", |
| 2364 | p->zBgColor, zLink, p->zMUuid, p->zDate, p->zUser); |
| 2365 | fossil_free(zLink); |
| @@ -2315,11 +2367,11 @@ | |
| 2367 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%36s", ""); |
| 2368 | } |
| 2369 | }else{ |
| 2370 | if( iVers>=0 ){ |
| 2371 | struct AnnVers *p = ann.aVers+iVers; |
| 2372 | char *zLink = xhref("target='infowindow'", "%R/info/%s", p->zMUuid); |
| 2373 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 2374 | "<span style='background-color:%s'>" |
| 2375 | "%s%.10s</a> %s</span> %4d:", |
| 2376 | p->zBgColor, zLink, p->zMUuid, p->zDate, i+1); |
| 2377 | fossil_free(zLink); |
| @@ -2348,12 +2400,12 @@ | |
| 2400 | ** |
| 2401 | ** Options: |
| 2402 | ** --filevers Show file version numbers rather than check-in versions |
| 2403 | ** -l|--log List all versions analyzed |
| 2404 | ** -n|--limit N Only look backwards in time by N versions |
| 2405 | ** -w|--ignore-all-space Ignore white space when comparing lines |
| 2406 | ** -Z|--ignore-trailing-space Ignore whitespace at line end |
| 2407 | ** |
| 2408 | ** See also: info, finfo, timeline |
| 2409 | */ |
| 2410 | void annotate_cmd(void){ |
| 2411 | int fnid; /* Filename ID */ |
| @@ -2374,12 +2426,16 @@ | |
| 2426 | bBlame = g.argv[1][0]!='a'; |
| 2427 | zLimit = find_option("limit","n",1); |
| 2428 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2429 | iLimit = atoi(zLimit); |
| 2430 | showLog = find_option("log","l",0)!=0; |
| 2431 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 2432 | annFlags = DIFF_IGNORE_EOLWS; |
| 2433 | } |
| 2434 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 2435 | annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 2436 | } |
| 2437 | fileVers = find_option("filevers",0,0)!=0; |
| 2438 | db_must_be_within_tree(); |
| 2439 | if( g.argc<3 ) { |
| 2440 | usage("FILENAME"); |
| 2441 | } |
| @@ -2404,11 +2460,11 @@ | |
| 2460 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2461 | fid, fnid); |
| 2462 | if( mid==0 ){ |
| 2463 | fossil_fatal("unable to find manifest"); |
| 2464 | } |
| 2465 | annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2466 | annotate_file(&ann, fnid, mid, iLimit, annFlags); |
| 2467 | if( showLog ){ |
| 2468 | struct AnnVers *p; |
| 2469 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2470 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2471 |
+37
-6
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -943,13 +943,39 @@ | ||
| 943 | 943 | @ foreach e $::difftxt {puts $out [list $e]} |
| 944 | 944 | @ puts $out "\175" |
| 945 | 945 | @ puts $out "eval \$prog" |
| 946 | 946 | @ close $out |
| 947 | 947 | @ } |
| 948 | +@ proc invertDiff {} { | |
| 949 | +@ global CFG | |
| 950 | +@ array set x [grid info .txtA] | |
| 951 | +@ if {$x(-column)==1} { | |
| 952 | +@ grid config .lnB -column 0 | |
| 953 | +@ grid config .txtB -column 1 | |
| 954 | +@ .txtB tag config add -background $CFG(RM_BG) | |
| 955 | +@ grid config .lnA -column 3 | |
| 956 | +@ grid config .txtA -column 4 | |
| 957 | +@ .txtA tag config rm -background $CFG(ADD_BG) | |
| 958 | +@ } else { | |
| 959 | +@ grid config .lnA -column 0 | |
| 960 | +@ grid config .txtA -column 1 | |
| 961 | +@ .txtA tag config rm -background $CFG(RM_BG) | |
| 962 | +@ grid config .lnB -column 3 | |
| 963 | +@ grid config .txtB -column 4 | |
| 964 | +@ .txtB tag config add -background $CFG(ADD_BG) | |
| 965 | +@ } | |
| 966 | +@ .mkr config -state normal | |
| 967 | +@ set clt [.mkr search -all < 1.0 end] | |
| 968 | +@ set cgt [.mkr search -all > 1.0 end] | |
| 969 | +@ foreach c $clt {.mkr replace $c "$c +1 chars" >} | |
| 970 | +@ foreach c $cgt {.mkr replace $c "$c +1 chars" <} | |
| 971 | +@ .mkr config -state disabled | |
| 972 | +@ } | |
| 948 | 973 | @ ::ttk::button .bb.quit -text {Quit} -command exit |
| 974 | +@ ::ttk::button .bb.invert -text {Invert} -command invertDiff | |
| 949 | 975 | @ ::ttk::button .bb.save -text {Save As...} -command saveDiff |
| 950 | -@ pack .bb.quit -side left | |
| 976 | +@ pack .bb.quit .bb.invert -side left | |
| 951 | 977 | @ if {$fossilcmd!=""} {pack .bb.save -side left} |
| 952 | 978 | @ pack .bb.files -side left |
| 953 | 979 | @ grid rowconfigure . 1 -weight 1 |
| 954 | 980 | @ grid columnconfigure . 1 -weight 1 |
| 955 | 981 | @ grid columnconfigure . 4 -weight 1 |
| @@ -998,12 +1024,17 @@ | ||
| 998 | 1024 | i++; |
| 999 | 1025 | zTempFile = g.argv[i]; |
| 1000 | 1026 | continue; |
| 1001 | 1027 | } |
| 1002 | 1028 | } |
| 1003 | - blob_append(&script, " ", 1); | |
| 1004 | - shell_escape(&script, z); | |
| 1029 | + if( sqlite3_strglob("*}*",z) ){ | |
| 1030 | + blob_appendf(&script, " {%/}", z); | |
| 1031 | + }else{ | |
| 1032 | + int j; | |
| 1033 | + blob_append(&script, " ", 1); | |
| 1034 | + for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]); | |
| 1035 | + } | |
| 1005 | 1036 | } |
| 1006 | 1037 | blob_appendf(&script, "}\n%s", zDiffScript); |
| 1007 | 1038 | if( zTempFile ){ |
| 1008 | 1039 | blob_write_to_file(&script, zTempFile); |
| 1009 | 1040 | fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile); |
| @@ -1097,17 +1128,17 @@ | ||
| 1097 | 1128 | ** --context|-c N Use N lines of context |
| 1098 | 1129 | ** --diff-binary BOOL Include binary files when using external commands |
| 1099 | 1130 | ** --from|-r VERSION select VERSION as source for the diff |
| 1100 | 1131 | ** --internal|-i use internal diff logic |
| 1101 | 1132 | ** --side-by-side|-y side-by-side diff |
| 1133 | +** --strip-trailing-cr Strip trailing CR | |
| 1102 | 1134 | ** --tk Launch a Tcl/Tk GUI for display |
| 1103 | 1135 | ** --to VERSION select VERSION as target for the diff |
| 1104 | 1136 | ** --unified unified diff |
| 1105 | 1137 | ** -v|--verbose output complete text of added or deleted files |
| 1106 | -** -w|--ignore-all-space Ignore changes to start-of-line and end-of-line | |
| 1107 | -** whitespace | |
| 1108 | -** -W|--width Width of lines in side-by-side diff | |
| 1138 | +** -w|--ignore-all-space Ignore white space when comparing lines | |
| 1139 | +** -W|--width <num> Width of lines in side-by-side diff | |
| 1109 | 1140 | ** -Z|--ignore-trailing-space Ignore changes to end-of-line whitespace |
| 1110 | 1141 | */ |
| 1111 | 1142 | void diff_cmd(void){ |
| 1112 | 1143 | int isGDiff; /* True for gdiff. False for normal diff */ |
| 1113 | 1144 | int isInternDiff; /* True for internal diff */ |
| 1114 | 1145 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -943,13 +943,39 @@ | |
| 943 | @ foreach e $::difftxt {puts $out [list $e]} |
| 944 | @ puts $out "\175" |
| 945 | @ puts $out "eval \$prog" |
| 946 | @ close $out |
| 947 | @ } |
| 948 | @ ::ttk::button .bb.quit -text {Quit} -command exit |
| 949 | @ ::ttk::button .bb.save -text {Save As...} -command saveDiff |
| 950 | @ pack .bb.quit -side left |
| 951 | @ if {$fossilcmd!=""} {pack .bb.save -side left} |
| 952 | @ pack .bb.files -side left |
| 953 | @ grid rowconfigure . 1 -weight 1 |
| 954 | @ grid columnconfigure . 1 -weight 1 |
| 955 | @ grid columnconfigure . 4 -weight 1 |
| @@ -998,12 +1024,17 @@ | |
| 998 | i++; |
| 999 | zTempFile = g.argv[i]; |
| 1000 | continue; |
| 1001 | } |
| 1002 | } |
| 1003 | blob_append(&script, " ", 1); |
| 1004 | shell_escape(&script, z); |
| 1005 | } |
| 1006 | blob_appendf(&script, "}\n%s", zDiffScript); |
| 1007 | if( zTempFile ){ |
| 1008 | blob_write_to_file(&script, zTempFile); |
| 1009 | fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile); |
| @@ -1097,17 +1128,17 @@ | |
| 1097 | ** --context|-c N Use N lines of context |
| 1098 | ** --diff-binary BOOL Include binary files when using external commands |
| 1099 | ** --from|-r VERSION select VERSION as source for the diff |
| 1100 | ** --internal|-i use internal diff logic |
| 1101 | ** --side-by-side|-y side-by-side diff |
| 1102 | ** --tk Launch a Tcl/Tk GUI for display |
| 1103 | ** --to VERSION select VERSION as target for the diff |
| 1104 | ** --unified unified diff |
| 1105 | ** -v|--verbose output complete text of added or deleted files |
| 1106 | ** -w|--ignore-all-space Ignore changes to start-of-line and end-of-line |
| 1107 | ** whitespace |
| 1108 | ** -W|--width Width of lines in side-by-side diff |
| 1109 | ** -Z|--ignore-trailing-space Ignore changes to end-of-line whitespace |
| 1110 | */ |
| 1111 | void diff_cmd(void){ |
| 1112 | int isGDiff; /* True for gdiff. False for normal diff */ |
| 1113 | int isInternDiff; /* True for internal diff */ |
| 1114 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -943,13 +943,39 @@ | |
| 943 | @ foreach e $::difftxt {puts $out [list $e]} |
| 944 | @ puts $out "\175" |
| 945 | @ puts $out "eval \$prog" |
| 946 | @ close $out |
| 947 | @ } |
| 948 | @ proc invertDiff {} { |
| 949 | @ global CFG |
| 950 | @ array set x [grid info .txtA] |
| 951 | @ if {$x(-column)==1} { |
| 952 | @ grid config .lnB -column 0 |
| 953 | @ grid config .txtB -column 1 |
| 954 | @ .txtB tag config add -background $CFG(RM_BG) |
| 955 | @ grid config .lnA -column 3 |
| 956 | @ grid config .txtA -column 4 |
| 957 | @ .txtA tag config rm -background $CFG(ADD_BG) |
| 958 | @ } else { |
| 959 | @ grid config .lnA -column 0 |
| 960 | @ grid config .txtA -column 1 |
| 961 | @ .txtA tag config rm -background $CFG(RM_BG) |
| 962 | @ grid config .lnB -column 3 |
| 963 | @ grid config .txtB -column 4 |
| 964 | @ .txtB tag config add -background $CFG(ADD_BG) |
| 965 | @ } |
| 966 | @ .mkr config -state normal |
| 967 | @ set clt [.mkr search -all < 1.0 end] |
| 968 | @ set cgt [.mkr search -all > 1.0 end] |
| 969 | @ foreach c $clt {.mkr replace $c "$c +1 chars" >} |
| 970 | @ foreach c $cgt {.mkr replace $c "$c +1 chars" <} |
| 971 | @ .mkr config -state disabled |
| 972 | @ } |
| 973 | @ ::ttk::button .bb.quit -text {Quit} -command exit |
| 974 | @ ::ttk::button .bb.invert -text {Invert} -command invertDiff |
| 975 | @ ::ttk::button .bb.save -text {Save As...} -command saveDiff |
| 976 | @ pack .bb.quit .bb.invert -side left |
| 977 | @ if {$fossilcmd!=""} {pack .bb.save -side left} |
| 978 | @ pack .bb.files -side left |
| 979 | @ grid rowconfigure . 1 -weight 1 |
| 980 | @ grid columnconfigure . 1 -weight 1 |
| 981 | @ grid columnconfigure . 4 -weight 1 |
| @@ -998,12 +1024,17 @@ | |
| 1024 | i++; |
| 1025 | zTempFile = g.argv[i]; |
| 1026 | continue; |
| 1027 | } |
| 1028 | } |
| 1029 | if( sqlite3_strglob("*}*",z) ){ |
| 1030 | blob_appendf(&script, " {%/}", z); |
| 1031 | }else{ |
| 1032 | int j; |
| 1033 | blob_append(&script, " ", 1); |
| 1034 | for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]); |
| 1035 | } |
| 1036 | } |
| 1037 | blob_appendf(&script, "}\n%s", zDiffScript); |
| 1038 | if( zTempFile ){ |
| 1039 | blob_write_to_file(&script, zTempFile); |
| 1040 | fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile); |
| @@ -1097,17 +1128,17 @@ | |
| 1128 | ** --context|-c N Use N lines of context |
| 1129 | ** --diff-binary BOOL Include binary files when using external commands |
| 1130 | ** --from|-r VERSION select VERSION as source for the diff |
| 1131 | ** --internal|-i use internal diff logic |
| 1132 | ** --side-by-side|-y side-by-side diff |
| 1133 | ** --strip-trailing-cr Strip trailing CR |
| 1134 | ** --tk Launch a Tcl/Tk GUI for display |
| 1135 | ** --to VERSION select VERSION as target for the diff |
| 1136 | ** --unified unified diff |
| 1137 | ** -v|--verbose output complete text of added or deleted files |
| 1138 | ** -w|--ignore-all-space Ignore white space when comparing lines |
| 1139 | ** -W|--width <num> Width of lines in side-by-side diff |
| 1140 | ** -Z|--ignore-trailing-space Ignore changes to end-of-line whitespace |
| 1141 | */ |
| 1142 | void diff_cmd(void){ |
| 1143 | int isGDiff; /* True for gdiff. False for normal diff */ |
| 1144 | int isInternDiff; /* True for internal diff */ |
| 1145 |
+7
-1
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -977,10 +977,12 @@ | ||
| 977 | 977 | for(j=i+1; zPwd[j]; j++){ |
| 978 | 978 | if( zPwd[j]=='/' ){ |
| 979 | 979 | blob_append(pOut, "/..", 3); |
| 980 | 980 | } |
| 981 | 981 | } |
| 982 | + while( i>0 && (zPwd[i]!='/')) --i; | |
| 983 | + blob_append(pOut, zPath+i, j-i); | |
| 982 | 984 | } |
| 983 | 985 | if( slash && i>0 && zPath[strlen(zPath)-1]=='/'){ |
| 984 | 986 | blob_append(pOut, "/", 1); |
| 985 | 987 | } |
| 986 | 988 | blob_reset(&tmp); |
| @@ -1044,11 +1046,14 @@ | ||
| 1044 | 1046 | int nFull; |
| 1045 | 1047 | char *zFull; |
| 1046 | 1048 | int (*xCmp)(const char*,const char*,int); |
| 1047 | 1049 | |
| 1048 | 1050 | blob_zero(pOut); |
| 1049 | - db_must_be_within_tree(); | |
| 1051 | + if( !g.localOpen ){ | |
| 1052 | + blob_appendf(pOut, "%s", zOrigName); | |
| 1053 | + return 1; | |
| 1054 | + } | |
| 1050 | 1055 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 1051 | 1056 | nLocalRoot = blob_size(&localRoot); |
| 1052 | 1057 | zLocalRoot = blob_buffer(&localRoot); |
| 1053 | 1058 | assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' ); |
| 1054 | 1059 | file_canonical_name(zOrigName, &full, 0); |
| @@ -1093,10 +1098,11 @@ | ||
| 1093 | 1098 | ** a boolean: "yes", "no", "true", "false", etc. |
| 1094 | 1099 | */ |
| 1095 | 1100 | void cmd_test_tree_name(void){ |
| 1096 | 1101 | int i; |
| 1097 | 1102 | Blob x; |
| 1103 | + db_find_and_open_repository(0,0); | |
| 1098 | 1104 | blob_zero(&x); |
| 1099 | 1105 | capture_case_sensitive_option(); |
| 1100 | 1106 | for(i=2; i<g.argc; i++){ |
| 1101 | 1107 | if( file_tree_name(g.argv[i], &x, 1) ){ |
| 1102 | 1108 | fossil_print("%s\n", blob_buffer(&x)); |
| 1103 | 1109 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -977,10 +977,12 @@ | |
| 977 | for(j=i+1; zPwd[j]; j++){ |
| 978 | if( zPwd[j]=='/' ){ |
| 979 | blob_append(pOut, "/..", 3); |
| 980 | } |
| 981 | } |
| 982 | } |
| 983 | if( slash && i>0 && zPath[strlen(zPath)-1]=='/'){ |
| 984 | blob_append(pOut, "/", 1); |
| 985 | } |
| 986 | blob_reset(&tmp); |
| @@ -1044,11 +1046,14 @@ | |
| 1044 | int nFull; |
| 1045 | char *zFull; |
| 1046 | int (*xCmp)(const char*,const char*,int); |
| 1047 | |
| 1048 | blob_zero(pOut); |
| 1049 | db_must_be_within_tree(); |
| 1050 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 1051 | nLocalRoot = blob_size(&localRoot); |
| 1052 | zLocalRoot = blob_buffer(&localRoot); |
| 1053 | assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' ); |
| 1054 | file_canonical_name(zOrigName, &full, 0); |
| @@ -1093,10 +1098,11 @@ | |
| 1093 | ** a boolean: "yes", "no", "true", "false", etc. |
| 1094 | */ |
| 1095 | void cmd_test_tree_name(void){ |
| 1096 | int i; |
| 1097 | Blob x; |
| 1098 | blob_zero(&x); |
| 1099 | capture_case_sensitive_option(); |
| 1100 | for(i=2; i<g.argc; i++){ |
| 1101 | if( file_tree_name(g.argv[i], &x, 1) ){ |
| 1102 | fossil_print("%s\n", blob_buffer(&x)); |
| 1103 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -977,10 +977,12 @@ | |
| 977 | for(j=i+1; zPwd[j]; j++){ |
| 978 | if( zPwd[j]=='/' ){ |
| 979 | blob_append(pOut, "/..", 3); |
| 980 | } |
| 981 | } |
| 982 | while( i>0 && (zPwd[i]!='/')) --i; |
| 983 | blob_append(pOut, zPath+i, j-i); |
| 984 | } |
| 985 | if( slash && i>0 && zPath[strlen(zPath)-1]=='/'){ |
| 986 | blob_append(pOut, "/", 1); |
| 987 | } |
| 988 | blob_reset(&tmp); |
| @@ -1044,11 +1046,14 @@ | |
| 1046 | int nFull; |
| 1047 | char *zFull; |
| 1048 | int (*xCmp)(const char*,const char*,int); |
| 1049 | |
| 1050 | blob_zero(pOut); |
| 1051 | if( !g.localOpen ){ |
| 1052 | blob_appendf(pOut, "%s", zOrigName); |
| 1053 | return 1; |
| 1054 | } |
| 1055 | file_canonical_name(g.zLocalRoot, &localRoot, 1); |
| 1056 | nLocalRoot = blob_size(&localRoot); |
| 1057 | zLocalRoot = blob_buffer(&localRoot); |
| 1058 | assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' ); |
| 1059 | file_canonical_name(zOrigName, &full, 0); |
| @@ -1093,10 +1098,11 @@ | |
| 1098 | ** a boolean: "yes", "no", "true", "false", etc. |
| 1099 | */ |
| 1100 | void cmd_test_tree_name(void){ |
| 1101 | int i; |
| 1102 | Blob x; |
| 1103 | db_find_and_open_repository(0,0); |
| 1104 | blob_zero(&x); |
| 1105 | capture_case_sensitive_option(); |
| 1106 | for(i=2; i<g.argc; i++){ |
| 1107 | if( file_tree_name(g.argv[i], &x, 1) ){ |
| 1108 | fossil_print("%s\n", blob_buffer(&x)); |
| 1109 |
+6
-10
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -374,11 +374,11 @@ | ||
| 374 | 374 | } |
| 375 | 375 | blob_reset(&sql); |
| 376 | 376 | blob_zero(&title); |
| 377 | 377 | if( baseCheckin ){ |
| 378 | 378 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 379 | - char *zLink = href("%R/info/%S", zUuid); | |
| 379 | + char *zLink = href("%R/info/%s", zUuid); | |
| 380 | 380 | blob_appendf(&title, "Ancestors of file "); |
| 381 | 381 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 382 | 382 | blob_appendf(&title, " from check-in %z%.10s</a>", zLink, zUuid); |
| 383 | 383 | fossil_free(zUuid); |
| 384 | 384 | }else{ |
| @@ -404,12 +404,10 @@ | ||
| 404 | 404 | const char *zBr = db_column_text(&q, 9); |
| 405 | 405 | int fmid = db_column_int(&q, 10); |
| 406 | 406 | int pfnid = db_column_int(&q, 11); |
| 407 | 407 | int gidx; |
| 408 | 408 | char zTime[10]; |
| 409 | - char zShort[20]; | |
| 410 | - char zShortCkin[20]; | |
| 411 | 409 | if( zBr==0 ) zBr = "trunk"; |
| 412 | 410 | if( uBg ){ |
| 413 | 411 | zBgClr = hash_color(zUser); |
| 414 | 412 | }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ |
| 415 | 413 | zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); |
| @@ -430,12 +428,10 @@ | ||
| 430 | 428 | if( zBgClr && zBgClr[0] ){ |
| 431 | 429 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 432 | 430 | }else{ |
| 433 | 431 | @ <td class="timelineTableCell"> |
| 434 | 432 | } |
| 435 | - sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); | |
| 436 | - sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); | |
| 437 | 433 | if( zUuid ){ |
| 438 | 434 | if( fpid==0 ){ |
| 439 | 435 | @ <b>Added</b> |
| 440 | 436 | }else if( pfnid ){ |
| 441 | 437 | char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", |
| @@ -458,23 +454,23 @@ | ||
| 458 | 454 | fossil_free(zNewName); |
| 459 | 455 | }else{ |
| 460 | 456 | @ <b>Deleted</b> by check-in |
| 461 | 457 | } |
| 462 | 458 | } |
| 463 | - hyperlink_to_uuid(zShortCkin); | |
| 459 | + hyperlink_to_uuid(zCkin); | |
| 464 | 460 | @ %w(zCom) (user: |
| 465 | 461 | hyperlink_to_user(zUser, zDate, ""); |
| 466 | 462 | @ branch: %h(zBr)) |
| 467 | 463 | if( g.perm.Hyperlink && zUuid ){ |
| 468 | 464 | const char *z = zFilename; |
| 469 | - @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) | |
| 465 | + @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) | |
| 470 | 466 | @ [annotate]</a> |
| 471 | - @ %z(href("%R/blame?checkin=%S&filename=%h",zCkin,z)) | |
| 467 | + @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) | |
| 472 | 468 | @ [blame]</a> |
| 473 | - @ %z(href("%R/timeline?n=200&uf=%S",zUuid))[checkins using]</a> | |
| 469 | + @ %z(href("%R/timeline?n=200&uf=%s",zUuid))[checkins using]</a> | |
| 474 | 470 | if( fpid ){ |
| 475 | - @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zPUuid,zUuid))[diff]</a> | |
| 471 | + @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> | |
| 476 | 472 | } |
| 477 | 473 | } |
| 478 | 474 | if( fDebug & FINFO_DEBUG_MLINK ){ |
| 479 | 475 | int srcid = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", frid); |
| 480 | 476 | int sz = db_int(0, "SELECT length(content) FROM blob WHERE rid=%d", frid); |
| 481 | 477 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -374,11 +374,11 @@ | |
| 374 | } |
| 375 | blob_reset(&sql); |
| 376 | blob_zero(&title); |
| 377 | if( baseCheckin ){ |
| 378 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 379 | char *zLink = href("%R/info/%S", zUuid); |
| 380 | blob_appendf(&title, "Ancestors of file "); |
| 381 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 382 | blob_appendf(&title, " from check-in %z%.10s</a>", zLink, zUuid); |
| 383 | fossil_free(zUuid); |
| 384 | }else{ |
| @@ -404,12 +404,10 @@ | |
| 404 | const char *zBr = db_column_text(&q, 9); |
| 405 | int fmid = db_column_int(&q, 10); |
| 406 | int pfnid = db_column_int(&q, 11); |
| 407 | int gidx; |
| 408 | char zTime[10]; |
| 409 | char zShort[20]; |
| 410 | char zShortCkin[20]; |
| 411 | if( zBr==0 ) zBr = "trunk"; |
| 412 | if( uBg ){ |
| 413 | zBgClr = hash_color(zUser); |
| 414 | }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ |
| 415 | zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); |
| @@ -430,12 +428,10 @@ | |
| 430 | if( zBgClr && zBgClr[0] ){ |
| 431 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 432 | }else{ |
| 433 | @ <td class="timelineTableCell"> |
| 434 | } |
| 435 | sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid); |
| 436 | sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin); |
| 437 | if( zUuid ){ |
| 438 | if( fpid==0 ){ |
| 439 | @ <b>Added</b> |
| 440 | }else if( pfnid ){ |
| 441 | char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", |
| @@ -458,23 +454,23 @@ | |
| 458 | fossil_free(zNewName); |
| 459 | }else{ |
| 460 | @ <b>Deleted</b> by check-in |
| 461 | } |
| 462 | } |
| 463 | hyperlink_to_uuid(zShortCkin); |
| 464 | @ %w(zCom) (user: |
| 465 | hyperlink_to_user(zUser, zDate, ""); |
| 466 | @ branch: %h(zBr)) |
| 467 | if( g.perm.Hyperlink && zUuid ){ |
| 468 | const char *z = zFilename; |
| 469 | @ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z)) |
| 470 | @ [annotate]</a> |
| 471 | @ %z(href("%R/blame?checkin=%S&filename=%h",zCkin,z)) |
| 472 | @ [blame]</a> |
| 473 | @ %z(href("%R/timeline?n=200&uf=%S",zUuid))[checkins using]</a> |
| 474 | if( fpid ){ |
| 475 | @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zPUuid,zUuid))[diff]</a> |
| 476 | } |
| 477 | } |
| 478 | if( fDebug & FINFO_DEBUG_MLINK ){ |
| 479 | int srcid = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", frid); |
| 480 | int sz = db_int(0, "SELECT length(content) FROM blob WHERE rid=%d", frid); |
| 481 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -374,11 +374,11 @@ | |
| 374 | } |
| 375 | blob_reset(&sql); |
| 376 | blob_zero(&title); |
| 377 | if( baseCheckin ){ |
| 378 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 379 | char *zLink = href("%R/info/%s", zUuid); |
| 380 | blob_appendf(&title, "Ancestors of file "); |
| 381 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 382 | blob_appendf(&title, " from check-in %z%.10s</a>", zLink, zUuid); |
| 383 | fossil_free(zUuid); |
| 384 | }else{ |
| @@ -404,12 +404,10 @@ | |
| 404 | const char *zBr = db_column_text(&q, 9); |
| 405 | int fmid = db_column_int(&q, 10); |
| 406 | int pfnid = db_column_int(&q, 11); |
| 407 | int gidx; |
| 408 | char zTime[10]; |
| 409 | if( zBr==0 ) zBr = "trunk"; |
| 410 | if( uBg ){ |
| 411 | zBgClr = hash_color(zUser); |
| 412 | }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ |
| 413 | zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); |
| @@ -430,12 +428,10 @@ | |
| 428 | if( zBgClr && zBgClr[0] ){ |
| 429 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 430 | }else{ |
| 431 | @ <td class="timelineTableCell"> |
| 432 | } |
| 433 | if( zUuid ){ |
| 434 | if( fpid==0 ){ |
| 435 | @ <b>Added</b> |
| 436 | }else if( pfnid ){ |
| 437 | char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", |
| @@ -458,23 +454,23 @@ | |
| 454 | fossil_free(zNewName); |
| 455 | }else{ |
| 456 | @ <b>Deleted</b> by check-in |
| 457 | } |
| 458 | } |
| 459 | hyperlink_to_uuid(zCkin); |
| 460 | @ %w(zCom) (user: |
| 461 | hyperlink_to_user(zUser, zDate, ""); |
| 462 | @ branch: %h(zBr)) |
| 463 | if( g.perm.Hyperlink && zUuid ){ |
| 464 | const char *z = zFilename; |
| 465 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 466 | @ [annotate]</a> |
| 467 | @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) |
| 468 | @ [blame]</a> |
| 469 | @ %z(href("%R/timeline?n=200&uf=%s",zUuid))[checkins using]</a> |
| 470 | if( fpid ){ |
| 471 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> |
| 472 | } |
| 473 | } |
| 474 | if( fDebug & FINFO_DEBUG_MLINK ){ |
| 475 | int srcid = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", frid); |
| 476 | int sz = db_int(0, "SELECT length(content) FROM blob WHERE rid=%d", frid); |
| 477 |
+31
-31
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -55,31 +55,31 @@ | ||
| 55 | 55 | const char *zPw; /* The user password */ |
| 56 | 56 | Blob pw; /* The nonce with user password appended */ |
| 57 | 57 | Blob sig; /* The signature field */ |
| 58 | 58 | |
| 59 | 59 | blob_zero(pLogin); |
| 60 | - if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ | |
| 60 | + if( g.url.user==0 || fossil_strcmp(g.url.user, "anonymous")==0 ){ | |
| 61 | 61 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 62 | 62 | } |
| 63 | - if( g.urlIsSsh ){ | |
| 63 | + if( g.url.isSsh ){ | |
| 64 | 64 | return; /* If no login card for SSH: */ |
| 65 | 65 | } |
| 66 | 66 | blob_zero(&nonce); |
| 67 | 67 | blob_zero(&pw); |
| 68 | 68 | sha1sum_blob(pPayload, &nonce); |
| 69 | 69 | blob_copy(&pw, &nonce); |
| 70 | - zLogin = g.urlUser; | |
| 71 | - if( g.urlPasswd ){ | |
| 72 | - zPw = g.urlPasswd; | |
| 70 | + zLogin = g.url.user; | |
| 71 | + if( g.url.passwd ){ | |
| 72 | + zPw = g.url.passwd; | |
| 73 | 73 | }else if( g.cgiOutput ){ |
| 74 | 74 | /* Password failure while doing a sync from the web interface */ |
| 75 | 75 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| 76 | 76 | zPw = 0; |
| 77 | 77 | }else{ |
| 78 | 78 | /* Password failure while doing a sync from the command-line interface */ |
| 79 | 79 | url_prompt_for_password(); |
| 80 | - zPw = g.urlPasswd; | |
| 80 | + zPw = g.url.passwd; | |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | /* The login card wants the SHA1 hash of the password, so convert the |
| 84 | 84 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 85 | 85 | */ |
| @@ -102,29 +102,29 @@ | ||
| 102 | 102 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 103 | 103 | int i; |
| 104 | 104 | const char *zSep; |
| 105 | 105 | |
| 106 | 106 | blob_zero(pHdr); |
| 107 | - i = strlen(g.urlPath); | |
| 108 | - if( i>0 && g.urlPath[i-1]=='/' ){ | |
| 107 | + i = strlen(g.url.path); | |
| 108 | + if( i>0 && g.url.path[i-1]=='/' ){ | |
| 109 | 109 | zSep = ""; |
| 110 | 110 | }else{ |
| 111 | 111 | zSep = "/"; |
| 112 | 112 | } |
| 113 | - blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); | |
| 114 | - if( g.urlProxyAuth ){ | |
| 115 | - blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); | |
| 113 | + blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.url.path, zSep); | |
| 114 | + if( g.url.proxyAuth ){ | |
| 115 | + blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth); | |
| 116 | 116 | } |
| 117 | 117 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| 118 | 118 | const char *zCredentials = g.zHttpAuth; |
| 119 | 119 | char *zEncoded = encode64(zCredentials, -1); |
| 120 | 120 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 121 | 121 | fossil_free(zEncoded); |
| 122 | 122 | } |
| 123 | - blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); | |
| 123 | + blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname); | |
| 124 | 124 | blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent()); |
| 125 | - if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); | |
| 125 | + if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); | |
| 126 | 126 | if( g.fHttpTrace ){ |
| 127 | 127 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 128 | 128 | }else{ |
| 129 | 129 | blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n"); |
| 130 | 130 | } |
| @@ -147,11 +147,11 @@ | ||
| 147 | 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | 148 | */ |
| 149 | 149 | static int save_httpauth_prompt(void){ |
| 150 | 150 | Blob x; |
| 151 | 151 | char c; |
| 152 | - if( (g.urlFlags & URL_REMEMBER)==0 ) return; | |
| 152 | + if( (g.url.flags & URL_REMEMBER)==0 ) return 0; | |
| 153 | 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | 154 | c = blob_str(&x)[0]; |
| 155 | 155 | blob_reset(&x); |
| 156 | 156 | return ( c!='n' && c!='N' ); |
| 157 | 157 | } |
| @@ -166,15 +166,15 @@ | ||
| 166 | 166 | char *zPw; |
| 167 | 167 | char *zPrompt; |
| 168 | 168 | char *zHttpAuth = 0; |
| 169 | 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | - g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical); | |
| 171 | + g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); | |
| 172 | 172 | fossil_print(zPrompt); |
| 173 | 173 | free(zPrompt); |
| 174 | - if ( g.urlUser && g.urlPasswd && use_fossil_creds_for_httpauth_prompt() ){ | |
| 175 | - zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd); | |
| 174 | + if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ | |
| 175 | + zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); | |
| 176 | 176 | }else{ |
| 177 | 177 | prompt_user("Basic Authorization user: ", &x); |
| 178 | 178 | zUser = mprintf("%b", &x); |
| 179 | 179 | zPrompt = mprintf("HTTP password for %b: ", &x); |
| 180 | 180 | blob_reset(&x); |
| @@ -213,12 +213,12 @@ | ||
| 213 | 213 | char *zLine; /* A single line of the reply header */ |
| 214 | 214 | int i; /* Loop counter */ |
| 215 | 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | 217 | |
| 218 | - if( transport_open(GLOBAL_URL()) ){ | |
| 219 | - fossil_warning(transport_errmsg(GLOBAL_URL())); | |
| 218 | + if( transport_open(&g.url) ){ | |
| 219 | + fossil_warning(transport_errmsg(&g.url)); | |
| 220 | 220 | return 1; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | 224 | blob_zero(&login); |
| @@ -260,32 +260,32 @@ | ||
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | /* |
| 263 | 263 | ** Send the request to the server. |
| 264 | 264 | */ |
| 265 | - transport_send(GLOBAL_URL(), &hdr); | |
| 266 | - transport_send(GLOBAL_URL(), &payload); | |
| 265 | + transport_send(&g.url, &hdr); | |
| 266 | + transport_send(&g.url, &payload); | |
| 267 | 267 | blob_reset(&hdr); |
| 268 | 268 | blob_reset(&payload); |
| 269 | - transport_flip(GLOBAL_URL()); | |
| 269 | + transport_flip(&g.url); | |
| 270 | 270 | |
| 271 | 271 | /* |
| 272 | 272 | ** Read and interpret the server reply |
| 273 | 273 | */ |
| 274 | 274 | closeConnection = 1; |
| 275 | 275 | iLength = -1; |
| 276 | - while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){ | |
| 276 | + while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ | |
| 277 | 277 | /* printf("[%s]\n", zLine); fflush(stdout); */ |
| 278 | 278 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 279 | 279 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 280 | 280 | if( rc==401 ){ |
| 281 | 281 | if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){ |
| 282 | 282 | if( g.zHttpAuth ){ |
| 283 | 283 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 284 | 284 | } |
| 285 | 285 | g.zHttpAuth = prompt_for_httpauth_creds(); |
| 286 | - transport_close(GLOBAL_URL()); | |
| 286 | + transport_close(&g.url); | |
| 287 | 287 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 288 | 288 | } |
| 289 | 289 | } |
| 290 | 290 | if( rc!=200 && rc!=302 ){ |
| 291 | 291 | int ii; |
| @@ -297,11 +297,11 @@ | ||
| 297 | 297 | if( iHttpVersion==0 ){ |
| 298 | 298 | closeConnection = 1; |
| 299 | 299 | }else{ |
| 300 | 300 | closeConnection = 0; |
| 301 | 301 | } |
| 302 | - }else if( g.urlIsSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ | |
| 302 | + }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ | |
| 303 | 303 | if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err; |
| 304 | 304 | if( rc!=200 && rc!=302 ){ |
| 305 | 305 | int ii; |
| 306 | 306 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 307 | 307 | while( zLine[ii]==' ' ) ii++; |
| @@ -337,11 +337,11 @@ | ||
| 337 | 337 | fossil_print("redirect to %s\n", &zLine[i]); |
| 338 | 338 | url_parse(&zLine[i], 0); |
| 339 | 339 | fSeenHttpAuth = 0; |
| 340 | 340 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 341 | 341 | g.zHttpAuth = get_httpauth(); |
| 342 | - transport_close(GLOBAL_URL()); | |
| 342 | + transport_close(&g.url); | |
| 343 | 343 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 344 | 344 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 345 | 345 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 346 | 346 | isCompressed = 0; |
| 347 | 347 | }else if( fossil_strnicmp(&zLine[14], |
| @@ -364,11 +364,11 @@ | ||
| 364 | 364 | /* |
| 365 | 365 | ** Extract the reply payload that follows the header |
| 366 | 366 | */ |
| 367 | 367 | blob_zero(pReply); |
| 368 | 368 | blob_resize(pReply, iLength); |
| 369 | - iLength = transport_receive(GLOBAL_URL(), blob_buffer(pReply), iLength); | |
| 369 | + iLength = transport_receive(&g.url, blob_buffer(pReply), iLength); | |
| 370 | 370 | blob_resize(pReply, iLength); |
| 371 | 371 | if( isError ){ |
| 372 | 372 | char *z; |
| 373 | 373 | int i, j; |
| 374 | 374 | z = blob_str(pReply); |
| @@ -391,20 +391,20 @@ | ||
| 391 | 391 | ** connection from remaining open. The easiest fix for now is to |
| 392 | 392 | ** simply close and restart the connection for each round-trip. |
| 393 | 393 | ** |
| 394 | 394 | ** For SSH we will leave the connection open. |
| 395 | 395 | */ |
| 396 | - if( ! g.urlIsSsh ) closeConnection = 1; /* FIX ME */ | |
| 396 | + if( ! g.url.isSsh ) closeConnection = 1; /* FIX ME */ | |
| 397 | 397 | if( closeConnection ){ |
| 398 | - transport_close(GLOBAL_URL()); | |
| 398 | + transport_close(&g.url); | |
| 399 | 399 | }else{ |
| 400 | - transport_rewind(GLOBAL_URL()); | |
| 400 | + transport_rewind(&g.url); | |
| 401 | 401 | } |
| 402 | 402 | return 0; |
| 403 | 403 | |
| 404 | 404 | /* |
| 405 | 405 | ** Jump to here if an error is seen. |
| 406 | 406 | */ |
| 407 | 407 | write_err: |
| 408 | - transport_close(GLOBAL_URL()); | |
| 408 | + transport_close(&g.url); | |
| 409 | 409 | return 1; |
| 410 | 410 | } |
| 411 | 411 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -55,31 +55,31 @@ | |
| 55 | const char *zPw; /* The user password */ |
| 56 | Blob pw; /* The nonce with user password appended */ |
| 57 | Blob sig; /* The signature field */ |
| 58 | |
| 59 | blob_zero(pLogin); |
| 60 | if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ |
| 61 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 62 | } |
| 63 | if( g.urlIsSsh ){ |
| 64 | return; /* If no login card for SSH: */ |
| 65 | } |
| 66 | blob_zero(&nonce); |
| 67 | blob_zero(&pw); |
| 68 | sha1sum_blob(pPayload, &nonce); |
| 69 | blob_copy(&pw, &nonce); |
| 70 | zLogin = g.urlUser; |
| 71 | if( g.urlPasswd ){ |
| 72 | zPw = g.urlPasswd; |
| 73 | }else if( g.cgiOutput ){ |
| 74 | /* Password failure while doing a sync from the web interface */ |
| 75 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| 76 | zPw = 0; |
| 77 | }else{ |
| 78 | /* Password failure while doing a sync from the command-line interface */ |
| 79 | url_prompt_for_password(); |
| 80 | zPw = g.urlPasswd; |
| 81 | } |
| 82 | |
| 83 | /* The login card wants the SHA1 hash of the password, so convert the |
| 84 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 85 | */ |
| @@ -102,29 +102,29 @@ | |
| 102 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 103 | int i; |
| 104 | const char *zSep; |
| 105 | |
| 106 | blob_zero(pHdr); |
| 107 | i = strlen(g.urlPath); |
| 108 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 109 | zSep = ""; |
| 110 | }else{ |
| 111 | zSep = "/"; |
| 112 | } |
| 113 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 114 | if( g.urlProxyAuth ){ |
| 115 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 116 | } |
| 117 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| 118 | const char *zCredentials = g.zHttpAuth; |
| 119 | char *zEncoded = encode64(zCredentials, -1); |
| 120 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 121 | fossil_free(zEncoded); |
| 122 | } |
| 123 | blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); |
| 124 | blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent()); |
| 125 | if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); |
| 126 | if( g.fHttpTrace ){ |
| 127 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 128 | }else{ |
| 129 | blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n"); |
| 130 | } |
| @@ -147,11 +147,11 @@ | |
| 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | */ |
| 149 | static int save_httpauth_prompt(void){ |
| 150 | Blob x; |
| 151 | char c; |
| 152 | if( (g.urlFlags & URL_REMEMBER)==0 ) return; |
| 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | c = blob_str(&x)[0]; |
| 155 | blob_reset(&x); |
| 156 | return ( c!='n' && c!='N' ); |
| 157 | } |
| @@ -166,15 +166,15 @@ | |
| 166 | char *zPw; |
| 167 | char *zPrompt; |
| 168 | char *zHttpAuth = 0; |
| 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical); |
| 172 | fossil_print(zPrompt); |
| 173 | free(zPrompt); |
| 174 | if ( g.urlUser && g.urlPasswd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 176 | }else{ |
| 177 | prompt_user("Basic Authorization user: ", &x); |
| 178 | zUser = mprintf("%b", &x); |
| 179 | zPrompt = mprintf("HTTP password for %b: ", &x); |
| 180 | blob_reset(&x); |
| @@ -213,12 +213,12 @@ | |
| 213 | char *zLine; /* A single line of the reply header */ |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | |
| 218 | if( transport_open(GLOBAL_URL()) ){ |
| 219 | fossil_warning(transport_errmsg(GLOBAL_URL())); |
| 220 | return 1; |
| 221 | } |
| 222 | |
| 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | blob_zero(&login); |
| @@ -260,32 +260,32 @@ | |
| 260 | } |
| 261 | |
| 262 | /* |
| 263 | ** Send the request to the server. |
| 264 | */ |
| 265 | transport_send(GLOBAL_URL(), &hdr); |
| 266 | transport_send(GLOBAL_URL(), &payload); |
| 267 | blob_reset(&hdr); |
| 268 | blob_reset(&payload); |
| 269 | transport_flip(GLOBAL_URL()); |
| 270 | |
| 271 | /* |
| 272 | ** Read and interpret the server reply |
| 273 | */ |
| 274 | closeConnection = 1; |
| 275 | iLength = -1; |
| 276 | while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){ |
| 277 | /* printf("[%s]\n", zLine); fflush(stdout); */ |
| 278 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 279 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 280 | if( rc==401 ){ |
| 281 | if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){ |
| 282 | if( g.zHttpAuth ){ |
| 283 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 284 | } |
| 285 | g.zHttpAuth = prompt_for_httpauth_creds(); |
| 286 | transport_close(GLOBAL_URL()); |
| 287 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 288 | } |
| 289 | } |
| 290 | if( rc!=200 && rc!=302 ){ |
| 291 | int ii; |
| @@ -297,11 +297,11 @@ | |
| 297 | if( iHttpVersion==0 ){ |
| 298 | closeConnection = 1; |
| 299 | }else{ |
| 300 | closeConnection = 0; |
| 301 | } |
| 302 | }else if( g.urlIsSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ |
| 303 | if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err; |
| 304 | if( rc!=200 && rc!=302 ){ |
| 305 | int ii; |
| 306 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 307 | while( zLine[ii]==' ' ) ii++; |
| @@ -337,11 +337,11 @@ | |
| 337 | fossil_print("redirect to %s\n", &zLine[i]); |
| 338 | url_parse(&zLine[i], 0); |
| 339 | fSeenHttpAuth = 0; |
| 340 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 341 | g.zHttpAuth = get_httpauth(); |
| 342 | transport_close(GLOBAL_URL()); |
| 343 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 344 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 345 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 346 | isCompressed = 0; |
| 347 | }else if( fossil_strnicmp(&zLine[14], |
| @@ -364,11 +364,11 @@ | |
| 364 | /* |
| 365 | ** Extract the reply payload that follows the header |
| 366 | */ |
| 367 | blob_zero(pReply); |
| 368 | blob_resize(pReply, iLength); |
| 369 | iLength = transport_receive(GLOBAL_URL(), blob_buffer(pReply), iLength); |
| 370 | blob_resize(pReply, iLength); |
| 371 | if( isError ){ |
| 372 | char *z; |
| 373 | int i, j; |
| 374 | z = blob_str(pReply); |
| @@ -391,20 +391,20 @@ | |
| 391 | ** connection from remaining open. The easiest fix for now is to |
| 392 | ** simply close and restart the connection for each round-trip. |
| 393 | ** |
| 394 | ** For SSH we will leave the connection open. |
| 395 | */ |
| 396 | if( ! g.urlIsSsh ) closeConnection = 1; /* FIX ME */ |
| 397 | if( closeConnection ){ |
| 398 | transport_close(GLOBAL_URL()); |
| 399 | }else{ |
| 400 | transport_rewind(GLOBAL_URL()); |
| 401 | } |
| 402 | return 0; |
| 403 | |
| 404 | /* |
| 405 | ** Jump to here if an error is seen. |
| 406 | */ |
| 407 | write_err: |
| 408 | transport_close(GLOBAL_URL()); |
| 409 | return 1; |
| 410 | } |
| 411 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -55,31 +55,31 @@ | |
| 55 | const char *zPw; /* The user password */ |
| 56 | Blob pw; /* The nonce with user password appended */ |
| 57 | Blob sig; /* The signature field */ |
| 58 | |
| 59 | blob_zero(pLogin); |
| 60 | if( g.url.user==0 || fossil_strcmp(g.url.user, "anonymous")==0 ){ |
| 61 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 62 | } |
| 63 | if( g.url.isSsh ){ |
| 64 | return; /* If no login card for SSH: */ |
| 65 | } |
| 66 | blob_zero(&nonce); |
| 67 | blob_zero(&pw); |
| 68 | sha1sum_blob(pPayload, &nonce); |
| 69 | blob_copy(&pw, &nonce); |
| 70 | zLogin = g.url.user; |
| 71 | if( g.url.passwd ){ |
| 72 | zPw = g.url.passwd; |
| 73 | }else if( g.cgiOutput ){ |
| 74 | /* Password failure while doing a sync from the web interface */ |
| 75 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| 76 | zPw = 0; |
| 77 | }else{ |
| 78 | /* Password failure while doing a sync from the command-line interface */ |
| 79 | url_prompt_for_password(); |
| 80 | zPw = g.url.passwd; |
| 81 | } |
| 82 | |
| 83 | /* The login card wants the SHA1 hash of the password, so convert the |
| 84 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 85 | */ |
| @@ -102,29 +102,29 @@ | |
| 102 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 103 | int i; |
| 104 | const char *zSep; |
| 105 | |
| 106 | blob_zero(pHdr); |
| 107 | i = strlen(g.url.path); |
| 108 | if( i>0 && g.url.path[i-1]=='/' ){ |
| 109 | zSep = ""; |
| 110 | }else{ |
| 111 | zSep = "/"; |
| 112 | } |
| 113 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.url.path, zSep); |
| 114 | if( g.url.proxyAuth ){ |
| 115 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth); |
| 116 | } |
| 117 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| 118 | const char *zCredentials = g.zHttpAuth; |
| 119 | char *zEncoded = encode64(zCredentials, -1); |
| 120 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 121 | fossil_free(zEncoded); |
| 122 | } |
| 123 | blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname); |
| 124 | blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent()); |
| 125 | if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); |
| 126 | if( g.fHttpTrace ){ |
| 127 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 128 | }else{ |
| 129 | blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n"); |
| 130 | } |
| @@ -147,11 +147,11 @@ | |
| 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | */ |
| 149 | static int save_httpauth_prompt(void){ |
| 150 | Blob x; |
| 151 | char c; |
| 152 | if( (g.url.flags & URL_REMEMBER)==0 ) return 0; |
| 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | c = blob_str(&x)[0]; |
| 155 | blob_reset(&x); |
| 156 | return ( c!='n' && c!='N' ); |
| 157 | } |
| @@ -166,15 +166,15 @@ | |
| 166 | char *zPw; |
| 167 | char *zPrompt; |
| 168 | char *zHttpAuth = 0; |
| 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); |
| 172 | fossil_print(zPrompt); |
| 173 | free(zPrompt); |
| 174 | if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 176 | }else{ |
| 177 | prompt_user("Basic Authorization user: ", &x); |
| 178 | zUser = mprintf("%b", &x); |
| 179 | zPrompt = mprintf("HTTP password for %b: ", &x); |
| 180 | blob_reset(&x); |
| @@ -213,12 +213,12 @@ | |
| 213 | char *zLine; /* A single line of the reply header */ |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | |
| 218 | if( transport_open(&g.url) ){ |
| 219 | fossil_warning(transport_errmsg(&g.url)); |
| 220 | return 1; |
| 221 | } |
| 222 | |
| 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | blob_zero(&login); |
| @@ -260,32 +260,32 @@ | |
| 260 | } |
| 261 | |
| 262 | /* |
| 263 | ** Send the request to the server. |
| 264 | */ |
| 265 | transport_send(&g.url, &hdr); |
| 266 | transport_send(&g.url, &payload); |
| 267 | blob_reset(&hdr); |
| 268 | blob_reset(&payload); |
| 269 | transport_flip(&g.url); |
| 270 | |
| 271 | /* |
| 272 | ** Read and interpret the server reply |
| 273 | */ |
| 274 | closeConnection = 1; |
| 275 | iLength = -1; |
| 276 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 277 | /* printf("[%s]\n", zLine); fflush(stdout); */ |
| 278 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 279 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 280 | if( rc==401 ){ |
| 281 | if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){ |
| 282 | if( g.zHttpAuth ){ |
| 283 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 284 | } |
| 285 | g.zHttpAuth = prompt_for_httpauth_creds(); |
| 286 | transport_close(&g.url); |
| 287 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 288 | } |
| 289 | } |
| 290 | if( rc!=200 && rc!=302 ){ |
| 291 | int ii; |
| @@ -297,11 +297,11 @@ | |
| 297 | if( iHttpVersion==0 ){ |
| 298 | closeConnection = 1; |
| 299 | }else{ |
| 300 | closeConnection = 0; |
| 301 | } |
| 302 | }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ |
| 303 | if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err; |
| 304 | if( rc!=200 && rc!=302 ){ |
| 305 | int ii; |
| 306 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 307 | while( zLine[ii]==' ' ) ii++; |
| @@ -337,11 +337,11 @@ | |
| 337 | fossil_print("redirect to %s\n", &zLine[i]); |
| 338 | url_parse(&zLine[i], 0); |
| 339 | fSeenHttpAuth = 0; |
| 340 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 341 | g.zHttpAuth = get_httpauth(); |
| 342 | transport_close(&g.url); |
| 343 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 344 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 345 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 346 | isCompressed = 0; |
| 347 | }else if( fossil_strnicmp(&zLine[14], |
| @@ -364,11 +364,11 @@ | |
| 364 | /* |
| 365 | ** Extract the reply payload that follows the header |
| 366 | */ |
| 367 | blob_zero(pReply); |
| 368 | blob_resize(pReply, iLength); |
| 369 | iLength = transport_receive(&g.url, blob_buffer(pReply), iLength); |
| 370 | blob_resize(pReply, iLength); |
| 371 | if( isError ){ |
| 372 | char *z; |
| 373 | int i, j; |
| 374 | z = blob_str(pReply); |
| @@ -391,20 +391,20 @@ | |
| 391 | ** connection from remaining open. The easiest fix for now is to |
| 392 | ** simply close and restart the connection for each round-trip. |
| 393 | ** |
| 394 | ** For SSH we will leave the connection open. |
| 395 | */ |
| 396 | if( ! g.url.isSsh ) closeConnection = 1; /* FIX ME */ |
| 397 | if( closeConnection ){ |
| 398 | transport_close(&g.url); |
| 399 | }else{ |
| 400 | transport_rewind(&g.url); |
| 401 | } |
| 402 | return 0; |
| 403 | |
| 404 | /* |
| 405 | ** Jump to here if an error is seen. |
| 406 | */ |
| 407 | write_err: |
| 408 | transport_close(&g.url); |
| 409 | return 1; |
| 410 | } |
| 411 |
+7
-6
| --- src/http_socket.c | ||
| +++ src/http_socket.c | ||
| @@ -124,14 +124,14 @@ | ||
| 124 | 124 | } |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | /* |
| 128 | 128 | ** Open a socket connection. The identify of the server is determined |
| 129 | -** by global variables that are set using url_parse(): | |
| 129 | +** by pUrlData | |
| 130 | 130 | ** |
| 131 | -** g.urlName Name of the server. Ex: www.fossil-scm.org | |
| 132 | -** g.urlPort TCP/IP port to use. Ex: 80 | |
| 131 | +** pUrlDAta->name Name of the server. Ex: www.fossil-scm.org | |
| 132 | +** pUrlDAta->port TCP/IP port to use. Ex: 80 | |
| 133 | 133 | ** |
| 134 | 134 | ** Return the number of errors. |
| 135 | 135 | */ |
| 136 | 136 | int socket_open(UrlData *pUrlData){ |
| 137 | 137 | static struct sockaddr_in addr; /* The server address */ |
| @@ -212,13 +212,14 @@ | ||
| 212 | 212 | } |
| 213 | 213 | return total; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | 216 | /* |
| 217 | -** Attempt to resolve g.urlName to IP and setup g.zIpAddr so rcvfrom gets | |
| 218 | -** populated. For hostnames with more than one IP (or if overridden in | |
| 219 | -** ~/.ssh/config) the rcvfrom may not match the host to which we connect. | |
| 217 | +** Attempt to resolve pUrlData->name to an IP address and setup g.zIpAddr | |
| 218 | +** so rcvfrom gets populated. For hostnames with more than one IP (or | |
| 219 | +** if overridden in ~/.ssh/config) the rcvfrom may not match the host | |
| 220 | +** to which we connect. | |
| 220 | 221 | */ |
| 221 | 222 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 222 | 223 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 223 | 224 | struct sockaddr_in addr; |
| 224 | 225 | |
| 225 | 226 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -124,14 +124,14 @@ | |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | ** Open a socket connection. The identify of the server is determined |
| 129 | ** by global variables that are set using url_parse(): |
| 130 | ** |
| 131 | ** g.urlName Name of the server. Ex: www.fossil-scm.org |
| 132 | ** g.urlPort TCP/IP port to use. Ex: 80 |
| 133 | ** |
| 134 | ** Return the number of errors. |
| 135 | */ |
| 136 | int socket_open(UrlData *pUrlData){ |
| 137 | static struct sockaddr_in addr; /* The server address */ |
| @@ -212,13 +212,14 @@ | |
| 212 | } |
| 213 | return total; |
| 214 | } |
| 215 | |
| 216 | /* |
| 217 | ** Attempt to resolve g.urlName to IP and setup g.zIpAddr so rcvfrom gets |
| 218 | ** populated. For hostnames with more than one IP (or if overridden in |
| 219 | ** ~/.ssh/config) the rcvfrom may not match the host to which we connect. |
| 220 | */ |
| 221 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 222 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 223 | struct sockaddr_in addr; |
| 224 | |
| 225 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -124,14 +124,14 @@ | |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | ** Open a socket connection. The identify of the server is determined |
| 129 | ** by pUrlData |
| 130 | ** |
| 131 | ** pUrlDAta->name Name of the server. Ex: www.fossil-scm.org |
| 132 | ** pUrlDAta->port TCP/IP port to use. Ex: 80 |
| 133 | ** |
| 134 | ** Return the number of errors. |
| 135 | */ |
| 136 | int socket_open(UrlData *pUrlData){ |
| 137 | static struct sockaddr_in addr; /* The server address */ |
| @@ -212,13 +212,14 @@ | |
| 212 | } |
| 213 | return total; |
| 214 | } |
| 215 | |
| 216 | /* |
| 217 | ** Attempt to resolve pUrlData->name to an IP address and setup g.zIpAddr |
| 218 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 219 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 220 | ** to which we connect. |
| 221 | */ |
| 222 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 223 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 224 | struct sockaddr_in addr; |
| 225 | |
| 226 |
+8
-6
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -224,13 +224,13 @@ | ||
| 224 | 224 | return rc; |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 227 | /* |
| 228 | 228 | ** Open an SSL connection. The identify of the server is determined |
| 229 | -** by variables that are set using url_parse(): | |
| 229 | +** as follows: | |
| 230 | 230 | ** |
| 231 | -** pUrlData->name Name of the server. Ex: www.fossil-scm.org | |
| 231 | +** g.url.name Name of the server. Ex: www.fossil-scm.org | |
| 232 | 232 | ** pUrlData->port TCP/IP port to use. Ex: 80 |
| 233 | 233 | ** |
| 234 | 234 | ** Return the number of errors. |
| 235 | 235 | */ |
| 236 | 236 | int ssl_open(UrlData *pUrlData){ |
| @@ -253,11 +253,11 @@ | ||
| 253 | 253 | |
| 254 | 254 | if( pUrlData->useProxy ){ |
| 255 | 255 | int rc; |
| 256 | 256 | BIO *sBio; |
| 257 | 257 | char *connStr; |
| 258 | - connStr = mprintf("%s:%d", g.urlName, pUrlData->port); | |
| 258 | + connStr = mprintf("%s:%d", g.url.name, pUrlData->port); | |
| 259 | 259 | sBio = BIO_new_connect(connStr); |
| 260 | 260 | free(connStr); |
| 261 | 261 | if( BIO_do_connect(sBio)<=0 ){ |
| 262 | 262 | ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)", |
| 263 | 263 | pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error())); |
| @@ -417,26 +417,28 @@ | ||
| 417 | 417 | free(zHost); |
| 418 | 418 | BIO_free(mem); |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | /* |
| 422 | -** Get certificate for g.urlName from global config. | |
| 422 | +** Get certificate for pUrlData->urlName from global config. | |
| 423 | 423 | ** Return NULL if no certificate found. |
| 424 | 424 | */ |
| 425 | 425 | X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){ |
| 426 | 426 | char *zHost, *zCert; |
| 427 | 427 | BIO *mem; |
| 428 | 428 | X509 *cert; |
| 429 | 429 | |
| 430 | - zHost = mprintf("cert:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); | |
| 430 | + zHost = mprintf("cert:%s", | |
| 431 | + pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); | |
| 431 | 432 | zCert = db_get(zHost, NULL); |
| 432 | 433 | free(zHost); |
| 433 | 434 | if ( zCert==NULL ) |
| 434 | 435 | return NULL; |
| 435 | 436 | |
| 436 | 437 | if ( pTrusted!=0 ){ |
| 437 | - zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); | |
| 438 | + zHost = mprintf("trusted:%s", | |
| 439 | + pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); | |
| 438 | 440 | *pTrusted = db_get_int(zHost, 0); |
| 439 | 441 | free(zHost); |
| 440 | 442 | } |
| 441 | 443 | |
| 442 | 444 | mem = BIO_new(BIO_s_mem()); |
| 443 | 445 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -224,13 +224,13 @@ | |
| 224 | return rc; |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | ** Open an SSL connection. The identify of the server is determined |
| 229 | ** by variables that are set using url_parse(): |
| 230 | ** |
| 231 | ** pUrlData->name Name of the server. Ex: www.fossil-scm.org |
| 232 | ** pUrlData->port TCP/IP port to use. Ex: 80 |
| 233 | ** |
| 234 | ** Return the number of errors. |
| 235 | */ |
| 236 | int ssl_open(UrlData *pUrlData){ |
| @@ -253,11 +253,11 @@ | |
| 253 | |
| 254 | if( pUrlData->useProxy ){ |
| 255 | int rc; |
| 256 | BIO *sBio; |
| 257 | char *connStr; |
| 258 | connStr = mprintf("%s:%d", g.urlName, pUrlData->port); |
| 259 | sBio = BIO_new_connect(connStr); |
| 260 | free(connStr); |
| 261 | if( BIO_do_connect(sBio)<=0 ){ |
| 262 | ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)", |
| 263 | pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error())); |
| @@ -417,26 +417,28 @@ | |
| 417 | free(zHost); |
| 418 | BIO_free(mem); |
| 419 | } |
| 420 | |
| 421 | /* |
| 422 | ** Get certificate for g.urlName from global config. |
| 423 | ** Return NULL if no certificate found. |
| 424 | */ |
| 425 | X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){ |
| 426 | char *zHost, *zCert; |
| 427 | BIO *mem; |
| 428 | X509 *cert; |
| 429 | |
| 430 | zHost = mprintf("cert:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); |
| 431 | zCert = db_get(zHost, NULL); |
| 432 | free(zHost); |
| 433 | if ( zCert==NULL ) |
| 434 | return NULL; |
| 435 | |
| 436 | if ( pTrusted!=0 ){ |
| 437 | zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); |
| 438 | *pTrusted = db_get_int(zHost, 0); |
| 439 | free(zHost); |
| 440 | } |
| 441 | |
| 442 | mem = BIO_new(BIO_s_mem()); |
| 443 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -224,13 +224,13 @@ | |
| 224 | return rc; |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | ** Open an SSL connection. The identify of the server is determined |
| 229 | ** as follows: |
| 230 | ** |
| 231 | ** g.url.name Name of the server. Ex: www.fossil-scm.org |
| 232 | ** pUrlData->port TCP/IP port to use. Ex: 80 |
| 233 | ** |
| 234 | ** Return the number of errors. |
| 235 | */ |
| 236 | int ssl_open(UrlData *pUrlData){ |
| @@ -253,11 +253,11 @@ | |
| 253 | |
| 254 | if( pUrlData->useProxy ){ |
| 255 | int rc; |
| 256 | BIO *sBio; |
| 257 | char *connStr; |
| 258 | connStr = mprintf("%s:%d", g.url.name, pUrlData->port); |
| 259 | sBio = BIO_new_connect(connStr); |
| 260 | free(connStr); |
| 261 | if( BIO_do_connect(sBio)<=0 ){ |
| 262 | ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)", |
| 263 | pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error())); |
| @@ -417,26 +417,28 @@ | |
| 417 | free(zHost); |
| 418 | BIO_free(mem); |
| 419 | } |
| 420 | |
| 421 | /* |
| 422 | ** Get certificate for pUrlData->urlName from global config. |
| 423 | ** Return NULL if no certificate found. |
| 424 | */ |
| 425 | X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){ |
| 426 | char *zHost, *zCert; |
| 427 | BIO *mem; |
| 428 | X509 *cert; |
| 429 | |
| 430 | zHost = mprintf("cert:%s", |
| 431 | pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); |
| 432 | zCert = db_get(zHost, NULL); |
| 433 | free(zHost); |
| 434 | if ( zCert==NULL ) |
| 435 | return NULL; |
| 436 | |
| 437 | if ( pTrusted!=0 ){ |
| 438 | zHost = mprintf("trusted:%s", |
| 439 | pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); |
| 440 | *pTrusted = db_get_int(zHost, 0); |
| 441 | free(zHost); |
| 442 | } |
| 443 | |
| 444 | mem = BIO_new(BIO_s_mem()); |
| 445 |
+4
-4
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -138,15 +138,15 @@ | ||
| 138 | 138 | return sshPid==0; |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | 141 | /* |
| 142 | 142 | ** Open a connection to the server. The server is defined by the following |
| 143 | -** global variables: | |
| 143 | +** variables: | |
| 144 | 144 | ** |
| 145 | -** g.urlName Name of the server. Ex: www.fossil-scm.org | |
| 146 | -** g.urlPort TCP/IP port. Ex: 80 | |
| 147 | -** g.urlIsHttps Use TLS for the connection | |
| 145 | +** pUrlData->name Name of the server. Ex: www.fossil-scm.org | |
| 146 | +** pUrlData->port TCP/IP port. Ex: 80 | |
| 147 | +** pUrlData->isHttps Use TLS for the connection | |
| 148 | 148 | ** |
| 149 | 149 | ** Return the number of errors. |
| 150 | 150 | */ |
| 151 | 151 | int transport_open(UrlData *pUrlData){ |
| 152 | 152 | int rc = 0; |
| 153 | 153 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -138,15 +138,15 @@ | |
| 138 | return sshPid==0; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** Open a connection to the server. The server is defined by the following |
| 143 | ** global variables: |
| 144 | ** |
| 145 | ** g.urlName Name of the server. Ex: www.fossil-scm.org |
| 146 | ** g.urlPort TCP/IP port. Ex: 80 |
| 147 | ** g.urlIsHttps Use TLS for the connection |
| 148 | ** |
| 149 | ** Return the number of errors. |
| 150 | */ |
| 151 | int transport_open(UrlData *pUrlData){ |
| 152 | int rc = 0; |
| 153 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -138,15 +138,15 @@ | |
| 138 | return sshPid==0; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** Open a connection to the server. The server is defined by the following |
| 143 | ** variables: |
| 144 | ** |
| 145 | ** pUrlData->name Name of the server. Ex: www.fossil-scm.org |
| 146 | ** pUrlData->port TCP/IP port. Ex: 80 |
| 147 | ** pUrlData->isHttps Use TLS for the connection |
| 148 | ** |
| 149 | ** Return the number of errors. |
| 150 | */ |
| 151 | int transport_open(UrlData *pUrlData){ |
| 152 | int rc = 0; |
| 153 |
+34
-36
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -399,11 +399,11 @@ | ||
| 399 | 399 | } |
| 400 | 400 | if( diffFlags ){ |
| 401 | 401 | append_diff(zOld, zNew, diffFlags, pRe); |
| 402 | 402 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 403 | 403 | @ |
| 404 | - @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a> | |
| 404 | + @ %z(href("%R/fdiff?v1=%s&v2=%s&sbs=1",zOld,zNew))[diff]</a> | |
| 405 | 405 | } |
| 406 | 406 | } |
| 407 | 407 | } |
| 408 | 408 | |
| 409 | 409 | /* |
| @@ -443,24 +443,20 @@ | ||
| 443 | 443 | /* |
| 444 | 444 | ** Construct an appropriate diffFlag for text_diff() based on query |
| 445 | 445 | ** parameters and the to boolean arguments. |
| 446 | 446 | */ |
| 447 | 447 | u64 construct_diff_flags(int verboseFlag, int sideBySide){ |
| 448 | - u64 diffFlags; | |
| 449 | - if( verboseFlag==0 ){ | |
| 450 | - diffFlags = 0; /* Zero means do not show any diff */ | |
| 451 | - }else{ | |
| 448 | + u64 diffFlags = 0; /* Zero means do not show any diff */ | |
| 449 | + if( verboseFlag!=0 ){ | |
| 452 | 450 | int x; |
| 453 | 451 | if( sideBySide ){ |
| 454 | 452 | diffFlags = DIFF_SIDEBYSIDE; |
| 455 | 453 | |
| 456 | 454 | /* "dw" query parameter determines width of each column */ |
| 457 | 455 | x = atoi(PD("dw","80"))*(DIFF_CONTEXT_MASK+1); |
| 458 | 456 | if( x<0 || x>DIFF_WIDTH_MASK ) x = DIFF_WIDTH_MASK; |
| 459 | 457 | diffFlags += x; |
| 460 | - }else{ | |
| 461 | - diffFlags = DIFF_INLINE; | |
| 462 | 458 | } |
| 463 | 459 | |
| 464 | 460 | if( P("w") ){ |
| 465 | 461 | diffFlags |= DIFF_IGNORE_ALLWS; |
| 466 | 462 | } |
| @@ -469,10 +465,11 @@ | ||
| 469 | 465 | if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK; |
| 470 | 466 | diffFlags += x; |
| 471 | 467 | |
| 472 | 468 | /* The "noopt" parameter disables diff optimization */ |
| 473 | 469 | if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 470 | + diffFlags |= DIFF_STRIP_EOLCR; | |
| 474 | 471 | } |
| 475 | 472 | return diffFlags; |
| 476 | 473 | } |
| 477 | 474 | |
| 478 | 475 | /* |
| @@ -615,19 +612,19 @@ | ||
| 615 | 612 | if( (zPJ[jj]>0 && zPJ[jj]<' ') || strchr("\"*/:<>?\\|", zPJ[jj]) ){ |
| 616 | 613 | zPJ[jj] = '_'; |
| 617 | 614 | } |
| 618 | 615 | } |
| 619 | 616 | @ <tr><th>Timelines:</th><td> |
| 620 | - @ %z(href("%R/timeline?f=%S&unhide",zUuid))family</a> | |
| 617 | + @ %z(href("%R/timeline?f=%s&unhide",zUuid))family</a> | |
| 621 | 618 | if( zParent ){ |
| 622 | - @ | %z(href("%R/timeline?p=%S&unhide",zUuid))ancestors</a> | |
| 619 | + @ | %z(href("%R/timeline?p=%s&unhide",zUuid))ancestors</a> | |
| 623 | 620 | } |
| 624 | 621 | if( !isLeaf ){ |
| 625 | - @ | %z(href("%R/timeline?d=%S&unhide",zUuid))descendants</a> | |
| 622 | + @ | %z(href("%R/timeline?d=%s&unhide",zUuid))descendants</a> | |
| 626 | 623 | } |
| 627 | 624 | if( zParent && !isLeaf ){ |
| 628 | - @ | %z(href("%R/timeline?dp=%S&unhide",zUuid))both</a> | |
| 625 | + @ | %z(href("%R/timeline?dp=%s&unhide",zUuid))both</a> | |
| 629 | 626 | } |
| 630 | 627 | db_prepare(&q2,"SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 631 | 628 | " WHERE rid=%d AND tagtype>0 " |
| 632 | 629 | " AND tag.tagid=tagxref.tagid " |
| 633 | 630 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| @@ -650,16 +647,16 @@ | ||
| 650 | 647 | fossil_free(zUrl); |
| 651 | 648 | } |
| 652 | 649 | @ </td></tr> |
| 653 | 650 | @ <tr><th>Other Links:</th> |
| 654 | 651 | @ <td> |
| 655 | - @ %z(href("%R/tree?ci=%S",zUuid))files</a> | |
| 656 | - @ | %z(href("%R/fileage?name=%S",zUuid))file ages</a> | |
| 657 | - @ | %z(href("%R/tree?ci=%S&nofiles",zUuid))folders</a> | |
| 658 | - @ | %z(href("%R/artifact/%S",zUuid))manifest</a> | |
| 652 | + @ %z(href("%R/tree?ci=%s",zUuid))files</a> | |
| 653 | + @ | %z(href("%R/fileage?name=%s",zUuid))file ages</a> | |
| 654 | + @ | %z(href("%R/tree?ci=%s&nofiles",zUuid))folders</a> | |
| 655 | + @ | %z(href("%R/artifact/%s",zUuid))manifest</a> | |
| 659 | 656 | if( g.perm.Write ){ |
| 660 | - @ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a> | |
| 657 | + @ | %z(href("%R/ci_edit?r=%s",zUuid))edit</a> | |
| 661 | 658 | } |
| 662 | 659 | @ </td> |
| 663 | 660 | @ </tr> |
| 664 | 661 | blob_reset(&projName); |
| 665 | 662 | } |
| @@ -702,11 +699,11 @@ | ||
| 702 | 699 | @ Show Unified Diffs</a> |
| 703 | 700 | @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName)) |
| 704 | 701 | @ Show Side-by-Side Diffs</a> |
| 705 | 702 | } |
| 706 | 703 | if( zParent ){ |
| 707 | - @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid)) | |
| 704 | + @ %z(xhref("class='button'","%R/vpatch?from=%s&to=%s",zParent,zUuid)) | |
| 708 | 705 | @ Patch</a> |
| 709 | 706 | } |
| 710 | 707 | @</div> |
| 711 | 708 | if( pRe ){ |
| 712 | 709 | @ <p><b>Only differences that match regular expression "%h(zRe)" |
| @@ -773,11 +770,11 @@ | ||
| 773 | 770 | } |
| 774 | 771 | } |
| 775 | 772 | style_header("Update of \"%h\"", pWiki->zWikiTitle); |
| 776 | 773 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 777 | 774 | zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate); |
| 778 | - style_submenu_element("Raw", "Raw", "artifact/%S", zUuid); | |
| 775 | + style_submenu_element("Raw", "Raw", "artifact/%s", zUuid); | |
| 779 | 776 | style_submenu_element("History", "History", "whistory?name=%t", |
| 780 | 777 | pWiki->zWikiTitle); |
| 781 | 778 | style_submenu_element("Page", "Page", "wiki?name=%t", |
| 782 | 779 | pWiki->zWikiTitle); |
| 783 | 780 | login_anonymous_available(); |
| @@ -801,11 +798,11 @@ | ||
| 801 | 798 | if( pWiki->nParent>0 ){ |
| 802 | 799 | int i; |
| 803 | 800 | @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td> |
| 804 | 801 | for(i=0; i<pWiki->nParent; i++){ |
| 805 | 802 | char *zParent = pWiki->azParent[i]; |
| 806 | - @ %z(href("info/%S",zParent))%s(zParent)</a> | |
| 803 | + @ %z(href("info/%s",zParent))%s(zParent)</a> | |
| 807 | 804 | } |
| 808 | 805 | @ </td></tr> |
| 809 | 806 | } |
| 810 | 807 | @ </table> |
| 811 | 808 | |
| @@ -1191,14 +1188,14 @@ | ||
| 1191 | 1188 | @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a> |
| 1192 | 1189 | } |
| 1193 | 1190 | @ - %!w(zCom) (user: |
| 1194 | 1191 | hyperlink_to_user(zUser,zDate,")"); |
| 1195 | 1192 | if( g.perm.Hyperlink ){ |
| 1196 | - @ %z(href("%R/finfo?name=%T&ci=%S",zName,zVers))[ancestry]</a> | |
| 1197 | - @ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName)) | |
| 1193 | + @ %z(href("%R/finfo?name=%T&ci=%s",zName,zVers))[ancestry]</a> | |
| 1194 | + @ %z(href("%R/annotate?filename=%T&checkin=%s",zName,zVers)) | |
| 1198 | 1195 | @ [annotate]</a> |
| 1199 | - @ %z(href("%R/blame?checkin=%S&filename=%T",zVers,zName)) | |
| 1196 | + @ %z(href("%R/blame?filename=%T&checkin=%s",zName,zVers)) | |
| 1200 | 1197 | @ [blame]</a> |
| 1201 | 1198 | } |
| 1202 | 1199 | cnt++; |
| 1203 | 1200 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1204 | 1201 | blob_append(pDownloadName, zName, -1); |
| @@ -1305,11 +1302,11 @@ | ||
| 1305 | 1302 | @ Attachment "%h(zFilename)" to |
| 1306 | 1303 | } |
| 1307 | 1304 | objType |= OBJTYPE_ATTACHMENT; |
| 1308 | 1305 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1309 | 1306 | if( g.perm.Hyperlink && g.perm.RdTkt ){ |
| 1310 | - @ ticket [%z(href("%R/tktview?name=%S",zTarget))%S(zTarget)</a>] | |
| 1307 | + @ ticket [%z(href("%R/tktview?name=%s",zTarget))%S(zTarget)</a>] | |
| 1311 | 1308 | }else{ |
| 1312 | 1309 | @ ticket [%S(zTarget)] |
| 1313 | 1310 | } |
| 1314 | 1311 | }else{ |
| 1315 | 1312 | if( g.perm.Hyperlink && g.perm.RdWiki ){ |
| @@ -1331,11 +1328,11 @@ | ||
| 1331 | 1328 | @ Control artifact. |
| 1332 | 1329 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1333 | 1330 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1334 | 1331 | } |
| 1335 | 1332 | }else if( linkToView && g.perm.Hyperlink ){ |
| 1336 | - @ %z(href("%R/artifact/%S",zUuid))[view]</a> | |
| 1333 | + @ %z(href("%R/artifact/%s",zUuid))[view]</a> | |
| 1337 | 1334 | } |
| 1338 | 1335 | return objType; |
| 1339 | 1336 | } |
| 1340 | 1337 | |
| 1341 | 1338 | |
| @@ -1407,17 +1404,17 @@ | ||
| 1407 | 1404 | g.zTop, P("v1"), P("v2"), zW); |
| 1408 | 1405 | } |
| 1409 | 1406 | |
| 1410 | 1407 | if( P("smhdr")!=0 ){ |
| 1411 | 1408 | @ <h2>Differences From Artifact |
| 1412 | - @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To | |
| 1413 | - @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2> | |
| 1409 | + @ %z(href("%R/artifact/%s",zV1))[%S(zV1)]</a> To | |
| 1410 | + @ %z(href("%R/artifact/%s",zV2))[%S(zV2)]</a>.</h2> | |
| 1414 | 1411 | }else{ |
| 1415 | 1412 | @ <h2>Differences From |
| 1416 | - @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2> | |
| 1413 | + @ Artifact %z(href("%R/artifact/%s",zV1))[%S(zV1)]</a>:</h2> | |
| 1417 | 1414 | object_description(v1, 0, 0); |
| 1418 | - @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2> | |
| 1415 | + @ <h2>To Artifact %z(href("%R/artifact/%s",zV2))[%S(zV2)]</a>:</h2> | |
| 1419 | 1416 | object_description(v2, 0, 0); |
| 1420 | 1417 | } |
| 1421 | 1418 | if( pRe ){ |
| 1422 | 1419 | @ <b>Only differences that match regular expression "%h(zRe)" |
| 1423 | 1420 | @ are shown.</b> |
| @@ -1722,11 +1719,12 @@ | ||
| 1722 | 1719 | }else{ |
| 1723 | 1720 | renderAsHtml = 1; |
| 1724 | 1721 | style_submenu_element("Text", "Text", |
| 1725 | 1722 | "%s/artifact/%s?txt=1", g.zTop, zUuid); |
| 1726 | 1723 | } |
| 1727 | - }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){ | |
| 1724 | + }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 | |
| 1725 | + || fossil_strcmp(zMime, "text/x-markdown")==0 ){ | |
| 1728 | 1726 | if( asText ){ |
| 1729 | 1727 | style_submenu_element("Wiki", "Wiki", |
| 1730 | 1728 | "%s/artifact/%s", g.zTop, zUuid); |
| 1731 | 1729 | }else{ |
| 1732 | 1730 | renderAsWiki = 1; |
| @@ -1739,11 +1737,11 @@ | ||
| 1739 | 1737 | style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid); |
| 1740 | 1738 | } |
| 1741 | 1739 | @ <hr /> |
| 1742 | 1740 | content_get(rid, &content); |
| 1743 | 1741 | if( renderAsWiki ){ |
| 1744 | - wiki_convert(&content, 0, 0); | |
| 1742 | + wiki_render_by_mimetype(&content, zMime); | |
| 1745 | 1743 | }else if( renderAsHtml ){ |
| 1746 | 1744 | @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)" |
| 1747 | 1745 | @ width="100%%" frameborder="0" marginwidth="0" marginheight="0" |
| 1748 | 1746 | @ sandbox="allow-same-origin" |
| 1749 | 1747 | @ onload="this.height = this.contentDocument.documentElement.scrollHeight;"> |
| @@ -1763,13 +1761,13 @@ | ||
| 1763 | 1761 | @ <pre> |
| 1764 | 1762 | @ %h(z) |
| 1765 | 1763 | @ </pre> |
| 1766 | 1764 | } |
| 1767 | 1765 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 1768 | - @ <img src="%R/raw/%S(zUuid)?m=%s(zMime)" /> | |
| 1766 | + @ <img src="%R/raw/%s(zUuid)?m=%s(zMime)" /> | |
| 1769 | 1767 | style_submenu_element("Image", "Image", |
| 1770 | - "%R/raw/%S?m=%s", zUuid, zMime); | |
| 1768 | + "%R/raw/%s?m=%s", zUuid, zMime); | |
| 1771 | 1769 | }else{ |
| 1772 | 1770 | @ <i>(file is %d(blob_size(&content)) bytes of binary data)</i> |
| 1773 | 1771 | } |
| 1774 | 1772 | @ </blockquote> |
| 1775 | 1773 | } |
| @@ -1821,19 +1819,19 @@ | ||
| 1821 | 1819 | } |
| 1822 | 1820 | zTktTitle = db_table_has_column( "ticket", "title" ) |
| 1823 | 1821 | ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName) |
| 1824 | 1822 | : 0; |
| 1825 | 1823 | style_header("Ticket Change Details"); |
| 1826 | - style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid); | |
| 1824 | + style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid); | |
| 1827 | 1825 | style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName); |
| 1828 | 1826 | style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName); |
| 1829 | 1827 | style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName); |
| 1830 | 1828 | if( P("plaintext") ){ |
| 1831 | - style_submenu_element("Formatted", "Formatted", "%R/info/%S", zUuid); | |
| 1829 | + style_submenu_element("Formatted", "Formatted", "%R/info/%s", zUuid); | |
| 1832 | 1830 | }else{ |
| 1833 | 1831 | style_submenu_element("Plaintext", "Plaintext", |
| 1834 | - "%R/info/%S?plaintext", zUuid); | |
| 1832 | + "%R/info/%s?plaintext", zUuid); | |
| 1835 | 1833 | } |
| 1836 | 1834 | |
| 1837 | 1835 | @ <div class="section">Overview</div> |
| 1838 | 1836 | @ <p><table class="label-value"> |
| 1839 | 1837 | @ <tr><th>Artifact ID:</th> |
| @@ -2343,11 +2341,11 @@ | ||
| 2343 | 2341 | } |
| 2344 | 2342 | @ <p>Make changes to attributes of check-in |
| 2345 | 2343 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 2346 | 2344 | form_begin(0, "%R/ci_edit"); |
| 2347 | 2345 | login_insert_csrf_secret(); |
| 2348 | - @ <div><input type="hidden" name="r" value="%S(zUuid)" /> | |
| 2346 | + @ <div><input type="hidden" name="r" value="%s(zUuid)" /> | |
| 2349 | 2347 | @ <table border="0" cellspacing="10"> |
| 2350 | 2348 | |
| 2351 | 2349 | @ <tr><th align="right" valign="top">User:</th> |
| 2352 | 2350 | @ <td valign="top"> |
| 2353 | 2351 | @ <input type="text" name="u" size="20" value="%h(zNewUser)" /> |
| 2354 | 2352 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -399,11 +399,11 @@ | |
| 399 | } |
| 400 | if( diffFlags ){ |
| 401 | append_diff(zOld, zNew, diffFlags, pRe); |
| 402 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 403 | @ |
| 404 | @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a> |
| 405 | } |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | /* |
| @@ -443,24 +443,20 @@ | |
| 443 | /* |
| 444 | ** Construct an appropriate diffFlag for text_diff() based on query |
| 445 | ** parameters and the to boolean arguments. |
| 446 | */ |
| 447 | u64 construct_diff_flags(int verboseFlag, int sideBySide){ |
| 448 | u64 diffFlags; |
| 449 | if( verboseFlag==0 ){ |
| 450 | diffFlags = 0; /* Zero means do not show any diff */ |
| 451 | }else{ |
| 452 | int x; |
| 453 | if( sideBySide ){ |
| 454 | diffFlags = DIFF_SIDEBYSIDE; |
| 455 | |
| 456 | /* "dw" query parameter determines width of each column */ |
| 457 | x = atoi(PD("dw","80"))*(DIFF_CONTEXT_MASK+1); |
| 458 | if( x<0 || x>DIFF_WIDTH_MASK ) x = DIFF_WIDTH_MASK; |
| 459 | diffFlags += x; |
| 460 | }else{ |
| 461 | diffFlags = DIFF_INLINE; |
| 462 | } |
| 463 | |
| 464 | if( P("w") ){ |
| 465 | diffFlags |= DIFF_IGNORE_ALLWS; |
| 466 | } |
| @@ -469,10 +465,11 @@ | |
| 469 | if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK; |
| 470 | diffFlags += x; |
| 471 | |
| 472 | /* The "noopt" parameter disables diff optimization */ |
| 473 | if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 474 | } |
| 475 | return diffFlags; |
| 476 | } |
| 477 | |
| 478 | /* |
| @@ -615,19 +612,19 @@ | |
| 615 | if( (zPJ[jj]>0 && zPJ[jj]<' ') || strchr("\"*/:<>?\\|", zPJ[jj]) ){ |
| 616 | zPJ[jj] = '_'; |
| 617 | } |
| 618 | } |
| 619 | @ <tr><th>Timelines:</th><td> |
| 620 | @ %z(href("%R/timeline?f=%S&unhide",zUuid))family</a> |
| 621 | if( zParent ){ |
| 622 | @ | %z(href("%R/timeline?p=%S&unhide",zUuid))ancestors</a> |
| 623 | } |
| 624 | if( !isLeaf ){ |
| 625 | @ | %z(href("%R/timeline?d=%S&unhide",zUuid))descendants</a> |
| 626 | } |
| 627 | if( zParent && !isLeaf ){ |
| 628 | @ | %z(href("%R/timeline?dp=%S&unhide",zUuid))both</a> |
| 629 | } |
| 630 | db_prepare(&q2,"SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 631 | " WHERE rid=%d AND tagtype>0 " |
| 632 | " AND tag.tagid=tagxref.tagid " |
| 633 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| @@ -650,16 +647,16 @@ | |
| 650 | fossil_free(zUrl); |
| 651 | } |
| 652 | @ </td></tr> |
| 653 | @ <tr><th>Other Links:</th> |
| 654 | @ <td> |
| 655 | @ %z(href("%R/tree?ci=%S",zUuid))files</a> |
| 656 | @ | %z(href("%R/fileage?name=%S",zUuid))file ages</a> |
| 657 | @ | %z(href("%R/tree?ci=%S&nofiles",zUuid))folders</a> |
| 658 | @ | %z(href("%R/artifact/%S",zUuid))manifest</a> |
| 659 | if( g.perm.Write ){ |
| 660 | @ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a> |
| 661 | } |
| 662 | @ </td> |
| 663 | @ </tr> |
| 664 | blob_reset(&projName); |
| 665 | } |
| @@ -702,11 +699,11 @@ | |
| 702 | @ Show Unified Diffs</a> |
| 703 | @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName)) |
| 704 | @ Show Side-by-Side Diffs</a> |
| 705 | } |
| 706 | if( zParent ){ |
| 707 | @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid)) |
| 708 | @ Patch</a> |
| 709 | } |
| 710 | @</div> |
| 711 | if( pRe ){ |
| 712 | @ <p><b>Only differences that match regular expression "%h(zRe)" |
| @@ -773,11 +770,11 @@ | |
| 773 | } |
| 774 | } |
| 775 | style_header("Update of \"%h\"", pWiki->zWikiTitle); |
| 776 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 777 | zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate); |
| 778 | style_submenu_element("Raw", "Raw", "artifact/%S", zUuid); |
| 779 | style_submenu_element("History", "History", "whistory?name=%t", |
| 780 | pWiki->zWikiTitle); |
| 781 | style_submenu_element("Page", "Page", "wiki?name=%t", |
| 782 | pWiki->zWikiTitle); |
| 783 | login_anonymous_available(); |
| @@ -801,11 +798,11 @@ | |
| 801 | if( pWiki->nParent>0 ){ |
| 802 | int i; |
| 803 | @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td> |
| 804 | for(i=0; i<pWiki->nParent; i++){ |
| 805 | char *zParent = pWiki->azParent[i]; |
| 806 | @ %z(href("info/%S",zParent))%s(zParent)</a> |
| 807 | } |
| 808 | @ </td></tr> |
| 809 | } |
| 810 | @ </table> |
| 811 | |
| @@ -1191,14 +1188,14 @@ | |
| 1191 | @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a> |
| 1192 | } |
| 1193 | @ - %!w(zCom) (user: |
| 1194 | hyperlink_to_user(zUser,zDate,")"); |
| 1195 | if( g.perm.Hyperlink ){ |
| 1196 | @ %z(href("%R/finfo?name=%T&ci=%S",zName,zVers))[ancestry]</a> |
| 1197 | @ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName)) |
| 1198 | @ [annotate]</a> |
| 1199 | @ %z(href("%R/blame?checkin=%S&filename=%T",zVers,zName)) |
| 1200 | @ [blame]</a> |
| 1201 | } |
| 1202 | cnt++; |
| 1203 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1204 | blob_append(pDownloadName, zName, -1); |
| @@ -1305,11 +1302,11 @@ | |
| 1305 | @ Attachment "%h(zFilename)" to |
| 1306 | } |
| 1307 | objType |= OBJTYPE_ATTACHMENT; |
| 1308 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1309 | if( g.perm.Hyperlink && g.perm.RdTkt ){ |
| 1310 | @ ticket [%z(href("%R/tktview?name=%S",zTarget))%S(zTarget)</a>] |
| 1311 | }else{ |
| 1312 | @ ticket [%S(zTarget)] |
| 1313 | } |
| 1314 | }else{ |
| 1315 | if( g.perm.Hyperlink && g.perm.RdWiki ){ |
| @@ -1331,11 +1328,11 @@ | |
| 1331 | @ Control artifact. |
| 1332 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1333 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1334 | } |
| 1335 | }else if( linkToView && g.perm.Hyperlink ){ |
| 1336 | @ %z(href("%R/artifact/%S",zUuid))[view]</a> |
| 1337 | } |
| 1338 | return objType; |
| 1339 | } |
| 1340 | |
| 1341 | |
| @@ -1407,17 +1404,17 @@ | |
| 1407 | g.zTop, P("v1"), P("v2"), zW); |
| 1408 | } |
| 1409 | |
| 1410 | if( P("smhdr")!=0 ){ |
| 1411 | @ <h2>Differences From Artifact |
| 1412 | @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To |
| 1413 | @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2> |
| 1414 | }else{ |
| 1415 | @ <h2>Differences From |
| 1416 | @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2> |
| 1417 | object_description(v1, 0, 0); |
| 1418 | @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2> |
| 1419 | object_description(v2, 0, 0); |
| 1420 | } |
| 1421 | if( pRe ){ |
| 1422 | @ <b>Only differences that match regular expression "%h(zRe)" |
| 1423 | @ are shown.</b> |
| @@ -1722,11 +1719,12 @@ | |
| 1722 | }else{ |
| 1723 | renderAsHtml = 1; |
| 1724 | style_submenu_element("Text", "Text", |
| 1725 | "%s/artifact/%s?txt=1", g.zTop, zUuid); |
| 1726 | } |
| 1727 | }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){ |
| 1728 | if( asText ){ |
| 1729 | style_submenu_element("Wiki", "Wiki", |
| 1730 | "%s/artifact/%s", g.zTop, zUuid); |
| 1731 | }else{ |
| 1732 | renderAsWiki = 1; |
| @@ -1739,11 +1737,11 @@ | |
| 1739 | style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid); |
| 1740 | } |
| 1741 | @ <hr /> |
| 1742 | content_get(rid, &content); |
| 1743 | if( renderAsWiki ){ |
| 1744 | wiki_convert(&content, 0, 0); |
| 1745 | }else if( renderAsHtml ){ |
| 1746 | @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)" |
| 1747 | @ width="100%%" frameborder="0" marginwidth="0" marginheight="0" |
| 1748 | @ sandbox="allow-same-origin" |
| 1749 | @ onload="this.height = this.contentDocument.documentElement.scrollHeight;"> |
| @@ -1763,13 +1761,13 @@ | |
| 1763 | @ <pre> |
| 1764 | @ %h(z) |
| 1765 | @ </pre> |
| 1766 | } |
| 1767 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 1768 | @ <img src="%R/raw/%S(zUuid)?m=%s(zMime)" /> |
| 1769 | style_submenu_element("Image", "Image", |
| 1770 | "%R/raw/%S?m=%s", zUuid, zMime); |
| 1771 | }else{ |
| 1772 | @ <i>(file is %d(blob_size(&content)) bytes of binary data)</i> |
| 1773 | } |
| 1774 | @ </blockquote> |
| 1775 | } |
| @@ -1821,19 +1819,19 @@ | |
| 1821 | } |
| 1822 | zTktTitle = db_table_has_column( "ticket", "title" ) |
| 1823 | ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName) |
| 1824 | : 0; |
| 1825 | style_header("Ticket Change Details"); |
| 1826 | style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid); |
| 1827 | style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName); |
| 1828 | style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName); |
| 1829 | style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName); |
| 1830 | if( P("plaintext") ){ |
| 1831 | style_submenu_element("Formatted", "Formatted", "%R/info/%S", zUuid); |
| 1832 | }else{ |
| 1833 | style_submenu_element("Plaintext", "Plaintext", |
| 1834 | "%R/info/%S?plaintext", zUuid); |
| 1835 | } |
| 1836 | |
| 1837 | @ <div class="section">Overview</div> |
| 1838 | @ <p><table class="label-value"> |
| 1839 | @ <tr><th>Artifact ID:</th> |
| @@ -2343,11 +2341,11 @@ | |
| 2343 | } |
| 2344 | @ <p>Make changes to attributes of check-in |
| 2345 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 2346 | form_begin(0, "%R/ci_edit"); |
| 2347 | login_insert_csrf_secret(); |
| 2348 | @ <div><input type="hidden" name="r" value="%S(zUuid)" /> |
| 2349 | @ <table border="0" cellspacing="10"> |
| 2350 | |
| 2351 | @ <tr><th align="right" valign="top">User:</th> |
| 2352 | @ <td valign="top"> |
| 2353 | @ <input type="text" name="u" size="20" value="%h(zNewUser)" /> |
| 2354 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -399,11 +399,11 @@ | |
| 399 | } |
| 400 | if( diffFlags ){ |
| 401 | append_diff(zOld, zNew, diffFlags, pRe); |
| 402 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 403 | @ |
| 404 | @ %z(href("%R/fdiff?v1=%s&v2=%s&sbs=1",zOld,zNew))[diff]</a> |
| 405 | } |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | /* |
| @@ -443,24 +443,20 @@ | |
| 443 | /* |
| 444 | ** Construct an appropriate diffFlag for text_diff() based on query |
| 445 | ** parameters and the to boolean arguments. |
| 446 | */ |
| 447 | u64 construct_diff_flags(int verboseFlag, int sideBySide){ |
| 448 | u64 diffFlags = 0; /* Zero means do not show any diff */ |
| 449 | if( verboseFlag!=0 ){ |
| 450 | int x; |
| 451 | if( sideBySide ){ |
| 452 | diffFlags = DIFF_SIDEBYSIDE; |
| 453 | |
| 454 | /* "dw" query parameter determines width of each column */ |
| 455 | x = atoi(PD("dw","80"))*(DIFF_CONTEXT_MASK+1); |
| 456 | if( x<0 || x>DIFF_WIDTH_MASK ) x = DIFF_WIDTH_MASK; |
| 457 | diffFlags += x; |
| 458 | } |
| 459 | |
| 460 | if( P("w") ){ |
| 461 | diffFlags |= DIFF_IGNORE_ALLWS; |
| 462 | } |
| @@ -469,10 +465,11 @@ | |
| 465 | if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK; |
| 466 | diffFlags += x; |
| 467 | |
| 468 | /* The "noopt" parameter disables diff optimization */ |
| 469 | if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 470 | diffFlags |= DIFF_STRIP_EOLCR; |
| 471 | } |
| 472 | return diffFlags; |
| 473 | } |
| 474 | |
| 475 | /* |
| @@ -615,19 +612,19 @@ | |
| 612 | if( (zPJ[jj]>0 && zPJ[jj]<' ') || strchr("\"*/:<>?\\|", zPJ[jj]) ){ |
| 613 | zPJ[jj] = '_'; |
| 614 | } |
| 615 | } |
| 616 | @ <tr><th>Timelines:</th><td> |
| 617 | @ %z(href("%R/timeline?f=%s&unhide",zUuid))family</a> |
| 618 | if( zParent ){ |
| 619 | @ | %z(href("%R/timeline?p=%s&unhide",zUuid))ancestors</a> |
| 620 | } |
| 621 | if( !isLeaf ){ |
| 622 | @ | %z(href("%R/timeline?d=%s&unhide",zUuid))descendants</a> |
| 623 | } |
| 624 | if( zParent && !isLeaf ){ |
| 625 | @ | %z(href("%R/timeline?dp=%s&unhide",zUuid))both</a> |
| 626 | } |
| 627 | db_prepare(&q2,"SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 628 | " WHERE rid=%d AND tagtype>0 " |
| 629 | " AND tag.tagid=tagxref.tagid " |
| 630 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| @@ -650,16 +647,16 @@ | |
| 647 | fossil_free(zUrl); |
| 648 | } |
| 649 | @ </td></tr> |
| 650 | @ <tr><th>Other Links:</th> |
| 651 | @ <td> |
| 652 | @ %z(href("%R/tree?ci=%s",zUuid))files</a> |
| 653 | @ | %z(href("%R/fileage?name=%s",zUuid))file ages</a> |
| 654 | @ | %z(href("%R/tree?ci=%s&nofiles",zUuid))folders</a> |
| 655 | @ | %z(href("%R/artifact/%s",zUuid))manifest</a> |
| 656 | if( g.perm.Write ){ |
| 657 | @ | %z(href("%R/ci_edit?r=%s",zUuid))edit</a> |
| 658 | } |
| 659 | @ </td> |
| 660 | @ </tr> |
| 661 | blob_reset(&projName); |
| 662 | } |
| @@ -702,11 +699,11 @@ | |
| 699 | @ Show Unified Diffs</a> |
| 700 | @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName)) |
| 701 | @ Show Side-by-Side Diffs</a> |
| 702 | } |
| 703 | if( zParent ){ |
| 704 | @ %z(xhref("class='button'","%R/vpatch?from=%s&to=%s",zParent,zUuid)) |
| 705 | @ Patch</a> |
| 706 | } |
| 707 | @</div> |
| 708 | if( pRe ){ |
| 709 | @ <p><b>Only differences that match regular expression "%h(zRe)" |
| @@ -773,11 +770,11 @@ | |
| 770 | } |
| 771 | } |
| 772 | style_header("Update of \"%h\"", pWiki->zWikiTitle); |
| 773 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 774 | zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate); |
| 775 | style_submenu_element("Raw", "Raw", "artifact/%s", zUuid); |
| 776 | style_submenu_element("History", "History", "whistory?name=%t", |
| 777 | pWiki->zWikiTitle); |
| 778 | style_submenu_element("Page", "Page", "wiki?name=%t", |
| 779 | pWiki->zWikiTitle); |
| 780 | login_anonymous_available(); |
| @@ -801,11 +798,11 @@ | |
| 798 | if( pWiki->nParent>0 ){ |
| 799 | int i; |
| 800 | @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td> |
| 801 | for(i=0; i<pWiki->nParent; i++){ |
| 802 | char *zParent = pWiki->azParent[i]; |
| 803 | @ %z(href("info/%s",zParent))%s(zParent)</a> |
| 804 | } |
| 805 | @ </td></tr> |
| 806 | } |
| 807 | @ </table> |
| 808 | |
| @@ -1191,14 +1188,14 @@ | |
| 1188 | @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a> |
| 1189 | } |
| 1190 | @ - %!w(zCom) (user: |
| 1191 | hyperlink_to_user(zUser,zDate,")"); |
| 1192 | if( g.perm.Hyperlink ){ |
| 1193 | @ %z(href("%R/finfo?name=%T&ci=%s",zName,zVers))[ancestry]</a> |
| 1194 | @ %z(href("%R/annotate?filename=%T&checkin=%s",zName,zVers)) |
| 1195 | @ [annotate]</a> |
| 1196 | @ %z(href("%R/blame?filename=%T&checkin=%s",zName,zVers)) |
| 1197 | @ [blame]</a> |
| 1198 | } |
| 1199 | cnt++; |
| 1200 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1201 | blob_append(pDownloadName, zName, -1); |
| @@ -1305,11 +1302,11 @@ | |
| 1302 | @ Attachment "%h(zFilename)" to |
| 1303 | } |
| 1304 | objType |= OBJTYPE_ATTACHMENT; |
| 1305 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1306 | if( g.perm.Hyperlink && g.perm.RdTkt ){ |
| 1307 | @ ticket [%z(href("%R/tktview?name=%s",zTarget))%S(zTarget)</a>] |
| 1308 | }else{ |
| 1309 | @ ticket [%S(zTarget)] |
| 1310 | } |
| 1311 | }else{ |
| 1312 | if( g.perm.Hyperlink && g.perm.RdWiki ){ |
| @@ -1331,11 +1328,11 @@ | |
| 1328 | @ Control artifact. |
| 1329 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1330 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1331 | } |
| 1332 | }else if( linkToView && g.perm.Hyperlink ){ |
| 1333 | @ %z(href("%R/artifact/%s",zUuid))[view]</a> |
| 1334 | } |
| 1335 | return objType; |
| 1336 | } |
| 1337 | |
| 1338 | |
| @@ -1407,17 +1404,17 @@ | |
| 1404 | g.zTop, P("v1"), P("v2"), zW); |
| 1405 | } |
| 1406 | |
| 1407 | if( P("smhdr")!=0 ){ |
| 1408 | @ <h2>Differences From Artifact |
| 1409 | @ %z(href("%R/artifact/%s",zV1))[%S(zV1)]</a> To |
| 1410 | @ %z(href("%R/artifact/%s",zV2))[%S(zV2)]</a>.</h2> |
| 1411 | }else{ |
| 1412 | @ <h2>Differences From |
| 1413 | @ Artifact %z(href("%R/artifact/%s",zV1))[%S(zV1)]</a>:</h2> |
| 1414 | object_description(v1, 0, 0); |
| 1415 | @ <h2>To Artifact %z(href("%R/artifact/%s",zV2))[%S(zV2)]</a>:</h2> |
| 1416 | object_description(v2, 0, 0); |
| 1417 | } |
| 1418 | if( pRe ){ |
| 1419 | @ <b>Only differences that match regular expression "%h(zRe)" |
| 1420 | @ are shown.</b> |
| @@ -1722,11 +1719,12 @@ | |
| 1719 | }else{ |
| 1720 | renderAsHtml = 1; |
| 1721 | style_submenu_element("Text", "Text", |
| 1722 | "%s/artifact/%s?txt=1", g.zTop, zUuid); |
| 1723 | } |
| 1724 | }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 |
| 1725 | || fossil_strcmp(zMime, "text/x-markdown")==0 ){ |
| 1726 | if( asText ){ |
| 1727 | style_submenu_element("Wiki", "Wiki", |
| 1728 | "%s/artifact/%s", g.zTop, zUuid); |
| 1729 | }else{ |
| 1730 | renderAsWiki = 1; |
| @@ -1739,11 +1737,11 @@ | |
| 1737 | style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid); |
| 1738 | } |
| 1739 | @ <hr /> |
| 1740 | content_get(rid, &content); |
| 1741 | if( renderAsWiki ){ |
| 1742 | wiki_render_by_mimetype(&content, zMime); |
| 1743 | }else if( renderAsHtml ){ |
| 1744 | @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)" |
| 1745 | @ width="100%%" frameborder="0" marginwidth="0" marginheight="0" |
| 1746 | @ sandbox="allow-same-origin" |
| 1747 | @ onload="this.height = this.contentDocument.documentElement.scrollHeight;"> |
| @@ -1763,13 +1761,13 @@ | |
| 1761 | @ <pre> |
| 1762 | @ %h(z) |
| 1763 | @ </pre> |
| 1764 | } |
| 1765 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 1766 | @ <img src="%R/raw/%s(zUuid)?m=%s(zMime)" /> |
| 1767 | style_submenu_element("Image", "Image", |
| 1768 | "%R/raw/%s?m=%s", zUuid, zMime); |
| 1769 | }else{ |
| 1770 | @ <i>(file is %d(blob_size(&content)) bytes of binary data)</i> |
| 1771 | } |
| 1772 | @ </blockquote> |
| 1773 | } |
| @@ -1821,19 +1819,19 @@ | |
| 1819 | } |
| 1820 | zTktTitle = db_table_has_column( "ticket", "title" ) |
| 1821 | ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName) |
| 1822 | : 0; |
| 1823 | style_header("Ticket Change Details"); |
| 1824 | style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid); |
| 1825 | style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName); |
| 1826 | style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName); |
| 1827 | style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName); |
| 1828 | if( P("plaintext") ){ |
| 1829 | style_submenu_element("Formatted", "Formatted", "%R/info/%s", zUuid); |
| 1830 | }else{ |
| 1831 | style_submenu_element("Plaintext", "Plaintext", |
| 1832 | "%R/info/%s?plaintext", zUuid); |
| 1833 | } |
| 1834 | |
| 1835 | @ <div class="section">Overview</div> |
| 1836 | @ <p><table class="label-value"> |
| 1837 | @ <tr><th>Artifact ID:</th> |
| @@ -2343,11 +2341,11 @@ | |
| 2341 | } |
| 2342 | @ <p>Make changes to attributes of check-in |
| 2343 | @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p> |
| 2344 | form_begin(0, "%R/ci_edit"); |
| 2345 | login_insert_csrf_secret(); |
| 2346 | @ <div><input type="hidden" name="r" value="%s(zUuid)" /> |
| 2347 | @ <table border="0" cellspacing="10"> |
| 2348 | |
| 2349 | @ <tr><th align="right" valign="top">User:</th> |
| 2350 | @ <td valign="top"> |
| 2351 | @ <input type="text" name="u" size="20" value="%h(zNewUser)" /> |
| 2352 |
+14
-14
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -1275,15 +1275,15 @@ | ||
| 1275 | 1275 | INT(g, xlinkClusterOnly); |
| 1276 | 1276 | INT(g, fTimeFormat); |
| 1277 | 1277 | INT(g, markPrivate); |
| 1278 | 1278 | INT(g, clockSkewSeen); |
| 1279 | 1279 | INT(g, isHTTP); |
| 1280 | - INT(g, urlIsFile); | |
| 1281 | - INT(g, urlIsHttps); | |
| 1282 | - INT(g, urlIsSsh); | |
| 1283 | - INT(g, urlPort); | |
| 1284 | - INT(g, urlDfltPort); | |
| 1280 | + INT(g.url, isFile); | |
| 1281 | + INT(g.url, isHttps); | |
| 1282 | + INT(g.url, isSsh); | |
| 1283 | + INT(g.url, port); | |
| 1284 | + INT(g.url, dfltPort); | |
| 1285 | 1285 | INT(g, useLocalauth); |
| 1286 | 1286 | INT(g, noPswd); |
| 1287 | 1287 | INT(g, userUid); |
| 1288 | 1288 | INT(g, rcvid); |
| 1289 | 1289 | INT(g, okCsrf); |
| @@ -1299,19 +1299,19 @@ | ||
| 1299 | 1299 | CSTR(g, zExtra); |
| 1300 | 1300 | CSTR(g, zBaseURL); |
| 1301 | 1301 | CSTR(g, zTop); |
| 1302 | 1302 | CSTR(g, zContentType); |
| 1303 | 1303 | CSTR(g, zErrMsg); |
| 1304 | - CSTR(g, urlName); | |
| 1305 | - CSTR(g, urlHostname); | |
| 1306 | - CSTR(g, urlProtocol); | |
| 1307 | - CSTR(g, urlPath); | |
| 1308 | - CSTR(g, urlUser); | |
| 1309 | - CSTR(g, urlPasswd); | |
| 1310 | - CSTR(g, urlCanonical); | |
| 1311 | - CSTR(g, urlProxyAuth); | |
| 1312 | - CSTR(g, urlFossil); | |
| 1304 | + CSTR(g.url, name); | |
| 1305 | + CSTR(g.url, hostname); | |
| 1306 | + CSTR(g.url, protocol); | |
| 1307 | + CSTR(g.url, path); | |
| 1308 | + CSTR(g.url, user); | |
| 1309 | + CSTR(g.url, passwd); | |
| 1310 | + CSTR(g.url, canonical); | |
| 1311 | + CSTR(g.url, proxyAuth); | |
| 1312 | + CSTR(g.url, fossil); | |
| 1313 | 1313 | CSTR(g, zLogin); |
| 1314 | 1314 | CSTR(g, zSSLIdentity); |
| 1315 | 1315 | CSTR(g, zIpAddr); |
| 1316 | 1316 | CSTR(g, zNonce); |
| 1317 | 1317 | CSTR(g, zCsrfToken); |
| 1318 | 1318 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1275,15 +1275,15 @@ | |
| 1275 | INT(g, xlinkClusterOnly); |
| 1276 | INT(g, fTimeFormat); |
| 1277 | INT(g, markPrivate); |
| 1278 | INT(g, clockSkewSeen); |
| 1279 | INT(g, isHTTP); |
| 1280 | INT(g, urlIsFile); |
| 1281 | INT(g, urlIsHttps); |
| 1282 | INT(g, urlIsSsh); |
| 1283 | INT(g, urlPort); |
| 1284 | INT(g, urlDfltPort); |
| 1285 | INT(g, useLocalauth); |
| 1286 | INT(g, noPswd); |
| 1287 | INT(g, userUid); |
| 1288 | INT(g, rcvid); |
| 1289 | INT(g, okCsrf); |
| @@ -1299,19 +1299,19 @@ | |
| 1299 | CSTR(g, zExtra); |
| 1300 | CSTR(g, zBaseURL); |
| 1301 | CSTR(g, zTop); |
| 1302 | CSTR(g, zContentType); |
| 1303 | CSTR(g, zErrMsg); |
| 1304 | CSTR(g, urlName); |
| 1305 | CSTR(g, urlHostname); |
| 1306 | CSTR(g, urlProtocol); |
| 1307 | CSTR(g, urlPath); |
| 1308 | CSTR(g, urlUser); |
| 1309 | CSTR(g, urlPasswd); |
| 1310 | CSTR(g, urlCanonical); |
| 1311 | CSTR(g, urlProxyAuth); |
| 1312 | CSTR(g, urlFossil); |
| 1313 | CSTR(g, zLogin); |
| 1314 | CSTR(g, zSSLIdentity); |
| 1315 | CSTR(g, zIpAddr); |
| 1316 | CSTR(g, zNonce); |
| 1317 | CSTR(g, zCsrfToken); |
| 1318 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1275,15 +1275,15 @@ | |
| 1275 | INT(g, xlinkClusterOnly); |
| 1276 | INT(g, fTimeFormat); |
| 1277 | INT(g, markPrivate); |
| 1278 | INT(g, clockSkewSeen); |
| 1279 | INT(g, isHTTP); |
| 1280 | INT(g.url, isFile); |
| 1281 | INT(g.url, isHttps); |
| 1282 | INT(g.url, isSsh); |
| 1283 | INT(g.url, port); |
| 1284 | INT(g.url, dfltPort); |
| 1285 | INT(g, useLocalauth); |
| 1286 | INT(g, noPswd); |
| 1287 | INT(g, userUid); |
| 1288 | INT(g, rcvid); |
| 1289 | INT(g, okCsrf); |
| @@ -1299,19 +1299,19 @@ | |
| 1299 | CSTR(g, zExtra); |
| 1300 | CSTR(g, zBaseURL); |
| 1301 | CSTR(g, zTop); |
| 1302 | CSTR(g, zContentType); |
| 1303 | CSTR(g, zErrMsg); |
| 1304 | CSTR(g.url, name); |
| 1305 | CSTR(g.url, hostname); |
| 1306 | CSTR(g.url, protocol); |
| 1307 | CSTR(g.url, path); |
| 1308 | CSTR(g.url, user); |
| 1309 | CSTR(g.url, passwd); |
| 1310 | CSTR(g.url, canonical); |
| 1311 | CSTR(g.url, proxyAuth); |
| 1312 | CSTR(g.url, fossil); |
| 1313 | CSTR(g, zLogin); |
| 1314 | CSTR(g, zSSLIdentity); |
| 1315 | CSTR(g, zIpAddr); |
| 1316 | CSTR(g, zNonce); |
| 1317 | CSTR(g, zCsrfToken); |
| 1318 |
+1
-1
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -542,11 +542,11 @@ | ||
| 542 | 542 | |
| 543 | 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | 544 | blob_zero(&w2); |
| 545 | 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | 546 | blob_zero(&d); |
| 547 | - diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE; | |
| 547 | + diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR; | |
| 548 | 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | 549 | blob_reset(&w1); |
| 550 | 550 | blob_reset(&w2); |
| 551 | 551 | |
| 552 | 552 | pay = cson_new_object(); |
| 553 | 553 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | |
| 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | blob_zero(&w2); |
| 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | blob_zero(&d); |
| 547 | diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE; |
| 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | blob_reset(&w1); |
| 550 | blob_reset(&w2); |
| 551 | |
| 552 | pay = cson_new_object(); |
| 553 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | |
| 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | blob_zero(&w2); |
| 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | blob_zero(&d); |
| 547 | diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR; |
| 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | blob_reset(&w1); |
| 550 | blob_reset(&w2); |
| 551 | |
| 552 | pay = cson_new_object(); |
| 553 |
+5
-12
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -112,15 +112,10 @@ | ||
| 112 | 112 | void *xPostEval; /* Optional, called after Tcl_Eval*(). */ |
| 113 | 113 | void *pPostContext; /* Optional, provided to xPostEval(). */ |
| 114 | 114 | }; |
| 115 | 115 | #endif |
| 116 | 116 | |
| 117 | -/* | |
| 118 | -** All global variables are in this structure. | |
| 119 | -*/ | |
| 120 | -#define GLOBAL_URL() ((UrlData *)(&g.urlIsFile)) | |
| 121 | - | |
| 122 | 117 | struct Global { |
| 123 | 118 | int argc; char **argv; /* Command-line arguments to the program */ |
| 124 | 119 | char *nameOfExe; /* Full path of executable. */ |
| 125 | 120 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 126 | 121 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -171,11 +166,12 @@ | ||
| 171 | 166 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 172 | 167 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 173 | 168 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 174 | 169 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 175 | 170 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 176 | - | |
| 171 | + UrlData url; /* Information about current URL */ | |
| 172 | +#if 0 | |
| 177 | 173 | /* |
| 178 | 174 | ** NOTE: These members MUST be kept in sync with those in the "UrlData" |
| 179 | 175 | ** structure defined in "url.c". |
| 180 | 176 | */ |
| 181 | 177 | int urlIsFile; /* True if a "file:" url */ |
| @@ -194,10 +190,12 @@ | ||
| 194 | 190 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 195 | 191 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 196 | 192 | int useProxy; /* Used to remember that a proxy is in use */ |
| 197 | 193 | char *proxyUrlPath; |
| 198 | 194 | int proxyOrigPort; /* Tunneled port number for https through proxy */ |
| 195 | +#endif | |
| 196 | + | |
| 199 | 197 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 200 | 198 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 201 | 199 | ** SSL client identity */ |
| 202 | 200 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 203 | 201 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| @@ -604,15 +602,10 @@ | ||
| 604 | 602 | #endif |
| 605 | 603 | g.mainTimerId = fossil_timer_start(); |
| 606 | 604 | g.zVfsName = find_option("vfs",0,1); |
| 607 | 605 | if( g.zVfsName==0 ){ |
| 608 | 606 | g.zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 609 | -#if defined(__CYGWIN__) | |
| 610 | - if( g.zVfsName==0 ){ | |
| 611 | - g.zVfsName = "win32-longpath"; | |
| 612 | - } | |
| 613 | -#endif | |
| 614 | 607 | } |
| 615 | 608 | if( g.zVfsName ){ |
| 616 | 609 | sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); |
| 617 | 610 | if( pVfs ){ |
| 618 | 611 | sqlite3_vfs_register(pVfs, 1); |
| @@ -1070,11 +1063,11 @@ | ||
| 1070 | 1063 | if( j>0 ){ |
| 1071 | 1064 | @ </ul></td> |
| 1072 | 1065 | } |
| 1073 | 1066 | @ </tr></table> |
| 1074 | 1067 | |
| 1075 | - @ <h1>Available pages:</h1> | |
| 1068 | + @ <h1>Available web UI pages:</h1> | |
| 1076 | 1069 | @ (Only pages with help text are linked.) |
| 1077 | 1070 | @ <table border="0"><tr> |
| 1078 | 1071 | for(i=j=0; i<count(aCommand); i++){ |
| 1079 | 1072 | const char *z = aCommand[i].zName; |
| 1080 | 1073 | if( '/'!=*z ) continue; |
| 1081 | 1074 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -112,15 +112,10 @@ | |
| 112 | void *xPostEval; /* Optional, called after Tcl_Eval*(). */ |
| 113 | void *pPostContext; /* Optional, provided to xPostEval(). */ |
| 114 | }; |
| 115 | #endif |
| 116 | |
| 117 | /* |
| 118 | ** All global variables are in this structure. |
| 119 | */ |
| 120 | #define GLOBAL_URL() ((UrlData *)(&g.urlIsFile)) |
| 121 | |
| 122 | struct Global { |
| 123 | int argc; char **argv; /* Command-line arguments to the program */ |
| 124 | char *nameOfExe; /* Full path of executable. */ |
| 125 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 126 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -171,11 +166,12 @@ | |
| 171 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 172 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 173 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 174 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 175 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 176 | |
| 177 | /* |
| 178 | ** NOTE: These members MUST be kept in sync with those in the "UrlData" |
| 179 | ** structure defined in "url.c". |
| 180 | */ |
| 181 | int urlIsFile; /* True if a "file:" url */ |
| @@ -194,10 +190,12 @@ | |
| 194 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 195 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 196 | int useProxy; /* Used to remember that a proxy is in use */ |
| 197 | char *proxyUrlPath; |
| 198 | int proxyOrigPort; /* Tunneled port number for https through proxy */ |
| 199 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 200 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 201 | ** SSL client identity */ |
| 202 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 203 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| @@ -604,15 +602,10 @@ | |
| 604 | #endif |
| 605 | g.mainTimerId = fossil_timer_start(); |
| 606 | g.zVfsName = find_option("vfs",0,1); |
| 607 | if( g.zVfsName==0 ){ |
| 608 | g.zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 609 | #if defined(__CYGWIN__) |
| 610 | if( g.zVfsName==0 ){ |
| 611 | g.zVfsName = "win32-longpath"; |
| 612 | } |
| 613 | #endif |
| 614 | } |
| 615 | if( g.zVfsName ){ |
| 616 | sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); |
| 617 | if( pVfs ){ |
| 618 | sqlite3_vfs_register(pVfs, 1); |
| @@ -1070,11 +1063,11 @@ | |
| 1070 | if( j>0 ){ |
| 1071 | @ </ul></td> |
| 1072 | } |
| 1073 | @ </tr></table> |
| 1074 | |
| 1075 | @ <h1>Available pages:</h1> |
| 1076 | @ (Only pages with help text are linked.) |
| 1077 | @ <table border="0"><tr> |
| 1078 | for(i=j=0; i<count(aCommand); i++){ |
| 1079 | const char *z = aCommand[i].zName; |
| 1080 | if( '/'!=*z ) continue; |
| 1081 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -112,15 +112,10 @@ | |
| 112 | void *xPostEval; /* Optional, called after Tcl_Eval*(). */ |
| 113 | void *pPostContext; /* Optional, provided to xPostEval(). */ |
| 114 | }; |
| 115 | #endif |
| 116 | |
| 117 | struct Global { |
| 118 | int argc; char **argv; /* Command-line arguments to the program */ |
| 119 | char *nameOfExe; /* Full path of executable. */ |
| 120 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 121 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -171,11 +166,12 @@ | |
| 166 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 167 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 168 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 169 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 170 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 171 | UrlData url; /* Information about current URL */ |
| 172 | #if 0 |
| 173 | /* |
| 174 | ** NOTE: These members MUST be kept in sync with those in the "UrlData" |
| 175 | ** structure defined in "url.c". |
| 176 | */ |
| 177 | int urlIsFile; /* True if a "file:" url */ |
| @@ -194,10 +190,12 @@ | |
| 190 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 191 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 192 | int useProxy; /* Used to remember that a proxy is in use */ |
| 193 | char *proxyUrlPath; |
| 194 | int proxyOrigPort; /* Tunneled port number for https through proxy */ |
| 195 | #endif |
| 196 | |
| 197 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 198 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 199 | ** SSL client identity */ |
| 200 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 201 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| @@ -604,15 +602,10 @@ | |
| 602 | #endif |
| 603 | g.mainTimerId = fossil_timer_start(); |
| 604 | g.zVfsName = find_option("vfs",0,1); |
| 605 | if( g.zVfsName==0 ){ |
| 606 | g.zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 607 | } |
| 608 | if( g.zVfsName ){ |
| 609 | sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); |
| 610 | if( pVfs ){ |
| 611 | sqlite3_vfs_register(pVfs, 1); |
| @@ -1070,11 +1063,11 @@ | |
| 1063 | if( j>0 ){ |
| 1064 | @ </ul></td> |
| 1065 | } |
| 1066 | @ </tr></table> |
| 1067 | |
| 1068 | @ <h1>Available web UI pages:</h1> |
| 1069 | @ (Only pages with help text are linked.) |
| 1070 | @ <table border="0"><tr> |
| 1071 | for(i=j=0; i<count(aCommand); i++){ |
| 1072 | const char *z = aCommand[i].zName; |
| 1073 | if( '/'!=*z ) continue; |
| 1074 |
+1
-8
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -400,18 +400,11 @@ | ||
| 400 | 400 | # using -lsqlite3. |
| 401 | 401 | SQLITE3_OBJ.1 = |
| 402 | 402 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 403 | 403 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 404 | 404 | |
| 405 | -# The FOSSIL_ENABLE_TCL variable may be undefined, set to 0, or set to 1. | |
| 406 | -# If it is set to 1, then we need to build the Tcl integration code and | |
| 407 | -# link to the Tcl library. | |
| 408 | -TCL_OBJ.0 = | |
| 409 | -TCL_OBJ.1 = $(OBJDIR)/th_tcl.o | |
| 410 | -TCL_OBJ. = $(TCL_OBJ.0) | |
| 411 | - | |
| 412 | -EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) $(OBJDIR)/cson_amalgamation.o | |
| 405 | +EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o | |
| 413 | 406 | |
| 414 | 407 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 415 | 408 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 416 | 409 | |
| 417 | 410 | # This rule prevents make from using its default rules to try build |
| 418 | 411 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -400,18 +400,11 @@ | |
| 400 | # using -lsqlite3. |
| 401 | SQLITE3_OBJ.1 = |
| 402 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 403 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 404 | |
| 405 | # The FOSSIL_ENABLE_TCL variable may be undefined, set to 0, or set to 1. |
| 406 | # If it is set to 1, then we need to build the Tcl integration code and |
| 407 | # link to the Tcl library. |
| 408 | TCL_OBJ.0 = |
| 409 | TCL_OBJ.1 = $(OBJDIR)/th_tcl.o |
| 410 | TCL_OBJ. = $(TCL_OBJ.0) |
| 411 | |
| 412 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) $(OBJDIR)/cson_amalgamation.o |
| 413 | |
| 414 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 415 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 416 | |
| 417 | # This rule prevents make from using its default rules to try build |
| 418 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -400,18 +400,11 @@ | |
| 400 | # using -lsqlite3. |
| 401 | SQLITE3_OBJ.1 = |
| 402 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 403 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 404 | |
| 405 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o |
| 406 | |
| 407 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 408 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 409 | |
| 410 | # This rule prevents make from using its default rules to try build |
| 411 |
+9
-29
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -268,23 +268,16 @@ | ||
| 268 | 268 | # using -lsqlite3. |
| 269 | 269 | SQLITE3_OBJ.1 = |
| 270 | 270 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 271 | 271 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 272 | 272 | |
| 273 | -# The FOSSIL_ENABLE_TCL variable may be undefined, set to 0, or set to 1. | |
| 274 | -# If it is set to 1, then we need to build the Tcl integration code and | |
| 275 | -# link to the Tcl library. | |
| 276 | -TCL_OBJ.0 = | |
| 277 | -TCL_OBJ.1 = $(OBJDIR)/th_tcl.o | |
| 278 | -TCL_OBJ. = $(TCL_OBJ.0) | |
| 279 | - | |
| 280 | 273 | EXTRAOBJ = \ |
| 281 | 274 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 282 | 275 | $(OBJDIR)/shell.o \ |
| 283 | 276 | $(OBJDIR)/th.o \ |
| 284 | 277 | $(OBJDIR)/th_lang.o \ |
| 285 | - $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \ | |
| 278 | + $(OBJDIR)/th_tcl.o \ | |
| 286 | 279 | $(OBJDIR)/cson_amalgamation.o |
| 287 | 280 | |
| 288 | 281 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 289 | 282 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 290 | 283 | |
| @@ -451,12 +444,12 @@ | ||
| 451 | 444 | #### The directories where the OpenSSL include and library files are located. |
| 452 | 445 | # The recommended usage here is to use the Sysinternals junction tool |
| 453 | 446 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 454 | 447 | # Fossil source code directory and the target OpenSSL source directory. |
| 455 | 448 | # |
| 456 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1f/include | |
| 457 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1f | |
| 449 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1g/include | |
| 450 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1g | |
| 458 | 451 | |
| 459 | 452 | #### Either the directory where the Tcl library is installed or the Tcl |
| 460 | 453 | # source code directory resides (depending on the value of the macro |
| 461 | 454 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 462 | 455 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -724,16 +717,13 @@ | ||
| 724 | 717 | EXTRAOBJ = \ |
| 725 | 718 | $(OBJDIR)/sqlite3.o \ |
| 726 | 719 | $(OBJDIR)/shell.o \ |
| 727 | 720 | $(OBJDIR)/th.o \ |
| 728 | 721 | $(OBJDIR)/th_lang.o \ |
| 722 | + $(OBJDIR)/th_tcl.o \ | |
| 729 | 723 | $(OBJDIR)/cson_amalgamation.o |
| 730 | 724 | |
| 731 | -ifdef FOSSIL_ENABLE_TCL | |
| 732 | -EXTRAOBJ += $(OBJDIR)/th_tcl.o | |
| 733 | -endif | |
| 734 | - | |
| 735 | 725 | zlib: |
| 736 | 726 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 737 | 727 | |
| 738 | 728 | clean-zlib: |
| 739 | 729 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean |
| @@ -824,14 +814,12 @@ | ||
| 824 | 814 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n" |
| 825 | 815 | |
| 826 | 816 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 827 | 817 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 828 | 818 | |
| 829 | -writeln {ifdef FOSSIL_ENABLE_TCL | |
| 830 | -$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c | |
| 831 | - $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o | |
| 832 | -endif} | |
| 819 | +writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" | |
| 820 | +writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" | |
| 833 | 821 | |
| 834 | 822 | close $output_file |
| 835 | 823 | # |
| 836 | 824 | # End of the win/Makefile.mingw output |
| 837 | 825 | ############################################################################## |
| @@ -1024,12 +1012,12 @@ | ||
| 1024 | 1012 | |
| 1025 | 1013 | # Uncomment to enable Tcl support |
| 1026 | 1014 | # FOSSIL_ENABLE_TCL = 1 |
| 1027 | 1015 | |
| 1028 | 1016 | !ifdef FOSSIL_ENABLE_SSL |
| 1029 | -SSLINCDIR = $(B)\compat\openssl-1.0.1f\include | |
| 1030 | -SSLLIBDIR = $(B)\compat\openssl-1.0.1f\out32 | |
| 1017 | +SSLINCDIR = $(B)\compat\openssl-1.0.1g\include | |
| 1018 | +SSLLIBDIR = $(B)\compat\openssl-1.0.1g\out32 | |
| 1031 | 1019 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1032 | 1020 | !endif |
| 1033 | 1021 | |
| 1034 | 1022 | !ifdef FOSSIL_ENABLE_TCL |
| 1035 | 1023 | TCLDIR = $(B)\compat\tcl-8.6 |
| @@ -1107,11 +1095,11 @@ | ||
| 1107 | 1095 | writeln -nonewline " " |
| 1108 | 1096 | } |
| 1109 | 1097 | writeln -nonewline "${s}_.c"; incr i |
| 1110 | 1098 | } |
| 1111 | 1099 | writeln "\n" |
| 1112 | -set AdditionalObj [list shell sqlite3 th th_lang cson_amalgamation] | |
| 1100 | +set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation] | |
| 1113 | 1101 | writeln -nonewline "OBJ = " |
| 1114 | 1102 | set i 0 |
| 1115 | 1103 | foreach s [lsort [concat $src $AdditionalObj]] { |
| 1116 | 1104 | if {$i > 0} { |
| 1117 | 1105 | writeln " \\" |
| @@ -1119,13 +1107,10 @@ | ||
| 1119 | 1107 | } |
| 1120 | 1108 | writeln -nonewline "\$(OX)\\$s\$O"; incr i |
| 1121 | 1109 | } |
| 1122 | 1110 | writeln " \\" |
| 1123 | 1111 | writeln -nonewline " \$(OX)\\fossil.res\n\n" |
| 1124 | -writeln "!ifdef FOSSIL_ENABLE_TCL" | |
| 1125 | -writeln "OBJ = \$(OBJ) \$(OX)\\th_tcl\$O" | |
| 1126 | -writeln "!endif" | |
| 1127 | 1112 | writeln { |
| 1128 | 1113 | APPNAME = $(OX)\fossil$(E) |
| 1129 | 1114 | PDBNAME = $(OX)\fossil$(P) |
| 1130 | 1115 | |
| 1131 | 1116 | all: $(OX) $(APPNAME) |
| @@ -1142,14 +1127,11 @@ | ||
| 1142 | 1127 | set redir {>} |
| 1143 | 1128 | foreach s [lsort [concat $src $AdditionalObj]] { |
| 1144 | 1129 | writeln "\techo \$(OX)\\$s.obj $redir \$@" |
| 1145 | 1130 | set redir {>>} |
| 1146 | 1131 | } |
| 1147 | -writeln "!ifdef FOSSIL_ENABLE_TCL" | |
| 1148 | -writeln "\techo \$(OX)\\th_tcl.obj $redir \$@" | |
| 1149 | 1132 | set redir {>>} |
| 1150 | -writeln "!endif" | |
| 1151 | 1133 | writeln "\techo \$(LIBS) $redir \$@" |
| 1152 | 1134 | writeln { |
| 1153 | 1135 | $(OX): |
| 1154 | 1136 | @-mkdir $@ |
| 1155 | 1137 | |
| @@ -1175,14 +1157,12 @@ | ||
| 1175 | 1157 | $(TCC) /Fo$@ -c $** |
| 1176 | 1158 | |
| 1177 | 1159 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 1178 | 1160 | $(TCC) /Fo$@ -c $** |
| 1179 | 1161 | |
| 1180 | -!ifdef FOSSIL_ENABLE_TCL | |
| 1181 | 1162 | $(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c |
| 1182 | 1163 | $(TCC) /Fo$@ -c $** |
| 1183 | -!endif | |
| 1184 | 1164 | |
| 1185 | 1165 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 1186 | 1166 | $** > $@ |
| 1187 | 1167 | $(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c |
| 1188 | 1168 | $(TCC) /Fo$@ /c $** |
| 1189 | 1169 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -268,23 +268,16 @@ | |
| 268 | # using -lsqlite3. |
| 269 | SQLITE3_OBJ.1 = |
| 270 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 271 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 272 | |
| 273 | # The FOSSIL_ENABLE_TCL variable may be undefined, set to 0, or set to 1. |
| 274 | # If it is set to 1, then we need to build the Tcl integration code and |
| 275 | # link to the Tcl library. |
| 276 | TCL_OBJ.0 = |
| 277 | TCL_OBJ.1 = $(OBJDIR)/th_tcl.o |
| 278 | TCL_OBJ. = $(TCL_OBJ.0) |
| 279 | |
| 280 | EXTRAOBJ = \ |
| 281 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 282 | $(OBJDIR)/shell.o \ |
| 283 | $(OBJDIR)/th.o \ |
| 284 | $(OBJDIR)/th_lang.o \ |
| 285 | $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \ |
| 286 | $(OBJDIR)/cson_amalgamation.o |
| 287 | |
| 288 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 289 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 290 | |
| @@ -451,12 +444,12 @@ | |
| 451 | #### The directories where the OpenSSL include and library files are located. |
| 452 | # The recommended usage here is to use the Sysinternals junction tool |
| 453 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 454 | # Fossil source code directory and the target OpenSSL source directory. |
| 455 | # |
| 456 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1f/include |
| 457 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1f |
| 458 | |
| 459 | #### Either the directory where the Tcl library is installed or the Tcl |
| 460 | # source code directory resides (depending on the value of the macro |
| 461 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 462 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -724,16 +717,13 @@ | |
| 724 | EXTRAOBJ = \ |
| 725 | $(OBJDIR)/sqlite3.o \ |
| 726 | $(OBJDIR)/shell.o \ |
| 727 | $(OBJDIR)/th.o \ |
| 728 | $(OBJDIR)/th_lang.o \ |
| 729 | $(OBJDIR)/cson_amalgamation.o |
| 730 | |
| 731 | ifdef FOSSIL_ENABLE_TCL |
| 732 | EXTRAOBJ += $(OBJDIR)/th_tcl.o |
| 733 | endif |
| 734 | |
| 735 | zlib: |
| 736 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 737 | |
| 738 | clean-zlib: |
| 739 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean |
| @@ -824,14 +814,12 @@ | |
| 824 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n" |
| 825 | |
| 826 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 827 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 828 | |
| 829 | writeln {ifdef FOSSIL_ENABLE_TCL |
| 830 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 831 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 832 | endif} |
| 833 | |
| 834 | close $output_file |
| 835 | # |
| 836 | # End of the win/Makefile.mingw output |
| 837 | ############################################################################## |
| @@ -1024,12 +1012,12 @@ | |
| 1024 | |
| 1025 | # Uncomment to enable Tcl support |
| 1026 | # FOSSIL_ENABLE_TCL = 1 |
| 1027 | |
| 1028 | !ifdef FOSSIL_ENABLE_SSL |
| 1029 | SSLINCDIR = $(B)\compat\openssl-1.0.1f\include |
| 1030 | SSLLIBDIR = $(B)\compat\openssl-1.0.1f\out32 |
| 1031 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1032 | !endif |
| 1033 | |
| 1034 | !ifdef FOSSIL_ENABLE_TCL |
| 1035 | TCLDIR = $(B)\compat\tcl-8.6 |
| @@ -1107,11 +1095,11 @@ | |
| 1107 | writeln -nonewline " " |
| 1108 | } |
| 1109 | writeln -nonewline "${s}_.c"; incr i |
| 1110 | } |
| 1111 | writeln "\n" |
| 1112 | set AdditionalObj [list shell sqlite3 th th_lang cson_amalgamation] |
| 1113 | writeln -nonewline "OBJ = " |
| 1114 | set i 0 |
| 1115 | foreach s [lsort [concat $src $AdditionalObj]] { |
| 1116 | if {$i > 0} { |
| 1117 | writeln " \\" |
| @@ -1119,13 +1107,10 @@ | |
| 1119 | } |
| 1120 | writeln -nonewline "\$(OX)\\$s\$O"; incr i |
| 1121 | } |
| 1122 | writeln " \\" |
| 1123 | writeln -nonewline " \$(OX)\\fossil.res\n\n" |
| 1124 | writeln "!ifdef FOSSIL_ENABLE_TCL" |
| 1125 | writeln "OBJ = \$(OBJ) \$(OX)\\th_tcl\$O" |
| 1126 | writeln "!endif" |
| 1127 | writeln { |
| 1128 | APPNAME = $(OX)\fossil$(E) |
| 1129 | PDBNAME = $(OX)\fossil$(P) |
| 1130 | |
| 1131 | all: $(OX) $(APPNAME) |
| @@ -1142,14 +1127,11 @@ | |
| 1142 | set redir {>} |
| 1143 | foreach s [lsort [concat $src $AdditionalObj]] { |
| 1144 | writeln "\techo \$(OX)\\$s.obj $redir \$@" |
| 1145 | set redir {>>} |
| 1146 | } |
| 1147 | writeln "!ifdef FOSSIL_ENABLE_TCL" |
| 1148 | writeln "\techo \$(OX)\\th_tcl.obj $redir \$@" |
| 1149 | set redir {>>} |
| 1150 | writeln "!endif" |
| 1151 | writeln "\techo \$(LIBS) $redir \$@" |
| 1152 | writeln { |
| 1153 | $(OX): |
| 1154 | @-mkdir $@ |
| 1155 | |
| @@ -1175,14 +1157,12 @@ | |
| 1175 | $(TCC) /Fo$@ -c $** |
| 1176 | |
| 1177 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 1178 | $(TCC) /Fo$@ -c $** |
| 1179 | |
| 1180 | !ifdef FOSSIL_ENABLE_TCL |
| 1181 | $(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c |
| 1182 | $(TCC) /Fo$@ -c $** |
| 1183 | !endif |
| 1184 | |
| 1185 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 1186 | $** > $@ |
| 1187 | $(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c |
| 1188 | $(TCC) /Fo$@ /c $** |
| 1189 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -268,23 +268,16 @@ | |
| 268 | # using -lsqlite3. |
| 269 | SQLITE3_OBJ.1 = |
| 270 | SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o |
| 271 | SQLITE3_OBJ. = $(SQLITE3_OBJ.0) |
| 272 | |
| 273 | EXTRAOBJ = \ |
| 274 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 275 | $(OBJDIR)/shell.o \ |
| 276 | $(OBJDIR)/th.o \ |
| 277 | $(OBJDIR)/th_lang.o \ |
| 278 | $(OBJDIR)/th_tcl.o \ |
| 279 | $(OBJDIR)/cson_amalgamation.o |
| 280 | |
| 281 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 282 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 283 | |
| @@ -451,12 +444,12 @@ | |
| 444 | #### The directories where the OpenSSL include and library files are located. |
| 445 | # The recommended usage here is to use the Sysinternals junction tool |
| 446 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 447 | # Fossil source code directory and the target OpenSSL source directory. |
| 448 | # |
| 449 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1g/include |
| 450 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1g |
| 451 | |
| 452 | #### Either the directory where the Tcl library is installed or the Tcl |
| 453 | # source code directory resides (depending on the value of the macro |
| 454 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 455 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -724,16 +717,13 @@ | |
| 717 | EXTRAOBJ = \ |
| 718 | $(OBJDIR)/sqlite3.o \ |
| 719 | $(OBJDIR)/shell.o \ |
| 720 | $(OBJDIR)/th.o \ |
| 721 | $(OBJDIR)/th_lang.o \ |
| 722 | $(OBJDIR)/th_tcl.o \ |
| 723 | $(OBJDIR)/cson_amalgamation.o |
| 724 | |
| 725 | zlib: |
| 726 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 727 | |
| 728 | clean-zlib: |
| 729 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean |
| @@ -824,14 +814,12 @@ | |
| 814 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n" |
| 815 | |
| 816 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 817 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 818 | |
| 819 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 820 | writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 821 | |
| 822 | close $output_file |
| 823 | # |
| 824 | # End of the win/Makefile.mingw output |
| 825 | ############################################################################## |
| @@ -1024,12 +1012,12 @@ | |
| 1012 | |
| 1013 | # Uncomment to enable Tcl support |
| 1014 | # FOSSIL_ENABLE_TCL = 1 |
| 1015 | |
| 1016 | !ifdef FOSSIL_ENABLE_SSL |
| 1017 | SSLINCDIR = $(B)\compat\openssl-1.0.1g\include |
| 1018 | SSLLIBDIR = $(B)\compat\openssl-1.0.1g\out32 |
| 1019 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1020 | !endif |
| 1021 | |
| 1022 | !ifdef FOSSIL_ENABLE_TCL |
| 1023 | TCLDIR = $(B)\compat\tcl-8.6 |
| @@ -1107,11 +1095,11 @@ | |
| 1095 | writeln -nonewline " " |
| 1096 | } |
| 1097 | writeln -nonewline "${s}_.c"; incr i |
| 1098 | } |
| 1099 | writeln "\n" |
| 1100 | set AdditionalObj [list shell sqlite3 th th_lang th_tcl cson_amalgamation] |
| 1101 | writeln -nonewline "OBJ = " |
| 1102 | set i 0 |
| 1103 | foreach s [lsort [concat $src $AdditionalObj]] { |
| 1104 | if {$i > 0} { |
| 1105 | writeln " \\" |
| @@ -1119,13 +1107,10 @@ | |
| 1107 | } |
| 1108 | writeln -nonewline "\$(OX)\\$s\$O"; incr i |
| 1109 | } |
| 1110 | writeln " \\" |
| 1111 | writeln -nonewline " \$(OX)\\fossil.res\n\n" |
| 1112 | writeln { |
| 1113 | APPNAME = $(OX)\fossil$(E) |
| 1114 | PDBNAME = $(OX)\fossil$(P) |
| 1115 | |
| 1116 | all: $(OX) $(APPNAME) |
| @@ -1142,14 +1127,11 @@ | |
| 1127 | set redir {>} |
| 1128 | foreach s [lsort [concat $src $AdditionalObj]] { |
| 1129 | writeln "\techo \$(OX)\\$s.obj $redir \$@" |
| 1130 | set redir {>>} |
| 1131 | } |
| 1132 | set redir {>>} |
| 1133 | writeln "\techo \$(LIBS) $redir \$@" |
| 1134 | writeln { |
| 1135 | $(OX): |
| 1136 | @-mkdir $@ |
| 1137 | |
| @@ -1175,14 +1157,12 @@ | |
| 1157 | $(TCC) /Fo$@ -c $** |
| 1158 | |
| 1159 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 1160 | $(TCC) /Fo$@ -c $** |
| 1161 | |
| 1162 | $(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c |
| 1163 | $(TCC) /Fo$@ -c $** |
| 1164 | |
| 1165 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 1166 | $** > $@ |
| 1167 | $(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c |
| 1168 | $(TCC) /Fo$@ /c $** |
| 1169 |
+54
-59
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -135,16 +135,16 @@ | ||
| 135 | 135 | ** Clear the memory allocated in a manifest object |
| 136 | 136 | */ |
| 137 | 137 | void manifest_destroy(Manifest *p){ |
| 138 | 138 | if( p ){ |
| 139 | 139 | blob_reset(&p->content); |
| 140 | - free(p->aFile); | |
| 141 | - free(p->azParent); | |
| 142 | - free(p->azCChild); | |
| 143 | - free(p->aTag); | |
| 144 | - free(p->aField); | |
| 145 | - free(p->aCherrypick); | |
| 140 | + fossil_free(p->aFile); | |
| 141 | + fossil_free(p->azParent); | |
| 142 | + fossil_free(p->azCChild); | |
| 143 | + fossil_free(p->aTag); | |
| 144 | + fossil_free(p->aField); | |
| 145 | + fossil_free(p->aCherrypick); | |
| 146 | 146 | if( p->pBaseline ) manifest_destroy(p->pBaseline); |
| 147 | 147 | memset(p, 0, sizeof(*p)); |
| 148 | 148 | fossil_free(p); |
| 149 | 149 | } |
| 150 | 150 | } |
| @@ -1589,42 +1589,43 @@ | ||
| 1589 | 1589 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| 1590 | 1590 | zNewStatus = pManifest->aField[i].zValue; |
| 1591 | 1591 | } |
| 1592 | 1592 | } |
| 1593 | 1593 | if( zNewStatus ){ |
| 1594 | - blob_appendf(&comment, "%h ticket [%.10s]: <i>%h</i>", | |
| 1595 | - zNewStatus, pManifest->zTicketUuid, zTitle | |
| 1594 | + blob_appendf(&comment, "%h ticket [%s|%.10s]: <i>%h</i>", | |
| 1595 | + zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle | |
| 1596 | 1596 | ); |
| 1597 | 1597 | if( pManifest->nField>1 ){ |
| 1598 | 1598 | blob_appendf(&comment, " plus %d other change%s", |
| 1599 | 1599 | pManifest->nField-1, pManifest->nField==2 ? "" : "s"); |
| 1600 | 1600 | } |
| 1601 | - blob_appendf(&brief, "%h ticket [%.10s].", | |
| 1602 | - zNewStatus, pManifest->zTicketUuid); | |
| 1601 | + blob_appendf(&brief, "%h ticket [%s|%.10s].", | |
| 1602 | + zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); | |
| 1603 | 1603 | }else{ |
| 1604 | 1604 | zNewStatus = db_text("unknown", |
| 1605 | 1605 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1606 | 1606 | zStatusColumn, pManifest->zTicketUuid |
| 1607 | 1607 | ); |
| 1608 | - blob_appendf(&comment, "Ticket [%.10s] <i>%h</i> status still %h with " | |
| 1608 | + blob_appendf(&comment, "Ticket [%s|%.10s] <i>%h</i> status still %h with " | |
| 1609 | 1609 | "%d other change%s", |
| 1610 | - pManifest->zTicketUuid, zTitle, zNewStatus, pManifest->nField, | |
| 1611 | - pManifest->nField==1 ? "" : "s" | |
| 1610 | + pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, | |
| 1611 | + pManifest->nField, pManifest->nField==1 ? "" : "s" | |
| 1612 | 1612 | ); |
| 1613 | - free(zNewStatus); | |
| 1614 | - blob_appendf(&brief, "Ticket [%.10s]: %d change%s", | |
| 1615 | - pManifest->zTicketUuid, pManifest->nField, | |
| 1613 | + fossil_free(zNewStatus); | |
| 1614 | + blob_appendf(&brief, "Ticket [%s|%.10s]: %d change%s", | |
| 1615 | + pManifest->zTicketUuid, pManifest->zTicketUuid, pManifest->nField, | |
| 1616 | 1616 | pManifest->nField==1 ? "" : "s" |
| 1617 | 1617 | ); |
| 1618 | 1618 | } |
| 1619 | 1619 | }else{ |
| 1620 | - blob_appendf(&comment, "New ticket [%.10s] <i>%h</i>.", | |
| 1621 | - pManifest->zTicketUuid, zTitle | |
| 1620 | + blob_appendf(&comment, "New ticket [%s|%.10s] <i>%h</i>.", | |
| 1621 | + pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle | |
| 1622 | 1622 | ); |
| 1623 | - blob_appendf(&brief, "New ticket [%.10s].", pManifest->zTicketUuid); | |
| 1623 | + blob_appendf(&brief, "New ticket [%s|%.10s].", pManifest->zTicketUuid, | |
| 1624 | + pManifest->zTicketUuid); | |
| 1624 | 1625 | } |
| 1625 | - free(zTitle); | |
| 1626 | + fossil_free(zTitle); | |
| 1626 | 1627 | db_multi_exec( |
| 1627 | 1628 | "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)" |
| 1628 | 1629 | "VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)", |
| 1629 | 1630 | tktTagId, pManifest->rDate, rid, pManifest->zUser, |
| 1630 | 1631 | blob_str(&comment), blob_str(&brief) |
| @@ -1752,11 +1753,11 @@ | ||
| 1752 | 1753 | TAG_COMMENT, rid, p->rDate |
| 1753 | 1754 | ); |
| 1754 | 1755 | zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event" |
| 1755 | 1756 | " WHERE rowid=last_insert_rowid()"); |
| 1756 | 1757 | wiki_extract_links(zCom, rid, 0, p->rDate, 1, WIKI_INLINE); |
| 1757 | - free(zCom); | |
| 1758 | + fossil_free(zCom); | |
| 1758 | 1759 | |
| 1759 | 1760 | /* If this is a delta-manifest, record the fact that this repository |
| 1760 | 1761 | ** contains delta manifests, to free the "commit" logic to generate |
| 1761 | 1762 | ** new delta manifests. |
| 1762 | 1763 | */ |
| @@ -1821,11 +1822,11 @@ | ||
| 1821 | 1822 | char zLength[40]; |
| 1822 | 1823 | while( fossil_isspace(p->zWiki[0]) ) p->zWiki++; |
| 1823 | 1824 | nWiki = strlen(p->zWiki); |
| 1824 | 1825 | sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki); |
| 1825 | 1826 | tag_insert(zTag, 1, zLength, rid, p->rDate, rid); |
| 1826 | - free(zTag); | |
| 1827 | + fossil_free(zTag); | |
| 1827 | 1828 | prior = db_int(0, |
| 1828 | 1829 | "SELECT rid FROM tagxref" |
| 1829 | 1830 | " WHERE tagid=%d AND mtime<%.17g" |
| 1830 | 1831 | " ORDER BY mtime DESC", |
| 1831 | 1832 | tagid, p->rDate |
| @@ -1849,11 +1850,11 @@ | ||
| 1849 | 1850 | TAG_BGCOLOR, rid, |
| 1850 | 1851 | TAG_BGCOLOR, rid, |
| 1851 | 1852 | TAG_USER, rid, |
| 1852 | 1853 | TAG_COMMENT, rid |
| 1853 | 1854 | ); |
| 1854 | - free(zComment); | |
| 1855 | + fossil_free(zComment); | |
| 1855 | 1856 | } |
| 1856 | 1857 | if( p->type==CFTYPE_EVENT ){ |
| 1857 | 1858 | char *zTag = mprintf("event-%s", p->zEventId); |
| 1858 | 1859 | int tagid = tag_findid(zTag, 1); |
| 1859 | 1860 | int prior, subsequent; |
| @@ -1861,11 +1862,11 @@ | ||
| 1861 | 1862 | char zLength[40]; |
| 1862 | 1863 | while( fossil_isspace(p->zWiki[0]) ) p->zWiki++; |
| 1863 | 1864 | nWiki = strlen(p->zWiki); |
| 1864 | 1865 | sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki); |
| 1865 | 1866 | tag_insert(zTag, 1, zLength, rid, p->rDate, rid); |
| 1866 | - free(zTag); | |
| 1867 | + fossil_free(zTag); | |
| 1867 | 1868 | prior = db_int(0, |
| 1868 | 1869 | "SELECT rid FROM tagxref" |
| 1869 | 1870 | " WHERE tagid=%d AND mtime<%.17g AND rid!=%d" |
| 1870 | 1871 | " ORDER BY mtime DESC", |
| 1871 | 1872 | tagid, p->rDate, rid |
| @@ -1900,22 +1901,26 @@ | ||
| 1900 | 1901 | ); |
| 1901 | 1902 | } |
| 1902 | 1903 | } |
| 1903 | 1904 | if( p->type==CFTYPE_TICKET ){ |
| 1904 | 1905 | char *zTag; |
| 1905 | - | |
| 1906 | 1906 | assert( manifest_crosslink_busy==1 ); |
| 1907 | 1907 | zTag = mprintf("tkt-%s", p->zTicketUuid); |
| 1908 | 1908 | tag_insert(zTag, 1, 0, rid, p->rDate, rid); |
| 1909 | - free(zTag); | |
| 1909 | + fossil_free(zTag); | |
| 1910 | 1910 | db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)", |
| 1911 | 1911 | p->zTicketUuid); |
| 1912 | 1912 | } |
| 1913 | 1913 | if( p->type==CFTYPE_ATTACHMENT ){ |
| 1914 | + char *zComment = 0; | |
| 1915 | + char const isAdd = (p->zAttachSrc && p->zAttachSrc[0]) ? 1 : 0; | |
| 1916 | + char const attachToType = fossil_is_uuid(p->zAttachTarget) | |
| 1917 | + ? 't' /* attach to ticket */ | |
| 1918 | + : 'w' /* attach to wiki page */; | |
| 1914 | 1919 | db_multi_exec( |
| 1915 | 1920 | "INSERT INTO attachment(attachid, mtime, src, target," |
| 1916 | - "filename, comment, user)" | |
| 1921 | + "filename, comment, user)" | |
| 1917 | 1922 | "VALUES(%d,%.17g,%Q,%Q,%Q,%Q,%Q);", |
| 1918 | 1923 | rid, p->rDate, p->zAttachSrc, p->zAttachTarget, p->zAttachName, |
| 1919 | 1924 | (p->zComment ? p->zComment : ""), p->zUser |
| 1920 | 1925 | ); |
| 1921 | 1926 | db_multi_exec( |
| @@ -1924,45 +1929,35 @@ | ||
| 1924 | 1929 | " WHERE target=%Q AND filename=%Q))" |
| 1925 | 1930 | " WHERE target=%Q AND filename=%Q", |
| 1926 | 1931 | p->zAttachTarget, p->zAttachName, |
| 1927 | 1932 | p->zAttachTarget, p->zAttachName |
| 1928 | 1933 | ); |
| 1929 | - if( strlen(p->zAttachTarget)!=UUID_SIZE | |
| 1930 | - || !validate16(p->zAttachTarget, UUID_SIZE) | |
| 1931 | - ){ | |
| 1932 | - char *zComment; | |
| 1933 | - if( p->zAttachSrc && p->zAttachSrc[0] ){ | |
| 1934 | + if( 'w' == attachToType ){ | |
| 1935 | + if( isAdd ){ | |
| 1934 | 1936 | zComment = mprintf( |
| 1935 | - "Add attachment [/artifact/%S|%h] to wiki page [%h]", | |
| 1937 | + "Add attachment [/artifact/%s|%h] to wiki page [%h]", | |
| 1936 | 1938 | p->zAttachSrc, p->zAttachName, p->zAttachTarget); |
| 1937 | 1939 | }else{ |
| 1938 | 1940 | zComment = mprintf("Delete attachment \"%h\" from wiki page [%h]", |
| 1939 | 1941 | p->zAttachName, p->zAttachTarget); |
| 1940 | 1942 | } |
| 1941 | - db_multi_exec( | |
| 1942 | - "REPLACE INTO event(type,mtime,objid,user,comment)" | |
| 1943 | - "VALUES('w',%.17g,%d,%Q,%Q)", | |
| 1944 | - p->rDate, rid, p->zUser, zComment | |
| 1945 | - ); | |
| 1946 | - free(zComment); | |
| 1947 | - }else{ | |
| 1948 | - char *zComment; | |
| 1949 | - if( p->zAttachSrc && p->zAttachSrc[0] ){ | |
| 1950 | - zComment = mprintf( | |
| 1951 | - "Add attachment [/artifact/%S|%h] to ticket [%S]", | |
| 1952 | - p->zAttachSrc, p->zAttachName, p->zAttachTarget); | |
| 1953 | - }else{ | |
| 1954 | - zComment = mprintf("Delete attachment \"%h\" from ticket [%.10s]", | |
| 1955 | - p->zAttachName, p->zAttachTarget); | |
| 1956 | - } | |
| 1957 | - db_multi_exec( | |
| 1958 | - "REPLACE INTO event(type,mtime,objid,user,comment)" | |
| 1959 | - "VALUES('t',%.17g,%d,%Q,%Q)", | |
| 1960 | - p->rDate, rid, p->zUser, zComment | |
| 1961 | - ); | |
| 1962 | - free(zComment); | |
| 1963 | - } | |
| 1943 | + }else{ | |
| 1944 | + if( isAdd ){ | |
| 1945 | + zComment = mprintf( | |
| 1946 | + "Add attachment [/artifact/%s|%h] to ticket [%s|%.10s]", | |
| 1947 | + p->zAttachSrc, p->zAttachName, p->zAttachTarget, p->zAttachTarget); | |
| 1948 | + }else{ | |
| 1949 | + zComment = mprintf("Delete attachment \"%h\" from ticket [%s|%.10s]", | |
| 1950 | + p->zAttachName, p->zAttachTarget, p->zAttachTarget); | |
| 1951 | + } | |
| 1952 | + } | |
| 1953 | + db_multi_exec( | |
| 1954 | + "REPLACE INTO event(type,mtime,objid,user,comment)" | |
| 1955 | + "VALUES('%c',%.17g,%d,%Q,%Q)", | |
| 1956 | + attachToType, p->rDate, rid, p->zUser, zComment | |
| 1957 | + ); | |
| 1958 | + fossil_free(zComment); | |
| 1964 | 1959 | } |
| 1965 | 1960 | if( p->type==CFTYPE_CONTROL ){ |
| 1966 | 1961 | Blob comment; |
| 1967 | 1962 | int i; |
| 1968 | 1963 | const char *zName; |
| @@ -1978,12 +1973,12 @@ | ||
| 1978 | 1973 | for(i=0; i<p->nTag; i++){ |
| 1979 | 1974 | zTagUuid = p->aTag[i].zUuid; |
| 1980 | 1975 | if( !zTagUuid ) continue; |
| 1981 | 1976 | if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1982 | 1977 | blob_appendf(&comment, |
| 1983 | - " Edit [%S]:", | |
| 1984 | - zTagUuid); | |
| 1978 | + " Edit [%s|%.10s]:", | |
| 1979 | + zTagUuid, zTagUuid); | |
| 1985 | 1980 | branchMove = 0; |
| 1986 | 1981 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 1987 | 1982 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 1988 | 1983 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 1989 | 1984 | zScript = xfer_commit_code(); |
| @@ -1992,11 +1987,11 @@ | ||
| 1992 | 1987 | } |
| 1993 | 1988 | zName = p->aTag[i].zName; |
| 1994 | 1989 | zValue = p->aTag[i].zValue; |
| 1995 | 1990 | if( strcmp(zName, "*branch")==0 ){ |
| 1996 | 1991 | blob_appendf(&comment, |
| 1997 | - " Move to branch [/timeline?r=%h&nd&dp=%S&unhide | %h].", | |
| 1992 | + " Move to branch [/timeline?r=%h&nd&dp=%s&unhide | %h].", | |
| 1998 | 1993 | zValue, zTagUuid, zValue); |
| 1999 | 1994 | branchMove = 1; |
| 2000 | 1995 | continue; |
| 2001 | 1996 | }else if( strcmp(zName, "*bgcolor")==0 ){ |
| 2002 | 1997 | blob_appendf(&comment, |
| 2003 | 1998 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -135,16 +135,16 @@ | |
| 135 | ** Clear the memory allocated in a manifest object |
| 136 | */ |
| 137 | void manifest_destroy(Manifest *p){ |
| 138 | if( p ){ |
| 139 | blob_reset(&p->content); |
| 140 | free(p->aFile); |
| 141 | free(p->azParent); |
| 142 | free(p->azCChild); |
| 143 | free(p->aTag); |
| 144 | free(p->aField); |
| 145 | free(p->aCherrypick); |
| 146 | if( p->pBaseline ) manifest_destroy(p->pBaseline); |
| 147 | memset(p, 0, sizeof(*p)); |
| 148 | fossil_free(p); |
| 149 | } |
| 150 | } |
| @@ -1589,42 +1589,43 @@ | |
| 1589 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| 1590 | zNewStatus = pManifest->aField[i].zValue; |
| 1591 | } |
| 1592 | } |
| 1593 | if( zNewStatus ){ |
| 1594 | blob_appendf(&comment, "%h ticket [%.10s]: <i>%h</i>", |
| 1595 | zNewStatus, pManifest->zTicketUuid, zTitle |
| 1596 | ); |
| 1597 | if( pManifest->nField>1 ){ |
| 1598 | blob_appendf(&comment, " plus %d other change%s", |
| 1599 | pManifest->nField-1, pManifest->nField==2 ? "" : "s"); |
| 1600 | } |
| 1601 | blob_appendf(&brief, "%h ticket [%.10s].", |
| 1602 | zNewStatus, pManifest->zTicketUuid); |
| 1603 | }else{ |
| 1604 | zNewStatus = db_text("unknown", |
| 1605 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1606 | zStatusColumn, pManifest->zTicketUuid |
| 1607 | ); |
| 1608 | blob_appendf(&comment, "Ticket [%.10s] <i>%h</i> status still %h with " |
| 1609 | "%d other change%s", |
| 1610 | pManifest->zTicketUuid, zTitle, zNewStatus, pManifest->nField, |
| 1611 | pManifest->nField==1 ? "" : "s" |
| 1612 | ); |
| 1613 | free(zNewStatus); |
| 1614 | blob_appendf(&brief, "Ticket [%.10s]: %d change%s", |
| 1615 | pManifest->zTicketUuid, pManifest->nField, |
| 1616 | pManifest->nField==1 ? "" : "s" |
| 1617 | ); |
| 1618 | } |
| 1619 | }else{ |
| 1620 | blob_appendf(&comment, "New ticket [%.10s] <i>%h</i>.", |
| 1621 | pManifest->zTicketUuid, zTitle |
| 1622 | ); |
| 1623 | blob_appendf(&brief, "New ticket [%.10s].", pManifest->zTicketUuid); |
| 1624 | } |
| 1625 | free(zTitle); |
| 1626 | db_multi_exec( |
| 1627 | "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)" |
| 1628 | "VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)", |
| 1629 | tktTagId, pManifest->rDate, rid, pManifest->zUser, |
| 1630 | blob_str(&comment), blob_str(&brief) |
| @@ -1752,11 +1753,11 @@ | |
| 1752 | TAG_COMMENT, rid, p->rDate |
| 1753 | ); |
| 1754 | zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event" |
| 1755 | " WHERE rowid=last_insert_rowid()"); |
| 1756 | wiki_extract_links(zCom, rid, 0, p->rDate, 1, WIKI_INLINE); |
| 1757 | free(zCom); |
| 1758 | |
| 1759 | /* If this is a delta-manifest, record the fact that this repository |
| 1760 | ** contains delta manifests, to free the "commit" logic to generate |
| 1761 | ** new delta manifests. |
| 1762 | */ |
| @@ -1821,11 +1822,11 @@ | |
| 1821 | char zLength[40]; |
| 1822 | while( fossil_isspace(p->zWiki[0]) ) p->zWiki++; |
| 1823 | nWiki = strlen(p->zWiki); |
| 1824 | sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki); |
| 1825 | tag_insert(zTag, 1, zLength, rid, p->rDate, rid); |
| 1826 | free(zTag); |
| 1827 | prior = db_int(0, |
| 1828 | "SELECT rid FROM tagxref" |
| 1829 | " WHERE tagid=%d AND mtime<%.17g" |
| 1830 | " ORDER BY mtime DESC", |
| 1831 | tagid, p->rDate |
| @@ -1849,11 +1850,11 @@ | |
| 1849 | TAG_BGCOLOR, rid, |
| 1850 | TAG_BGCOLOR, rid, |
| 1851 | TAG_USER, rid, |
| 1852 | TAG_COMMENT, rid |
| 1853 | ); |
| 1854 | free(zComment); |
| 1855 | } |
| 1856 | if( p->type==CFTYPE_EVENT ){ |
| 1857 | char *zTag = mprintf("event-%s", p->zEventId); |
| 1858 | int tagid = tag_findid(zTag, 1); |
| 1859 | int prior, subsequent; |
| @@ -1861,11 +1862,11 @@ | |
| 1861 | char zLength[40]; |
| 1862 | while( fossil_isspace(p->zWiki[0]) ) p->zWiki++; |
| 1863 | nWiki = strlen(p->zWiki); |
| 1864 | sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki); |
| 1865 | tag_insert(zTag, 1, zLength, rid, p->rDate, rid); |
| 1866 | free(zTag); |
| 1867 | prior = db_int(0, |
| 1868 | "SELECT rid FROM tagxref" |
| 1869 | " WHERE tagid=%d AND mtime<%.17g AND rid!=%d" |
| 1870 | " ORDER BY mtime DESC", |
| 1871 | tagid, p->rDate, rid |
| @@ -1900,22 +1901,26 @@ | |
| 1900 | ); |
| 1901 | } |
| 1902 | } |
| 1903 | if( p->type==CFTYPE_TICKET ){ |
| 1904 | char *zTag; |
| 1905 | |
| 1906 | assert( manifest_crosslink_busy==1 ); |
| 1907 | zTag = mprintf("tkt-%s", p->zTicketUuid); |
| 1908 | tag_insert(zTag, 1, 0, rid, p->rDate, rid); |
| 1909 | free(zTag); |
| 1910 | db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)", |
| 1911 | p->zTicketUuid); |
| 1912 | } |
| 1913 | if( p->type==CFTYPE_ATTACHMENT ){ |
| 1914 | db_multi_exec( |
| 1915 | "INSERT INTO attachment(attachid, mtime, src, target," |
| 1916 | "filename, comment, user)" |
| 1917 | "VALUES(%d,%.17g,%Q,%Q,%Q,%Q,%Q);", |
| 1918 | rid, p->rDate, p->zAttachSrc, p->zAttachTarget, p->zAttachName, |
| 1919 | (p->zComment ? p->zComment : ""), p->zUser |
| 1920 | ); |
| 1921 | db_multi_exec( |
| @@ -1924,45 +1929,35 @@ | |
| 1924 | " WHERE target=%Q AND filename=%Q))" |
| 1925 | " WHERE target=%Q AND filename=%Q", |
| 1926 | p->zAttachTarget, p->zAttachName, |
| 1927 | p->zAttachTarget, p->zAttachName |
| 1928 | ); |
| 1929 | if( strlen(p->zAttachTarget)!=UUID_SIZE |
| 1930 | || !validate16(p->zAttachTarget, UUID_SIZE) |
| 1931 | ){ |
| 1932 | char *zComment; |
| 1933 | if( p->zAttachSrc && p->zAttachSrc[0] ){ |
| 1934 | zComment = mprintf( |
| 1935 | "Add attachment [/artifact/%S|%h] to wiki page [%h]", |
| 1936 | p->zAttachSrc, p->zAttachName, p->zAttachTarget); |
| 1937 | }else{ |
| 1938 | zComment = mprintf("Delete attachment \"%h\" from wiki page [%h]", |
| 1939 | p->zAttachName, p->zAttachTarget); |
| 1940 | } |
| 1941 | db_multi_exec( |
| 1942 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| 1943 | "VALUES('w',%.17g,%d,%Q,%Q)", |
| 1944 | p->rDate, rid, p->zUser, zComment |
| 1945 | ); |
| 1946 | free(zComment); |
| 1947 | }else{ |
| 1948 | char *zComment; |
| 1949 | if( p->zAttachSrc && p->zAttachSrc[0] ){ |
| 1950 | zComment = mprintf( |
| 1951 | "Add attachment [/artifact/%S|%h] to ticket [%S]", |
| 1952 | p->zAttachSrc, p->zAttachName, p->zAttachTarget); |
| 1953 | }else{ |
| 1954 | zComment = mprintf("Delete attachment \"%h\" from ticket [%.10s]", |
| 1955 | p->zAttachName, p->zAttachTarget); |
| 1956 | } |
| 1957 | db_multi_exec( |
| 1958 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| 1959 | "VALUES('t',%.17g,%d,%Q,%Q)", |
| 1960 | p->rDate, rid, p->zUser, zComment |
| 1961 | ); |
| 1962 | free(zComment); |
| 1963 | } |
| 1964 | } |
| 1965 | if( p->type==CFTYPE_CONTROL ){ |
| 1966 | Blob comment; |
| 1967 | int i; |
| 1968 | const char *zName; |
| @@ -1978,12 +1973,12 @@ | |
| 1978 | for(i=0; i<p->nTag; i++){ |
| 1979 | zTagUuid = p->aTag[i].zUuid; |
| 1980 | if( !zTagUuid ) continue; |
| 1981 | if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1982 | blob_appendf(&comment, |
| 1983 | " Edit [%S]:", |
| 1984 | zTagUuid); |
| 1985 | branchMove = 0; |
| 1986 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 1987 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 1988 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 1989 | zScript = xfer_commit_code(); |
| @@ -1992,11 +1987,11 @@ | |
| 1992 | } |
| 1993 | zName = p->aTag[i].zName; |
| 1994 | zValue = p->aTag[i].zValue; |
| 1995 | if( strcmp(zName, "*branch")==0 ){ |
| 1996 | blob_appendf(&comment, |
| 1997 | " Move to branch [/timeline?r=%h&nd&dp=%S&unhide | %h].", |
| 1998 | zValue, zTagUuid, zValue); |
| 1999 | branchMove = 1; |
| 2000 | continue; |
| 2001 | }else if( strcmp(zName, "*bgcolor")==0 ){ |
| 2002 | blob_appendf(&comment, |
| 2003 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -135,16 +135,16 @@ | |
| 135 | ** Clear the memory allocated in a manifest object |
| 136 | */ |
| 137 | void manifest_destroy(Manifest *p){ |
| 138 | if( p ){ |
| 139 | blob_reset(&p->content); |
| 140 | fossil_free(p->aFile); |
| 141 | fossil_free(p->azParent); |
| 142 | fossil_free(p->azCChild); |
| 143 | fossil_free(p->aTag); |
| 144 | fossil_free(p->aField); |
| 145 | fossil_free(p->aCherrypick); |
| 146 | if( p->pBaseline ) manifest_destroy(p->pBaseline); |
| 147 | memset(p, 0, sizeof(*p)); |
| 148 | fossil_free(p); |
| 149 | } |
| 150 | } |
| @@ -1589,42 +1589,43 @@ | |
| 1589 | if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ |
| 1590 | zNewStatus = pManifest->aField[i].zValue; |
| 1591 | } |
| 1592 | } |
| 1593 | if( zNewStatus ){ |
| 1594 | blob_appendf(&comment, "%h ticket [%s|%.10s]: <i>%h</i>", |
| 1595 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1596 | ); |
| 1597 | if( pManifest->nField>1 ){ |
| 1598 | blob_appendf(&comment, " plus %d other change%s", |
| 1599 | pManifest->nField-1, pManifest->nField==2 ? "" : "s"); |
| 1600 | } |
| 1601 | blob_appendf(&brief, "%h ticket [%s|%.10s].", |
| 1602 | zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid); |
| 1603 | }else{ |
| 1604 | zNewStatus = db_text("unknown", |
| 1605 | "SELECT %s FROM ticket WHERE tkt_uuid='%s'", |
| 1606 | zStatusColumn, pManifest->zTicketUuid |
| 1607 | ); |
| 1608 | blob_appendf(&comment, "Ticket [%s|%.10s] <i>%h</i> status still %h with " |
| 1609 | "%d other change%s", |
| 1610 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus, |
| 1611 | pManifest->nField, pManifest->nField==1 ? "" : "s" |
| 1612 | ); |
| 1613 | fossil_free(zNewStatus); |
| 1614 | blob_appendf(&brief, "Ticket [%s|%.10s]: %d change%s", |
| 1615 | pManifest->zTicketUuid, pManifest->zTicketUuid, pManifest->nField, |
| 1616 | pManifest->nField==1 ? "" : "s" |
| 1617 | ); |
| 1618 | } |
| 1619 | }else{ |
| 1620 | blob_appendf(&comment, "New ticket [%s|%.10s] <i>%h</i>.", |
| 1621 | pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle |
| 1622 | ); |
| 1623 | blob_appendf(&brief, "New ticket [%s|%.10s].", pManifest->zTicketUuid, |
| 1624 | pManifest->zTicketUuid); |
| 1625 | } |
| 1626 | fossil_free(zTitle); |
| 1627 | db_multi_exec( |
| 1628 | "REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)" |
| 1629 | "VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)", |
| 1630 | tktTagId, pManifest->rDate, rid, pManifest->zUser, |
| 1631 | blob_str(&comment), blob_str(&brief) |
| @@ -1752,11 +1753,11 @@ | |
| 1753 | TAG_COMMENT, rid, p->rDate |
| 1754 | ); |
| 1755 | zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event" |
| 1756 | " WHERE rowid=last_insert_rowid()"); |
| 1757 | wiki_extract_links(zCom, rid, 0, p->rDate, 1, WIKI_INLINE); |
| 1758 | fossil_free(zCom); |
| 1759 | |
| 1760 | /* If this is a delta-manifest, record the fact that this repository |
| 1761 | ** contains delta manifests, to free the "commit" logic to generate |
| 1762 | ** new delta manifests. |
| 1763 | */ |
| @@ -1821,11 +1822,11 @@ | |
| 1822 | char zLength[40]; |
| 1823 | while( fossil_isspace(p->zWiki[0]) ) p->zWiki++; |
| 1824 | nWiki = strlen(p->zWiki); |
| 1825 | sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki); |
| 1826 | tag_insert(zTag, 1, zLength, rid, p->rDate, rid); |
| 1827 | fossil_free(zTag); |
| 1828 | prior = db_int(0, |
| 1829 | "SELECT rid FROM tagxref" |
| 1830 | " WHERE tagid=%d AND mtime<%.17g" |
| 1831 | " ORDER BY mtime DESC", |
| 1832 | tagid, p->rDate |
| @@ -1849,11 +1850,11 @@ | |
| 1850 | TAG_BGCOLOR, rid, |
| 1851 | TAG_BGCOLOR, rid, |
| 1852 | TAG_USER, rid, |
| 1853 | TAG_COMMENT, rid |
| 1854 | ); |
| 1855 | fossil_free(zComment); |
| 1856 | } |
| 1857 | if( p->type==CFTYPE_EVENT ){ |
| 1858 | char *zTag = mprintf("event-%s", p->zEventId); |
| 1859 | int tagid = tag_findid(zTag, 1); |
| 1860 | int prior, subsequent; |
| @@ -1861,11 +1862,11 @@ | |
| 1862 | char zLength[40]; |
| 1863 | while( fossil_isspace(p->zWiki[0]) ) p->zWiki++; |
| 1864 | nWiki = strlen(p->zWiki); |
| 1865 | sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki); |
| 1866 | tag_insert(zTag, 1, zLength, rid, p->rDate, rid); |
| 1867 | fossil_free(zTag); |
| 1868 | prior = db_int(0, |
| 1869 | "SELECT rid FROM tagxref" |
| 1870 | " WHERE tagid=%d AND mtime<%.17g AND rid!=%d" |
| 1871 | " ORDER BY mtime DESC", |
| 1872 | tagid, p->rDate, rid |
| @@ -1900,22 +1901,26 @@ | |
| 1901 | ); |
| 1902 | } |
| 1903 | } |
| 1904 | if( p->type==CFTYPE_TICKET ){ |
| 1905 | char *zTag; |
| 1906 | assert( manifest_crosslink_busy==1 ); |
| 1907 | zTag = mprintf("tkt-%s", p->zTicketUuid); |
| 1908 | tag_insert(zTag, 1, 0, rid, p->rDate, rid); |
| 1909 | fossil_free(zTag); |
| 1910 | db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)", |
| 1911 | p->zTicketUuid); |
| 1912 | } |
| 1913 | if( p->type==CFTYPE_ATTACHMENT ){ |
| 1914 | char *zComment = 0; |
| 1915 | char const isAdd = (p->zAttachSrc && p->zAttachSrc[0]) ? 1 : 0; |
| 1916 | char const attachToType = fossil_is_uuid(p->zAttachTarget) |
| 1917 | ? 't' /* attach to ticket */ |
| 1918 | : 'w' /* attach to wiki page */; |
| 1919 | db_multi_exec( |
| 1920 | "INSERT INTO attachment(attachid, mtime, src, target," |
| 1921 | "filename, comment, user)" |
| 1922 | "VALUES(%d,%.17g,%Q,%Q,%Q,%Q,%Q);", |
| 1923 | rid, p->rDate, p->zAttachSrc, p->zAttachTarget, p->zAttachName, |
| 1924 | (p->zComment ? p->zComment : ""), p->zUser |
| 1925 | ); |
| 1926 | db_multi_exec( |
| @@ -1924,45 +1929,35 @@ | |
| 1929 | " WHERE target=%Q AND filename=%Q))" |
| 1930 | " WHERE target=%Q AND filename=%Q", |
| 1931 | p->zAttachTarget, p->zAttachName, |
| 1932 | p->zAttachTarget, p->zAttachName |
| 1933 | ); |
| 1934 | if( 'w' == attachToType ){ |
| 1935 | if( isAdd ){ |
| 1936 | zComment = mprintf( |
| 1937 | "Add attachment [/artifact/%s|%h] to wiki page [%h]", |
| 1938 | p->zAttachSrc, p->zAttachName, p->zAttachTarget); |
| 1939 | }else{ |
| 1940 | zComment = mprintf("Delete attachment \"%h\" from wiki page [%h]", |
| 1941 | p->zAttachName, p->zAttachTarget); |
| 1942 | } |
| 1943 | }else{ |
| 1944 | if( isAdd ){ |
| 1945 | zComment = mprintf( |
| 1946 | "Add attachment [/artifact/%s|%h] to ticket [%s|%.10s]", |
| 1947 | p->zAttachSrc, p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1948 | }else{ |
| 1949 | zComment = mprintf("Delete attachment \"%h\" from ticket [%s|%.10s]", |
| 1950 | p->zAttachName, p->zAttachTarget, p->zAttachTarget); |
| 1951 | } |
| 1952 | } |
| 1953 | db_multi_exec( |
| 1954 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| 1955 | "VALUES('%c',%.17g,%d,%Q,%Q)", |
| 1956 | attachToType, p->rDate, rid, p->zUser, zComment |
| 1957 | ); |
| 1958 | fossil_free(zComment); |
| 1959 | } |
| 1960 | if( p->type==CFTYPE_CONTROL ){ |
| 1961 | Blob comment; |
| 1962 | int i; |
| 1963 | const char *zName; |
| @@ -1978,12 +1973,12 @@ | |
| 1973 | for(i=0; i<p->nTag; i++){ |
| 1974 | zTagUuid = p->aTag[i].zUuid; |
| 1975 | if( !zTagUuid ) continue; |
| 1976 | if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1977 | blob_appendf(&comment, |
| 1978 | " Edit [%s|%.10s]:", |
| 1979 | zTagUuid, zTagUuid); |
| 1980 | branchMove = 0; |
| 1981 | if( permitHooks && db_exists("SELECT 1 FROM event, blob" |
| 1982 | " WHERE event.type='ci' AND event.objid=blob.rid" |
| 1983 | " AND blob.uuid='%s'", zTagUuid) ){ |
| 1984 | zScript = xfer_commit_code(); |
| @@ -1992,11 +1987,11 @@ | |
| 1987 | } |
| 1988 | zName = p->aTag[i].zName; |
| 1989 | zValue = p->aTag[i].zValue; |
| 1990 | if( strcmp(zName, "*branch")==0 ){ |
| 1991 | blob_appendf(&comment, |
| 1992 | " Move to branch [/timeline?r=%h&nd&dp=%s&unhide | %h].", |
| 1993 | zValue, zTagUuid, zValue); |
| 1994 | branchMove = 1; |
| 1995 | continue; |
| 1996 | }else if( strcmp(zName, "*bgcolor")==0 ){ |
| 1997 | blob_appendf(&comment, |
| 1998 |
+176
-70
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -402,16 +402,17 @@ | ||
| 402 | 402 | canonical16(z, strlen(z)); |
| 403 | 403 | db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z); |
| 404 | 404 | while( db_step(&q)==SQLITE_ROW ){ |
| 405 | 405 | const char *zUuid = db_column_text(&q, 0); |
| 406 | 406 | int rid = db_column_int(&q, 1); |
| 407 | - @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%S(zUuid)"> | |
| 408 | - @ %S(zUuid)</a> - | |
| 407 | + @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> | |
| 408 | + @ %s(zUuid)</a> - | |
| 409 | 409 | object_description(rid, 0, 0); |
| 410 | 410 | @ </p></li> |
| 411 | 411 | } |
| 412 | 412 | @ </ol> |
| 413 | + db_finalize(&q); | |
| 413 | 414 | style_footer(); |
| 414 | 415 | } |
| 415 | 416 | |
| 416 | 417 | /* |
| 417 | 418 | ** Convert the name in CGI parameter zParamName into a rid and return that |
| @@ -433,10 +434,152 @@ | ||
| 433 | 434 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 434 | 435 | rid = 0; |
| 435 | 436 | } |
| 436 | 437 | return rid; |
| 437 | 438 | } |
| 439 | + | |
| 440 | +/* | |
| 441 | +** Generate a description of artifact "rid" | |
| 442 | +*/ | |
| 443 | +static void whatis_rid(int rid, int verboseFlag){ | |
| 444 | + Stmt q; | |
| 445 | + int cnt; | |
| 446 | + | |
| 447 | + /* Basic information about the object. */ | |
| 448 | + db_prepare(&q, | |
| 449 | + "SELECT uuid, size, datetime(mtime%s), ipaddr" | |
| 450 | + " FROM blob, rcvfrom" | |
| 451 | + " WHERE rid=%d" | |
| 452 | + " AND rcvfrom.rcvid=blob.rcvid", | |
| 453 | + timeline_utc(), rid); | |
| 454 | + if( db_step(&q)==SQLITE_ROW ){ | |
| 455 | + if( verboseFlag ){ | |
| 456 | + fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); | |
| 457 | + fossil_print("size: %d bytes\n", db_column_int(&q,1)); | |
| 458 | + fossil_print("received: %s from %s\n", | |
| 459 | + db_column_text(&q, 2), | |
| 460 | + db_column_text(&q, 3)); | |
| 461 | + }else{ | |
| 462 | + fossil_print("artifact: %s\n", db_column_text(&q,0)); | |
| 463 | + fossil_print("size: %d bytes\n", db_column_int(&q,1)); | |
| 464 | + } | |
| 465 | + } | |
| 466 | + db_finalize(&q); | |
| 467 | + | |
| 468 | + /* Report any symbolic tags on this artifact */ | |
| 469 | + db_prepare(&q, | |
| 470 | + "SELECT substr(tagname,5)" | |
| 471 | + " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" | |
| 472 | + " WHERE tagxref.rid=%d" | |
| 473 | + " AND tagname GLOB 'sym-*'" | |
| 474 | + " ORDER BY 1", | |
| 475 | + rid | |
| 476 | + ); | |
| 477 | + cnt = 0; | |
| 478 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 479 | + const char *zPrefix = cnt++ ? ", " : "tags: "; | |
| 480 | + fossil_print("%s%s", zPrefix, db_column_text(&q,0)); | |
| 481 | + } | |
| 482 | + if( cnt ) fossil_print("\n"); | |
| 483 | + db_finalize(&q); | |
| 484 | + | |
| 485 | + /* Report any HIDDEN, PRIVATE, CLUSTER, or CLOSED tags on this artifact */ | |
| 486 | + db_prepare(&q, | |
| 487 | + "SELECT tagname" | |
| 488 | + " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" | |
| 489 | + " WHERE tagxref.rid=%d" | |
| 490 | + " AND tag.tagid IN (5,6,7,9)" | |
| 491 | + " ORDER BY 1", | |
| 492 | + rid, rid | |
| 493 | + ); | |
| 494 | + cnt = 0; | |
| 495 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 496 | + const char *zPrefix = cnt++ ? ", " : "raw-tags: "; | |
| 497 | + fossil_print("%s%s", zPrefix, db_column_text(&q,0)); | |
| 498 | + } | |
| 499 | + if( cnt ) fossil_print("\n"); | |
| 500 | + db_finalize(&q); | |
| 501 | + | |
| 502 | + /* Check for entries on the timeline that reference this object */ | |
| 503 | + db_prepare(&q, | |
| 504 | + "SELECT type, datetime(mtime%s)," | |
| 505 | + " coalesce(euser,user), coalesce(ecomment,comment)" | |
| 506 | + " FROM event WHERE objid=%d", timeline_utc(), rid); | |
| 507 | + if( db_step(&q)==SQLITE_ROW ){ | |
| 508 | + const char *zType; | |
| 509 | + switch( db_column_text(&q,0)[0] ){ | |
| 510 | + case 'c': zType = "Check-in"; break; | |
| 511 | + case 'w': zType = "Wiki-edit"; break; | |
| 512 | + case 'e': zType = "Event"; break; | |
| 513 | + case 't': zType = "Ticket-change"; break; | |
| 514 | + case 'g': zType = "Tag-change"; break; | |
| 515 | + default: zType = "Unknown"; break; | |
| 516 | + } | |
| 517 | + fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), | |
| 518 | + db_column_text(&q, 1)); | |
| 519 | + fossil_print("comment: "); | |
| 520 | + comment_print(db_column_text(&q,3), 12, 78); | |
| 521 | + } | |
| 522 | + db_finalize(&q); | |
| 523 | + | |
| 524 | + /* Check to see if this object is used as a file in a check-in */ | |
| 525 | + db_prepare(&q, | |
| 526 | + "SELECT filename.name, blob.uuid, datetime(event.mtime%s)," | |
| 527 | + " coalesce(euser,user), coalesce(ecomment,comment)" | |
| 528 | + " FROM mlink, filename, blob, event" | |
| 529 | + " WHERE mlink.fid=%d" | |
| 530 | + " AND filename.fnid=mlink.fnid" | |
| 531 | + " AND event.objid=mlink.mid" | |
| 532 | + " AND blob.rid=mlink.mid" | |
| 533 | + " ORDER BY event.mtime DESC /*sort*/", | |
| 534 | + timeline_utc(), rid); | |
| 535 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 536 | + fossil_print("file: %s\n", db_column_text(&q,0)); | |
| 537 | + fossil_print(" part of [%.10s] by %s on %s\n", | |
| 538 | + db_column_text(&q, 1), | |
| 539 | + db_column_text(&q, 3), | |
| 540 | + db_column_text(&q, 2)); | |
| 541 | + fossil_print(" "); | |
| 542 | + comment_print(db_column_text(&q,4), 12, 78); | |
| 543 | + } | |
| 544 | + db_finalize(&q); | |
| 545 | + | |
| 546 | + /* Check to see if this object is used as an attachment */ | |
| 547 | + db_prepare(&q, | |
| 548 | + "SELECT attachment.filename," | |
| 549 | + " attachment.comment," | |
| 550 | + " attachment.user," | |
| 551 | + " datetime(attachment.mtime%s)," | |
| 552 | + " attachment.target," | |
| 553 | + " CASE WHEN EXISTS(SELECT 1 FROM tag WHERE tagname=('tkt-'||target))" | |
| 554 | + " THEN 'ticket'" | |
| 555 | + " WHEN EXISTS(SELECT 1 FROM tag WHERE tagname=('wiki-'||target))" | |
| 556 | + " THEN 'wiki' END," | |
| 557 | + " attachment.attachid," | |
| 558 | + " (SELECT uuid FROM blob WHERE rid=attachid)" | |
| 559 | + " FROM attachment JOIN blob ON attachment.src=blob.uuid" | |
| 560 | + " WHERE blob.rid=%d", | |
| 561 | + timeline_utc(), rid | |
| 562 | + ); | |
| 563 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 564 | + fossil_print("attachment: %s\n", db_column_text(&q,0)); | |
| 565 | + fossil_print(" attached to %s %s\n", | |
| 566 | + db_column_text(&q,5), db_column_text(&q,4)); | |
| 567 | + if( verboseFlag ){ | |
| 568 | + fossil_print(" via %s (%d)\n", | |
| 569 | + db_column_text(&q,7), db_column_int(&q,6)); | |
| 570 | + }else{ | |
| 571 | + fossil_print(" via %s\n", | |
| 572 | + db_column_text(&q,7)); | |
| 573 | + } | |
| 574 | + fossil_print(" by user %s on %s\n", | |
| 575 | + db_column_text(&q,2), db_column_text(&q,3)); | |
| 576 | + fossil_print(" "); | |
| 577 | + comment_print(db_column_text(&q,1), 12, 78); | |
| 578 | + } | |
| 579 | + db_finalize(&q); | |
| 580 | +} | |
| 438 | 581 | |
| 439 | 582 | /* |
| 440 | 583 | ** COMMAND: whatis* |
| 441 | 584 | ** Usage: %fossil whatis NAME |
| 442 | 585 | ** |
| @@ -452,78 +595,41 @@ | ||
| 452 | 595 | verboseFlag = find_option("verbose","v",0)!=0; |
| 453 | 596 | if( g.argc!=3 ) usage("whatis NAME"); |
| 454 | 597 | zName = g.argv[2]; |
| 455 | 598 | rid = symbolic_name_to_rid(zName, 0); |
| 456 | 599 | if( rid<0 ){ |
| 600 | + Stmt q; | |
| 601 | + int cnt = 0; | |
| 457 | 602 | fossil_print("Ambiguous artifact name prefix: %s\n", zName); |
| 603 | + db_prepare(&q, | |
| 604 | + "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", | |
| 605 | + zName, zName | |
| 606 | + ); | |
| 607 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 608 | + if( cnt++ ) fossil_print("%.79c\n", '-'); | |
| 609 | + whatis_rid(db_column_int(&q, 0), verboseFlag); | |
| 610 | + } | |
| 611 | + db_finalize(&q); | |
| 458 | 612 | }else if( rid==0 ){ |
| 459 | 613 | fossil_print("Unknown artifact: %s\n", zName); |
| 460 | 614 | }else{ |
| 461 | - Stmt q; | |
| 462 | - db_prepare(&q, | |
| 463 | - "SELECT uuid, size, datetime(mtime%s), ipaddr," | |
| 464 | - " (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref" | |
| 465 | - " WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid" | |
| 466 | - " AND tagxref.rid=blob.rid AND tagxref.tagtype>0)" | |
| 467 | - " FROM blob, rcvfrom" | |
| 468 | - " WHERE rid=%d" | |
| 469 | - " AND rcvfrom.rcvid=blob.rcvid", | |
| 470 | - timeline_utc(), rid); | |
| 471 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 472 | - const char *zTagList = db_column_text(&q, 4); | |
| 473 | - if( verboseFlag ){ | |
| 474 | - fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); | |
| 475 | - fossil_print("size: %d bytes\n", db_column_int(&q,1)); | |
| 476 | - fossil_print("received: %s from %s\n", | |
| 477 | - db_column_text(&q, 2), | |
| 478 | - db_column_text(&q, 3)); | |
| 479 | - }else{ | |
| 480 | - fossil_print("artifact: %s\n", db_column_text(&q,0)); | |
| 481 | - fossil_print("size: %d bytes\n", db_column_int(&q,1)); | |
| 482 | - } | |
| 483 | - if( zTagList && zTagList[0] ){ | |
| 484 | - fossil_print("tags: %s\n", zTagList); | |
| 485 | - } | |
| 486 | - } | |
| 487 | - db_finalize(&q); | |
| 488 | - db_prepare(&q, | |
| 489 | - "SELECT type, datetime(mtime%s)," | |
| 490 | - " coalesce(euser,user), coalesce(ecomment,comment)" | |
| 491 | - " FROM event WHERE objid=%d", timeline_utc(), rid); | |
| 492 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 493 | - const char *zType; | |
| 494 | - switch( db_column_text(&q,0)[0] ){ | |
| 495 | - case 'c': zType = "Check-in"; break; | |
| 496 | - case 'w': zType = "Wiki-edit"; break; | |
| 497 | - case 'e': zType = "Event"; break; | |
| 498 | - case 't': zType = "Ticket-change"; break; | |
| 499 | - case 'g': zType = "Tag-change"; break; | |
| 500 | - default: zType = "Unknown"; break; | |
| 501 | - } | |
| 502 | - fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), | |
| 503 | - db_column_text(&q, 1)); | |
| 504 | - fossil_print("comment: "); | |
| 505 | - comment_print(db_column_text(&q,3), 10, 78); | |
| 506 | - } | |
| 507 | - db_finalize(&q); | |
| 508 | - db_prepare(&q, | |
| 509 | - "SELECT filename.name, blob.uuid, datetime(event.mtime%s)," | |
| 510 | - " coalesce(euser,user), coalesce(ecomment,comment)" | |
| 511 | - " FROM mlink, filename, blob, event" | |
| 512 | - " WHERE mlink.fid=%d" | |
| 513 | - " AND filename.fnid=mlink.fnid" | |
| 514 | - " AND event.objid=mlink.mid" | |
| 515 | - " AND blob.rid=mlink.mid" | |
| 516 | - " ORDER BY event.mtime DESC /*sort*/", | |
| 517 | - timeline_utc(), rid); | |
| 518 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 519 | - fossil_print("file: %s\n", db_column_text(&q,0)); | |
| 520 | - fossil_print(" part of [%.10s] by %s on %s\n", | |
| 521 | - db_column_text(&q, 1), | |
| 522 | - db_column_text(&q, 3), | |
| 523 | - db_column_text(&q, 2)); | |
| 524 | - fossil_print(" "); | |
| 525 | - comment_print(db_column_text(&q,4), 10, 78); | |
| 526 | - } | |
| 527 | - db_finalize(&q); | |
| 528 | - } | |
| 615 | + whatis_rid(rid, verboseFlag); | |
| 616 | + } | |
| 617 | +} | |
| 618 | + | |
| 619 | +/* | |
| 620 | +** COMMAND: test-whatis-all | |
| 621 | +** Usage: %fossil test-whatis-all | |
| 622 | +** | |
| 623 | +** Show "whatis" information about every artifact in the repository | |
| 624 | +*/ | |
| 625 | +void test_whatis_all_cmd(void){ | |
| 626 | + Stmt q; | |
| 627 | + int cnt = 0; | |
| 628 | + db_find_and_open_repository(0,0); | |
| 629 | + db_prepare(&q, "SELECT rid FROM blob ORDER BY rid"); | |
| 630 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 631 | + if( cnt++ ) fossil_print("%.79c\n", '-'); | |
| 632 | + whatis_rid(db_column_int(&q,0), 1); | |
| 633 | + } | |
| 634 | + db_finalize(&q); | |
| 529 | 635 | } |
| 530 | 636 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -402,16 +402,17 @@ | |
| 402 | canonical16(z, strlen(z)); |
| 403 | db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z); |
| 404 | while( db_step(&q)==SQLITE_ROW ){ |
| 405 | const char *zUuid = db_column_text(&q, 0); |
| 406 | int rid = db_column_int(&q, 1); |
| 407 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%S(zUuid)"> |
| 408 | @ %S(zUuid)</a> - |
| 409 | object_description(rid, 0, 0); |
| 410 | @ </p></li> |
| 411 | } |
| 412 | @ </ol> |
| 413 | style_footer(); |
| 414 | } |
| 415 | |
| 416 | /* |
| 417 | ** Convert the name in CGI parameter zParamName into a rid and return that |
| @@ -433,10 +434,152 @@ | |
| 433 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 434 | rid = 0; |
| 435 | } |
| 436 | return rid; |
| 437 | } |
| 438 | |
| 439 | /* |
| 440 | ** COMMAND: whatis* |
| 441 | ** Usage: %fossil whatis NAME |
| 442 | ** |
| @@ -452,78 +595,41 @@ | |
| 452 | verboseFlag = find_option("verbose","v",0)!=0; |
| 453 | if( g.argc!=3 ) usage("whatis NAME"); |
| 454 | zName = g.argv[2]; |
| 455 | rid = symbolic_name_to_rid(zName, 0); |
| 456 | if( rid<0 ){ |
| 457 | fossil_print("Ambiguous artifact name prefix: %s\n", zName); |
| 458 | }else if( rid==0 ){ |
| 459 | fossil_print("Unknown artifact: %s\n", zName); |
| 460 | }else{ |
| 461 | Stmt q; |
| 462 | db_prepare(&q, |
| 463 | "SELECT uuid, size, datetime(mtime%s), ipaddr," |
| 464 | " (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref" |
| 465 | " WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid" |
| 466 | " AND tagxref.rid=blob.rid AND tagxref.tagtype>0)" |
| 467 | " FROM blob, rcvfrom" |
| 468 | " WHERE rid=%d" |
| 469 | " AND rcvfrom.rcvid=blob.rcvid", |
| 470 | timeline_utc(), rid); |
| 471 | if( db_step(&q)==SQLITE_ROW ){ |
| 472 | const char *zTagList = db_column_text(&q, 4); |
| 473 | if( verboseFlag ){ |
| 474 | fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); |
| 475 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 476 | fossil_print("received: %s from %s\n", |
| 477 | db_column_text(&q, 2), |
| 478 | db_column_text(&q, 3)); |
| 479 | }else{ |
| 480 | fossil_print("artifact: %s\n", db_column_text(&q,0)); |
| 481 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 482 | } |
| 483 | if( zTagList && zTagList[0] ){ |
| 484 | fossil_print("tags: %s\n", zTagList); |
| 485 | } |
| 486 | } |
| 487 | db_finalize(&q); |
| 488 | db_prepare(&q, |
| 489 | "SELECT type, datetime(mtime%s)," |
| 490 | " coalesce(euser,user), coalesce(ecomment,comment)" |
| 491 | " FROM event WHERE objid=%d", timeline_utc(), rid); |
| 492 | if( db_step(&q)==SQLITE_ROW ){ |
| 493 | const char *zType; |
| 494 | switch( db_column_text(&q,0)[0] ){ |
| 495 | case 'c': zType = "Check-in"; break; |
| 496 | case 'w': zType = "Wiki-edit"; break; |
| 497 | case 'e': zType = "Event"; break; |
| 498 | case 't': zType = "Ticket-change"; break; |
| 499 | case 'g': zType = "Tag-change"; break; |
| 500 | default: zType = "Unknown"; break; |
| 501 | } |
| 502 | fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), |
| 503 | db_column_text(&q, 1)); |
| 504 | fossil_print("comment: "); |
| 505 | comment_print(db_column_text(&q,3), 10, 78); |
| 506 | } |
| 507 | db_finalize(&q); |
| 508 | db_prepare(&q, |
| 509 | "SELECT filename.name, blob.uuid, datetime(event.mtime%s)," |
| 510 | " coalesce(euser,user), coalesce(ecomment,comment)" |
| 511 | " FROM mlink, filename, blob, event" |
| 512 | " WHERE mlink.fid=%d" |
| 513 | " AND filename.fnid=mlink.fnid" |
| 514 | " AND event.objid=mlink.mid" |
| 515 | " AND blob.rid=mlink.mid" |
| 516 | " ORDER BY event.mtime DESC /*sort*/", |
| 517 | timeline_utc(), rid); |
| 518 | while( db_step(&q)==SQLITE_ROW ){ |
| 519 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 520 | fossil_print(" part of [%.10s] by %s on %s\n", |
| 521 | db_column_text(&q, 1), |
| 522 | db_column_text(&q, 3), |
| 523 | db_column_text(&q, 2)); |
| 524 | fossil_print(" "); |
| 525 | comment_print(db_column_text(&q,4), 10, 78); |
| 526 | } |
| 527 | db_finalize(&q); |
| 528 | } |
| 529 | } |
| 530 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -402,16 +402,17 @@ | |
| 402 | canonical16(z, strlen(z)); |
| 403 | db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z); |
| 404 | while( db_step(&q)==SQLITE_ROW ){ |
| 405 | const char *zUuid = db_column_text(&q, 0); |
| 406 | int rid = db_column_int(&q, 1); |
| 407 | @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)"> |
| 408 | @ %s(zUuid)</a> - |
| 409 | object_description(rid, 0, 0); |
| 410 | @ </p></li> |
| 411 | } |
| 412 | @ </ol> |
| 413 | db_finalize(&q); |
| 414 | style_footer(); |
| 415 | } |
| 416 | |
| 417 | /* |
| 418 | ** Convert the name in CGI parameter zParamName into a rid and return that |
| @@ -433,10 +434,152 @@ | |
| 434 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 435 | rid = 0; |
| 436 | } |
| 437 | return rid; |
| 438 | } |
| 439 | |
| 440 | /* |
| 441 | ** Generate a description of artifact "rid" |
| 442 | */ |
| 443 | static void whatis_rid(int rid, int verboseFlag){ |
| 444 | Stmt q; |
| 445 | int cnt; |
| 446 | |
| 447 | /* Basic information about the object. */ |
| 448 | db_prepare(&q, |
| 449 | "SELECT uuid, size, datetime(mtime%s), ipaddr" |
| 450 | " FROM blob, rcvfrom" |
| 451 | " WHERE rid=%d" |
| 452 | " AND rcvfrom.rcvid=blob.rcvid", |
| 453 | timeline_utc(), rid); |
| 454 | if( db_step(&q)==SQLITE_ROW ){ |
| 455 | if( verboseFlag ){ |
| 456 | fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); |
| 457 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 458 | fossil_print("received: %s from %s\n", |
| 459 | db_column_text(&q, 2), |
| 460 | db_column_text(&q, 3)); |
| 461 | }else{ |
| 462 | fossil_print("artifact: %s\n", db_column_text(&q,0)); |
| 463 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 464 | } |
| 465 | } |
| 466 | db_finalize(&q); |
| 467 | |
| 468 | /* Report any symbolic tags on this artifact */ |
| 469 | db_prepare(&q, |
| 470 | "SELECT substr(tagname,5)" |
| 471 | " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" |
| 472 | " WHERE tagxref.rid=%d" |
| 473 | " AND tagname GLOB 'sym-*'" |
| 474 | " ORDER BY 1", |
| 475 | rid |
| 476 | ); |
| 477 | cnt = 0; |
| 478 | while( db_step(&q)==SQLITE_ROW ){ |
| 479 | const char *zPrefix = cnt++ ? ", " : "tags: "; |
| 480 | fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 481 | } |
| 482 | if( cnt ) fossil_print("\n"); |
| 483 | db_finalize(&q); |
| 484 | |
| 485 | /* Report any HIDDEN, PRIVATE, CLUSTER, or CLOSED tags on this artifact */ |
| 486 | db_prepare(&q, |
| 487 | "SELECT tagname" |
| 488 | " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid" |
| 489 | " WHERE tagxref.rid=%d" |
| 490 | " AND tag.tagid IN (5,6,7,9)" |
| 491 | " ORDER BY 1", |
| 492 | rid, rid |
| 493 | ); |
| 494 | cnt = 0; |
| 495 | while( db_step(&q)==SQLITE_ROW ){ |
| 496 | const char *zPrefix = cnt++ ? ", " : "raw-tags: "; |
| 497 | fossil_print("%s%s", zPrefix, db_column_text(&q,0)); |
| 498 | } |
| 499 | if( cnt ) fossil_print("\n"); |
| 500 | db_finalize(&q); |
| 501 | |
| 502 | /* Check for entries on the timeline that reference this object */ |
| 503 | db_prepare(&q, |
| 504 | "SELECT type, datetime(mtime%s)," |
| 505 | " coalesce(euser,user), coalesce(ecomment,comment)" |
| 506 | " FROM event WHERE objid=%d", timeline_utc(), rid); |
| 507 | if( db_step(&q)==SQLITE_ROW ){ |
| 508 | const char *zType; |
| 509 | switch( db_column_text(&q,0)[0] ){ |
| 510 | case 'c': zType = "Check-in"; break; |
| 511 | case 'w': zType = "Wiki-edit"; break; |
| 512 | case 'e': zType = "Event"; break; |
| 513 | case 't': zType = "Ticket-change"; break; |
| 514 | case 'g': zType = "Tag-change"; break; |
| 515 | default: zType = "Unknown"; break; |
| 516 | } |
| 517 | fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), |
| 518 | db_column_text(&q, 1)); |
| 519 | fossil_print("comment: "); |
| 520 | comment_print(db_column_text(&q,3), 12, 78); |
| 521 | } |
| 522 | db_finalize(&q); |
| 523 | |
| 524 | /* Check to see if this object is used as a file in a check-in */ |
| 525 | db_prepare(&q, |
| 526 | "SELECT filename.name, blob.uuid, datetime(event.mtime%s)," |
| 527 | " coalesce(euser,user), coalesce(ecomment,comment)" |
| 528 | " FROM mlink, filename, blob, event" |
| 529 | " WHERE mlink.fid=%d" |
| 530 | " AND filename.fnid=mlink.fnid" |
| 531 | " AND event.objid=mlink.mid" |
| 532 | " AND blob.rid=mlink.mid" |
| 533 | " ORDER BY event.mtime DESC /*sort*/", |
| 534 | timeline_utc(), rid); |
| 535 | while( db_step(&q)==SQLITE_ROW ){ |
| 536 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 537 | fossil_print(" part of [%.10s] by %s on %s\n", |
| 538 | db_column_text(&q, 1), |
| 539 | db_column_text(&q, 3), |
| 540 | db_column_text(&q, 2)); |
| 541 | fossil_print(" "); |
| 542 | comment_print(db_column_text(&q,4), 12, 78); |
| 543 | } |
| 544 | db_finalize(&q); |
| 545 | |
| 546 | /* Check to see if this object is used as an attachment */ |
| 547 | db_prepare(&q, |
| 548 | "SELECT attachment.filename," |
| 549 | " attachment.comment," |
| 550 | " attachment.user," |
| 551 | " datetime(attachment.mtime%s)," |
| 552 | " attachment.target," |
| 553 | " CASE WHEN EXISTS(SELECT 1 FROM tag WHERE tagname=('tkt-'||target))" |
| 554 | " THEN 'ticket'" |
| 555 | " WHEN EXISTS(SELECT 1 FROM tag WHERE tagname=('wiki-'||target))" |
| 556 | " THEN 'wiki' END," |
| 557 | " attachment.attachid," |
| 558 | " (SELECT uuid FROM blob WHERE rid=attachid)" |
| 559 | " FROM attachment JOIN blob ON attachment.src=blob.uuid" |
| 560 | " WHERE blob.rid=%d", |
| 561 | timeline_utc(), rid |
| 562 | ); |
| 563 | while( db_step(&q)==SQLITE_ROW ){ |
| 564 | fossil_print("attachment: %s\n", db_column_text(&q,0)); |
| 565 | fossil_print(" attached to %s %s\n", |
| 566 | db_column_text(&q,5), db_column_text(&q,4)); |
| 567 | if( verboseFlag ){ |
| 568 | fossil_print(" via %s (%d)\n", |
| 569 | db_column_text(&q,7), db_column_int(&q,6)); |
| 570 | }else{ |
| 571 | fossil_print(" via %s\n", |
| 572 | db_column_text(&q,7)); |
| 573 | } |
| 574 | fossil_print(" by user %s on %s\n", |
| 575 | db_column_text(&q,2), db_column_text(&q,3)); |
| 576 | fossil_print(" "); |
| 577 | comment_print(db_column_text(&q,1), 12, 78); |
| 578 | } |
| 579 | db_finalize(&q); |
| 580 | } |
| 581 | |
| 582 | /* |
| 583 | ** COMMAND: whatis* |
| 584 | ** Usage: %fossil whatis NAME |
| 585 | ** |
| @@ -452,78 +595,41 @@ | |
| 595 | verboseFlag = find_option("verbose","v",0)!=0; |
| 596 | if( g.argc!=3 ) usage("whatis NAME"); |
| 597 | zName = g.argv[2]; |
| 598 | rid = symbolic_name_to_rid(zName, 0); |
| 599 | if( rid<0 ){ |
| 600 | Stmt q; |
| 601 | int cnt = 0; |
| 602 | fossil_print("Ambiguous artifact name prefix: %s\n", zName); |
| 603 | db_prepare(&q, |
| 604 | "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", |
| 605 | zName, zName |
| 606 | ); |
| 607 | while( db_step(&q)==SQLITE_ROW ){ |
| 608 | if( cnt++ ) fossil_print("%.79c\n", '-'); |
| 609 | whatis_rid(db_column_int(&q, 0), verboseFlag); |
| 610 | } |
| 611 | db_finalize(&q); |
| 612 | }else if( rid==0 ){ |
| 613 | fossil_print("Unknown artifact: %s\n", zName); |
| 614 | }else{ |
| 615 | whatis_rid(rid, verboseFlag); |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | /* |
| 620 | ** COMMAND: test-whatis-all |
| 621 | ** Usage: %fossil test-whatis-all |
| 622 | ** |
| 623 | ** Show "whatis" information about every artifact in the repository |
| 624 | */ |
| 625 | void test_whatis_all_cmd(void){ |
| 626 | Stmt q; |
| 627 | int cnt = 0; |
| 628 | db_find_and_open_repository(0,0); |
| 629 | db_prepare(&q, "SELECT rid FROM blob ORDER BY rid"); |
| 630 | while( db_step(&q)==SQLITE_ROW ){ |
| 631 | if( cnt++ ) fossil_print("%.79c\n", '-'); |
| 632 | whatis_rid(db_column_int(&q,0), 1); |
| 633 | } |
| 634 | db_finalize(&q); |
| 635 | } |
| 636 |
+1
-2
| --- src/popen.c | ||
| +++ src/popen.c | ||
| @@ -204,19 +204,18 @@ | ||
| 204 | 204 | #endif |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | 207 | /* |
| 208 | 208 | ** Close the connection to a child process previously created using |
| 209 | -** popen2(). Kill off the child process, then close the pipes. | |
| 209 | +** popen2(). | |
| 210 | 210 | */ |
| 211 | 211 | void pclose2(int fdIn, FILE *pOut, int childPid){ |
| 212 | 212 | #ifdef _WIN32 |
| 213 | 213 | /* Not implemented, yet */ |
| 214 | 214 | close(fdIn); |
| 215 | 215 | fclose(pOut); |
| 216 | 216 | #else |
| 217 | 217 | close(fdIn); |
| 218 | 218 | fclose(pOut); |
| 219 | - kill(childPid, SIGINT); | |
| 220 | 219 | while( waitpid(0, 0, WNOHANG)>0 ) {} |
| 221 | 220 | #endif |
| 222 | 221 | } |
| 223 | 222 |
| --- src/popen.c | |
| +++ src/popen.c | |
| @@ -204,19 +204,18 @@ | |
| 204 | #endif |
| 205 | } |
| 206 | |
| 207 | /* |
| 208 | ** Close the connection to a child process previously created using |
| 209 | ** popen2(). Kill off the child process, then close the pipes. |
| 210 | */ |
| 211 | void pclose2(int fdIn, FILE *pOut, int childPid){ |
| 212 | #ifdef _WIN32 |
| 213 | /* Not implemented, yet */ |
| 214 | close(fdIn); |
| 215 | fclose(pOut); |
| 216 | #else |
| 217 | close(fdIn); |
| 218 | fclose(pOut); |
| 219 | kill(childPid, SIGINT); |
| 220 | while( waitpid(0, 0, WNOHANG)>0 ) {} |
| 221 | #endif |
| 222 | } |
| 223 |
| --- src/popen.c | |
| +++ src/popen.c | |
| @@ -204,19 +204,18 @@ | |
| 204 | #endif |
| 205 | } |
| 206 | |
| 207 | /* |
| 208 | ** Close the connection to a child process previously created using |
| 209 | ** popen2(). |
| 210 | */ |
| 211 | void pclose2(int fdIn, FILE *pOut, int childPid){ |
| 212 | #ifdef _WIN32 |
| 213 | /* Not implemented, yet */ |
| 214 | close(fdIn); |
| 215 | fclose(pOut); |
| 216 | #else |
| 217 | close(fdIn); |
| 218 | fclose(pOut); |
| 219 | while( waitpid(0, 0, WNOHANG)>0 ) {} |
| 220 | #endif |
| 221 | } |
| 222 |
+3
-13
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -302,10 +302,11 @@ | ||
| 302 | 302 | "FROM reportfmt WHERE rn=%d",rn); |
| 303 | 303 | style_header("SQL For Report Format Number %d", rn); |
| 304 | 304 | if( db_step(&q)!=SQLITE_ROW ){ |
| 305 | 305 | @ <p>Unknown report number: %d(rn)</p> |
| 306 | 306 | style_footer(); |
| 307 | + db_finalize(&q); | |
| 307 | 308 | return; |
| 308 | 309 | } |
| 309 | 310 | zTitle = db_column_text(&q, 0); |
| 310 | 311 | zSQL = db_column_text(&q, 1); |
| 311 | 312 | zOwner = db_column_text(&q, 2); |
| @@ -323,10 +324,11 @@ | ||
| 323 | 324 | output_color_key(zClrKey, 0, "border=0 cellspacing=0 cellpadding=3"); |
| 324 | 325 | @ </td> |
| 325 | 326 | @ </tr></table> |
| 326 | 327 | report_format_hints(); |
| 327 | 328 | style_footer(); |
| 329 | + db_finalize(&q); | |
| 328 | 330 | } |
| 329 | 331 | |
| 330 | 332 | /* |
| 331 | 333 | ** WEBPAGE: /rptnew |
| 332 | 334 | ** WEBPAGE: /rptedit |
| @@ -612,23 +614,10 @@ | ||
| 612 | 614 | @ priority AS 'Pri', |
| 613 | 615 | @ title AS 'Title', |
| 614 | 616 | @ description AS '_Description', -- When the column name begins with '_' |
| 615 | 617 | @ remarks AS '_Remarks' -- content is rendered as wiki |
| 616 | 618 | @ FROM ticket |
| 617 | - @ </pre></blockquote> | |
| 618 | - @ | |
| 619 | - @ <p>Or, to see part of the description on the same row, use the | |
| 620 | - @ <b>wiki()</b> function with some string manipulation. Using the | |
| 621 | - @ <b>tkt()</b> function on the ticket number will also generate a linked | |
| 622 | - @ field, but without the extra <i>edit</i> column: | |
| 623 | - @ </p> | |
| 624 | - @ <blockquote><pre> | |
| 625 | - @ SELECT | |
| 626 | - @ tkt(tn) AS '', | |
| 627 | - @ title AS 'Title', | |
| 628 | - @ wiki(substr(description,0,80)) AS 'Description' | |
| 629 | - @ FROM ticket | |
| 630 | 619 | @ </pre></blockquote> |
| 631 | 620 | @ |
| 632 | 621 | } |
| 633 | 622 | |
| 634 | 623 | /* |
| @@ -1039,10 +1028,11 @@ | ||
| 1039 | 1028 | /* view_add_functions(tabs); */ |
| 1040 | 1029 | db_prepare(&q, |
| 1041 | 1030 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); |
| 1042 | 1031 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1043 | 1032 | cgi_redirect("reportlist"); |
| 1033 | + db_finalize(&q); | |
| 1044 | 1034 | return; |
| 1045 | 1035 | } |
| 1046 | 1036 | zTitle = db_column_malloc(&q, 0); |
| 1047 | 1037 | zSql = db_column_malloc(&q, 1); |
| 1048 | 1038 | zOwner = db_column_malloc(&q, 2); |
| 1049 | 1039 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -302,10 +302,11 @@ | |
| 302 | "FROM reportfmt WHERE rn=%d",rn); |
| 303 | style_header("SQL For Report Format Number %d", rn); |
| 304 | if( db_step(&q)!=SQLITE_ROW ){ |
| 305 | @ <p>Unknown report number: %d(rn)</p> |
| 306 | style_footer(); |
| 307 | return; |
| 308 | } |
| 309 | zTitle = db_column_text(&q, 0); |
| 310 | zSQL = db_column_text(&q, 1); |
| 311 | zOwner = db_column_text(&q, 2); |
| @@ -323,10 +324,11 @@ | |
| 323 | output_color_key(zClrKey, 0, "border=0 cellspacing=0 cellpadding=3"); |
| 324 | @ </td> |
| 325 | @ </tr></table> |
| 326 | report_format_hints(); |
| 327 | style_footer(); |
| 328 | } |
| 329 | |
| 330 | /* |
| 331 | ** WEBPAGE: /rptnew |
| 332 | ** WEBPAGE: /rptedit |
| @@ -612,23 +614,10 @@ | |
| 612 | @ priority AS 'Pri', |
| 613 | @ title AS 'Title', |
| 614 | @ description AS '_Description', -- When the column name begins with '_' |
| 615 | @ remarks AS '_Remarks' -- content is rendered as wiki |
| 616 | @ FROM ticket |
| 617 | @ </pre></blockquote> |
| 618 | @ |
| 619 | @ <p>Or, to see part of the description on the same row, use the |
| 620 | @ <b>wiki()</b> function with some string manipulation. Using the |
| 621 | @ <b>tkt()</b> function on the ticket number will also generate a linked |
| 622 | @ field, but without the extra <i>edit</i> column: |
| 623 | @ </p> |
| 624 | @ <blockquote><pre> |
| 625 | @ SELECT |
| 626 | @ tkt(tn) AS '', |
| 627 | @ title AS 'Title', |
| 628 | @ wiki(substr(description,0,80)) AS 'Description' |
| 629 | @ FROM ticket |
| 630 | @ </pre></blockquote> |
| 631 | @ |
| 632 | } |
| 633 | |
| 634 | /* |
| @@ -1039,10 +1028,11 @@ | |
| 1039 | /* view_add_functions(tabs); */ |
| 1040 | db_prepare(&q, |
| 1041 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); |
| 1042 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1043 | cgi_redirect("reportlist"); |
| 1044 | return; |
| 1045 | } |
| 1046 | zTitle = db_column_malloc(&q, 0); |
| 1047 | zSql = db_column_malloc(&q, 1); |
| 1048 | zOwner = db_column_malloc(&q, 2); |
| 1049 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -302,10 +302,11 @@ | |
| 302 | "FROM reportfmt WHERE rn=%d",rn); |
| 303 | style_header("SQL For Report Format Number %d", rn); |
| 304 | if( db_step(&q)!=SQLITE_ROW ){ |
| 305 | @ <p>Unknown report number: %d(rn)</p> |
| 306 | style_footer(); |
| 307 | db_finalize(&q); |
| 308 | return; |
| 309 | } |
| 310 | zTitle = db_column_text(&q, 0); |
| 311 | zSQL = db_column_text(&q, 1); |
| 312 | zOwner = db_column_text(&q, 2); |
| @@ -323,10 +324,11 @@ | |
| 324 | output_color_key(zClrKey, 0, "border=0 cellspacing=0 cellpadding=3"); |
| 325 | @ </td> |
| 326 | @ </tr></table> |
| 327 | report_format_hints(); |
| 328 | style_footer(); |
| 329 | db_finalize(&q); |
| 330 | } |
| 331 | |
| 332 | /* |
| 333 | ** WEBPAGE: /rptnew |
| 334 | ** WEBPAGE: /rptedit |
| @@ -612,23 +614,10 @@ | |
| 614 | @ priority AS 'Pri', |
| 615 | @ title AS 'Title', |
| 616 | @ description AS '_Description', -- When the column name begins with '_' |
| 617 | @ remarks AS '_Remarks' -- content is rendered as wiki |
| 618 | @ FROM ticket |
| 619 | @ </pre></blockquote> |
| 620 | @ |
| 621 | } |
| 622 | |
| 623 | /* |
| @@ -1039,10 +1028,11 @@ | |
| 1028 | /* view_add_functions(tabs); */ |
| 1029 | db_prepare(&q, |
| 1030 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); |
| 1031 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1032 | cgi_redirect("reportlist"); |
| 1033 | db_finalize(&q); |
| 1034 | return; |
| 1035 | } |
| 1036 | zTitle = db_column_malloc(&q, 0); |
| 1037 | zSql = db_column_malloc(&q, 1); |
| 1038 | zOwner = db_column_malloc(&q, 2); |
| 1039 |
+1
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -277,10 +277,11 @@ | ||
| 277 | 277 | @ </p></li> |
| 278 | 278 | @ |
| 279 | 279 | @ </ol> |
| 280 | 280 | @ </td></tr></table> |
| 281 | 281 | style_footer(); |
| 282 | + db_finalize(&s); | |
| 282 | 283 | } |
| 283 | 284 | |
| 284 | 285 | /* |
| 285 | 286 | ** Return true if zPw is a valid password string. A valid |
| 286 | 287 | ** password string is: |
| 287 | 288 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -277,10 +277,11 @@ | |
| 277 | @ </p></li> |
| 278 | @ |
| 279 | @ </ol> |
| 280 | @ </td></tr></table> |
| 281 | style_footer(); |
| 282 | } |
| 283 | |
| 284 | /* |
| 285 | ** Return true if zPw is a valid password string. A valid |
| 286 | ** password string is: |
| 287 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -277,10 +277,11 @@ | |
| 277 | @ </p></li> |
| 278 | @ |
| 279 | @ </ol> |
| 280 | @ </td></tr></table> |
| 281 | style_footer(); |
| 282 | db_finalize(&s); |
| 283 | } |
| 284 | |
| 285 | /* |
| 286 | ** Return true if zPw is a valid password string. A valid |
| 287 | ** password string is: |
| 288 |
+2
-1
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -1193,11 +1193,12 @@ | ||
| 1193 | 1193 | const char *z; /* Used to check if this is an EXPLAIN */ |
| 1194 | 1194 | int *abYield = 0; /* True if op is an OP_Yield */ |
| 1195 | 1195 | int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ |
| 1196 | 1196 | int iOp; /* Index of operation in p->aiIndent[] */ |
| 1197 | 1197 | |
| 1198 | - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; | |
| 1198 | + const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", | |
| 1199 | + "NextIfOpen", "PrevIfOpen", 0 }; | |
| 1199 | 1200 | const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 }; |
| 1200 | 1201 | const char *azGoto[] = { "Goto", 0 }; |
| 1201 | 1202 | |
| 1202 | 1203 | /* Try to figure out if this is really an EXPLAIN statement. If this |
| 1203 | 1204 | ** cannot be verified, return early. */ |
| 1204 | 1205 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -1193,11 +1193,12 @@ | |
| 1193 | const char *z; /* Used to check if this is an EXPLAIN */ |
| 1194 | int *abYield = 0; /* True if op is an OP_Yield */ |
| 1195 | int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ |
| 1196 | int iOp; /* Index of operation in p->aiIndent[] */ |
| 1197 | |
| 1198 | const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; |
| 1199 | const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 }; |
| 1200 | const char *azGoto[] = { "Goto", 0 }; |
| 1201 | |
| 1202 | /* Try to figure out if this is really an EXPLAIN statement. If this |
| 1203 | ** cannot be verified, return early. */ |
| 1204 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -1193,11 +1193,12 @@ | |
| 1193 | const char *z; /* Used to check if this is an EXPLAIN */ |
| 1194 | int *abYield = 0; /* True if op is an OP_Yield */ |
| 1195 | int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ |
| 1196 | int iOp; /* Index of operation in p->aiIndent[] */ |
| 1197 | |
| 1198 | const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", |
| 1199 | "NextIfOpen", "PrevIfOpen", 0 }; |
| 1200 | const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 }; |
| 1201 | const char *azGoto[] = { "Goto", 0 }; |
| 1202 | |
| 1203 | /* Try to figure out if this is really an EXPLAIN statement. If this |
| 1204 | ** cannot be verified, return early. */ |
| 1205 |
+19
-12
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | -** version 3.8.4.1. By combining all the individual C code files into this | |
| 3 | +** version 3.8.4.3. By combining all the individual C code files into this | |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| @@ -220,13 +220,13 @@ | ||
| 220 | 220 | ** |
| 221 | 221 | ** See also: [sqlite3_libversion()], |
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | -#define SQLITE_VERSION "3.8.4.1" | |
| 225 | +#define SQLITE_VERSION "3.8.4.3" | |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008004 |
| 227 | -#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" | |
| 227 | +#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" | |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| @@ -35489,25 +35489,31 @@ | ||
| 35489 | 35489 | |
| 35490 | 35490 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35491 | 35491 | if( nChar==0 ){ |
| 35492 | 35492 | return 0; |
| 35493 | 35493 | } |
| 35494 | - zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+8 ); | |
| 35494 | + zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); | |
| 35495 | 35495 | if( zWideFilename==0 ){ |
| 35496 | 35496 | return 0; |
| 35497 | 35497 | } |
| 35498 | 35498 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35499 | - zWideFilename+4, nChar); | |
| 35499 | + zWideFilename, nChar); | |
| 35500 | 35500 | if( nChar==0 ){ |
| 35501 | 35501 | sqlite3_free(zWideFilename); |
| 35502 | 35502 | return 0; |
| 35503 | - }else if( nChar>SQLITE_WIN32_MAX_PATH_CHARS | |
| 35504 | - && winIsDriveLetterAndColon(zFilename) | |
| 35505 | - && zFilename[2] == '\\' ){ | |
| 35506 | - memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 35507 | - }else{ | |
| 35508 | - memmove(zWideFilename, zWideFilename+4, nChar*sizeof(WCHAR)); | |
| 35503 | + } | |
| 35504 | + if( nChar>MAX_PATH ){ | |
| 35505 | + if( winIsDriveLetterAndColon(zFilename) | |
| 35506 | + && winIsDirSep(zFilename[2]) ){ | |
| 35507 | + memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); | |
| 35508 | + zWideFilename[2] = '\\'; | |
| 35509 | + memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 35510 | + }else if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) | |
| 35511 | + && zFilename[2] != '?' ){ | |
| 35512 | + memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); | |
| 35513 | + memcpy(zWideFilename, L"\\\\?\\UNC", 14); | |
| 35514 | + } | |
| 35509 | 35515 | } |
| 35510 | 35516 | zConverted = zWideFilename; |
| 35511 | 35517 | } |
| 35512 | 35518 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35513 | 35519 | else{ |
| @@ -64803,10 +64809,11 @@ | ||
| 64803 | 64809 | i = 1; |
| 64804 | 64810 | pRhs++; |
| 64805 | 64811 | }else{ |
| 64806 | 64812 | idx1 = getVarint32(aKey1, szHdr1); |
| 64807 | 64813 | d1 = szHdr1; |
| 64814 | + if( d1>(unsigned)nKey1 ) return 1; /* Corruption */ | |
| 64808 | 64815 | i = 0; |
| 64809 | 64816 | } |
| 64810 | 64817 | |
| 64811 | 64818 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64812 | 64819 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| @@ -115289,11 +115296,11 @@ | ||
| 115289 | 115296 | k = pLevel->addrBody; |
| 115290 | 115297 | pOp = sqlite3VdbeGetOp(v, k); |
| 115291 | 115298 | for(; k<last; k++, pOp++){ |
| 115292 | 115299 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115293 | 115300 | if( pOp->opcode==OP_Column ){ |
| 115294 | - pOp->opcode = OP_SCopy; | |
| 115301 | + pOp->opcode = OP_Copy; | |
| 115295 | 115302 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115296 | 115303 | pOp->p2 = pOp->p3; |
| 115297 | 115304 | pOp->p3 = 0; |
| 115298 | 115305 | }else if( pOp->opcode==OP_Rowid ){ |
| 115299 | 115306 | pOp->opcode = OP_Null; |
| 115300 | 115307 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.4.1. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -220,13 +220,13 @@ | |
| 220 | ** |
| 221 | ** See also: [sqlite3_libversion()], |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.4.1" |
| 226 | #define SQLITE_VERSION_NUMBER 3008004 |
| 227 | #define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -35489,25 +35489,31 @@ | |
| 35489 | |
| 35490 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35491 | if( nChar==0 ){ |
| 35492 | return 0; |
| 35493 | } |
| 35494 | zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+8 ); |
| 35495 | if( zWideFilename==0 ){ |
| 35496 | return 0; |
| 35497 | } |
| 35498 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35499 | zWideFilename+4, nChar); |
| 35500 | if( nChar==0 ){ |
| 35501 | sqlite3_free(zWideFilename); |
| 35502 | return 0; |
| 35503 | }else if( nChar>SQLITE_WIN32_MAX_PATH_CHARS |
| 35504 | && winIsDriveLetterAndColon(zFilename) |
| 35505 | && zFilename[2] == '\\' ){ |
| 35506 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35507 | }else{ |
| 35508 | memmove(zWideFilename, zWideFilename+4, nChar*sizeof(WCHAR)); |
| 35509 | } |
| 35510 | zConverted = zWideFilename; |
| 35511 | } |
| 35512 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35513 | else{ |
| @@ -64803,10 +64809,11 @@ | |
| 64803 | i = 1; |
| 64804 | pRhs++; |
| 64805 | }else{ |
| 64806 | idx1 = getVarint32(aKey1, szHdr1); |
| 64807 | d1 = szHdr1; |
| 64808 | i = 0; |
| 64809 | } |
| 64810 | |
| 64811 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64812 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| @@ -115289,11 +115296,11 @@ | |
| 115289 | k = pLevel->addrBody; |
| 115290 | pOp = sqlite3VdbeGetOp(v, k); |
| 115291 | for(; k<last; k++, pOp++){ |
| 115292 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115293 | if( pOp->opcode==OP_Column ){ |
| 115294 | pOp->opcode = OP_SCopy; |
| 115295 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115296 | pOp->p2 = pOp->p3; |
| 115297 | pOp->p3 = 0; |
| 115298 | }else if( pOp->opcode==OP_Rowid ){ |
| 115299 | pOp->opcode = OP_Null; |
| 115300 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.4.3. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -220,13 +220,13 @@ | |
| 220 | ** |
| 221 | ** See also: [sqlite3_libversion()], |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.4.3" |
| 226 | #define SQLITE_VERSION_NUMBER 3008004 |
| 227 | #define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -35489,25 +35489,31 @@ | |
| 35489 | |
| 35490 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35491 | if( nChar==0 ){ |
| 35492 | return 0; |
| 35493 | } |
| 35494 | zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); |
| 35495 | if( zWideFilename==0 ){ |
| 35496 | return 0; |
| 35497 | } |
| 35498 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35499 | zWideFilename, nChar); |
| 35500 | if( nChar==0 ){ |
| 35501 | sqlite3_free(zWideFilename); |
| 35502 | return 0; |
| 35503 | } |
| 35504 | if( nChar>MAX_PATH ){ |
| 35505 | if( winIsDriveLetterAndColon(zFilename) |
| 35506 | && winIsDirSep(zFilename[2]) ){ |
| 35507 | memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); |
| 35508 | zWideFilename[2] = '\\'; |
| 35509 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35510 | }else if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 35511 | && zFilename[2] != '?' ){ |
| 35512 | memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); |
| 35513 | memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 35514 | } |
| 35515 | } |
| 35516 | zConverted = zWideFilename; |
| 35517 | } |
| 35518 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35519 | else{ |
| @@ -64803,10 +64809,11 @@ | |
| 64809 | i = 1; |
| 64810 | pRhs++; |
| 64811 | }else{ |
| 64812 | idx1 = getVarint32(aKey1, szHdr1); |
| 64813 | d1 = szHdr1; |
| 64814 | if( d1>(unsigned)nKey1 ) return 1; /* Corruption */ |
| 64815 | i = 0; |
| 64816 | } |
| 64817 | |
| 64818 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64819 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| @@ -115289,11 +115296,11 @@ | |
| 115296 | k = pLevel->addrBody; |
| 115297 | pOp = sqlite3VdbeGetOp(v, k); |
| 115298 | for(; k<last; k++, pOp++){ |
| 115299 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115300 | if( pOp->opcode==OP_Column ){ |
| 115301 | pOp->opcode = OP_Copy; |
| 115302 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115303 | pOp->p2 = pOp->p3; |
| 115304 | pOp->p3 = 0; |
| 115305 | }else if( pOp->opcode==OP_Rowid ){ |
| 115306 | pOp->opcode = OP_Null; |
| 115307 |
+19
-12
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | -** version 3.8.4.1. By combining all the individual C code files into this | |
| 3 | +** version 3.8.4.3. By combining all the individual C code files into this | |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| @@ -220,13 +220,13 @@ | ||
| 220 | 220 | ** |
| 221 | 221 | ** See also: [sqlite3_libversion()], |
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | -#define SQLITE_VERSION "3.8.4.1" | |
| 225 | +#define SQLITE_VERSION "3.8.4.3" | |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008004 |
| 227 | -#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" | |
| 227 | +#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" | |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| @@ -35489,25 +35489,31 @@ | ||
| 35489 | 35489 | |
| 35490 | 35490 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35491 | 35491 | if( nChar==0 ){ |
| 35492 | 35492 | return 0; |
| 35493 | 35493 | } |
| 35494 | - zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+8 ); | |
| 35494 | + zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); | |
| 35495 | 35495 | if( zWideFilename==0 ){ |
| 35496 | 35496 | return 0; |
| 35497 | 35497 | } |
| 35498 | 35498 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35499 | - zWideFilename+4, nChar); | |
| 35499 | + zWideFilename, nChar); | |
| 35500 | 35500 | if( nChar==0 ){ |
| 35501 | 35501 | sqlite3_free(zWideFilename); |
| 35502 | 35502 | return 0; |
| 35503 | - }else if( nChar>SQLITE_WIN32_MAX_PATH_CHARS | |
| 35504 | - && winIsDriveLetterAndColon(zFilename) | |
| 35505 | - && zFilename[2] == '\\' ){ | |
| 35506 | - memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 35507 | - }else{ | |
| 35508 | - memmove(zWideFilename, zWideFilename+4, nChar*sizeof(WCHAR)); | |
| 35503 | + } | |
| 35504 | + if( nChar>MAX_PATH ){ | |
| 35505 | + if( winIsDriveLetterAndColon(zFilename) | |
| 35506 | + && winIsDirSep(zFilename[2]) ){ | |
| 35507 | + memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); | |
| 35508 | + zWideFilename[2] = '\\'; | |
| 35509 | + memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 35510 | + }else if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) | |
| 35511 | + && zFilename[2] != '?' ){ | |
| 35512 | + memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); | |
| 35513 | + memcpy(zWideFilename, L"\\\\?\\UNC", 14); | |
| 35514 | + } | |
| 35509 | 35515 | } |
| 35510 | 35516 | zConverted = zWideFilename; |
| 35511 | 35517 | } |
| 35512 | 35518 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35513 | 35519 | else{ |
| @@ -64803,10 +64809,11 @@ | ||
| 64803 | 64809 | i = 1; |
| 64804 | 64810 | pRhs++; |
| 64805 | 64811 | }else{ |
| 64806 | 64812 | idx1 = getVarint32(aKey1, szHdr1); |
| 64807 | 64813 | d1 = szHdr1; |
| 64814 | + if( d1>(unsigned)nKey1 ) return 1; /* Corruption */ | |
| 64808 | 64815 | i = 0; |
| 64809 | 64816 | } |
| 64810 | 64817 | |
| 64811 | 64818 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64812 | 64819 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| @@ -115289,11 +115296,11 @@ | ||
| 115289 | 115296 | k = pLevel->addrBody; |
| 115290 | 115297 | pOp = sqlite3VdbeGetOp(v, k); |
| 115291 | 115298 | for(; k<last; k++, pOp++){ |
| 115292 | 115299 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115293 | 115300 | if( pOp->opcode==OP_Column ){ |
| 115294 | - pOp->opcode = OP_SCopy; | |
| 115301 | + pOp->opcode = OP_Copy; | |
| 115295 | 115302 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115296 | 115303 | pOp->p2 = pOp->p3; |
| 115297 | 115304 | pOp->p3 = 0; |
| 115298 | 115305 | }else if( pOp->opcode==OP_Rowid ){ |
| 115299 | 115306 | pOp->opcode = OP_Null; |
| 115300 | 115307 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.4.1. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -220,13 +220,13 @@ | |
| 220 | ** |
| 221 | ** See also: [sqlite3_libversion()], |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.4.1" |
| 226 | #define SQLITE_VERSION_NUMBER 3008004 |
| 227 | #define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -35489,25 +35489,31 @@ | |
| 35489 | |
| 35490 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35491 | if( nChar==0 ){ |
| 35492 | return 0; |
| 35493 | } |
| 35494 | zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+8 ); |
| 35495 | if( zWideFilename==0 ){ |
| 35496 | return 0; |
| 35497 | } |
| 35498 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35499 | zWideFilename+4, nChar); |
| 35500 | if( nChar==0 ){ |
| 35501 | sqlite3_free(zWideFilename); |
| 35502 | return 0; |
| 35503 | }else if( nChar>SQLITE_WIN32_MAX_PATH_CHARS |
| 35504 | && winIsDriveLetterAndColon(zFilename) |
| 35505 | && zFilename[2] == '\\' ){ |
| 35506 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35507 | }else{ |
| 35508 | memmove(zWideFilename, zWideFilename+4, nChar*sizeof(WCHAR)); |
| 35509 | } |
| 35510 | zConverted = zWideFilename; |
| 35511 | } |
| 35512 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35513 | else{ |
| @@ -64803,10 +64809,11 @@ | |
| 64803 | i = 1; |
| 64804 | pRhs++; |
| 64805 | }else{ |
| 64806 | idx1 = getVarint32(aKey1, szHdr1); |
| 64807 | d1 = szHdr1; |
| 64808 | i = 0; |
| 64809 | } |
| 64810 | |
| 64811 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64812 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| @@ -115289,11 +115296,11 @@ | |
| 115289 | k = pLevel->addrBody; |
| 115290 | pOp = sqlite3VdbeGetOp(v, k); |
| 115291 | for(; k<last; k++, pOp++){ |
| 115292 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115293 | if( pOp->opcode==OP_Column ){ |
| 115294 | pOp->opcode = OP_SCopy; |
| 115295 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115296 | pOp->p2 = pOp->p3; |
| 115297 | pOp->p3 = 0; |
| 115298 | }else if( pOp->opcode==OP_Rowid ){ |
| 115299 | pOp->opcode = OP_Null; |
| 115300 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.4.3. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -220,13 +220,13 @@ | |
| 220 | ** |
| 221 | ** See also: [sqlite3_libversion()], |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.4.3" |
| 226 | #define SQLITE_VERSION_NUMBER 3008004 |
| 227 | #define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -35489,25 +35489,31 @@ | |
| 35489 | |
| 35490 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35491 | if( nChar==0 ){ |
| 35492 | return 0; |
| 35493 | } |
| 35494 | zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); |
| 35495 | if( zWideFilename==0 ){ |
| 35496 | return 0; |
| 35497 | } |
| 35498 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 35499 | zWideFilename, nChar); |
| 35500 | if( nChar==0 ){ |
| 35501 | sqlite3_free(zWideFilename); |
| 35502 | return 0; |
| 35503 | } |
| 35504 | if( nChar>MAX_PATH ){ |
| 35505 | if( winIsDriveLetterAndColon(zFilename) |
| 35506 | && winIsDirSep(zFilename[2]) ){ |
| 35507 | memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); |
| 35508 | zWideFilename[2] = '\\'; |
| 35509 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35510 | }else if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 35511 | && zFilename[2] != '?' ){ |
| 35512 | memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); |
| 35513 | memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 35514 | } |
| 35515 | } |
| 35516 | zConverted = zWideFilename; |
| 35517 | } |
| 35518 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35519 | else{ |
| @@ -64803,10 +64809,11 @@ | |
| 64809 | i = 1; |
| 64810 | pRhs++; |
| 64811 | }else{ |
| 64812 | idx1 = getVarint32(aKey1, szHdr1); |
| 64813 | d1 = szHdr1; |
| 64814 | if( d1>(unsigned)nKey1 ) return 1; /* Corruption */ |
| 64815 | i = 0; |
| 64816 | } |
| 64817 | |
| 64818 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64819 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| @@ -115289,11 +115296,11 @@ | |
| 115296 | k = pLevel->addrBody; |
| 115297 | pOp = sqlite3VdbeGetOp(v, k); |
| 115298 | for(; k<last; k++, pOp++){ |
| 115299 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115300 | if( pOp->opcode==OP_Column ){ |
| 115301 | pOp->opcode = OP_Copy; |
| 115302 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115303 | pOp->p2 = pOp->p3; |
| 115304 | pOp->p3 = 0; |
| 115305 | }else if( pOp->opcode==OP_Rowid ){ |
| 115306 | pOp->opcode = OP_Null; |
| 115307 |
+2
-2
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -105,13 +105,13 @@ | ||
| 105 | 105 | ** |
| 106 | 106 | ** See also: [sqlite3_libversion()], |
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | -#define SQLITE_VERSION "3.8.4.1" | |
| 110 | +#define SQLITE_VERSION "3.8.4.3" | |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008004 |
| 112 | -#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" | |
| 112 | +#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -105,13 +105,13 @@ | |
| 105 | ** |
| 106 | ** See also: [sqlite3_libversion()], |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.4.1" |
| 111 | #define SQLITE_VERSION_NUMBER 3008004 |
| 112 | #define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -105,13 +105,13 @@ | |
| 105 | ** |
| 106 | ** See also: [sqlite3_libversion()], |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.4.3" |
| 111 | #define SQLITE_VERSION_NUMBER 3008004 |
| 112 | #define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
+10
-10
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -48,14 +48,14 @@ | ||
| 48 | 48 | } |
| 49 | 49 | }else{ |
| 50 | 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | 51 | } |
| 52 | 52 | url_parse(0, URL_REMEMBER); |
| 53 | - if( g.urlProtocol==0 ) return 0; | |
| 54 | - if( g.urlUser!=0 && g.urlPasswd==0 ){ | |
| 55 | - g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); | |
| 56 | - g.urlFlags |= URL_PROMPT_PW; | |
| 53 | + if( g.url.protocol==0 ) return 0; | |
| 54 | + if( g.url.user!=0 && g.url.passwd==0 ){ | |
| 55 | + g.url.passwd = unobscure(db_get("last-sync-pw", 0)); | |
| 56 | + g.url.flags |= URL_PROMPT_PW; | |
| 57 | 57 | url_prompt_for_password(); |
| 58 | 58 | } |
| 59 | 59 | g.zHttpAuth = get_httpauth(); |
| 60 | 60 | url_remember(); |
| 61 | 61 | #if 0 /* Disabled for now */ |
| @@ -69,11 +69,11 @@ | ||
| 69 | 69 | */ |
| 70 | 70 | configSync = CONFIGSET_SHUN; |
| 71 | 71 | } |
| 72 | 72 | #endif |
| 73 | 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | - fossil_print("Autosync: %s\n", g.urlCanonical); | |
| 74 | + fossil_print("Autosync: %s\n", g.url.canonical); | |
| 75 | 75 | url_enable_proxy("via proxy: "); |
| 76 | 76 | rc = client_sync(flags, configSync, 0); |
| 77 | 77 | if( rc ) fossil_warning("Autosync failed"); |
| 78 | 78 | return rc; |
| 79 | 79 | } |
| @@ -121,22 +121,22 @@ | ||
| 121 | 121 | clone_ssh_db_set_options(); |
| 122 | 122 | } |
| 123 | 123 | url_parse(zUrl, urlFlags); |
| 124 | 124 | remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl); |
| 125 | 125 | url_remember(); |
| 126 | - if( g.urlProtocol==0 ){ | |
| 126 | + if( g.url.protocol==0 ){ | |
| 127 | 127 | if( urlOptional ) fossil_exit(0); |
| 128 | 128 | usage("URL"); |
| 129 | 129 | } |
| 130 | 130 | user_select(); |
| 131 | 131 | if( g.argc==2 ){ |
| 132 | 132 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 133 | - fossil_print("Sync with %s\n", g.urlCanonical); | |
| 133 | + fossil_print("Sync with %s\n", g.url.canonical); | |
| 134 | 134 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 135 | - fossil_print("Push to %s\n", g.urlCanonical); | |
| 135 | + fossil_print("Push to %s\n", g.url.canonical); | |
| 136 | 136 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 137 | - fossil_print("Pull from %s\n", g.urlCanonical); | |
| 137 | + fossil_print("Pull from %s\n", g.url.canonical); | |
| 138 | 138 | } |
| 139 | 139 | } |
| 140 | 140 | url_enable_proxy("via proxy: "); |
| 141 | 141 | *pConfigFlags |= configSync; |
| 142 | 142 | } |
| @@ -278,8 +278,8 @@ | ||
| 278 | 278 | if( zUrl==0 ){ |
| 279 | 279 | fossil_print("off\n"); |
| 280 | 280 | return; |
| 281 | 281 | }else{ |
| 282 | 282 | url_parse(zUrl, 0); |
| 283 | - fossil_print("%s\n", g.urlCanonical); | |
| 283 | + fossil_print("%s\n", g.url.canonical); | |
| 284 | 284 | } |
| 285 | 285 | } |
| 286 | 286 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -48,14 +48,14 @@ | |
| 48 | } |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.urlProtocol==0 ) return 0; |
| 54 | if( g.urlUser!=0 && g.urlPasswd==0 ){ |
| 55 | g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | g.urlFlags |= URL_PROMPT_PW; |
| 57 | url_prompt_for_password(); |
| 58 | } |
| 59 | g.zHttpAuth = get_httpauth(); |
| 60 | url_remember(); |
| 61 | #if 0 /* Disabled for now */ |
| @@ -69,11 +69,11 @@ | |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| 72 | #endif |
| 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 75 | url_enable_proxy("via proxy: "); |
| 76 | rc = client_sync(flags, configSync, 0); |
| 77 | if( rc ) fossil_warning("Autosync failed"); |
| 78 | return rc; |
| 79 | } |
| @@ -121,22 +121,22 @@ | |
| 121 | clone_ssh_db_set_options(); |
| 122 | } |
| 123 | url_parse(zUrl, urlFlags); |
| 124 | remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl); |
| 125 | url_remember(); |
| 126 | if( g.urlProtocol==0 ){ |
| 127 | if( urlOptional ) fossil_exit(0); |
| 128 | usage("URL"); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 133 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 134 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 135 | fossil_print("Push to %s\n", g.urlCanonical); |
| 136 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 137 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 138 | } |
| 139 | } |
| 140 | url_enable_proxy("via proxy: "); |
| 141 | *pConfigFlags |= configSync; |
| 142 | } |
| @@ -278,8 +278,8 @@ | |
| 278 | if( zUrl==0 ){ |
| 279 | fossil_print("off\n"); |
| 280 | return; |
| 281 | }else{ |
| 282 | url_parse(zUrl, 0); |
| 283 | fossil_print("%s\n", g.urlCanonical); |
| 284 | } |
| 285 | } |
| 286 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -48,14 +48,14 @@ | |
| 48 | } |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.url.protocol==0 ) return 0; |
| 54 | if( g.url.user!=0 && g.url.passwd==0 ){ |
| 55 | g.url.passwd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | g.url.flags |= URL_PROMPT_PW; |
| 57 | url_prompt_for_password(); |
| 58 | } |
| 59 | g.zHttpAuth = get_httpauth(); |
| 60 | url_remember(); |
| 61 | #if 0 /* Disabled for now */ |
| @@ -69,11 +69,11 @@ | |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| 72 | #endif |
| 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | fossil_print("Autosync: %s\n", g.url.canonical); |
| 75 | url_enable_proxy("via proxy: "); |
| 76 | rc = client_sync(flags, configSync, 0); |
| 77 | if( rc ) fossil_warning("Autosync failed"); |
| 78 | return rc; |
| 79 | } |
| @@ -121,22 +121,22 @@ | |
| 121 | clone_ssh_db_set_options(); |
| 122 | } |
| 123 | url_parse(zUrl, urlFlags); |
| 124 | remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl); |
| 125 | url_remember(); |
| 126 | if( g.url.protocol==0 ){ |
| 127 | if( urlOptional ) fossil_exit(0); |
| 128 | usage("URL"); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 133 | fossil_print("Sync with %s\n", g.url.canonical); |
| 134 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 135 | fossil_print("Push to %s\n", g.url.canonical); |
| 136 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 137 | fossil_print("Pull from %s\n", g.url.canonical); |
| 138 | } |
| 139 | } |
| 140 | url_enable_proxy("via proxy: "); |
| 141 | *pConfigFlags |= configSync; |
| 142 | } |
| @@ -278,8 +278,8 @@ | |
| 278 | if( zUrl==0 ){ |
| 279 | fossil_print("off\n"); |
| 280 | return; |
| 281 | }else{ |
| 282 | url_parse(zUrl, 0); |
| 283 | fossil_print("%s\n", g.url.canonical); |
| 284 | } |
| 285 | } |
| 286 |
+9
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -571,10 +571,19 @@ | ||
| 571 | 571 | ** WEBPAGE: tarball |
| 572 | 572 | ** URL: /tarball/RID.tar.gz |
| 573 | 573 | ** |
| 574 | 574 | ** Generate a compressed tarball for a checkin. |
| 575 | 575 | ** Return that tarball as the HTTP reply content. |
| 576 | +** | |
| 577 | +** Optional URL Parameters: | |
| 578 | +** | |
| 579 | +** - name=base name of the output file. Defaults to | |
| 580 | +** something project/version-specific. | |
| 581 | +** | |
| 582 | +** - uuid=the version to tar (may be a tag/branch name). | |
| 583 | +** Defaults to trunk. | |
| 584 | +** | |
| 576 | 585 | */ |
| 577 | 586 | void tarball_page(void){ |
| 578 | 587 | int rid; |
| 579 | 588 | char *zName, *zRid; |
| 580 | 589 | int nName, nRid; |
| 581 | 590 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -571,10 +571,19 @@ | |
| 571 | ** WEBPAGE: tarball |
| 572 | ** URL: /tarball/RID.tar.gz |
| 573 | ** |
| 574 | ** Generate a compressed tarball for a checkin. |
| 575 | ** Return that tarball as the HTTP reply content. |
| 576 | */ |
| 577 | void tarball_page(void){ |
| 578 | int rid; |
| 579 | char *zName, *zRid; |
| 580 | int nName, nRid; |
| 581 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -571,10 +571,19 @@ | |
| 571 | ** WEBPAGE: tarball |
| 572 | ** URL: /tarball/RID.tar.gz |
| 573 | ** |
| 574 | ** Generate a compressed tarball for a checkin. |
| 575 | ** Return that tarball as the HTTP reply content. |
| 576 | ** |
| 577 | ** Optional URL Parameters: |
| 578 | ** |
| 579 | ** - name=base name of the output file. Defaults to |
| 580 | ** something project/version-specific. |
| 581 | ** |
| 582 | ** - uuid=the version to tar (may be a tag/branch name). |
| 583 | ** Defaults to trunk. |
| 584 | ** |
| 585 | */ |
| 586 | void tarball_page(void){ |
| 587 | int rid; |
| 588 | char *zName, *zRid; |
| 589 | int nName, nRid; |
| 590 |
M
src/th.c
+90
-10
| --- src/th.c | ||
| +++ src/th.c | ||
| @@ -128,10 +128,11 @@ | ||
| 128 | 128 | */ |
| 129 | 129 | static int thNextCommand(Th_Interp*, const char *z, int n, int *pN); |
| 130 | 130 | static int thNextEscape (Th_Interp*, const char *z, int n, int *pN); |
| 131 | 131 | static int thNextVarname(Th_Interp*, const char *z, int n, int *pN); |
| 132 | 132 | static int thNextNumber (Th_Interp*, const char *z, int n, int *pN); |
| 133 | +static int thNextInteger (Th_Interp*, const char *z, int n, int *pN); | |
| 133 | 134 | static int thNextSpace (Th_Interp*, const char *z, int n, int *pN); |
| 134 | 135 | |
| 135 | 136 | /* |
| 136 | 137 | ** Given that the input string (z, n) contains a language construct of |
| 137 | 138 | ** the relevant type (a command enclosed in [], an escape sequence |
| @@ -1866,10 +1867,43 @@ | ||
| 1866 | 1867 | {"^", OP_BITWISE_XOR, 9, ARG_INTEGER}, |
| 1867 | 1868 | {"|", OP_BITWISE_OR, 10, ARG_INTEGER}, |
| 1868 | 1869 | |
| 1869 | 1870 | {0,0,0,0} |
| 1870 | 1871 | }; |
| 1872 | + | |
| 1873 | +/* | |
| 1874 | +** The first part of the string (zInput,nInput) contains an integer. | |
| 1875 | +** Set *pnVarname to the number of bytes in the numeric string. | |
| 1876 | +*/ | |
| 1877 | +static int thNextInteger( | |
| 1878 | + Th_Interp *interp, | |
| 1879 | + const char *zInput, | |
| 1880 | + int nInput, | |
| 1881 | + int *pnLiteral | |
| 1882 | +){ | |
| 1883 | + int i; | |
| 1884 | + int (*isdigit)(char) = th_isdigit; | |
| 1885 | + char c; | |
| 1886 | + | |
| 1887 | + if( nInput<2) return TH_ERROR; | |
| 1888 | + assert(zInput[0]=='0'); | |
| 1889 | + c = zInput[1]; | |
| 1890 | + if( c>='A' && c<='Z' ) c += 'a' - 'A'; | |
| 1891 | + if( c=='x' ){ | |
| 1892 | + isdigit = th_ishexdig; | |
| 1893 | + }else if( c!='o' && c!='b' ){ | |
| 1894 | + return TH_ERROR; | |
| 1895 | + } | |
| 1896 | + for(i=2; i<nInput; i++){ | |
| 1897 | + c = zInput[i]; | |
| 1898 | + if( !isdigit(c) ){ | |
| 1899 | + break; | |
| 1900 | + } | |
| 1901 | + } | |
| 1902 | + *pnLiteral = i; | |
| 1903 | + return TH_OK; | |
| 1904 | +} | |
| 1871 | 1905 | |
| 1872 | 1906 | /* |
| 1873 | 1907 | ** The first part of the string (zInput,nInput) contains a number. |
| 1874 | 1908 | ** Set *pnVarname to the number of bytes in the numeric string. |
| 1875 | 1909 | */ |
| @@ -1877,13 +1911,13 @@ | ||
| 1877 | 1911 | Th_Interp *interp, |
| 1878 | 1912 | const char *zInput, |
| 1879 | 1913 | int nInput, |
| 1880 | 1914 | int *pnLiteral |
| 1881 | 1915 | ){ |
| 1882 | - int i; | |
| 1916 | + int i = 0; | |
| 1883 | 1917 | int seenDot = 0; |
| 1884 | - for(i=0; i<nInput; i++){ | |
| 1918 | + for(; i<nInput; i++){ | |
| 1885 | 1919 | char c = zInput[i]; |
| 1886 | 1920 | if( (seenDot || c!='.') && !th_isdigit(c) ) break; |
| 1887 | 1921 | if( c=='.' ) seenDot = 1; |
| 1888 | 1922 | } |
| 1889 | 1923 | *pnLiteral = i; |
| @@ -1996,10 +2030,11 @@ | ||
| 1996 | 2030 | case OP_BITWISE_OR: iRes = iLeft|iRight; break; |
| 1997 | 2031 | case OP_LOGICAL_AND: iRes = iLeft&&iRight; break; |
| 1998 | 2032 | case OP_LOGICAL_OR: iRes = iLeft||iRight; break; |
| 1999 | 2033 | case OP_UNARY_MINUS: iRes = -iLeft; break; |
| 2000 | 2034 | case OP_UNARY_PLUS: iRes = +iLeft; break; |
| 2035 | + case OP_BITWISE_NOT: iRes = ~iLeft; break; | |
| 2001 | 2036 | case OP_LOGICAL_NOT: iRes = !iLeft; break; |
| 2002 | 2037 | default: assert(!"Internal error"); |
| 2003 | 2038 | } |
| 2004 | 2039 | Th_SetResultInt(interp, iRes); |
| 2005 | 2040 | }else if( rc==TH_OK && eArgType==ARG_NUMBER ){ |
| @@ -2154,12 +2189,17 @@ | ||
| 2154 | 2189 | }else{ |
| 2155 | 2190 | Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr)); |
| 2156 | 2191 | const char *z = &zExpr[i]; |
| 2157 | 2192 | |
| 2158 | 2193 | switch (c) { |
| 2159 | - case '0': case '1': case '2': case '3': case '4': | |
| 2160 | - case '5': case '6': case '7': case '8': case '9': | |
| 2194 | + case '0': | |
| 2195 | + if( thNextInteger(interp, z, nExpr-i, &pNew->nValue)==TH_OK ){ | |
| 2196 | + break; | |
| 2197 | + } | |
| 2198 | + /* fall through */ | |
| 2199 | + case '1': case '2': case '3': case '4': case '5': | |
| 2200 | + case '6': case '7': case '8': case '9': | |
| 2161 | 2201 | thNextNumber(interp, z, nExpr-i, &pNew->nValue); |
| 2162 | 2202 | break; |
| 2163 | 2203 | |
| 2164 | 2204 | case '$': |
| 2165 | 2205 | thNextVarname(interp, z, nExpr-i, &pNew->nValue); |
| @@ -2410,11 +2450,12 @@ | ||
| 2410 | 2450 | ** '\f' 0x0C |
| 2411 | 2451 | ** '\r' 0x0D |
| 2412 | 2452 | ** |
| 2413 | 2453 | ** Whitespace characters have the 0x01 flag set. Decimal digits have the |
| 2414 | 2454 | ** 0x2 flag set. Single byte printable characters have the 0x4 flag set. |
| 2415 | -** Alphabet characters have the 0x8 bit set. | |
| 2455 | +** Alphabet characters have the 0x8 bit set. Hexadecimal digits have the | |
| 2456 | +** 0x20 flag set. | |
| 2416 | 2457 | ** |
| 2417 | 2458 | ** The special list characters have the 0x10 flag set |
| 2418 | 2459 | ** |
| 2419 | 2460 | ** { } [ ] \ ; ' " |
| 2420 | 2461 | ** |
| @@ -2423,14 +2464,14 @@ | ||
| 2423 | 2464 | */ |
| 2424 | 2465 | static unsigned char aCharProp[256] = { |
| 2425 | 2466 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, /* 0x0. */ |
| 2426 | 2467 | 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1. */ |
| 2427 | 2468 | 5, 4, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x2. */ |
| 2428 | - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 20, 4, 4, 4, 4, /* 0x3. */ | |
| 2429 | - 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x4. */ | |
| 2469 | + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 4, 20, 4, 4, 4, 4, /* 0x3. */ | |
| 2470 | + 4, 44, 44, 44, 44, 44, 44, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x4. */ | |
| 2430 | 2471 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 4, 4, /* 0x5. */ |
| 2431 | - 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x6. */ | |
| 2472 | + 4, 44, 44, 44, 44, 44, 44, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x6. */ | |
| 2432 | 2473 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 4, 20, 4, 4, /* 0x7. */ |
| 2433 | 2474 | |
| 2434 | 2475 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8. */ |
| 2435 | 2476 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9. */ |
| 2436 | 2477 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA. */ |
| @@ -2454,10 +2495,22 @@ | ||
| 2454 | 2495 | return (aCharProp[(unsigned char)c] & 0x11); |
| 2455 | 2496 | } |
| 2456 | 2497 | int th_isalnum(char c){ |
| 2457 | 2498 | return (aCharProp[(unsigned char)c] & 0x0A); |
| 2458 | 2499 | } |
| 2500 | +int th_isalpha(char c){ | |
| 2501 | + return (aCharProp[(unsigned char)c] & 0x08); | |
| 2502 | +} | |
| 2503 | +int th_ishexdig(char c){ | |
| 2504 | + return (aCharProp[(unsigned char)c] & 0x20); | |
| 2505 | +} | |
| 2506 | +int th_isoctdig(char c){ | |
| 2507 | + return ((c|7) == '7'); | |
| 2508 | +} | |
| 2509 | +int th_isbindig(char c){ | |
| 2510 | + return ((c|1) == '1'); | |
| 2511 | +} | |
| 2459 | 2512 | |
| 2460 | 2513 | #ifndef LONGDOUBLE_TYPE |
| 2461 | 2514 | # define LONGDOUBLE_TYPE long double |
| 2462 | 2515 | #endif |
| 2463 | 2516 | |
| @@ -2570,24 +2623,51 @@ | ||
| 2570 | 2623 | ** interpreter result too. |
| 2571 | 2624 | */ |
| 2572 | 2625 | int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ |
| 2573 | 2626 | int i = 0; |
| 2574 | 2627 | int iOut = 0; |
| 2628 | + int base = 10; | |
| 2629 | + int (*isdigit)(char) = th_isdigit; | |
| 2575 | 2630 | |
| 2576 | 2631 | if( n<0 ){ |
| 2577 | 2632 | n = th_strlen(z); |
| 2578 | 2633 | } |
| 2579 | 2634 | |
| 2580 | 2635 | if( n>0 && (z[0]=='-' || z[0]=='+') ){ |
| 2581 | 2636 | i = 1; |
| 2637 | + } | |
| 2638 | + if( n>2 ){ | |
| 2639 | + if( z[i]=='0' ){ | |
| 2640 | + if( z[i+1]=='x' || z[i+1]=='X' ){ | |
| 2641 | + i += 2; | |
| 2642 | + base = 16; | |
| 2643 | + isdigit = th_ishexdig; | |
| 2644 | + }else if( z[i+1]=='o' || z[i+1]=='O' ){ | |
| 2645 | + i += 2; | |
| 2646 | + base = 8; | |
| 2647 | + isdigit = th_isoctdig; | |
| 2648 | + }else if( z[i+1]=='b' || z[i+1]=='B' ){ | |
| 2649 | + i += 2; | |
| 2650 | + base = 2; | |
| 2651 | + isdigit = th_isbindig; | |
| 2652 | + } | |
| 2653 | + } | |
| 2582 | 2654 | } |
| 2583 | 2655 | for(; i<n; i++){ |
| 2584 | - if( !th_isdigit(z[i]) ){ | |
| 2656 | + char c = z[i]; | |
| 2657 | + if( !isdigit(c) ){ | |
| 2585 | 2658 | Th_ErrorMessage(interp, "expected integer, got: \"", z, n); |
| 2586 | 2659 | return TH_ERROR; |
| 2587 | 2660 | } |
| 2588 | - iOut = iOut * 10 + (z[i] - 48); | |
| 2661 | + if( c>='a' ){ | |
| 2662 | + c -= 'a'-10; | |
| 2663 | + }else if( c>='A' ){ | |
| 2664 | + c -= 'A'-10; | |
| 2665 | + }else{ | |
| 2666 | + c -= '0'; | |
| 2667 | + } | |
| 2668 | + iOut = iOut * base + c; | |
| 2589 | 2669 | } |
| 2590 | 2670 | |
| 2591 | 2671 | if( n>0 && z[0]=='-' ){ |
| 2592 | 2672 | iOut *= -1; |
| 2593 | 2673 | } |
| 2594 | 2674 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -128,10 +128,11 @@ | |
| 128 | */ |
| 129 | static int thNextCommand(Th_Interp*, const char *z, int n, int *pN); |
| 130 | static int thNextEscape (Th_Interp*, const char *z, int n, int *pN); |
| 131 | static int thNextVarname(Th_Interp*, const char *z, int n, int *pN); |
| 132 | static int thNextNumber (Th_Interp*, const char *z, int n, int *pN); |
| 133 | static int thNextSpace (Th_Interp*, const char *z, int n, int *pN); |
| 134 | |
| 135 | /* |
| 136 | ** Given that the input string (z, n) contains a language construct of |
| 137 | ** the relevant type (a command enclosed in [], an escape sequence |
| @@ -1866,10 +1867,43 @@ | |
| 1866 | {"^", OP_BITWISE_XOR, 9, ARG_INTEGER}, |
| 1867 | {"|", OP_BITWISE_OR, 10, ARG_INTEGER}, |
| 1868 | |
| 1869 | {0,0,0,0} |
| 1870 | }; |
| 1871 | |
| 1872 | /* |
| 1873 | ** The first part of the string (zInput,nInput) contains a number. |
| 1874 | ** Set *pnVarname to the number of bytes in the numeric string. |
| 1875 | */ |
| @@ -1877,13 +1911,13 @@ | |
| 1877 | Th_Interp *interp, |
| 1878 | const char *zInput, |
| 1879 | int nInput, |
| 1880 | int *pnLiteral |
| 1881 | ){ |
| 1882 | int i; |
| 1883 | int seenDot = 0; |
| 1884 | for(i=0; i<nInput; i++){ |
| 1885 | char c = zInput[i]; |
| 1886 | if( (seenDot || c!='.') && !th_isdigit(c) ) break; |
| 1887 | if( c=='.' ) seenDot = 1; |
| 1888 | } |
| 1889 | *pnLiteral = i; |
| @@ -1996,10 +2030,11 @@ | |
| 1996 | case OP_BITWISE_OR: iRes = iLeft|iRight; break; |
| 1997 | case OP_LOGICAL_AND: iRes = iLeft&&iRight; break; |
| 1998 | case OP_LOGICAL_OR: iRes = iLeft||iRight; break; |
| 1999 | case OP_UNARY_MINUS: iRes = -iLeft; break; |
| 2000 | case OP_UNARY_PLUS: iRes = +iLeft; break; |
| 2001 | case OP_LOGICAL_NOT: iRes = !iLeft; break; |
| 2002 | default: assert(!"Internal error"); |
| 2003 | } |
| 2004 | Th_SetResultInt(interp, iRes); |
| 2005 | }else if( rc==TH_OK && eArgType==ARG_NUMBER ){ |
| @@ -2154,12 +2189,17 @@ | |
| 2154 | }else{ |
| 2155 | Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr)); |
| 2156 | const char *z = &zExpr[i]; |
| 2157 | |
| 2158 | switch (c) { |
| 2159 | case '0': case '1': case '2': case '3': case '4': |
| 2160 | case '5': case '6': case '7': case '8': case '9': |
| 2161 | thNextNumber(interp, z, nExpr-i, &pNew->nValue); |
| 2162 | break; |
| 2163 | |
| 2164 | case '$': |
| 2165 | thNextVarname(interp, z, nExpr-i, &pNew->nValue); |
| @@ -2410,11 +2450,12 @@ | |
| 2410 | ** '\f' 0x0C |
| 2411 | ** '\r' 0x0D |
| 2412 | ** |
| 2413 | ** Whitespace characters have the 0x01 flag set. Decimal digits have the |
| 2414 | ** 0x2 flag set. Single byte printable characters have the 0x4 flag set. |
| 2415 | ** Alphabet characters have the 0x8 bit set. |
| 2416 | ** |
| 2417 | ** The special list characters have the 0x10 flag set |
| 2418 | ** |
| 2419 | ** { } [ ] \ ; ' " |
| 2420 | ** |
| @@ -2423,14 +2464,14 @@ | |
| 2423 | */ |
| 2424 | static unsigned char aCharProp[256] = { |
| 2425 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, /* 0x0. */ |
| 2426 | 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1. */ |
| 2427 | 5, 4, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x2. */ |
| 2428 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 20, 4, 4, 4, 4, /* 0x3. */ |
| 2429 | 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x4. */ |
| 2430 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 4, 4, /* 0x5. */ |
| 2431 | 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x6. */ |
| 2432 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 4, 20, 4, 4, /* 0x7. */ |
| 2433 | |
| 2434 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8. */ |
| 2435 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9. */ |
| 2436 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA. */ |
| @@ -2454,10 +2495,22 @@ | |
| 2454 | return (aCharProp[(unsigned char)c] & 0x11); |
| 2455 | } |
| 2456 | int th_isalnum(char c){ |
| 2457 | return (aCharProp[(unsigned char)c] & 0x0A); |
| 2458 | } |
| 2459 | |
| 2460 | #ifndef LONGDOUBLE_TYPE |
| 2461 | # define LONGDOUBLE_TYPE long double |
| 2462 | #endif |
| 2463 | |
| @@ -2570,24 +2623,51 @@ | |
| 2570 | ** interpreter result too. |
| 2571 | */ |
| 2572 | int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ |
| 2573 | int i = 0; |
| 2574 | int iOut = 0; |
| 2575 | |
| 2576 | if( n<0 ){ |
| 2577 | n = th_strlen(z); |
| 2578 | } |
| 2579 | |
| 2580 | if( n>0 && (z[0]=='-' || z[0]=='+') ){ |
| 2581 | i = 1; |
| 2582 | } |
| 2583 | for(; i<n; i++){ |
| 2584 | if( !th_isdigit(z[i]) ){ |
| 2585 | Th_ErrorMessage(interp, "expected integer, got: \"", z, n); |
| 2586 | return TH_ERROR; |
| 2587 | } |
| 2588 | iOut = iOut * 10 + (z[i] - 48); |
| 2589 | } |
| 2590 | |
| 2591 | if( n>0 && z[0]=='-' ){ |
| 2592 | iOut *= -1; |
| 2593 | } |
| 2594 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -128,10 +128,11 @@ | |
| 128 | */ |
| 129 | static int thNextCommand(Th_Interp*, const char *z, int n, int *pN); |
| 130 | static int thNextEscape (Th_Interp*, const char *z, int n, int *pN); |
| 131 | static int thNextVarname(Th_Interp*, const char *z, int n, int *pN); |
| 132 | static int thNextNumber (Th_Interp*, const char *z, int n, int *pN); |
| 133 | static int thNextInteger (Th_Interp*, const char *z, int n, int *pN); |
| 134 | static int thNextSpace (Th_Interp*, const char *z, int n, int *pN); |
| 135 | |
| 136 | /* |
| 137 | ** Given that the input string (z, n) contains a language construct of |
| 138 | ** the relevant type (a command enclosed in [], an escape sequence |
| @@ -1866,10 +1867,43 @@ | |
| 1867 | {"^", OP_BITWISE_XOR, 9, ARG_INTEGER}, |
| 1868 | {"|", OP_BITWISE_OR, 10, ARG_INTEGER}, |
| 1869 | |
| 1870 | {0,0,0,0} |
| 1871 | }; |
| 1872 | |
| 1873 | /* |
| 1874 | ** The first part of the string (zInput,nInput) contains an integer. |
| 1875 | ** Set *pnVarname to the number of bytes in the numeric string. |
| 1876 | */ |
| 1877 | static int thNextInteger( |
| 1878 | Th_Interp *interp, |
| 1879 | const char *zInput, |
| 1880 | int nInput, |
| 1881 | int *pnLiteral |
| 1882 | ){ |
| 1883 | int i; |
| 1884 | int (*isdigit)(char) = th_isdigit; |
| 1885 | char c; |
| 1886 | |
| 1887 | if( nInput<2) return TH_ERROR; |
| 1888 | assert(zInput[0]=='0'); |
| 1889 | c = zInput[1]; |
| 1890 | if( c>='A' && c<='Z' ) c += 'a' - 'A'; |
| 1891 | if( c=='x' ){ |
| 1892 | isdigit = th_ishexdig; |
| 1893 | }else if( c!='o' && c!='b' ){ |
| 1894 | return TH_ERROR; |
| 1895 | } |
| 1896 | for(i=2; i<nInput; i++){ |
| 1897 | c = zInput[i]; |
| 1898 | if( !isdigit(c) ){ |
| 1899 | break; |
| 1900 | } |
| 1901 | } |
| 1902 | *pnLiteral = i; |
| 1903 | return TH_OK; |
| 1904 | } |
| 1905 | |
| 1906 | /* |
| 1907 | ** The first part of the string (zInput,nInput) contains a number. |
| 1908 | ** Set *pnVarname to the number of bytes in the numeric string. |
| 1909 | */ |
| @@ -1877,13 +1911,13 @@ | |
| 1911 | Th_Interp *interp, |
| 1912 | const char *zInput, |
| 1913 | int nInput, |
| 1914 | int *pnLiteral |
| 1915 | ){ |
| 1916 | int i = 0; |
| 1917 | int seenDot = 0; |
| 1918 | for(; i<nInput; i++){ |
| 1919 | char c = zInput[i]; |
| 1920 | if( (seenDot || c!='.') && !th_isdigit(c) ) break; |
| 1921 | if( c=='.' ) seenDot = 1; |
| 1922 | } |
| 1923 | *pnLiteral = i; |
| @@ -1996,10 +2030,11 @@ | |
| 2030 | case OP_BITWISE_OR: iRes = iLeft|iRight; break; |
| 2031 | case OP_LOGICAL_AND: iRes = iLeft&&iRight; break; |
| 2032 | case OP_LOGICAL_OR: iRes = iLeft||iRight; break; |
| 2033 | case OP_UNARY_MINUS: iRes = -iLeft; break; |
| 2034 | case OP_UNARY_PLUS: iRes = +iLeft; break; |
| 2035 | case OP_BITWISE_NOT: iRes = ~iLeft; break; |
| 2036 | case OP_LOGICAL_NOT: iRes = !iLeft; break; |
| 2037 | default: assert(!"Internal error"); |
| 2038 | } |
| 2039 | Th_SetResultInt(interp, iRes); |
| 2040 | }else if( rc==TH_OK && eArgType==ARG_NUMBER ){ |
| @@ -2154,12 +2189,17 @@ | |
| 2189 | }else{ |
| 2190 | Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr)); |
| 2191 | const char *z = &zExpr[i]; |
| 2192 | |
| 2193 | switch (c) { |
| 2194 | case '0': |
| 2195 | if( thNextInteger(interp, z, nExpr-i, &pNew->nValue)==TH_OK ){ |
| 2196 | break; |
| 2197 | } |
| 2198 | /* fall through */ |
| 2199 | case '1': case '2': case '3': case '4': case '5': |
| 2200 | case '6': case '7': case '8': case '9': |
| 2201 | thNextNumber(interp, z, nExpr-i, &pNew->nValue); |
| 2202 | break; |
| 2203 | |
| 2204 | case '$': |
| 2205 | thNextVarname(interp, z, nExpr-i, &pNew->nValue); |
| @@ -2410,11 +2450,12 @@ | |
| 2450 | ** '\f' 0x0C |
| 2451 | ** '\r' 0x0D |
| 2452 | ** |
| 2453 | ** Whitespace characters have the 0x01 flag set. Decimal digits have the |
| 2454 | ** 0x2 flag set. Single byte printable characters have the 0x4 flag set. |
| 2455 | ** Alphabet characters have the 0x8 bit set. Hexadecimal digits have the |
| 2456 | ** 0x20 flag set. |
| 2457 | ** |
| 2458 | ** The special list characters have the 0x10 flag set |
| 2459 | ** |
| 2460 | ** { } [ ] \ ; ' " |
| 2461 | ** |
| @@ -2423,14 +2464,14 @@ | |
| 2464 | */ |
| 2465 | static unsigned char aCharProp[256] = { |
| 2466 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, /* 0x0. */ |
| 2467 | 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1. */ |
| 2468 | 5, 4, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x2. */ |
| 2469 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 4, 20, 4, 4, 4, 4, /* 0x3. */ |
| 2470 | 4, 44, 44, 44, 44, 44, 44, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x4. */ |
| 2471 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 4, 4, /* 0x5. */ |
| 2472 | 4, 44, 44, 44, 44, 44, 44, 12, 12, 12, 12, 12, 12, 12, 12, 12, /* 0x6. */ |
| 2473 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 4, 20, 4, 4, /* 0x7. */ |
| 2474 | |
| 2475 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8. */ |
| 2476 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9. */ |
| 2477 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA. */ |
| @@ -2454,10 +2495,22 @@ | |
| 2495 | return (aCharProp[(unsigned char)c] & 0x11); |
| 2496 | } |
| 2497 | int th_isalnum(char c){ |
| 2498 | return (aCharProp[(unsigned char)c] & 0x0A); |
| 2499 | } |
| 2500 | int th_isalpha(char c){ |
| 2501 | return (aCharProp[(unsigned char)c] & 0x08); |
| 2502 | } |
| 2503 | int th_ishexdig(char c){ |
| 2504 | return (aCharProp[(unsigned char)c] & 0x20); |
| 2505 | } |
| 2506 | int th_isoctdig(char c){ |
| 2507 | return ((c|7) == '7'); |
| 2508 | } |
| 2509 | int th_isbindig(char c){ |
| 2510 | return ((c|1) == '1'); |
| 2511 | } |
| 2512 | |
| 2513 | #ifndef LONGDOUBLE_TYPE |
| 2514 | # define LONGDOUBLE_TYPE long double |
| 2515 | #endif |
| 2516 | |
| @@ -2570,24 +2623,51 @@ | |
| 2623 | ** interpreter result too. |
| 2624 | */ |
| 2625 | int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ |
| 2626 | int i = 0; |
| 2627 | int iOut = 0; |
| 2628 | int base = 10; |
| 2629 | int (*isdigit)(char) = th_isdigit; |
| 2630 | |
| 2631 | if( n<0 ){ |
| 2632 | n = th_strlen(z); |
| 2633 | } |
| 2634 | |
| 2635 | if( n>0 && (z[0]=='-' || z[0]=='+') ){ |
| 2636 | i = 1; |
| 2637 | } |
| 2638 | if( n>2 ){ |
| 2639 | if( z[i]=='0' ){ |
| 2640 | if( z[i+1]=='x' || z[i+1]=='X' ){ |
| 2641 | i += 2; |
| 2642 | base = 16; |
| 2643 | isdigit = th_ishexdig; |
| 2644 | }else if( z[i+1]=='o' || z[i+1]=='O' ){ |
| 2645 | i += 2; |
| 2646 | base = 8; |
| 2647 | isdigit = th_isoctdig; |
| 2648 | }else if( z[i+1]=='b' || z[i+1]=='B' ){ |
| 2649 | i += 2; |
| 2650 | base = 2; |
| 2651 | isdigit = th_isbindig; |
| 2652 | } |
| 2653 | } |
| 2654 | } |
| 2655 | for(; i<n; i++){ |
| 2656 | char c = z[i]; |
| 2657 | if( !isdigit(c) ){ |
| 2658 | Th_ErrorMessage(interp, "expected integer, got: \"", z, n); |
| 2659 | return TH_ERROR; |
| 2660 | } |
| 2661 | if( c>='a' ){ |
| 2662 | c -= 'a'-10; |
| 2663 | }else if( c>='A' ){ |
| 2664 | c -= 'A'-10; |
| 2665 | }else{ |
| 2666 | c -= '0'; |
| 2667 | } |
| 2668 | iOut = iOut * base + c; |
| 2669 | } |
| 2670 | |
| 2671 | if( n>0 && z[0]=='-' ){ |
| 2672 | iOut *= -1; |
| 2673 | } |
| 2674 |
M
src/th.h
+4
| --- src/th.h | ||
| +++ src/th.h | ||
| @@ -145,11 +145,15 @@ | ||
| 145 | 145 | */ |
| 146 | 146 | int th_strlen(const char *); |
| 147 | 147 | int th_isdigit(char); |
| 148 | 148 | int th_isspace(char); |
| 149 | 149 | int th_isalnum(char); |
| 150 | +int th_isalpha(char); | |
| 150 | 151 | int th_isspecial(char); |
| 152 | +int th_ishexdig(char); | |
| 153 | +int th_isoctdig(char); | |
| 154 | +int th_isbindig(char); | |
| 151 | 155 | char *th_strdup(Th_Interp *interp, const char *z, int n); |
| 152 | 156 | |
| 153 | 157 | /* |
| 154 | 158 | ** Interfaces to register the language extensions. |
| 155 | 159 | */ |
| 156 | 160 |
| --- src/th.h | |
| +++ src/th.h | |
| @@ -145,11 +145,15 @@ | |
| 145 | */ |
| 146 | int th_strlen(const char *); |
| 147 | int th_isdigit(char); |
| 148 | int th_isspace(char); |
| 149 | int th_isalnum(char); |
| 150 | int th_isspecial(char); |
| 151 | char *th_strdup(Th_Interp *interp, const char *z, int n); |
| 152 | |
| 153 | /* |
| 154 | ** Interfaces to register the language extensions. |
| 155 | */ |
| 156 |
| --- src/th.h | |
| +++ src/th.h | |
| @@ -145,11 +145,15 @@ | |
| 145 | */ |
| 146 | int th_strlen(const char *); |
| 147 | int th_isdigit(char); |
| 148 | int th_isspace(char); |
| 149 | int th_isalnum(char); |
| 150 | int th_isalpha(char); |
| 151 | int th_isspecial(char); |
| 152 | int th_ishexdig(char); |
| 153 | int th_isoctdig(char); |
| 154 | int th_isbindig(char); |
| 155 | char *th_strdup(Th_Interp *interp, const char *z, int n); |
| 156 | |
| 157 | /* |
| 158 | ** Interfaces to register the language extensions. |
| 159 | */ |
| 160 |
+80
-20
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -48,29 +48,16 @@ | ||
| 48 | 48 | */ |
| 49 | 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | 50 | char z[UUID_SIZE+1]; |
| 51 | 51 | shorten_uuid(z, zUuid); |
| 52 | 52 | if( g.perm.Hyperlink ){ |
| 53 | - @ %z(xhref("class='timelineHistLink'","%R/info/%s",z))[%s(z)]</a> | |
| 53 | + @ %z(xhref("class='timelineHistLink'","%R/info/%s",zUuid))[%s(z)]</a> | |
| 54 | 54 | }else{ |
| 55 | 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | 56 | } |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | -/* | |
| 60 | -** Generate a hyperlink to a diff between two versions. | |
| 61 | -*/ | |
| 62 | -void hyperlink_to_diff(const char *zV1, const char *zV2){ | |
| 63 | - if( g.perm.Hyperlink ){ | |
| 64 | - if( zV2==0 ){ | |
| 65 | - @ %z(href("%R/diff?v2=%s",zV1))[diff]</a> | |
| 66 | - }else{ | |
| 67 | - @ %z(href("%R/diff?v1=%s&v2=%s",zV1,zV2))[diff]</a> | |
| 68 | - } | |
| 69 | - } | |
| 70 | -} | |
| 71 | - | |
| 72 | 59 | /* |
| 73 | 60 | ** Generate a hyperlink to a date & time. |
| 74 | 61 | */ |
| 75 | 62 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 76 | 63 | if( zSuffix==0 ) zSuffix = ""; |
| @@ -448,11 +435,11 @@ | ||
| 448 | 435 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 449 | 436 | } |
| 450 | 437 | |
| 451 | 438 | /* Generate a "detail" link for tags. */ |
| 452 | 439 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 453 | - @ [%z(href("%R/info/%S",zUuid))details</a>] | |
| 440 | + @ [%z(href("%R/info/%s",zUuid))details</a>] | |
| 454 | 441 | } |
| 455 | 442 | |
| 456 | 443 | /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 457 | 444 | ** with hyperlinks to the tag list. |
| 458 | 445 | */ |
| @@ -527,23 +514,23 @@ | ||
| 527 | 514 | } |
| 528 | 515 | continue; |
| 529 | 516 | } |
| 530 | 517 | if( isNew ){ |
| 531 | 518 | @ <li> %h(zFilename) (new file) |
| 532 | - @ %z(href("%R/artifact/%S",zNew))[view]</a></li> | |
| 519 | + @ %z(href("%R/artifact/%s",zNew))[view]</a></li> | |
| 533 | 520 | }else if( isDel ){ |
| 534 | 521 | @ <li> %h(zFilename) (deleted)</li> |
| 535 | 522 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 536 | 523 | @ <li> %h(zOldName) → %h(zFilename) |
| 537 | - @ %z(href("%R/artifact/%S",zNew))[view]</a></li> | |
| 524 | + @ %z(href("%R/artifact/%s",zNew))[view]</a></li> | |
| 538 | 525 | }else{ |
| 539 | 526 | if( zOldName!=0 ){ |
| 540 | 527 | @ <li> %h(zOldName) → %h(zFilename) |
| 541 | 528 | }else{ |
| 542 | 529 | @ <li> %h(zFilename) |
| 543 | 530 | } |
| 544 | - @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a></li> | |
| 531 | + @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li> | |
| 545 | 532 | } |
| 546 | 533 | } |
| 547 | 534 | db_reset(&fchngQuery); |
| 548 | 535 | if( inUl ){ |
| 549 | 536 | @ </ul> |
| @@ -1442,11 +1429,11 @@ | ||
| 1442 | 1429 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1443 | 1430 | } |
| 1444 | 1431 | if( zUses ){ |
| 1445 | 1432 | char *zFilenames = names_of_file(zUses); |
| 1446 | 1433 | blob_appendf(&desc, " using file %s version %z%S</a>", zFilenames, |
| 1447 | - href("%R/artifact/%S",zUses), zUses); | |
| 1434 | + href("%R/artifact/%s",zUses), zUses); | |
| 1448 | 1435 | tmFlags |= TIMELINE_DISJOINT; |
| 1449 | 1436 | } |
| 1450 | 1437 | if( renameOnly ){ |
| 1451 | 1438 | blob_appendf(&desc, " that contain filename changes"); |
| 1452 | 1439 | tmFlags |= TIMELINE_DISJOINT|TIMELINE_FRENAMES; |
| @@ -1963,11 +1950,11 @@ | ||
| 1963 | 1950 | " AND blob.rid=c.cid" |
| 1964 | 1951 | ); |
| 1965 | 1952 | while( db_step(&q)==SQLITE_ROW ){ |
| 1966 | 1953 | const char *zUuid = db_column_text(&q, 0); |
| 1967 | 1954 | @ <li> |
| 1968 | - @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)&unhide">%S(zUuid)</a> | |
| 1955 | + @ <a href="%s(g.zTop)/timeline?p=%s(zUuid)&d=%s(zUuid)&unhide">%S(zUuid)</a> | |
| 1969 | 1956 | } |
| 1970 | 1957 | db_finalize(&q); |
| 1971 | 1958 | style_footer(); |
| 1972 | 1959 | } |
| 1973 | 1960 | |
| @@ -2384,10 +2371,79 @@ | ||
| 2384 | 2371 | @ </tbody></table> |
| 2385 | 2372 | db_finalize(&query); |
| 2386 | 2373 | output_table_sorting_javascript("statsTable","tnx"); |
| 2387 | 2374 | } |
| 2388 | 2375 | |
| 2376 | +/* | |
| 2377 | +** Implements the "byweekday" view for /reports. | |
| 2378 | +*/ | |
| 2379 | +static void stats_report_day_of_week(){ | |
| 2380 | + Stmt query = empty_Stmt; | |
| 2381 | + int nRowNumber = 0; /* current TR number */ | |
| 2382 | + int nEventTotal = 0; /* Total event count */ | |
| 2383 | + int rowClass = 0; /* counter for alternating | |
| 2384 | + row colors */ | |
| 2385 | + Blob sql = empty_blob; /* SQL */ | |
| 2386 | + int nMaxEvents = 1; /* max number of events for | |
| 2387 | + all rows. */ | |
| 2388 | + static char const * daysOfWeek[] = { | |
| 2389 | + "Monday", "Tuesday", "Wednesday", "Thursday", | |
| 2390 | + "Friday", "Saturday", "Sunday" | |
| 2391 | + }; | |
| 2392 | + | |
| 2393 | + stats_report_init_view(); | |
| 2394 | + stats_report_event_types_menu("byweekday", NULL); | |
| 2395 | + blob_append(&sql, | |
| 2396 | + "SELECT cast(mtime %% 7 AS INTEGER) dow, " | |
| 2397 | + "COUNT(*) AS eventCount " | |
| 2398 | + "FROM v_reports " | |
| 2399 | + "GROUP BY dow ORDER BY dow", | |
| 2400 | + -1); | |
| 2401 | + db_prepare(&query, blob_str(&sql)); | |
| 2402 | + blob_reset(&sql); | |
| 2403 | + @ <h1>Timeline Events | |
| 2404 | + @ (%s(stats_report_label_for_type())) by Day of the Week</h1> | |
| 2405 | + @ <table class='statistics-report-table-events' border='0' | |
| 2406 | + @ cellpadding='2' cellspacing='0' id='statsTable'> | |
| 2407 | + @ <thead><tr> | |
| 2408 | + @ <th>DoW</th> | |
| 2409 | + @ <th>Day</th> | |
| 2410 | + @ <th>Events</th> | |
| 2411 | + @ <th width='90%%'><!-- relative commits graph --></th> | |
| 2412 | + @ </tr></thead><tbody> | |
| 2413 | + while( SQLITE_ROW == db_step(&query) ){ | |
| 2414 | + const int nCount = db_column_int(&query, 1); | |
| 2415 | + if(nCount>nMaxEvents){ | |
| 2416 | + nMaxEvents = nCount; | |
| 2417 | + } | |
| 2418 | + } | |
| 2419 | + db_reset(&query); | |
| 2420 | + while( SQLITE_ROW == db_step(&query) ){ | |
| 2421 | + int const dayNum =db_column_int(&query, 0); | |
| 2422 | + const int nCount = db_column_int(&query, 1); | |
| 2423 | + int nSize = nCount | |
| 2424 | + ? (int)(100 * nCount / nMaxEvents) | |
| 2425 | + : 0; | |
| 2426 | + if(!nCount) continue /* arguable! Possible? */; | |
| 2427 | + else if(!nSize) nSize = 1; | |
| 2428 | + rowClass = ++nRowNumber % 2; | |
| 2429 | + nEventTotal += nCount; | |
| 2430 | + @<tr class='row%d(rowClass)'> | |
| 2431 | + @ <td>%d(dayNum)</td> | |
| 2432 | + @ <td>%s(daysOfWeek[dayNum])</td> | |
| 2433 | + @ <td>%d(nCount)</td> | |
| 2434 | + @ <td> | |
| 2435 | + @ <div class='statistics-report-graph-line' | |
| 2436 | + @ style='width:%d(nSize)%%;'> </div> | |
| 2437 | + @ </td> | |
| 2438 | + @</tr> | |
| 2439 | + } | |
| 2440 | + @ </tbody></table> | |
| 2441 | + db_finalize(&query); | |
| 2442 | + output_table_sorting_javascript("statsTable","ntnx"); | |
| 2443 | +} | |
| 2444 | + | |
| 2389 | 2445 | |
| 2390 | 2446 | /* |
| 2391 | 2447 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2392 | 2448 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2393 | 2449 | ** or YYYY-MM. |
| @@ -2554,10 +2610,11 @@ | ||
| 2554 | 2610 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2555 | 2611 | } |
| 2556 | 2612 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2557 | 2613 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2558 | 2614 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2615 | + timeline_submenu(&url, "By Weekday", "view", "byweekday", 0); | |
| 2559 | 2616 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2560 | 2617 | url_reset(&url); |
| 2561 | 2618 | style_header("Activity Reports"); |
| 2562 | 2619 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2563 | 2620 | stats_report_by_month_year(0, 0, zUserName); |
| @@ -2565,17 +2622,20 @@ | ||
| 2565 | 2622 | stats_report_by_month_year(1, 0, zUserName); |
| 2566 | 2623 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2567 | 2624 | stats_report_year_weeks(zUserName); |
| 2568 | 2625 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2569 | 2626 | stats_report_by_user(); |
| 2627 | + }else if(0==fossil_strcmp(zView,"byweekday")){ | |
| 2628 | + stats_report_day_of_week(); | |
| 2570 | 2629 | }else{ |
| 2571 | 2630 | @ <h1>Select a report to show:</h1> |
| 2572 | 2631 | @ <ul> |
| 2573 | 2632 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2574 | 2633 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2575 | 2634 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2635 | + @ <li><a href='?view=byweekday'>Events by day of the week</a></li> | |
| 2576 | 2636 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2577 | 2637 | @ </ul> |
| 2578 | 2638 | } |
| 2579 | 2639 | |
| 2580 | 2640 | style_footer(); |
| 2581 | 2641 | } |
| 2582 | 2642 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -48,29 +48,16 @@ | |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char z[UUID_SIZE+1]; |
| 51 | shorten_uuid(z, zUuid); |
| 52 | if( g.perm.Hyperlink ){ |
| 53 | @ %z(xhref("class='timelineHistLink'","%R/info/%s",z))[%s(z)]</a> |
| 54 | }else{ |
| 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | ** Generate a hyperlink to a diff between two versions. |
| 61 | */ |
| 62 | void hyperlink_to_diff(const char *zV1, const char *zV2){ |
| 63 | if( g.perm.Hyperlink ){ |
| 64 | if( zV2==0 ){ |
| 65 | @ %z(href("%R/diff?v2=%s",zV1))[diff]</a> |
| 66 | }else{ |
| 67 | @ %z(href("%R/diff?v1=%s&v2=%s",zV1,zV2))[diff]</a> |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | /* |
| 73 | ** Generate a hyperlink to a date & time. |
| 74 | */ |
| 75 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 76 | if( zSuffix==0 ) zSuffix = ""; |
| @@ -448,11 +435,11 @@ | |
| 448 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 449 | } |
| 450 | |
| 451 | /* Generate a "detail" link for tags. */ |
| 452 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 453 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 454 | } |
| 455 | |
| 456 | /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 457 | ** with hyperlinks to the tag list. |
| 458 | */ |
| @@ -527,23 +514,23 @@ | |
| 527 | } |
| 528 | continue; |
| 529 | } |
| 530 | if( isNew ){ |
| 531 | @ <li> %h(zFilename) (new file) |
| 532 | @ %z(href("%R/artifact/%S",zNew))[view]</a></li> |
| 533 | }else if( isDel ){ |
| 534 | @ <li> %h(zFilename) (deleted)</li> |
| 535 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 536 | @ <li> %h(zOldName) → %h(zFilename) |
| 537 | @ %z(href("%R/artifact/%S",zNew))[view]</a></li> |
| 538 | }else{ |
| 539 | if( zOldName!=0 ){ |
| 540 | @ <li> %h(zOldName) → %h(zFilename) |
| 541 | }else{ |
| 542 | @ <li> %h(zFilename) |
| 543 | } |
| 544 | @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a></li> |
| 545 | } |
| 546 | } |
| 547 | db_reset(&fchngQuery); |
| 548 | if( inUl ){ |
| 549 | @ </ul> |
| @@ -1442,11 +1429,11 @@ | |
| 1442 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1443 | } |
| 1444 | if( zUses ){ |
| 1445 | char *zFilenames = names_of_file(zUses); |
| 1446 | blob_appendf(&desc, " using file %s version %z%S</a>", zFilenames, |
| 1447 | href("%R/artifact/%S",zUses), zUses); |
| 1448 | tmFlags |= TIMELINE_DISJOINT; |
| 1449 | } |
| 1450 | if( renameOnly ){ |
| 1451 | blob_appendf(&desc, " that contain filename changes"); |
| 1452 | tmFlags |= TIMELINE_DISJOINT|TIMELINE_FRENAMES; |
| @@ -1963,11 +1950,11 @@ | |
| 1963 | " AND blob.rid=c.cid" |
| 1964 | ); |
| 1965 | while( db_step(&q)==SQLITE_ROW ){ |
| 1966 | const char *zUuid = db_column_text(&q, 0); |
| 1967 | @ <li> |
| 1968 | @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)&unhide">%S(zUuid)</a> |
| 1969 | } |
| 1970 | db_finalize(&q); |
| 1971 | style_footer(); |
| 1972 | } |
| 1973 | |
| @@ -2384,10 +2371,79 @@ | |
| 2384 | @ </tbody></table> |
| 2385 | db_finalize(&query); |
| 2386 | output_table_sorting_javascript("statsTable","tnx"); |
| 2387 | } |
| 2388 | |
| 2389 | |
| 2390 | /* |
| 2391 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2392 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2393 | ** or YYYY-MM. |
| @@ -2554,10 +2610,11 @@ | |
| 2554 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2555 | } |
| 2556 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2557 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2558 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2559 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2560 | url_reset(&url); |
| 2561 | style_header("Activity Reports"); |
| 2562 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2563 | stats_report_by_month_year(0, 0, zUserName); |
| @@ -2565,17 +2622,20 @@ | |
| 2565 | stats_report_by_month_year(1, 0, zUserName); |
| 2566 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2567 | stats_report_year_weeks(zUserName); |
| 2568 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2569 | stats_report_by_user(); |
| 2570 | }else{ |
| 2571 | @ <h1>Select a report to show:</h1> |
| 2572 | @ <ul> |
| 2573 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2574 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2575 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2576 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2577 | @ </ul> |
| 2578 | } |
| 2579 | |
| 2580 | style_footer(); |
| 2581 | } |
| 2582 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -48,29 +48,16 @@ | |
| 48 | */ |
| 49 | void hyperlink_to_uuid(const char *zUuid){ |
| 50 | char z[UUID_SIZE+1]; |
| 51 | shorten_uuid(z, zUuid); |
| 52 | if( g.perm.Hyperlink ){ |
| 53 | @ %z(xhref("class='timelineHistLink'","%R/info/%s",zUuid))[%s(z)]</a> |
| 54 | }else{ |
| 55 | @ <span class="timelineHistDsp">[%s(z)]</span> |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | ** Generate a hyperlink to a date & time. |
| 61 | */ |
| 62 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 63 | if( zSuffix==0 ) zSuffix = ""; |
| @@ -448,11 +435,11 @@ | |
| 435 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 436 | } |
| 437 | |
| 438 | /* Generate a "detail" link for tags. */ |
| 439 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 440 | @ [%z(href("%R/info/%s",zUuid))details</a>] |
| 441 | } |
| 442 | |
| 443 | /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 444 | ** with hyperlinks to the tag list. |
| 445 | */ |
| @@ -527,23 +514,23 @@ | |
| 514 | } |
| 515 | continue; |
| 516 | } |
| 517 | if( isNew ){ |
| 518 | @ <li> %h(zFilename) (new file) |
| 519 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 520 | }else if( isDel ){ |
| 521 | @ <li> %h(zFilename) (deleted)</li> |
| 522 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 523 | @ <li> %h(zOldName) → %h(zFilename) |
| 524 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 525 | }else{ |
| 526 | if( zOldName!=0 ){ |
| 527 | @ <li> %h(zOldName) → %h(zFilename) |
| 528 | }else{ |
| 529 | @ <li> %h(zFilename) |
| 530 | } |
| 531 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li> |
| 532 | } |
| 533 | } |
| 534 | db_reset(&fchngQuery); |
| 535 | if( inUl ){ |
| 536 | @ </ul> |
| @@ -1442,11 +1429,11 @@ | |
| 1429 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1430 | } |
| 1431 | if( zUses ){ |
| 1432 | char *zFilenames = names_of_file(zUses); |
| 1433 | blob_appendf(&desc, " using file %s version %z%S</a>", zFilenames, |
| 1434 | href("%R/artifact/%s",zUses), zUses); |
| 1435 | tmFlags |= TIMELINE_DISJOINT; |
| 1436 | } |
| 1437 | if( renameOnly ){ |
| 1438 | blob_appendf(&desc, " that contain filename changes"); |
| 1439 | tmFlags |= TIMELINE_DISJOINT|TIMELINE_FRENAMES; |
| @@ -1963,11 +1950,11 @@ | |
| 1950 | " AND blob.rid=c.cid" |
| 1951 | ); |
| 1952 | while( db_step(&q)==SQLITE_ROW ){ |
| 1953 | const char *zUuid = db_column_text(&q, 0); |
| 1954 | @ <li> |
| 1955 | @ <a href="%s(g.zTop)/timeline?p=%s(zUuid)&d=%s(zUuid)&unhide">%S(zUuid)</a> |
| 1956 | } |
| 1957 | db_finalize(&q); |
| 1958 | style_footer(); |
| 1959 | } |
| 1960 | |
| @@ -2384,10 +2371,79 @@ | |
| 2371 | @ </tbody></table> |
| 2372 | db_finalize(&query); |
| 2373 | output_table_sorting_javascript("statsTable","tnx"); |
| 2374 | } |
| 2375 | |
| 2376 | /* |
| 2377 | ** Implements the "byweekday" view for /reports. |
| 2378 | */ |
| 2379 | static void stats_report_day_of_week(){ |
| 2380 | Stmt query = empty_Stmt; |
| 2381 | int nRowNumber = 0; /* current TR number */ |
| 2382 | int nEventTotal = 0; /* Total event count */ |
| 2383 | int rowClass = 0; /* counter for alternating |
| 2384 | row colors */ |
| 2385 | Blob sql = empty_blob; /* SQL */ |
| 2386 | int nMaxEvents = 1; /* max number of events for |
| 2387 | all rows. */ |
| 2388 | static char const * daysOfWeek[] = { |
| 2389 | "Monday", "Tuesday", "Wednesday", "Thursday", |
| 2390 | "Friday", "Saturday", "Sunday" |
| 2391 | }; |
| 2392 | |
| 2393 | stats_report_init_view(); |
| 2394 | stats_report_event_types_menu("byweekday", NULL); |
| 2395 | blob_append(&sql, |
| 2396 | "SELECT cast(mtime %% 7 AS INTEGER) dow, " |
| 2397 | "COUNT(*) AS eventCount " |
| 2398 | "FROM v_reports " |
| 2399 | "GROUP BY dow ORDER BY dow", |
| 2400 | -1); |
| 2401 | db_prepare(&query, blob_str(&sql)); |
| 2402 | blob_reset(&sql); |
| 2403 | @ <h1>Timeline Events |
| 2404 | @ (%s(stats_report_label_for_type())) by Day of the Week</h1> |
| 2405 | @ <table class='statistics-report-table-events' border='0' |
| 2406 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2407 | @ <thead><tr> |
| 2408 | @ <th>DoW</th> |
| 2409 | @ <th>Day</th> |
| 2410 | @ <th>Events</th> |
| 2411 | @ <th width='90%%'><!-- relative commits graph --></th> |
| 2412 | @ </tr></thead><tbody> |
| 2413 | while( SQLITE_ROW == db_step(&query) ){ |
| 2414 | const int nCount = db_column_int(&query, 1); |
| 2415 | if(nCount>nMaxEvents){ |
| 2416 | nMaxEvents = nCount; |
| 2417 | } |
| 2418 | } |
| 2419 | db_reset(&query); |
| 2420 | while( SQLITE_ROW == db_step(&query) ){ |
| 2421 | int const dayNum =db_column_int(&query, 0); |
| 2422 | const int nCount = db_column_int(&query, 1); |
| 2423 | int nSize = nCount |
| 2424 | ? (int)(100 * nCount / nMaxEvents) |
| 2425 | : 0; |
| 2426 | if(!nCount) continue /* arguable! Possible? */; |
| 2427 | else if(!nSize) nSize = 1; |
| 2428 | rowClass = ++nRowNumber % 2; |
| 2429 | nEventTotal += nCount; |
| 2430 | @<tr class='row%d(rowClass)'> |
| 2431 | @ <td>%d(dayNum)</td> |
| 2432 | @ <td>%s(daysOfWeek[dayNum])</td> |
| 2433 | @ <td>%d(nCount)</td> |
| 2434 | @ <td> |
| 2435 | @ <div class='statistics-report-graph-line' |
| 2436 | @ style='width:%d(nSize)%%;'> </div> |
| 2437 | @ </td> |
| 2438 | @</tr> |
| 2439 | } |
| 2440 | @ </tbody></table> |
| 2441 | db_finalize(&query); |
| 2442 | output_table_sorting_javascript("statsTable","ntnx"); |
| 2443 | } |
| 2444 | |
| 2445 | |
| 2446 | /* |
| 2447 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2448 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2449 | ** or YYYY-MM. |
| @@ -2554,10 +2610,11 @@ | |
| 2610 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2611 | } |
| 2612 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2613 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2614 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2615 | timeline_submenu(&url, "By Weekday", "view", "byweekday", 0); |
| 2616 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2617 | url_reset(&url); |
| 2618 | style_header("Activity Reports"); |
| 2619 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2620 | stats_report_by_month_year(0, 0, zUserName); |
| @@ -2565,17 +2622,20 @@ | |
| 2622 | stats_report_by_month_year(1, 0, zUserName); |
| 2623 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2624 | stats_report_year_weeks(zUserName); |
| 2625 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2626 | stats_report_by_user(); |
| 2627 | }else if(0==fossil_strcmp(zView,"byweekday")){ |
| 2628 | stats_report_day_of_week(); |
| 2629 | }else{ |
| 2630 | @ <h1>Select a report to show:</h1> |
| 2631 | @ <ul> |
| 2632 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2633 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2634 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2635 | @ <li><a href='?view=byweekday'>Events by day of the week</a></li> |
| 2636 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2637 | @ </ul> |
| 2638 | } |
| 2639 | |
| 2640 | style_footer(); |
| 2641 | } |
| 2642 |
+12
-19
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -446,14 +446,14 @@ | ||
| 446 | 446 | style_submenu_element("Attach", "Add An Attachment", |
| 447 | 447 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 448 | 448 | g.zTop, zUuid, g.zTop, zUuid); |
| 449 | 449 | } |
| 450 | 450 | if( P("plaintext") ){ |
| 451 | - style_submenu_element("Formatted", "Formatted", "%R/tktview/%S", zUuid); | |
| 451 | + style_submenu_element("Formatted", "Formatted", "%R/tktview/%s", zUuid); | |
| 452 | 452 | }else{ |
| 453 | 453 | style_submenu_element("Plaintext", "Plaintext", |
| 454 | - "%R/tktview/%S?plaintext", zUuid); | |
| 454 | + "%R/tktview/%s?plaintext", zUuid); | |
| 455 | 455 | } |
| 456 | 456 | style_header("View Ticket"); |
| 457 | 457 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1); |
| 458 | 458 | ticket_init(); |
| 459 | 459 | initializeVariablesFromCGI(); |
| @@ -895,14 +895,14 @@ | ||
| 895 | 895 | "%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid); |
| 896 | 896 | style_submenu_element("Timeline", "Timeline", |
| 897 | 897 | "%s/tkttimeline?name=%s", g.zTop, zUuid); |
| 898 | 898 | if( P("plaintext")!=0 ){ |
| 899 | 899 | style_submenu_element("Formatted", "Formatted", |
| 900 | - "%R/tkthistory/%S", zUuid); | |
| 900 | + "%R/tkthistory/%s", zUuid); | |
| 901 | 901 | }else{ |
| 902 | 902 | style_submenu_element("Plaintext", "Plaintext", |
| 903 | - "%R/tkthistory/%S?plaintext", zUuid); | |
| 903 | + "%R/tkthistory/%s?plaintext", zUuid); | |
| 904 | 904 | } |
| 905 | 905 | style_header(zTitle); |
| 906 | 906 | free(zTitle); |
| 907 | 907 | |
| 908 | 908 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| @@ -924,17 +924,14 @@ | ||
| 924 | 924 | " ORDER BY 1", |
| 925 | 925 | timeline_utc(), tagid, timeline_utc(), tagid |
| 926 | 926 | ); |
| 927 | 927 | while( db_step(&q)==SQLITE_ROW ){ |
| 928 | 928 | Manifest *pTicket; |
| 929 | - char zShort[12]; | |
| 930 | 929 | const char *zDate = db_column_text(&q, 0); |
| 931 | 930 | int rid = db_column_int(&q, 1); |
| 932 | 931 | const char *zChngUuid = db_column_text(&q, 2); |
| 933 | 932 | const char *zFile = db_column_text(&q, 4); |
| 934 | - memcpy(zShort, zChngUuid, 10); | |
| 935 | - zShort[10] = 0; | |
| 936 | 933 | if( nChng==0 ){ |
| 937 | 934 | @ <ol> |
| 938 | 935 | } |
| 939 | 936 | nChng++; |
| 940 | 937 | if( zFile!=0 ){ |
| @@ -944,22 +941,22 @@ | ||
| 944 | 941 | @ |
| 945 | 942 | @ <li><p>Delete attachment "%h(zFile)" |
| 946 | 943 | }else{ |
| 947 | 944 | @ |
| 948 | 945 | @ <li><p>Add attachment |
| 949 | - @ "%z(href("%R/artifact/%S",zSrc))%s(zFile)</a>" | |
| 946 | + @ "%z(href("%R/artifact/%s",zSrc))%s(zFile)</a>" | |
| 950 | 947 | } |
| 951 | - @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] | |
| 948 | + @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] | |
| 952 | 949 | @ (rid %d(rid)) by |
| 953 | 950 | hyperlink_to_user(zUser,zDate," on"); |
| 954 | 951 | hyperlink_to_date(zDate, ".</p>"); |
| 955 | 952 | }else{ |
| 956 | 953 | pTicket = manifest_get(rid, CFTYPE_TICKET, 0); |
| 957 | 954 | if( pTicket ){ |
| 958 | 955 | @ |
| 959 | 956 | @ <li><p>Ticket change |
| 960 | - @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] | |
| 957 | + @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] | |
| 961 | 958 | @ (rid %d(rid)) by |
| 962 | 959 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 963 | 960 | hyperlink_to_date(zDate, ":"); |
| 964 | 961 | @ </p> |
| 965 | 962 | ticket_output_change_artifact(pTicket, "a"); |
| @@ -1219,35 +1216,31 @@ | ||
| 1219 | 1216 | zTktUuid); |
| 1220 | 1217 | if( tagid==0 ){ |
| 1221 | 1218 | fossil_fatal("no such ticket %h", zTktUuid); |
| 1222 | 1219 | } |
| 1223 | 1220 | db_prepare(&q, |
| 1224 | - "SELECT datetime(mtime%s), objid, uuid, NULL, NULL, NULL" | |
| 1221 | + "SELECT datetime(mtime%s), objid, NULL, NULL, NULL" | |
| 1225 | 1222 | " FROM event, blob" |
| 1226 | 1223 | " WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)" |
| 1227 | 1224 | " AND blob.rid=event.objid" |
| 1228 | 1225 | " UNION " |
| 1229 | - "SELECT datetime(mtime%s), attachid, uuid, src, " | |
| 1230 | - " filename, user" | |
| 1226 | + "SELECT datetime(mtime%s), attachid, filename, " | |
| 1227 | + " src, user" | |
| 1231 | 1228 | " FROM attachment, blob" |
| 1232 | 1229 | " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)" |
| 1233 | 1230 | " AND blob.rid=attachid" |
| 1234 | 1231 | " ORDER BY 1 DESC", |
| 1235 | 1232 | timeline_utc(), tagid, timeline_utc(), tagid |
| 1236 | 1233 | ); |
| 1237 | 1234 | while( db_step(&q)==SQLITE_ROW ){ |
| 1238 | 1235 | Manifest *pTicket; |
| 1239 | - char zShort[12]; | |
| 1240 | 1236 | const char *zDate = db_column_text(&q, 0); |
| 1241 | 1237 | int rid = db_column_int(&q, 1); |
| 1242 | - const char *zChngUuid = db_column_text(&q, 2); | |
| 1243 | - const char *zFile = db_column_text(&q, 4); | |
| 1244 | - memcpy(zShort, zChngUuid, 10); | |
| 1245 | - zShort[10] = 0; | |
| 1238 | + const char *zFile = db_column_text(&q, 2); | |
| 1246 | 1239 | if( zFile!=0 ){ |
| 1247 | 1240 | const char *zSrc = db_column_text(&q, 3); |
| 1248 | - const char *zUser = db_column_text(&q, 5); | |
| 1241 | + const char *zUser = db_column_text(&q, 4); | |
| 1249 | 1242 | if( zSrc==0 || zSrc[0]==0 ){ |
| 1250 | 1243 | fossil_print("Delete attachment %s\n", zFile); |
| 1251 | 1244 | }else{ |
| 1252 | 1245 | fossil_print("Add attachment %s\n", zFile); |
| 1253 | 1246 | } |
| 1254 | 1247 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -446,14 +446,14 @@ | |
| 446 | style_submenu_element("Attach", "Add An Attachment", |
| 447 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 448 | g.zTop, zUuid, g.zTop, zUuid); |
| 449 | } |
| 450 | if( P("plaintext") ){ |
| 451 | style_submenu_element("Formatted", "Formatted", "%R/tktview/%S", zUuid); |
| 452 | }else{ |
| 453 | style_submenu_element("Plaintext", "Plaintext", |
| 454 | "%R/tktview/%S?plaintext", zUuid); |
| 455 | } |
| 456 | style_header("View Ticket"); |
| 457 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1); |
| 458 | ticket_init(); |
| 459 | initializeVariablesFromCGI(); |
| @@ -895,14 +895,14 @@ | |
| 895 | "%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid); |
| 896 | style_submenu_element("Timeline", "Timeline", |
| 897 | "%s/tkttimeline?name=%s", g.zTop, zUuid); |
| 898 | if( P("plaintext")!=0 ){ |
| 899 | style_submenu_element("Formatted", "Formatted", |
| 900 | "%R/tkthistory/%S", zUuid); |
| 901 | }else{ |
| 902 | style_submenu_element("Plaintext", "Plaintext", |
| 903 | "%R/tkthistory/%S?plaintext", zUuid); |
| 904 | } |
| 905 | style_header(zTitle); |
| 906 | free(zTitle); |
| 907 | |
| 908 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| @@ -924,17 +924,14 @@ | |
| 924 | " ORDER BY 1", |
| 925 | timeline_utc(), tagid, timeline_utc(), tagid |
| 926 | ); |
| 927 | while( db_step(&q)==SQLITE_ROW ){ |
| 928 | Manifest *pTicket; |
| 929 | char zShort[12]; |
| 930 | const char *zDate = db_column_text(&q, 0); |
| 931 | int rid = db_column_int(&q, 1); |
| 932 | const char *zChngUuid = db_column_text(&q, 2); |
| 933 | const char *zFile = db_column_text(&q, 4); |
| 934 | memcpy(zShort, zChngUuid, 10); |
| 935 | zShort[10] = 0; |
| 936 | if( nChng==0 ){ |
| 937 | @ <ol> |
| 938 | } |
| 939 | nChng++; |
| 940 | if( zFile!=0 ){ |
| @@ -944,22 +941,22 @@ | |
| 944 | @ |
| 945 | @ <li><p>Delete attachment "%h(zFile)" |
| 946 | }else{ |
| 947 | @ |
| 948 | @ <li><p>Add attachment |
| 949 | @ "%z(href("%R/artifact/%S",zSrc))%s(zFile)</a>" |
| 950 | } |
| 951 | @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] |
| 952 | @ (rid %d(rid)) by |
| 953 | hyperlink_to_user(zUser,zDate," on"); |
| 954 | hyperlink_to_date(zDate, ".</p>"); |
| 955 | }else{ |
| 956 | pTicket = manifest_get(rid, CFTYPE_TICKET, 0); |
| 957 | if( pTicket ){ |
| 958 | @ |
| 959 | @ <li><p>Ticket change |
| 960 | @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>] |
| 961 | @ (rid %d(rid)) by |
| 962 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 963 | hyperlink_to_date(zDate, ":"); |
| 964 | @ </p> |
| 965 | ticket_output_change_artifact(pTicket, "a"); |
| @@ -1219,35 +1216,31 @@ | |
| 1219 | zTktUuid); |
| 1220 | if( tagid==0 ){ |
| 1221 | fossil_fatal("no such ticket %h", zTktUuid); |
| 1222 | } |
| 1223 | db_prepare(&q, |
| 1224 | "SELECT datetime(mtime%s), objid, uuid, NULL, NULL, NULL" |
| 1225 | " FROM event, blob" |
| 1226 | " WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)" |
| 1227 | " AND blob.rid=event.objid" |
| 1228 | " UNION " |
| 1229 | "SELECT datetime(mtime%s), attachid, uuid, src, " |
| 1230 | " filename, user" |
| 1231 | " FROM attachment, blob" |
| 1232 | " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)" |
| 1233 | " AND blob.rid=attachid" |
| 1234 | " ORDER BY 1 DESC", |
| 1235 | timeline_utc(), tagid, timeline_utc(), tagid |
| 1236 | ); |
| 1237 | while( db_step(&q)==SQLITE_ROW ){ |
| 1238 | Manifest *pTicket; |
| 1239 | char zShort[12]; |
| 1240 | const char *zDate = db_column_text(&q, 0); |
| 1241 | int rid = db_column_int(&q, 1); |
| 1242 | const char *zChngUuid = db_column_text(&q, 2); |
| 1243 | const char *zFile = db_column_text(&q, 4); |
| 1244 | memcpy(zShort, zChngUuid, 10); |
| 1245 | zShort[10] = 0; |
| 1246 | if( zFile!=0 ){ |
| 1247 | const char *zSrc = db_column_text(&q, 3); |
| 1248 | const char *zUser = db_column_text(&q, 5); |
| 1249 | if( zSrc==0 || zSrc[0]==0 ){ |
| 1250 | fossil_print("Delete attachment %s\n", zFile); |
| 1251 | }else{ |
| 1252 | fossil_print("Add attachment %s\n", zFile); |
| 1253 | } |
| 1254 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -446,14 +446,14 @@ | |
| 446 | style_submenu_element("Attach", "Add An Attachment", |
| 447 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 448 | g.zTop, zUuid, g.zTop, zUuid); |
| 449 | } |
| 450 | if( P("plaintext") ){ |
| 451 | style_submenu_element("Formatted", "Formatted", "%R/tktview/%s", zUuid); |
| 452 | }else{ |
| 453 | style_submenu_element("Plaintext", "Plaintext", |
| 454 | "%R/tktview/%s?plaintext", zUuid); |
| 455 | } |
| 456 | style_header("View Ticket"); |
| 457 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1); |
| 458 | ticket_init(); |
| 459 | initializeVariablesFromCGI(); |
| @@ -895,14 +895,14 @@ | |
| 895 | "%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid); |
| 896 | style_submenu_element("Timeline", "Timeline", |
| 897 | "%s/tkttimeline?name=%s", g.zTop, zUuid); |
| 898 | if( P("plaintext")!=0 ){ |
| 899 | style_submenu_element("Formatted", "Formatted", |
| 900 | "%R/tkthistory/%s", zUuid); |
| 901 | }else{ |
| 902 | style_submenu_element("Plaintext", "Plaintext", |
| 903 | "%R/tkthistory/%s?plaintext", zUuid); |
| 904 | } |
| 905 | style_header(zTitle); |
| 906 | free(zTitle); |
| 907 | |
| 908 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); |
| @@ -924,17 +924,14 @@ | |
| 924 | " ORDER BY 1", |
| 925 | timeline_utc(), tagid, timeline_utc(), tagid |
| 926 | ); |
| 927 | while( db_step(&q)==SQLITE_ROW ){ |
| 928 | Manifest *pTicket; |
| 929 | const char *zDate = db_column_text(&q, 0); |
| 930 | int rid = db_column_int(&q, 1); |
| 931 | const char *zChngUuid = db_column_text(&q, 2); |
| 932 | const char *zFile = db_column_text(&q, 4); |
| 933 | if( nChng==0 ){ |
| 934 | @ <ol> |
| 935 | } |
| 936 | nChng++; |
| 937 | if( zFile!=0 ){ |
| @@ -944,22 +941,22 @@ | |
| 941 | @ |
| 942 | @ <li><p>Delete attachment "%h(zFile)" |
| 943 | }else{ |
| 944 | @ |
| 945 | @ <li><p>Add attachment |
| 946 | @ "%z(href("%R/artifact/%s",zSrc))%s(zFile)</a>" |
| 947 | } |
| 948 | @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] |
| 949 | @ (rid %d(rid)) by |
| 950 | hyperlink_to_user(zUser,zDate," on"); |
| 951 | hyperlink_to_date(zDate, ".</p>"); |
| 952 | }else{ |
| 953 | pTicket = manifest_get(rid, CFTYPE_TICKET, 0); |
| 954 | if( pTicket ){ |
| 955 | @ |
| 956 | @ <li><p>Ticket change |
| 957 | @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>] |
| 958 | @ (rid %d(rid)) by |
| 959 | hyperlink_to_user(pTicket->zUser,zDate," on"); |
| 960 | hyperlink_to_date(zDate, ":"); |
| 961 | @ </p> |
| 962 | ticket_output_change_artifact(pTicket, "a"); |
| @@ -1219,35 +1216,31 @@ | |
| 1216 | zTktUuid); |
| 1217 | if( tagid==0 ){ |
| 1218 | fossil_fatal("no such ticket %h", zTktUuid); |
| 1219 | } |
| 1220 | db_prepare(&q, |
| 1221 | "SELECT datetime(mtime%s), objid, NULL, NULL, NULL" |
| 1222 | " FROM event, blob" |
| 1223 | " WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)" |
| 1224 | " AND blob.rid=event.objid" |
| 1225 | " UNION " |
| 1226 | "SELECT datetime(mtime%s), attachid, filename, " |
| 1227 | " src, user" |
| 1228 | " FROM attachment, blob" |
| 1229 | " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)" |
| 1230 | " AND blob.rid=attachid" |
| 1231 | " ORDER BY 1 DESC", |
| 1232 | timeline_utc(), tagid, timeline_utc(), tagid |
| 1233 | ); |
| 1234 | while( db_step(&q)==SQLITE_ROW ){ |
| 1235 | Manifest *pTicket; |
| 1236 | const char *zDate = db_column_text(&q, 0); |
| 1237 | int rid = db_column_int(&q, 1); |
| 1238 | const char *zFile = db_column_text(&q, 2); |
| 1239 | if( zFile!=0 ){ |
| 1240 | const char *zSrc = db_column_text(&q, 3); |
| 1241 | const char *zUser = db_column_text(&q, 4); |
| 1242 | if( zSrc==0 || zSrc[0]==0 ){ |
| 1243 | fossil_print("Delete attachment %s\n", zFile); |
| 1244 | }else{ |
| 1245 | fossil_print("Add attachment %s\n", zFile); |
| 1246 | } |
| 1247 |
+2
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -625,10 +625,12 @@ | ||
| 625 | 625 | ManifestFile *pFile; |
| 626 | 626 | int rid=0; |
| 627 | 627 | |
| 628 | 628 | if( revision ){ |
| 629 | 629 | rid = name_to_typed_rid(revision,"ci"); |
| 630 | + }else if( !g.localOpen ){ | |
| 631 | + rid = name_to_typed_rid(db_get("main-branch","trunk"),"ci"); | |
| 630 | 632 | }else{ |
| 631 | 633 | rid = db_lget_int("checkout", 0); |
| 632 | 634 | } |
| 633 | 635 | if( !is_a_version(rid) ){ |
| 634 | 636 | if( errCode>0 ) return errCode; |
| 635 | 637 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -625,10 +625,12 @@ | |
| 625 | ManifestFile *pFile; |
| 626 | int rid=0; |
| 627 | |
| 628 | if( revision ){ |
| 629 | rid = name_to_typed_rid(revision,"ci"); |
| 630 | }else{ |
| 631 | rid = db_lget_int("checkout", 0); |
| 632 | } |
| 633 | if( !is_a_version(rid) ){ |
| 634 | if( errCode>0 ) return errCode; |
| 635 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -625,10 +625,12 @@ | |
| 625 | ManifestFile *pFile; |
| 626 | int rid=0; |
| 627 | |
| 628 | if( revision ){ |
| 629 | rid = name_to_typed_rid(revision,"ci"); |
| 630 | }else if( !g.localOpen ){ |
| 631 | rid = name_to_typed_rid(db_get("main-branch","trunk"),"ci"); |
| 632 | }else{ |
| 633 | rid = db_lget_int("checkout", 0); |
| 634 | } |
| 635 | if( !is_a_version(rid) ){ |
| 636 | if( errCode>0 ) return errCode; |
| 637 |
+61
-61
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -275,22 +275,22 @@ | ||
| 275 | 275 | |
| 276 | 276 | /* |
| 277 | 277 | ** Parse the given URL, which describes a sync server. Populate variables |
| 278 | 278 | ** in the global "g" structure as follows: |
| 279 | 279 | ** |
| 280 | -** g.urlIsFile True if FILE: | |
| 281 | -** g.urlIsHttps True if HTTPS: | |
| 282 | -** g.urlIsSsh True if SSH: | |
| 283 | -** g.urlProtocol "http" or "https" or "file" | |
| 284 | -** g.urlName Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: | |
| 285 | -** g.urlPort TCP port number for HTTP or HTTPS. | |
| 286 | -** g.urlDfltPort Default TCP port number (80 or 443). | |
| 287 | -** g.urlPath Path name for HTTP or HTTPS. | |
| 288 | -** g.urlUser Userid. | |
| 289 | -** g.urlPasswd Password. | |
| 290 | -** g.urlHostname HOST:PORT or just HOST if port is the default. | |
| 291 | -** g.urlCanonical The URL in canonical form, omitting the password | |
| 280 | +** g.url.isFile True if FILE: | |
| 281 | +** g.url.isHttps True if HTTPS: | |
| 282 | +** g.url.isSsh True if SSH: | |
| 283 | +** g.url.protocol "http" or "https" or "file" | |
| 284 | +** g.url.name Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: | |
| 285 | +** g.url.port TCP port number for HTTP or HTTPS. | |
| 286 | +** g.url.dfltPort Default TCP port number (80 or 443). | |
| 287 | +** g.url.path Path name for HTTP or HTTPS. | |
| 288 | +** g.url.user Userid. | |
| 289 | +** g.url.passwd Password. | |
| 290 | +** g.url.hostname HOST:PORT or just HOST if port is the default. | |
| 291 | +** g.url.canonical The URL in canonical form, omitting the password | |
| 292 | 292 | ** |
| 293 | 293 | ** HTTP url format as follows (HTTPS is the same with a different scheme): |
| 294 | 294 | ** |
| 295 | 295 | ** http://userid:password@host:port/path |
| 296 | 296 | ** |
| @@ -298,11 +298,11 @@ | ||
| 298 | 298 | ** |
| 299 | 299 | ** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 300 | 300 | ** |
| 301 | 301 | */ |
| 302 | 302 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 303 | - url_parse_local(zUrl, urlFlags, GLOBAL_URL()); | |
| 303 | + url_parse_local(zUrl, urlFlags, &g.url); | |
| 304 | 304 | } |
| 305 | 305 | |
| 306 | 306 | /* |
| 307 | 307 | ** COMMAND: test-urlparser |
| 308 | 308 | ** |
| @@ -323,25 +323,25 @@ | ||
| 323 | 323 | if( g.argc!=3 && g.argc!=4 ){ |
| 324 | 324 | usage("URL"); |
| 325 | 325 | } |
| 326 | 326 | url_parse(g.argv[2], fg); |
| 327 | 327 | for(i=0; i<2; i++){ |
| 328 | - fossil_print("g.urlIsFile = %d\n", g.urlIsFile); | |
| 329 | - fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); | |
| 330 | - fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); | |
| 331 | - fossil_print("g.urlProtocol = %s\n", g.urlProtocol); | |
| 332 | - fossil_print("g.urlName = %s\n", g.urlName); | |
| 333 | - fossil_print("g.urlPort = %d\n", g.urlPort); | |
| 334 | - fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); | |
| 335 | - fossil_print("g.urlHostname = %s\n", g.urlHostname); | |
| 336 | - fossil_print("g.urlPath = %s\n", g.urlPath); | |
| 337 | - fossil_print("g.urlUser = %s\n", g.urlUser); | |
| 338 | - fossil_print("g.urlPasswd = %s\n", g.urlPasswd); | |
| 339 | - fossil_print("g.urlCanonical = %s\n", g.urlCanonical); | |
| 340 | - fossil_print("g.urlFossil = %s\n", g.urlFossil); | |
| 341 | - fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); | |
| 342 | - if( g.urlIsFile || g.urlIsSsh ) break; | |
| 328 | + fossil_print("g.url.isFile = %d\n", g.url.isFile); | |
| 329 | + fossil_print("g.url.isHttps = %d\n", g.url.isHttps); | |
| 330 | + fossil_print("g.url.isSsh = %d\n", g.url.isSsh); | |
| 331 | + fossil_print("g.url.protocol = %s\n", g.url.protocol); | |
| 332 | + fossil_print("g.url.name = %s\n", g.url.name); | |
| 333 | + fossil_print("g.url.port = %d\n", g.url.port); | |
| 334 | + fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort); | |
| 335 | + fossil_print("g.url.hostname = %s\n", g.url.hostname); | |
| 336 | + fossil_print("g.url.path = %s\n", g.url.path); | |
| 337 | + fossil_print("g.url.user = %s\n", g.url.user); | |
| 338 | + fossil_print("g.url.passwd = %s\n", g.url.passwd); | |
| 339 | + fossil_print("g.url.canonical = %s\n", g.url.canonical); | |
| 340 | + fossil_print("g.url.fossil = %s\n", g.url.fossil); | |
| 341 | + fossil_print("g.url.flags = 0x%02x\n", g.url.flags); | |
| 342 | + if( g.url.isFile || g.url.isSsh ) break; | |
| 343 | 343 | if( i==0 ){ |
| 344 | 344 | fossil_print("********\n"); |
| 345 | 345 | url_enable_proxy("Using proxy: "); |
| 346 | 346 | } |
| 347 | 347 | } |
| @@ -385,38 +385,38 @@ | ||
| 385 | 385 | if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){ |
| 386 | 386 | zProxy = fossil_getenv("http_proxy"); |
| 387 | 387 | } |
| 388 | 388 | } |
| 389 | 389 | if( zProxy && zProxy[0] && !is_false(zProxy) |
| 390 | - && !g.urlIsSsh && !g.urlIsFile ){ | |
| 391 | - char *zOriginalUrl = g.urlCanonical; | |
| 392 | - char *zOriginalHost = g.urlHostname; | |
| 393 | - int fOriginalIsHttps = g.urlIsHttps; | |
| 394 | - char *zOriginalUser = g.urlUser; | |
| 395 | - char *zOriginalPasswd = g.urlPasswd; | |
| 396 | - char *zOriginalUrlPath = g.urlPath; | |
| 397 | - int iOriginalPort = g.urlPort; | |
| 398 | - unsigned uOriginalFlags = g.urlFlags; | |
| 399 | - g.urlUser = 0; | |
| 400 | - g.urlPasswd = ""; | |
| 390 | + && !g.url.isSsh && !g.url.isFile ){ | |
| 391 | + char *zOriginalUrl = g.url.canonical; | |
| 392 | + char *zOriginalHost = g.url.hostname; | |
| 393 | + int fOriginalIsHttps = g.url.isHttps; | |
| 394 | + char *zOriginalUser = g.url.user; | |
| 395 | + char *zOriginalPasswd = g.url.passwd; | |
| 396 | + char *zOriginalUrlPath = g.url.path; | |
| 397 | + int iOriginalPort = g.url.port; | |
| 398 | + unsigned uOriginalFlags = g.url.flags; | |
| 399 | + g.url.user = 0; | |
| 400 | + g.url.passwd = ""; | |
| 401 | 401 | url_parse(zProxy, 0); |
| 402 | - if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); | |
| 403 | - g.urlPath = zOriginalUrl; | |
| 404 | - g.urlHostname = zOriginalHost; | |
| 405 | - if( g.urlUser ){ | |
| 406 | - char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); | |
| 402 | + if( zMsg ) fossil_print("%s%s\n", zMsg, g.url.canonical); | |
| 403 | + g.url.path = zOriginalUrl; | |
| 404 | + g.url.hostname = zOriginalHost; | |
| 405 | + if( g.url.user ){ | |
| 406 | + char *zCredentials1 = mprintf("%s:%s", g.url.user, g.url.passwd); | |
| 407 | 407 | char *zCredentials2 = encode64(zCredentials1, -1); |
| 408 | - g.urlProxyAuth = mprintf("Basic %z", zCredentials2); | |
| 408 | + g.url.proxyAuth = mprintf("Basic %z", zCredentials2); | |
| 409 | 409 | free(zCredentials1); |
| 410 | 410 | } |
| 411 | - g.urlUser = zOriginalUser; | |
| 412 | - g.urlPasswd = zOriginalPasswd; | |
| 413 | - g.urlIsHttps = fOriginalIsHttps; | |
| 414 | - g.useProxy = 1; | |
| 415 | - g.proxyUrlPath = zOriginalUrlPath; | |
| 416 | - g.proxyOrigPort = iOriginalPort; | |
| 417 | - g.urlFlags = uOriginalFlags; | |
| 411 | + g.url.user = zOriginalUser; | |
| 412 | + g.url.passwd = zOriginalPasswd; | |
| 413 | + g.url.isHttps = fOriginalIsHttps; | |
| 414 | + g.url.useProxy = 1; | |
| 415 | + g.url.proxyUrlPath = zOriginalUrlPath; | |
| 416 | + g.url.proxyOrigPort = iOriginalPort; | |
| 417 | + g.url.flags = uOriginalFlags; | |
| 418 | 418 | } |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | #if INTERFACE |
| 422 | 422 | /* |
| @@ -529,35 +529,35 @@ | ||
| 529 | 529 | pUrlData->user); |
| 530 | 530 | } |
| 531 | 531 | } |
| 532 | 532 | |
| 533 | 533 | /* |
| 534 | -** Prompt the user for the password for g.urlUser. Store the result | |
| 535 | -** in g.urlPasswd. | |
| 534 | +** Prompt the user for the password for g.url.user. Store the result | |
| 535 | +** in g.url.passwd. | |
| 536 | 536 | */ |
| 537 | 537 | void url_prompt_for_password(void){ |
| 538 | - url_prompt_for_password_local(GLOBAL_URL()); | |
| 538 | + url_prompt_for_password_local(&g.url); | |
| 539 | 539 | } |
| 540 | 540 | |
| 541 | 541 | /* |
| 542 | 542 | ** Remember the URL and password if requested. |
| 543 | 543 | */ |
| 544 | 544 | void url_remember(void){ |
| 545 | - if( g.urlFlags & URL_REMEMBER ){ | |
| 546 | - db_set("last-sync-url", g.urlCanonical, 0); | |
| 547 | - if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ | |
| 548 | - db_set("last-sync-pw", obscure(g.urlPasswd), 0); | |
| 545 | + if( g.url.flags & URL_REMEMBER ){ | |
| 546 | + db_set("last-sync-url", g.url.canonical, 0); | |
| 547 | + if( g.url.user!=0 && g.url.passwd!=0 && ( g.url.flags & URL_REMEMBER_PW ) ){ | |
| 548 | + db_set("last-sync-pw", obscure(g.url.passwd), 0); | |
| 549 | 549 | } |
| 550 | 550 | } |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | /* Preemptively prompt for a password if a username is given in the |
| 554 | 554 | ** URL but no password. |
| 555 | 555 | */ |
| 556 | 556 | void url_get_password_if_needed(void){ |
| 557 | - if( (g.urlUser && g.urlUser[0]) | |
| 558 | - && (g.urlPasswd==0 || g.urlPasswd[0]==0) | |
| 557 | + if( (g.url.user && g.url.user[0]) | |
| 558 | + && (g.url.passwd==0 || g.url.passwd[0]==0) | |
| 559 | 559 | && isatty(fileno(stdin)) |
| 560 | 560 | ){ |
| 561 | 561 | url_prompt_for_password(); |
| 562 | 562 | } |
| 563 | 563 | } |
| 564 | 564 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -275,22 +275,22 @@ | |
| 275 | |
| 276 | /* |
| 277 | ** Parse the given URL, which describes a sync server. Populate variables |
| 278 | ** in the global "g" structure as follows: |
| 279 | ** |
| 280 | ** g.urlIsFile True if FILE: |
| 281 | ** g.urlIsHttps True if HTTPS: |
| 282 | ** g.urlIsSsh True if SSH: |
| 283 | ** g.urlProtocol "http" or "https" or "file" |
| 284 | ** g.urlName Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: |
| 285 | ** g.urlPort TCP port number for HTTP or HTTPS. |
| 286 | ** g.urlDfltPort Default TCP port number (80 or 443). |
| 287 | ** g.urlPath Path name for HTTP or HTTPS. |
| 288 | ** g.urlUser Userid. |
| 289 | ** g.urlPasswd Password. |
| 290 | ** g.urlHostname HOST:PORT or just HOST if port is the default. |
| 291 | ** g.urlCanonical The URL in canonical form, omitting the password |
| 292 | ** |
| 293 | ** HTTP url format as follows (HTTPS is the same with a different scheme): |
| 294 | ** |
| 295 | ** http://userid:password@host:port/path |
| 296 | ** |
| @@ -298,11 +298,11 @@ | |
| 298 | ** |
| 299 | ** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 300 | ** |
| 301 | */ |
| 302 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 303 | url_parse_local(zUrl, urlFlags, GLOBAL_URL()); |
| 304 | } |
| 305 | |
| 306 | /* |
| 307 | ** COMMAND: test-urlparser |
| 308 | ** |
| @@ -323,25 +323,25 @@ | |
| 323 | if( g.argc!=3 && g.argc!=4 ){ |
| 324 | usage("URL"); |
| 325 | } |
| 326 | url_parse(g.argv[2], fg); |
| 327 | for(i=0; i<2; i++){ |
| 328 | fossil_print("g.urlIsFile = %d\n", g.urlIsFile); |
| 329 | fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); |
| 330 | fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); |
| 331 | fossil_print("g.urlProtocol = %s\n", g.urlProtocol); |
| 332 | fossil_print("g.urlName = %s\n", g.urlName); |
| 333 | fossil_print("g.urlPort = %d\n", g.urlPort); |
| 334 | fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); |
| 335 | fossil_print("g.urlHostname = %s\n", g.urlHostname); |
| 336 | fossil_print("g.urlPath = %s\n", g.urlPath); |
| 337 | fossil_print("g.urlUser = %s\n", g.urlUser); |
| 338 | fossil_print("g.urlPasswd = %s\n", g.urlPasswd); |
| 339 | fossil_print("g.urlCanonical = %s\n", g.urlCanonical); |
| 340 | fossil_print("g.urlFossil = %s\n", g.urlFossil); |
| 341 | fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); |
| 342 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 343 | if( i==0 ){ |
| 344 | fossil_print("********\n"); |
| 345 | url_enable_proxy("Using proxy: "); |
| 346 | } |
| 347 | } |
| @@ -385,38 +385,38 @@ | |
| 385 | if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){ |
| 386 | zProxy = fossil_getenv("http_proxy"); |
| 387 | } |
| 388 | } |
| 389 | if( zProxy && zProxy[0] && !is_false(zProxy) |
| 390 | && !g.urlIsSsh && !g.urlIsFile ){ |
| 391 | char *zOriginalUrl = g.urlCanonical; |
| 392 | char *zOriginalHost = g.urlHostname; |
| 393 | int fOriginalIsHttps = g.urlIsHttps; |
| 394 | char *zOriginalUser = g.urlUser; |
| 395 | char *zOriginalPasswd = g.urlPasswd; |
| 396 | char *zOriginalUrlPath = g.urlPath; |
| 397 | int iOriginalPort = g.urlPort; |
| 398 | unsigned uOriginalFlags = g.urlFlags; |
| 399 | g.urlUser = 0; |
| 400 | g.urlPasswd = ""; |
| 401 | url_parse(zProxy, 0); |
| 402 | if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); |
| 403 | g.urlPath = zOriginalUrl; |
| 404 | g.urlHostname = zOriginalHost; |
| 405 | if( g.urlUser ){ |
| 406 | char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 407 | char *zCredentials2 = encode64(zCredentials1, -1); |
| 408 | g.urlProxyAuth = mprintf("Basic %z", zCredentials2); |
| 409 | free(zCredentials1); |
| 410 | } |
| 411 | g.urlUser = zOriginalUser; |
| 412 | g.urlPasswd = zOriginalPasswd; |
| 413 | g.urlIsHttps = fOriginalIsHttps; |
| 414 | g.useProxy = 1; |
| 415 | g.proxyUrlPath = zOriginalUrlPath; |
| 416 | g.proxyOrigPort = iOriginalPort; |
| 417 | g.urlFlags = uOriginalFlags; |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | #if INTERFACE |
| 422 | /* |
| @@ -529,35 +529,35 @@ | |
| 529 | pUrlData->user); |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | /* |
| 534 | ** Prompt the user for the password for g.urlUser. Store the result |
| 535 | ** in g.urlPasswd. |
| 536 | */ |
| 537 | void url_prompt_for_password(void){ |
| 538 | url_prompt_for_password_local(GLOBAL_URL()); |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | ** Remember the URL and password if requested. |
| 543 | */ |
| 544 | void url_remember(void){ |
| 545 | if( g.urlFlags & URL_REMEMBER ){ |
| 546 | db_set("last-sync-url", g.urlCanonical, 0); |
| 547 | if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ |
| 548 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 549 | } |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | /* Preemptively prompt for a password if a username is given in the |
| 554 | ** URL but no password. |
| 555 | */ |
| 556 | void url_get_password_if_needed(void){ |
| 557 | if( (g.urlUser && g.urlUser[0]) |
| 558 | && (g.urlPasswd==0 || g.urlPasswd[0]==0) |
| 559 | && isatty(fileno(stdin)) |
| 560 | ){ |
| 561 | url_prompt_for_password(); |
| 562 | } |
| 563 | } |
| 564 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -275,22 +275,22 @@ | |
| 275 | |
| 276 | /* |
| 277 | ** Parse the given URL, which describes a sync server. Populate variables |
| 278 | ** in the global "g" structure as follows: |
| 279 | ** |
| 280 | ** g.url.isFile True if FILE: |
| 281 | ** g.url.isHttps True if HTTPS: |
| 282 | ** g.url.isSsh True if SSH: |
| 283 | ** g.url.protocol "http" or "https" or "file" |
| 284 | ** g.url.name Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: |
| 285 | ** g.url.port TCP port number for HTTP or HTTPS. |
| 286 | ** g.url.dfltPort Default TCP port number (80 or 443). |
| 287 | ** g.url.path Path name for HTTP or HTTPS. |
| 288 | ** g.url.user Userid. |
| 289 | ** g.url.passwd Password. |
| 290 | ** g.url.hostname HOST:PORT or just HOST if port is the default. |
| 291 | ** g.url.canonical The URL in canonical form, omitting the password |
| 292 | ** |
| 293 | ** HTTP url format as follows (HTTPS is the same with a different scheme): |
| 294 | ** |
| 295 | ** http://userid:password@host:port/path |
| 296 | ** |
| @@ -298,11 +298,11 @@ | |
| 298 | ** |
| 299 | ** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 300 | ** |
| 301 | */ |
| 302 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 303 | url_parse_local(zUrl, urlFlags, &g.url); |
| 304 | } |
| 305 | |
| 306 | /* |
| 307 | ** COMMAND: test-urlparser |
| 308 | ** |
| @@ -323,25 +323,25 @@ | |
| 323 | if( g.argc!=3 && g.argc!=4 ){ |
| 324 | usage("URL"); |
| 325 | } |
| 326 | url_parse(g.argv[2], fg); |
| 327 | for(i=0; i<2; i++){ |
| 328 | fossil_print("g.url.isFile = %d\n", g.url.isFile); |
| 329 | fossil_print("g.url.isHttps = %d\n", g.url.isHttps); |
| 330 | fossil_print("g.url.isSsh = %d\n", g.url.isSsh); |
| 331 | fossil_print("g.url.protocol = %s\n", g.url.protocol); |
| 332 | fossil_print("g.url.name = %s\n", g.url.name); |
| 333 | fossil_print("g.url.port = %d\n", g.url.port); |
| 334 | fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort); |
| 335 | fossil_print("g.url.hostname = %s\n", g.url.hostname); |
| 336 | fossil_print("g.url.path = %s\n", g.url.path); |
| 337 | fossil_print("g.url.user = %s\n", g.url.user); |
| 338 | fossil_print("g.url.passwd = %s\n", g.url.passwd); |
| 339 | fossil_print("g.url.canonical = %s\n", g.url.canonical); |
| 340 | fossil_print("g.url.fossil = %s\n", g.url.fossil); |
| 341 | fossil_print("g.url.flags = 0x%02x\n", g.url.flags); |
| 342 | if( g.url.isFile || g.url.isSsh ) break; |
| 343 | if( i==0 ){ |
| 344 | fossil_print("********\n"); |
| 345 | url_enable_proxy("Using proxy: "); |
| 346 | } |
| 347 | } |
| @@ -385,38 +385,38 @@ | |
| 385 | if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){ |
| 386 | zProxy = fossil_getenv("http_proxy"); |
| 387 | } |
| 388 | } |
| 389 | if( zProxy && zProxy[0] && !is_false(zProxy) |
| 390 | && !g.url.isSsh && !g.url.isFile ){ |
| 391 | char *zOriginalUrl = g.url.canonical; |
| 392 | char *zOriginalHost = g.url.hostname; |
| 393 | int fOriginalIsHttps = g.url.isHttps; |
| 394 | char *zOriginalUser = g.url.user; |
| 395 | char *zOriginalPasswd = g.url.passwd; |
| 396 | char *zOriginalUrlPath = g.url.path; |
| 397 | int iOriginalPort = g.url.port; |
| 398 | unsigned uOriginalFlags = g.url.flags; |
| 399 | g.url.user = 0; |
| 400 | g.url.passwd = ""; |
| 401 | url_parse(zProxy, 0); |
| 402 | if( zMsg ) fossil_print("%s%s\n", zMsg, g.url.canonical); |
| 403 | g.url.path = zOriginalUrl; |
| 404 | g.url.hostname = zOriginalHost; |
| 405 | if( g.url.user ){ |
| 406 | char *zCredentials1 = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 407 | char *zCredentials2 = encode64(zCredentials1, -1); |
| 408 | g.url.proxyAuth = mprintf("Basic %z", zCredentials2); |
| 409 | free(zCredentials1); |
| 410 | } |
| 411 | g.url.user = zOriginalUser; |
| 412 | g.url.passwd = zOriginalPasswd; |
| 413 | g.url.isHttps = fOriginalIsHttps; |
| 414 | g.url.useProxy = 1; |
| 415 | g.url.proxyUrlPath = zOriginalUrlPath; |
| 416 | g.url.proxyOrigPort = iOriginalPort; |
| 417 | g.url.flags = uOriginalFlags; |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | #if INTERFACE |
| 422 | /* |
| @@ -529,35 +529,35 @@ | |
| 529 | pUrlData->user); |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | /* |
| 534 | ** Prompt the user for the password for g.url.user. Store the result |
| 535 | ** in g.url.passwd. |
| 536 | */ |
| 537 | void url_prompt_for_password(void){ |
| 538 | url_prompt_for_password_local(&g.url); |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | ** Remember the URL and password if requested. |
| 543 | */ |
| 544 | void url_remember(void){ |
| 545 | if( g.url.flags & URL_REMEMBER ){ |
| 546 | db_set("last-sync-url", g.url.canonical, 0); |
| 547 | if( g.url.user!=0 && g.url.passwd!=0 && ( g.url.flags & URL_REMEMBER_PW ) ){ |
| 548 | db_set("last-sync-pw", obscure(g.url.passwd), 0); |
| 549 | } |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | /* Preemptively prompt for a password if a username is given in the |
| 554 | ** URL but no password. |
| 555 | */ |
| 556 | void url_get_password_if_needed(void){ |
| 557 | if( (g.url.user && g.url.user[0]) |
| 558 | && (g.url.passwd==0 || g.url.passwd[0]==0) |
| 559 | && isatty(fileno(stdin)) |
| 560 | ){ |
| 561 | url_prompt_for_password(); |
| 562 | } |
| 563 | } |
| 564 |
+1
-1
| --- src/user.c | ||
| +++ src/user.c | ||
| @@ -375,11 +375,11 @@ | ||
| 375 | 375 | if( attempt_user(fossil_getenv("LOGNAME")) ) return; |
| 376 | 376 | |
| 377 | 377 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 378 | 378 | |
| 379 | 379 | url_parse(0, 0); |
| 380 | - if( g.urlUser && attempt_user(g.urlUser) ) return; | |
| 380 | + if( g.url.user && attempt_user(g.url.user) ) return; | |
| 381 | 381 | |
| 382 | 382 | fossil_print( |
| 383 | 383 | "Cannot figure out who you are! Consider using the --user\n" |
| 384 | 384 | "command line option, setting your USER environment variable,\n" |
| 385 | 385 | "or setting a default user with \"fossil user default USER\".\n" |
| 386 | 386 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -375,11 +375,11 @@ | |
| 375 | if( attempt_user(fossil_getenv("LOGNAME")) ) return; |
| 376 | |
| 377 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 378 | |
| 379 | url_parse(0, 0); |
| 380 | if( g.urlUser && attempt_user(g.urlUser) ) return; |
| 381 | |
| 382 | fossil_print( |
| 383 | "Cannot figure out who you are! Consider using the --user\n" |
| 384 | "command line option, setting your USER environment variable,\n" |
| 385 | "or setting a default user with \"fossil user default USER\".\n" |
| 386 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -375,11 +375,11 @@ | |
| 375 | if( attempt_user(fossil_getenv("LOGNAME")) ) return; |
| 376 | |
| 377 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 378 | |
| 379 | url_parse(0, 0); |
| 380 | if( g.url.user && attempt_user(g.url.user) ) return; |
| 381 | |
| 382 | fossil_print( |
| 383 | "Cannot figure out who you are! Consider using the --user\n" |
| 384 | "command line option, setting your USER environment variable,\n" |
| 385 | "or setting a default user with \"fossil user default USER\".\n" |
| 386 |
+10
| --- src/util.c | ||
| +++ src/util.c | ||
| @@ -312,5 +312,15 @@ | ||
| 312 | 312 | return 1; |
| 313 | 313 | #else |
| 314 | 314 | return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF; |
| 315 | 315 | #endif |
| 316 | 316 | } |
| 317 | + | |
| 318 | +/* | |
| 319 | +** Returns TRUE if zSym is exactly UUID_SIZE bytes long and contains | |
| 320 | +** only lower-case ASCII hexadecimal values. | |
| 321 | +*/ | |
| 322 | +int fossil_is_uuid(char const * zSym){ | |
| 323 | + return zSym | |
| 324 | + && (UUID_SIZE==strlen(zSym)) | |
| 325 | + && validate16(zSym, UUID_SIZE); | |
| 326 | +} | |
| 317 | 327 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -312,5 +312,15 @@ | |
| 312 | return 1; |
| 313 | #else |
| 314 | return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF; |
| 315 | #endif |
| 316 | } |
| 317 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -312,5 +312,15 @@ | |
| 312 | return 1; |
| 313 | #else |
| 314 | return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF; |
| 315 | #endif |
| 316 | } |
| 317 | |
| 318 | /* |
| 319 | ** Returns TRUE if zSym is exactly UUID_SIZE bytes long and contains |
| 320 | ** only lower-case ASCII hexadecimal values. |
| 321 | */ |
| 322 | int fossil_is_uuid(char const * zSym){ |
| 323 | return zSym |
| 324 | && (UUID_SIZE==strlen(zSym)) |
| 325 | && validate16(zSym, UUID_SIZE); |
| 326 | } |
| 327 |
+1
-1
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -241,11 +241,11 @@ | ||
| 241 | 241 | if( rid ){ |
| 242 | 242 | style_submenu_element("Diff", "Last change", |
| 243 | 243 | "%R/wdiff?name=%T&a=%d", zPageName, rid); |
| 244 | 244 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 245 | 245 | style_submenu_element("Details", "Details", |
| 246 | - "%R/info/%S", zUuid); | |
| 246 | + "%R/info/%s", zUuid); | |
| 247 | 247 | } |
| 248 | 248 | if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){ |
| 249 | 249 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 250 | 250 | style_submenu_element("Edit", "Edit Wiki Page", |
| 251 | 251 | "%s/wikiedit?name=%T&wysiwyg=1", |
| 252 | 252 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -241,11 +241,11 @@ | |
| 241 | if( rid ){ |
| 242 | style_submenu_element("Diff", "Last change", |
| 243 | "%R/wdiff?name=%T&a=%d", zPageName, rid); |
| 244 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 245 | style_submenu_element("Details", "Details", |
| 246 | "%R/info/%S", zUuid); |
| 247 | } |
| 248 | if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){ |
| 249 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 250 | style_submenu_element("Edit", "Edit Wiki Page", |
| 251 | "%s/wikiedit?name=%T&wysiwyg=1", |
| 252 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -241,11 +241,11 @@ | |
| 241 | if( rid ){ |
| 242 | style_submenu_element("Diff", "Last change", |
| 243 | "%R/wdiff?name=%T&a=%d", zPageName, rid); |
| 244 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 245 | style_submenu_element("Details", "Details", |
| 246 | "%R/info/%s", zUuid); |
| 247 | } |
| 248 | if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){ |
| 249 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 250 | style_submenu_element("Edit", "Edit Wiki Page", |
| 251 | "%s/wikiedit?name=%T&wysiwyg=1", |
| 252 |
+118
-96
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -35,103 +35,112 @@ | ||
| 35 | 35 | |
| 36 | 36 | |
| 37 | 37 | /* |
| 38 | 38 | ** These are the only markup attributes allowed. |
| 39 | 39 | */ |
| 40 | -#define ATTR_ALIGN 1 | |
| 41 | -#define ATTR_ALT 2 | |
| 42 | -#define ATTR_BGCOLOR 3 | |
| 43 | -#define ATTR_BORDER 4 | |
| 44 | -#define ATTR_CELLPADDING 5 | |
| 45 | -#define ATTR_CELLSPACING 6 | |
| 46 | -#define ATTR_CLASS 7 | |
| 47 | -#define ATTR_CLEAR 8 | |
| 48 | -#define ATTR_COLOR 9 | |
| 49 | -#define ATTR_COLSPAN 10 | |
| 50 | -#define ATTR_COMPACT 11 | |
| 51 | -#define ATTR_FACE 12 | |
| 52 | -#define ATTR_HEIGHT 13 | |
| 53 | -#define ATTR_HREF 14 | |
| 54 | -#define ATTR_HSPACE 15 | |
| 55 | -#define ATTR_ID 16 | |
| 56 | -#define ATTR_LINKS 17 | |
| 57 | -#define ATTR_NAME 18 | |
| 58 | -#define ATTR_ROWSPAN 19 | |
| 59 | -#define ATTR_SIZE 20 | |
| 60 | -#define ATTR_SRC 21 | |
| 61 | -#define ATTR_START 22 | |
| 62 | -#define ATTR_STYLE 23 | |
| 63 | -#define ATTR_TARGET 24 | |
| 64 | -#define ATTR_TYPE 25 | |
| 65 | -#define ATTR_VALIGN 26 | |
| 66 | -#define ATTR_VALUE 27 | |
| 67 | -#define ATTR_VSPACE 28 | |
| 68 | -#define ATTR_WIDTH 29 | |
| 69 | -#define AMSK_ALIGN 0x00000001 | |
| 70 | -#define AMSK_ALT 0x00000002 | |
| 71 | -#define AMSK_BGCOLOR 0x00000004 | |
| 72 | -#define AMSK_BORDER 0x00000008 | |
| 73 | -#define AMSK_CELLPADDING 0x00000010 | |
| 74 | -#define AMSK_CELLSPACING 0x00000020 | |
| 75 | -#define AMSK_CLASS 0x00000040 | |
| 76 | -#define AMSK_CLEAR 0x00000080 | |
| 77 | -#define AMSK_COLOR 0x00000100 | |
| 78 | -#define AMSK_COLSPAN 0x00000200 | |
| 79 | -#define AMSK_COMPACT 0x00000400 | |
| 80 | -#define AMSK_FACE 0x00000800 | |
| 81 | -#define AMSK_HEIGHT 0x00001000 | |
| 82 | -#define AMSK_HREF 0x00002000 | |
| 83 | -#define AMSK_HSPACE 0x00004000 | |
| 84 | -#define AMSK_ID 0x00008000 | |
| 85 | -#define AMSK_LINKS 0x00010000 | |
| 86 | -#define AMSK_NAME 0x00020000 | |
| 87 | -#define AMSK_ROWSPAN 0x00040000 | |
| 88 | -#define AMSK_SIZE 0x00080000 | |
| 89 | -#define AMSK_SRC 0x00100000 | |
| 90 | -#define AMSK_START 0x00200000 | |
| 91 | -#define AMSK_STYLE 0x00400000 | |
| 92 | -#define AMSK_TARGET 0x00800000 | |
| 93 | -#define AMSK_TYPE 0x01000000 | |
| 94 | -#define AMSK_VALIGN 0x02000000 | |
| 95 | -#define AMSK_VALUE 0x04000000 | |
| 96 | -#define AMSK_VSPACE 0x08000000 | |
| 97 | -#define AMSK_WIDTH 0x10000000 | |
| 40 | +enum allowed_attr_t { | |
| 41 | + ATTR_ALIGN = 1, | |
| 42 | + ATTR_ALT, | |
| 43 | + ATTR_BGCOLOR, | |
| 44 | + ATTR_BORDER, | |
| 45 | + ATTR_CELLPADDING, | |
| 46 | + ATTR_CELLSPACING, | |
| 47 | + ATTR_CLASS, | |
| 48 | + ATTR_CLEAR, | |
| 49 | + ATTR_COLOR, | |
| 50 | + ATTR_COLSPAN, | |
| 51 | + ATTR_COMPACT, | |
| 52 | + ATTR_FACE, | |
| 53 | + ATTR_HEIGHT, | |
| 54 | + ATTR_HREF, | |
| 55 | + ATTR_HSPACE, | |
| 56 | + ATTR_ID, | |
| 57 | + ATTR_LINKS, | |
| 58 | + ATTR_NAME, | |
| 59 | + ATTR_ROWSPAN, | |
| 60 | + ATTR_SIZE, | |
| 61 | + ATTR_SRC, | |
| 62 | + ATTR_START, | |
| 63 | + ATTR_STYLE, | |
| 64 | + ATTR_TARGET, | |
| 65 | + ATTR_TYPE, | |
| 66 | + ATTR_VALIGN, | |
| 67 | + ATTR_VALUE, | |
| 68 | + ATTR_VSPACE, | |
| 69 | + ATTR_WIDTH | |
| 70 | +}; | |
| 71 | + | |
| 72 | +enum amsk_t { | |
| 73 | + AMSK_ALIGN = 0x00000001, | |
| 74 | + AMSK_ALT = 0x00000002, | |
| 75 | + AMSK_BGCOLOR = 0x00000004, | |
| 76 | + AMSK_BORDER = 0x00000008, | |
| 77 | + AMSK_CELLPADDING = 0x00000010, | |
| 78 | + AMSK_CELLSPACING = 0x00000020, | |
| 79 | + AMSK_CLASS = 0x00000040, | |
| 80 | + AMSK_CLEAR = 0x00000080, | |
| 81 | + AMSK_COLOR = 0x00000100, | |
| 82 | + AMSK_COLSPAN = 0x00000200, | |
| 83 | + AMSK_COMPACT = 0x00000400, | |
| 84 | + /* re-use = 0x00000800, */ | |
| 85 | + AMSK_FACE = 0x00001000, | |
| 86 | + AMSK_HEIGHT = 0x00002000, | |
| 87 | + AMSK_HREF = 0x00004000, | |
| 88 | + AMSK_HSPACE = 0x00008000, | |
| 89 | + AMSK_ID = 0x00010000, | |
| 90 | + AMSK_LINKS = 0x00020000, | |
| 91 | + AMSK_NAME = 0x00040000, | |
| 92 | + AMSK_ROWSPAN = 0x00080000, | |
| 93 | + AMSK_SIZE = 0x00100000, | |
| 94 | + AMSK_SRC = 0x00200000, | |
| 95 | + AMSK_START = 0x00400000, | |
| 96 | + AMSK_STYLE = 0x00800000, | |
| 97 | + AMSK_TARGET = 0x01000000, | |
| 98 | + AMSK_TYPE = 0x02000000, | |
| 99 | + AMSK_VALIGN = 0x04000000, | |
| 100 | + AMSK_VALUE = 0x08000000, | |
| 101 | + AMSK_VSPACE = 0x10000000, | |
| 102 | + AMSK_WIDTH = 0x20000000 | |
| 103 | +}; | |
| 98 | 104 | |
| 99 | 105 | static const struct AllowedAttribute { |
| 100 | 106 | const char *zName; |
| 101 | 107 | unsigned int iMask; |
| 102 | 108 | } aAttribute[] = { |
| 109 | + /* These indexes MUST line up with their | |
| 110 | + corresponding allowed_attr_t enum values. | |
| 111 | + */ | |
| 103 | 112 | { 0, 0 }, |
| 104 | - { "align", AMSK_ALIGN, }, | |
| 105 | - { "alt", AMSK_ALT, }, | |
| 106 | - { "bgcolor", AMSK_BGCOLOR, }, | |
| 107 | - { "border", AMSK_BORDER, }, | |
| 108 | - { "cellpadding", AMSK_CELLPADDING, }, | |
| 109 | - { "cellspacing", AMSK_CELLSPACING, }, | |
| 110 | - { "class", AMSK_CLASS, }, | |
| 111 | - { "clear", AMSK_CLEAR, }, | |
| 112 | - { "color", AMSK_COLOR, }, | |
| 113 | - { "colspan", AMSK_COLSPAN, }, | |
| 114 | - { "compact", AMSK_COMPACT, }, | |
| 115 | - { "face", AMSK_FACE, }, | |
| 116 | - { "height", AMSK_HEIGHT, }, | |
| 117 | - { "href", AMSK_HREF, }, | |
| 118 | - { "hspace", AMSK_HSPACE, }, | |
| 119 | - { "id", AMSK_ID, }, | |
| 120 | - { "links", AMSK_LINKS, }, | |
| 121 | - { "name", AMSK_NAME, }, | |
| 122 | - { "rowspan", AMSK_ROWSPAN, }, | |
| 123 | - { "size", AMSK_SIZE, }, | |
| 124 | - { "src", AMSK_SRC, }, | |
| 125 | - { "start", AMSK_START, }, | |
| 126 | - { "style", AMSK_STYLE, }, | |
| 127 | - { "target", AMSK_TARGET, }, | |
| 128 | - { "type", AMSK_TYPE, }, | |
| 129 | - { "valign", AMSK_VALIGN, }, | |
| 130 | - { "value", AMSK_VALUE, }, | |
| 131 | - { "vspace", AMSK_VSPACE, }, | |
| 132 | - { "width", AMSK_WIDTH, }, | |
| 113 | + { "align", AMSK_ALIGN }, | |
| 114 | + { "alt", AMSK_ALT }, | |
| 115 | + { "bgcolor", AMSK_BGCOLOR }, | |
| 116 | + { "border", AMSK_BORDER }, | |
| 117 | + { "cellpadding", AMSK_CELLPADDING }, | |
| 118 | + { "cellspacing", AMSK_CELLSPACING }, | |
| 119 | + { "class", AMSK_CLASS }, | |
| 120 | + { "clear", AMSK_CLEAR }, | |
| 121 | + { "color", AMSK_COLOR }, | |
| 122 | + { "colspan", AMSK_COLSPAN }, | |
| 123 | + { "compact", AMSK_COMPACT }, | |
| 124 | + { "face", AMSK_FACE }, | |
| 125 | + { "height", AMSK_HEIGHT }, | |
| 126 | + { "href", AMSK_HREF }, | |
| 127 | + { "hspace", AMSK_HSPACE }, | |
| 128 | + { "id", AMSK_ID }, | |
| 129 | + { "links", AMSK_LINKS }, | |
| 130 | + { "name", AMSK_NAME }, | |
| 131 | + { "rowspan", AMSK_ROWSPAN }, | |
| 132 | + { "size", AMSK_SIZE }, | |
| 133 | + { "src", AMSK_SRC }, | |
| 134 | + { "start", AMSK_START }, | |
| 135 | + { "style", AMSK_STYLE }, | |
| 136 | + { "target", AMSK_TARGET }, | |
| 137 | + { "type", AMSK_TYPE }, | |
| 138 | + { "valign", AMSK_VALIGN }, | |
| 139 | + { "value", AMSK_VALUE }, | |
| 140 | + { "vspace", AMSK_VSPACE }, | |
| 141 | + { "width", AMSK_WIDTH }, | |
| 133 | 142 | }; |
| 134 | 143 | |
| 135 | 144 | /* |
| 136 | 145 | ** Use binary search to locate a tag in the aAttribute[] table. |
| 137 | 146 | */ |
| @@ -216,16 +225,17 @@ | ||
| 216 | 225 | #define MARKUP_TBODY 50 |
| 217 | 226 | #define MARKUP_TD 51 |
| 218 | 227 | #define MARKUP_TFOOT 52 |
| 219 | 228 | #define MARKUP_TH 53 |
| 220 | 229 | #define MARKUP_THEAD 54 |
| 221 | -#define MARKUP_TR 55 | |
| 222 | -#define MARKUP_TT 56 | |
| 223 | -#define MARKUP_U 57 | |
| 224 | -#define MARKUP_UL 58 | |
| 225 | -#define MARKUP_VAR 59 | |
| 226 | -#define MARKUP_VERBATIM 60 | |
| 230 | +#define MARKUP_TITLE 55 | |
| 231 | +#define MARKUP_TR 56 | |
| 232 | +#define MARKUP_TT 57 | |
| 233 | +#define MARKUP_U 58 | |
| 234 | +#define MARKUP_UL 59 | |
| 235 | +#define MARKUP_VAR 60 | |
| 236 | +#define MARKUP_VERBATIM 61 | |
| 227 | 237 | |
| 228 | 238 | /* |
| 229 | 239 | ** The various markup is divided into the following types: |
| 230 | 240 | */ |
| 231 | 241 | #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ |
| @@ -348,10 +358,11 @@ | ||
| 348 | 358 | { "th", MARKUP_TH, MUTYPE_TD, |
| 349 | 359 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| |
| 350 | 360 | AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 351 | 361 | { "thead", MARKUP_THEAD, MUTYPE_BLOCK, |
| 352 | 362 | AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 363 | + { "title", MARKUP_TITLE, MUTYPE_BLOCK, 0 }, | |
| 353 | 364 | { "tr", MARKUP_TR, MUTYPE_TR, |
| 354 | 365 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 355 | 366 | { "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE }, |
| 356 | 367 | { "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE }, |
| 357 | 368 | { "ul", MARKUP_UL, MUTYPE_LIST, |
| @@ -787,11 +798,11 @@ | ||
| 787 | 798 | p->nAttr = 1; |
| 788 | 799 | if( c=='>' ) return; |
| 789 | 800 | } |
| 790 | 801 | while( fossil_isspace(z[i]) ){ i++; } |
| 791 | 802 | while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){ |
| 792 | - int attrOk; /* True to preserver attribute. False to ignore it */ | |
| 803 | + int attrOk; /* True to preserve attribute. False to ignore it */ | |
| 793 | 804 | j = 0; |
| 794 | 805 | while( fossil_isalnum(z[i]) ){ |
| 795 | 806 | if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]); |
| 796 | 807 | i++; |
| 797 | 808 | } |
| @@ -869,12 +880,14 @@ | ||
| 869 | 880 | static void unparseMarkup(ParsedMarkup *p){ |
| 870 | 881 | int i, n; |
| 871 | 882 | for(i=0; i<p->nAttr; i++){ |
| 872 | 883 | char *z = p->aAttr[i].zValue; |
| 873 | 884 | if( z==0 ) continue; |
| 874 | - n = strlen(z); | |
| 875 | - z[n] = p->aAttr[i].cTerm; | |
| 885 | + if( p->aAttr[i].cTerm ){ | |
| 886 | + n = strlen(z); | |
| 887 | + z[n] = p->aAttr[i].cTerm; | |
| 888 | + } | |
| 876 | 889 | } |
| 877 | 890 | } |
| 878 | 891 | |
| 879 | 892 | /* |
| 880 | 893 | ** Return the value of attribute attrId. Return NULL if there is no |
| @@ -1468,10 +1481,19 @@ | ||
| 1468 | 1481 | } |
| 1469 | 1482 | case TOKEN_MARKUP: { |
| 1470 | 1483 | const char *zId; |
| 1471 | 1484 | int iDiv; |
| 1472 | 1485 | parseMarkup(&markup, z); |
| 1486 | + | |
| 1487 | + /* Convert <title> to <h1 align='center'> */ | |
| 1488 | + if( markup.iCode==MARKUP_TITLE && !p->inVerbatim ){ | |
| 1489 | + markup.iCode = MARKUP_H1; | |
| 1490 | + markup.nAttr = 1; | |
| 1491 | + markup.aAttr[0].iACode = AMSK_ALIGN; | |
| 1492 | + markup.aAttr[0].zValue = "center"; | |
| 1493 | + markup.aAttr[0].cTerm = 0; | |
| 1494 | + } | |
| 1473 | 1495 | |
| 1474 | 1496 | /* Markup of the form </div id=ID> where there is a matching |
| 1475 | 1497 | ** ID somewhere on the stack. Exit any contained verbatim. |
| 1476 | 1498 | ** Pop the stack up to the matching <div>. Discard the </div> |
| 1477 | 1499 | */ |
| 1478 | 1500 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -35,103 +35,112 @@ | |
| 35 | |
| 36 | |
| 37 | /* |
| 38 | ** These are the only markup attributes allowed. |
| 39 | */ |
| 40 | #define ATTR_ALIGN 1 |
| 41 | #define ATTR_ALT 2 |
| 42 | #define ATTR_BGCOLOR 3 |
| 43 | #define ATTR_BORDER 4 |
| 44 | #define ATTR_CELLPADDING 5 |
| 45 | #define ATTR_CELLSPACING 6 |
| 46 | #define ATTR_CLASS 7 |
| 47 | #define ATTR_CLEAR 8 |
| 48 | #define ATTR_COLOR 9 |
| 49 | #define ATTR_COLSPAN 10 |
| 50 | #define ATTR_COMPACT 11 |
| 51 | #define ATTR_FACE 12 |
| 52 | #define ATTR_HEIGHT 13 |
| 53 | #define ATTR_HREF 14 |
| 54 | #define ATTR_HSPACE 15 |
| 55 | #define ATTR_ID 16 |
| 56 | #define ATTR_LINKS 17 |
| 57 | #define ATTR_NAME 18 |
| 58 | #define ATTR_ROWSPAN 19 |
| 59 | #define ATTR_SIZE 20 |
| 60 | #define ATTR_SRC 21 |
| 61 | #define ATTR_START 22 |
| 62 | #define ATTR_STYLE 23 |
| 63 | #define ATTR_TARGET 24 |
| 64 | #define ATTR_TYPE 25 |
| 65 | #define ATTR_VALIGN 26 |
| 66 | #define ATTR_VALUE 27 |
| 67 | #define ATTR_VSPACE 28 |
| 68 | #define ATTR_WIDTH 29 |
| 69 | #define AMSK_ALIGN 0x00000001 |
| 70 | #define AMSK_ALT 0x00000002 |
| 71 | #define AMSK_BGCOLOR 0x00000004 |
| 72 | #define AMSK_BORDER 0x00000008 |
| 73 | #define AMSK_CELLPADDING 0x00000010 |
| 74 | #define AMSK_CELLSPACING 0x00000020 |
| 75 | #define AMSK_CLASS 0x00000040 |
| 76 | #define AMSK_CLEAR 0x00000080 |
| 77 | #define AMSK_COLOR 0x00000100 |
| 78 | #define AMSK_COLSPAN 0x00000200 |
| 79 | #define AMSK_COMPACT 0x00000400 |
| 80 | #define AMSK_FACE 0x00000800 |
| 81 | #define AMSK_HEIGHT 0x00001000 |
| 82 | #define AMSK_HREF 0x00002000 |
| 83 | #define AMSK_HSPACE 0x00004000 |
| 84 | #define AMSK_ID 0x00008000 |
| 85 | #define AMSK_LINKS 0x00010000 |
| 86 | #define AMSK_NAME 0x00020000 |
| 87 | #define AMSK_ROWSPAN 0x00040000 |
| 88 | #define AMSK_SIZE 0x00080000 |
| 89 | #define AMSK_SRC 0x00100000 |
| 90 | #define AMSK_START 0x00200000 |
| 91 | #define AMSK_STYLE 0x00400000 |
| 92 | #define AMSK_TARGET 0x00800000 |
| 93 | #define AMSK_TYPE 0x01000000 |
| 94 | #define AMSK_VALIGN 0x02000000 |
| 95 | #define AMSK_VALUE 0x04000000 |
| 96 | #define AMSK_VSPACE 0x08000000 |
| 97 | #define AMSK_WIDTH 0x10000000 |
| 98 | |
| 99 | static const struct AllowedAttribute { |
| 100 | const char *zName; |
| 101 | unsigned int iMask; |
| 102 | } aAttribute[] = { |
| 103 | { 0, 0 }, |
| 104 | { "align", AMSK_ALIGN, }, |
| 105 | { "alt", AMSK_ALT, }, |
| 106 | { "bgcolor", AMSK_BGCOLOR, }, |
| 107 | { "border", AMSK_BORDER, }, |
| 108 | { "cellpadding", AMSK_CELLPADDING, }, |
| 109 | { "cellspacing", AMSK_CELLSPACING, }, |
| 110 | { "class", AMSK_CLASS, }, |
| 111 | { "clear", AMSK_CLEAR, }, |
| 112 | { "color", AMSK_COLOR, }, |
| 113 | { "colspan", AMSK_COLSPAN, }, |
| 114 | { "compact", AMSK_COMPACT, }, |
| 115 | { "face", AMSK_FACE, }, |
| 116 | { "height", AMSK_HEIGHT, }, |
| 117 | { "href", AMSK_HREF, }, |
| 118 | { "hspace", AMSK_HSPACE, }, |
| 119 | { "id", AMSK_ID, }, |
| 120 | { "links", AMSK_LINKS, }, |
| 121 | { "name", AMSK_NAME, }, |
| 122 | { "rowspan", AMSK_ROWSPAN, }, |
| 123 | { "size", AMSK_SIZE, }, |
| 124 | { "src", AMSK_SRC, }, |
| 125 | { "start", AMSK_START, }, |
| 126 | { "style", AMSK_STYLE, }, |
| 127 | { "target", AMSK_TARGET, }, |
| 128 | { "type", AMSK_TYPE, }, |
| 129 | { "valign", AMSK_VALIGN, }, |
| 130 | { "value", AMSK_VALUE, }, |
| 131 | { "vspace", AMSK_VSPACE, }, |
| 132 | { "width", AMSK_WIDTH, }, |
| 133 | }; |
| 134 | |
| 135 | /* |
| 136 | ** Use binary search to locate a tag in the aAttribute[] table. |
| 137 | */ |
| @@ -216,16 +225,17 @@ | |
| 216 | #define MARKUP_TBODY 50 |
| 217 | #define MARKUP_TD 51 |
| 218 | #define MARKUP_TFOOT 52 |
| 219 | #define MARKUP_TH 53 |
| 220 | #define MARKUP_THEAD 54 |
| 221 | #define MARKUP_TR 55 |
| 222 | #define MARKUP_TT 56 |
| 223 | #define MARKUP_U 57 |
| 224 | #define MARKUP_UL 58 |
| 225 | #define MARKUP_VAR 59 |
| 226 | #define MARKUP_VERBATIM 60 |
| 227 | |
| 228 | /* |
| 229 | ** The various markup is divided into the following types: |
| 230 | */ |
| 231 | #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ |
| @@ -348,10 +358,11 @@ | |
| 348 | { "th", MARKUP_TH, MUTYPE_TD, |
| 349 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| |
| 350 | AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 351 | { "thead", MARKUP_THEAD, MUTYPE_BLOCK, |
| 352 | AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 353 | { "tr", MARKUP_TR, MUTYPE_TR, |
| 354 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 355 | { "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE }, |
| 356 | { "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE }, |
| 357 | { "ul", MARKUP_UL, MUTYPE_LIST, |
| @@ -787,11 +798,11 @@ | |
| 787 | p->nAttr = 1; |
| 788 | if( c=='>' ) return; |
| 789 | } |
| 790 | while( fossil_isspace(z[i]) ){ i++; } |
| 791 | while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){ |
| 792 | int attrOk; /* True to preserver attribute. False to ignore it */ |
| 793 | j = 0; |
| 794 | while( fossil_isalnum(z[i]) ){ |
| 795 | if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]); |
| 796 | i++; |
| 797 | } |
| @@ -869,12 +880,14 @@ | |
| 869 | static void unparseMarkup(ParsedMarkup *p){ |
| 870 | int i, n; |
| 871 | for(i=0; i<p->nAttr; i++){ |
| 872 | char *z = p->aAttr[i].zValue; |
| 873 | if( z==0 ) continue; |
| 874 | n = strlen(z); |
| 875 | z[n] = p->aAttr[i].cTerm; |
| 876 | } |
| 877 | } |
| 878 | |
| 879 | /* |
| 880 | ** Return the value of attribute attrId. Return NULL if there is no |
| @@ -1468,10 +1481,19 @@ | |
| 1468 | } |
| 1469 | case TOKEN_MARKUP: { |
| 1470 | const char *zId; |
| 1471 | int iDiv; |
| 1472 | parseMarkup(&markup, z); |
| 1473 | |
| 1474 | /* Markup of the form </div id=ID> where there is a matching |
| 1475 | ** ID somewhere on the stack. Exit any contained verbatim. |
| 1476 | ** Pop the stack up to the matching <div>. Discard the </div> |
| 1477 | */ |
| 1478 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -35,103 +35,112 @@ | |
| 35 | |
| 36 | |
| 37 | /* |
| 38 | ** These are the only markup attributes allowed. |
| 39 | */ |
| 40 | enum allowed_attr_t { |
| 41 | ATTR_ALIGN = 1, |
| 42 | ATTR_ALT, |
| 43 | ATTR_BGCOLOR, |
| 44 | ATTR_BORDER, |
| 45 | ATTR_CELLPADDING, |
| 46 | ATTR_CELLSPACING, |
| 47 | ATTR_CLASS, |
| 48 | ATTR_CLEAR, |
| 49 | ATTR_COLOR, |
| 50 | ATTR_COLSPAN, |
| 51 | ATTR_COMPACT, |
| 52 | ATTR_FACE, |
| 53 | ATTR_HEIGHT, |
| 54 | ATTR_HREF, |
| 55 | ATTR_HSPACE, |
| 56 | ATTR_ID, |
| 57 | ATTR_LINKS, |
| 58 | ATTR_NAME, |
| 59 | ATTR_ROWSPAN, |
| 60 | ATTR_SIZE, |
| 61 | ATTR_SRC, |
| 62 | ATTR_START, |
| 63 | ATTR_STYLE, |
| 64 | ATTR_TARGET, |
| 65 | ATTR_TYPE, |
| 66 | ATTR_VALIGN, |
| 67 | ATTR_VALUE, |
| 68 | ATTR_VSPACE, |
| 69 | ATTR_WIDTH |
| 70 | }; |
| 71 | |
| 72 | enum amsk_t { |
| 73 | AMSK_ALIGN = 0x00000001, |
| 74 | AMSK_ALT = 0x00000002, |
| 75 | AMSK_BGCOLOR = 0x00000004, |
| 76 | AMSK_BORDER = 0x00000008, |
| 77 | AMSK_CELLPADDING = 0x00000010, |
| 78 | AMSK_CELLSPACING = 0x00000020, |
| 79 | AMSK_CLASS = 0x00000040, |
| 80 | AMSK_CLEAR = 0x00000080, |
| 81 | AMSK_COLOR = 0x00000100, |
| 82 | AMSK_COLSPAN = 0x00000200, |
| 83 | AMSK_COMPACT = 0x00000400, |
| 84 | /* re-use = 0x00000800, */ |
| 85 | AMSK_FACE = 0x00001000, |
| 86 | AMSK_HEIGHT = 0x00002000, |
| 87 | AMSK_HREF = 0x00004000, |
| 88 | AMSK_HSPACE = 0x00008000, |
| 89 | AMSK_ID = 0x00010000, |
| 90 | AMSK_LINKS = 0x00020000, |
| 91 | AMSK_NAME = 0x00040000, |
| 92 | AMSK_ROWSPAN = 0x00080000, |
| 93 | AMSK_SIZE = 0x00100000, |
| 94 | AMSK_SRC = 0x00200000, |
| 95 | AMSK_START = 0x00400000, |
| 96 | AMSK_STYLE = 0x00800000, |
| 97 | AMSK_TARGET = 0x01000000, |
| 98 | AMSK_TYPE = 0x02000000, |
| 99 | AMSK_VALIGN = 0x04000000, |
| 100 | AMSK_VALUE = 0x08000000, |
| 101 | AMSK_VSPACE = 0x10000000, |
| 102 | AMSK_WIDTH = 0x20000000 |
| 103 | }; |
| 104 | |
| 105 | static const struct AllowedAttribute { |
| 106 | const char *zName; |
| 107 | unsigned int iMask; |
| 108 | } aAttribute[] = { |
| 109 | /* These indexes MUST line up with their |
| 110 | corresponding allowed_attr_t enum values. |
| 111 | */ |
| 112 | { 0, 0 }, |
| 113 | { "align", AMSK_ALIGN }, |
| 114 | { "alt", AMSK_ALT }, |
| 115 | { "bgcolor", AMSK_BGCOLOR }, |
| 116 | { "border", AMSK_BORDER }, |
| 117 | { "cellpadding", AMSK_CELLPADDING }, |
| 118 | { "cellspacing", AMSK_CELLSPACING }, |
| 119 | { "class", AMSK_CLASS }, |
| 120 | { "clear", AMSK_CLEAR }, |
| 121 | { "color", AMSK_COLOR }, |
| 122 | { "colspan", AMSK_COLSPAN }, |
| 123 | { "compact", AMSK_COMPACT }, |
| 124 | { "face", AMSK_FACE }, |
| 125 | { "height", AMSK_HEIGHT }, |
| 126 | { "href", AMSK_HREF }, |
| 127 | { "hspace", AMSK_HSPACE }, |
| 128 | { "id", AMSK_ID }, |
| 129 | { "links", AMSK_LINKS }, |
| 130 | { "name", AMSK_NAME }, |
| 131 | { "rowspan", AMSK_ROWSPAN }, |
| 132 | { "size", AMSK_SIZE }, |
| 133 | { "src", AMSK_SRC }, |
| 134 | { "start", AMSK_START }, |
| 135 | { "style", AMSK_STYLE }, |
| 136 | { "target", AMSK_TARGET }, |
| 137 | { "type", AMSK_TYPE }, |
| 138 | { "valign", AMSK_VALIGN }, |
| 139 | { "value", AMSK_VALUE }, |
| 140 | { "vspace", AMSK_VSPACE }, |
| 141 | { "width", AMSK_WIDTH }, |
| 142 | }; |
| 143 | |
| 144 | /* |
| 145 | ** Use binary search to locate a tag in the aAttribute[] table. |
| 146 | */ |
| @@ -216,16 +225,17 @@ | |
| 225 | #define MARKUP_TBODY 50 |
| 226 | #define MARKUP_TD 51 |
| 227 | #define MARKUP_TFOOT 52 |
| 228 | #define MARKUP_TH 53 |
| 229 | #define MARKUP_THEAD 54 |
| 230 | #define MARKUP_TITLE 55 |
| 231 | #define MARKUP_TR 56 |
| 232 | #define MARKUP_TT 57 |
| 233 | #define MARKUP_U 58 |
| 234 | #define MARKUP_UL 59 |
| 235 | #define MARKUP_VAR 60 |
| 236 | #define MARKUP_VERBATIM 61 |
| 237 | |
| 238 | /* |
| 239 | ** The various markup is divided into the following types: |
| 240 | */ |
| 241 | #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ |
| @@ -348,10 +358,11 @@ | |
| 358 | { "th", MARKUP_TH, MUTYPE_TD, |
| 359 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| |
| 360 | AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 361 | { "thead", MARKUP_THEAD, MUTYPE_BLOCK, |
| 362 | AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 363 | { "title", MARKUP_TITLE, MUTYPE_BLOCK, 0 }, |
| 364 | { "tr", MARKUP_TR, MUTYPE_TR, |
| 365 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 366 | { "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE }, |
| 367 | { "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE }, |
| 368 | { "ul", MARKUP_UL, MUTYPE_LIST, |
| @@ -787,11 +798,11 @@ | |
| 798 | p->nAttr = 1; |
| 799 | if( c=='>' ) return; |
| 800 | } |
| 801 | while( fossil_isspace(z[i]) ){ i++; } |
| 802 | while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){ |
| 803 | int attrOk; /* True to preserve attribute. False to ignore it */ |
| 804 | j = 0; |
| 805 | while( fossil_isalnum(z[i]) ){ |
| 806 | if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]); |
| 807 | i++; |
| 808 | } |
| @@ -869,12 +880,14 @@ | |
| 880 | static void unparseMarkup(ParsedMarkup *p){ |
| 881 | int i, n; |
| 882 | for(i=0; i<p->nAttr; i++){ |
| 883 | char *z = p->aAttr[i].zValue; |
| 884 | if( z==0 ) continue; |
| 885 | if( p->aAttr[i].cTerm ){ |
| 886 | n = strlen(z); |
| 887 | z[n] = p->aAttr[i].cTerm; |
| 888 | } |
| 889 | } |
| 890 | } |
| 891 | |
| 892 | /* |
| 893 | ** Return the value of attribute attrId. Return NULL if there is no |
| @@ -1468,10 +1481,19 @@ | |
| 1481 | } |
| 1482 | case TOKEN_MARKUP: { |
| 1483 | const char *zId; |
| 1484 | int iDiv; |
| 1485 | parseMarkup(&markup, z); |
| 1486 | |
| 1487 | /* Convert <title> to <h1 align='center'> */ |
| 1488 | if( markup.iCode==MARKUP_TITLE && !p->inVerbatim ){ |
| 1489 | markup.iCode = MARKUP_H1; |
| 1490 | markup.nAttr = 1; |
| 1491 | markup.aAttr[0].iACode = AMSK_ALIGN; |
| 1492 | markup.aAttr[0].zValue = "center"; |
| 1493 | markup.aAttr[0].cTerm = 0; |
| 1494 | } |
| 1495 | |
| 1496 | /* Markup of the form </div id=ID> where there is a matching |
| 1497 | ** ID somewhere on the stack. Exit any contained verbatim. |
| 1498 | ** Pop the stack up to the matching <div>. Discard the </div> |
| 1499 | */ |
| 1500 |
+6
-6
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1375,11 +1375,11 @@ | ||
| 1375 | 1375 | static double fossil_fabs(double x){ |
| 1376 | 1376 | return x>0.0 ? x : -x; |
| 1377 | 1377 | } |
| 1378 | 1378 | |
| 1379 | 1379 | /* |
| 1380 | -** Sync to the host identified in g.urlName and g.urlPath. This | |
| 1380 | +** Sync to the host identified in g.url.name and g.url.path. This | |
| 1381 | 1381 | ** routine is called by the client. |
| 1382 | 1382 | ** |
| 1383 | 1383 | ** Records are pushed to the server if pushFlag is true. Records |
| 1384 | 1384 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1385 | 1385 | ** true. |
| @@ -1823,15 +1823,15 @@ | ||
| 1823 | 1823 | defossilize(zMsg); |
| 1824 | 1824 | fossil_force_newline(); |
| 1825 | 1825 | fossil_print("Error: %s\n", zMsg); |
| 1826 | 1826 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1827 | 1827 | if( nCycle<2 ){ |
| 1828 | - g.urlPasswd = 0; | |
| 1828 | + g.url.passwd = 0; | |
| 1829 | 1829 | go = 1; |
| 1830 | 1830 | if( g.cgiOutput==0 ){ |
| 1831 | - g.urlFlags |= URL_PROMPT_PW; | |
| 1832 | - g.urlFlags &= ~URL_PROMPTED; | |
| 1831 | + g.url.flags |= URL_PROMPT_PW; | |
| 1832 | + g.url.flags &= ~URL_PROMPTED; | |
| 1833 | 1833 | url_prompt_for_password(); |
| 1834 | 1834 | url_remember(); |
| 1835 | 1835 | } |
| 1836 | 1836 | } |
| 1837 | 1837 | }else{ |
| @@ -1926,13 +1926,13 @@ | ||
| 1926 | 1926 | |
| 1927 | 1927 | fossil_force_newline(); |
| 1928 | 1928 | fossil_print( |
| 1929 | 1929 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1930 | 1930 | zOpType, nSent, nRcvd); |
| 1931 | - transport_close(GLOBAL_URL()); | |
| 1932 | - transport_global_shutdown(GLOBAL_URL()); | |
| 1931 | + transport_close(&g.url); | |
| 1932 | + transport_global_shutdown(&g.url); | |
| 1933 | 1933 | db_multi_exec("DROP TABLE onremote"); |
| 1934 | 1934 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1935 | 1935 | content_enable_dephantomize(1); |
| 1936 | 1936 | db_end_transaction(0); |
| 1937 | 1937 | return nErr; |
| 1938 | 1938 | } |
| 1939 | 1939 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1375,11 +1375,11 @@ | |
| 1375 | static double fossil_fabs(double x){ |
| 1376 | return x>0.0 ? x : -x; |
| 1377 | } |
| 1378 | |
| 1379 | /* |
| 1380 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1381 | ** routine is called by the client. |
| 1382 | ** |
| 1383 | ** Records are pushed to the server if pushFlag is true. Records |
| 1384 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1385 | ** true. |
| @@ -1823,15 +1823,15 @@ | |
| 1823 | defossilize(zMsg); |
| 1824 | fossil_force_newline(); |
| 1825 | fossil_print("Error: %s\n", zMsg); |
| 1826 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1827 | if( nCycle<2 ){ |
| 1828 | g.urlPasswd = 0; |
| 1829 | go = 1; |
| 1830 | if( g.cgiOutput==0 ){ |
| 1831 | g.urlFlags |= URL_PROMPT_PW; |
| 1832 | g.urlFlags &= ~URL_PROMPTED; |
| 1833 | url_prompt_for_password(); |
| 1834 | url_remember(); |
| 1835 | } |
| 1836 | } |
| 1837 | }else{ |
| @@ -1926,13 +1926,13 @@ | |
| 1926 | |
| 1927 | fossil_force_newline(); |
| 1928 | fossil_print( |
| 1929 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1930 | zOpType, nSent, nRcvd); |
| 1931 | transport_close(GLOBAL_URL()); |
| 1932 | transport_global_shutdown(GLOBAL_URL()); |
| 1933 | db_multi_exec("DROP TABLE onremote"); |
| 1934 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1935 | content_enable_dephantomize(1); |
| 1936 | db_end_transaction(0); |
| 1937 | return nErr; |
| 1938 | } |
| 1939 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1375,11 +1375,11 @@ | |
| 1375 | static double fossil_fabs(double x){ |
| 1376 | return x>0.0 ? x : -x; |
| 1377 | } |
| 1378 | |
| 1379 | /* |
| 1380 | ** Sync to the host identified in g.url.name and g.url.path. This |
| 1381 | ** routine is called by the client. |
| 1382 | ** |
| 1383 | ** Records are pushed to the server if pushFlag is true. Records |
| 1384 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1385 | ** true. |
| @@ -1823,15 +1823,15 @@ | |
| 1823 | defossilize(zMsg); |
| 1824 | fossil_force_newline(); |
| 1825 | fossil_print("Error: %s\n", zMsg); |
| 1826 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1827 | if( nCycle<2 ){ |
| 1828 | g.url.passwd = 0; |
| 1829 | go = 1; |
| 1830 | if( g.cgiOutput==0 ){ |
| 1831 | g.url.flags |= URL_PROMPT_PW; |
| 1832 | g.url.flags &= ~URL_PROMPTED; |
| 1833 | url_prompt_for_password(); |
| 1834 | url_remember(); |
| 1835 | } |
| 1836 | } |
| 1837 | }else{ |
| @@ -1926,13 +1926,13 @@ | |
| 1926 | |
| 1927 | fossil_force_newline(); |
| 1928 | fossil_print( |
| 1929 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1930 | zOpType, nSent, nRcvd); |
| 1931 | transport_close(&g.url); |
| 1932 | transport_global_shutdown(&g.url); |
| 1933 | db_multi_exec("DROP TABLE onremote"); |
| 1934 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1935 | content_enable_dephantomize(1); |
| 1936 | db_end_transaction(0); |
| 1937 | return nErr; |
| 1938 | } |
| 1939 |
+3
-3
| --- src/xfersetup.c | ||
| +++ src/xfersetup.c | ||
| @@ -44,11 +44,11 @@ | ||
| 44 | 44 | setup_menu_entry("Ticket", "xfersetup_ticket", |
| 45 | 45 | "Specific TH1 code to run after processing a ticket change."); |
| 46 | 46 | @ </table> |
| 47 | 47 | |
| 48 | 48 | url_parse(0, 0); |
| 49 | - if( g.urlProtocol ){ | |
| 49 | + if( g.url.protocol ){ | |
| 50 | 50 | unsigned syncFlags; |
| 51 | 51 | const char *zButton; |
| 52 | 52 | char *zWarning; |
| 53 | 53 | |
| 54 | 54 | if( db_get_boolean("dont-push", 0) ){ |
| @@ -57,19 +57,19 @@ | ||
| 57 | 57 | zWarning = 0; |
| 58 | 58 | }else{ |
| 59 | 59 | syncFlags = SYNC_PUSH | SYNC_PULL; |
| 60 | 60 | zButton = "Synchronize"; |
| 61 | 61 | zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.", |
| 62 | - g.urlCanonical); | |
| 62 | + g.url.canonical); | |
| 63 | 63 | } |
| 64 | 64 | if( P("sync") ){ |
| 65 | 65 | user_select(); |
| 66 | 66 | url_enable_proxy(0); |
| 67 | 67 | client_sync(syncFlags, 0, 0); |
| 68 | 68 | } |
| 69 | 69 | @ <p>Press the %h(zButton) button below to synchronize with the |
| 70 | - @ "%h(g.urlCanonical)" repository now. This may be useful when | |
| 70 | + @ "%h(g.url.canonical)" repository now. This may be useful when | |
| 71 | 71 | @ testing the various transfer scripts.</p> |
| 72 | 72 | @ <p>You can use the "http -async" command in your scripts, but |
| 73 | 73 | @ make sure the "th1-uri-regexp" setting is set first.</p> |
| 74 | 74 | if( zWarning ){ |
| 75 | 75 | @ |
| 76 | 76 |
| --- src/xfersetup.c | |
| +++ src/xfersetup.c | |
| @@ -44,11 +44,11 @@ | |
| 44 | setup_menu_entry("Ticket", "xfersetup_ticket", |
| 45 | "Specific TH1 code to run after processing a ticket change."); |
| 46 | @ </table> |
| 47 | |
| 48 | url_parse(0, 0); |
| 49 | if( g.urlProtocol ){ |
| 50 | unsigned syncFlags; |
| 51 | const char *zButton; |
| 52 | char *zWarning; |
| 53 | |
| 54 | if( db_get_boolean("dont-push", 0) ){ |
| @@ -57,19 +57,19 @@ | |
| 57 | zWarning = 0; |
| 58 | }else{ |
| 59 | syncFlags = SYNC_PUSH | SYNC_PULL; |
| 60 | zButton = "Synchronize"; |
| 61 | zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.", |
| 62 | g.urlCanonical); |
| 63 | } |
| 64 | if( P("sync") ){ |
| 65 | user_select(); |
| 66 | url_enable_proxy(0); |
| 67 | client_sync(syncFlags, 0, 0); |
| 68 | } |
| 69 | @ <p>Press the %h(zButton) button below to synchronize with the |
| 70 | @ "%h(g.urlCanonical)" repository now. This may be useful when |
| 71 | @ testing the various transfer scripts.</p> |
| 72 | @ <p>You can use the "http -async" command in your scripts, but |
| 73 | @ make sure the "th1-uri-regexp" setting is set first.</p> |
| 74 | if( zWarning ){ |
| 75 | @ |
| 76 |
| --- src/xfersetup.c | |
| +++ src/xfersetup.c | |
| @@ -44,11 +44,11 @@ | |
| 44 | setup_menu_entry("Ticket", "xfersetup_ticket", |
| 45 | "Specific TH1 code to run after processing a ticket change."); |
| 46 | @ </table> |
| 47 | |
| 48 | url_parse(0, 0); |
| 49 | if( g.url.protocol ){ |
| 50 | unsigned syncFlags; |
| 51 | const char *zButton; |
| 52 | char *zWarning; |
| 53 | |
| 54 | if( db_get_boolean("dont-push", 0) ){ |
| @@ -57,19 +57,19 @@ | |
| 57 | zWarning = 0; |
| 58 | }else{ |
| 59 | syncFlags = SYNC_PUSH | SYNC_PULL; |
| 60 | zButton = "Synchronize"; |
| 61 | zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.", |
| 62 | g.url.canonical); |
| 63 | } |
| 64 | if( P("sync") ){ |
| 65 | user_select(); |
| 66 | url_enable_proxy(0); |
| 67 | client_sync(syncFlags, 0, 0); |
| 68 | } |
| 69 | @ <p>Press the %h(zButton) button below to synchronize with the |
| 70 | @ "%h(g.url.canonical)" repository now. This may be useful when |
| 71 | @ testing the various transfer scripts.</p> |
| 72 | @ <p>You can use the "http -async" command in your scripts, but |
| 73 | @ make sure the "th1-uri-regexp" setting is set first.</p> |
| 74 | if( zWarning ){ |
| 75 | @ |
| 76 |
+9
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -418,10 +418,19 @@ | ||
| 418 | 418 | ** WEBPAGE: zip |
| 419 | 419 | ** URL: /zip/RID.zip |
| 420 | 420 | ** |
| 421 | 421 | ** Generate a ZIP archive for the baseline. |
| 422 | 422 | ** Return that ZIP archive as the HTTP reply content. |
| 423 | +** | |
| 424 | +** Optional URL Parameters: | |
| 425 | +** | |
| 426 | +** - name=base name of the output file. Defaults to | |
| 427 | +** something project/version-specific. | |
| 428 | +** | |
| 429 | +** - uuid=the version to zip (may be a tag/branch name). | |
| 430 | +** Defaults to trunk. | |
| 431 | +** | |
| 423 | 432 | */ |
| 424 | 433 | void baseline_zip_page(void){ |
| 425 | 434 | int rid; |
| 426 | 435 | char *zName, *zRid; |
| 427 | 436 | int nName, nRid; |
| 428 | 437 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -418,10 +418,19 @@ | |
| 418 | ** WEBPAGE: zip |
| 419 | ** URL: /zip/RID.zip |
| 420 | ** |
| 421 | ** Generate a ZIP archive for the baseline. |
| 422 | ** Return that ZIP archive as the HTTP reply content. |
| 423 | */ |
| 424 | void baseline_zip_page(void){ |
| 425 | int rid; |
| 426 | char *zName, *zRid; |
| 427 | int nName, nRid; |
| 428 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -418,10 +418,19 @@ | |
| 418 | ** WEBPAGE: zip |
| 419 | ** URL: /zip/RID.zip |
| 420 | ** |
| 421 | ** Generate a ZIP archive for the baseline. |
| 422 | ** Return that ZIP archive as the HTTP reply content. |
| 423 | ** |
| 424 | ** Optional URL Parameters: |
| 425 | ** |
| 426 | ** - name=base name of the output file. Defaults to |
| 427 | ** something project/version-specific. |
| 428 | ** |
| 429 | ** - uuid=the version to zip (may be a tag/branch name). |
| 430 | ** Defaults to trunk. |
| 431 | ** |
| 432 | */ |
| 433 | void baseline_zip_page(void){ |
| 434 | int rid; |
| 435 | char *zName, *zRid; |
| 436 | int nName, nRid; |
| 437 |
+20
| --- test/file1.test | ||
| +++ test/file1.test | ||
| @@ -24,10 +24,19 @@ | ||
| 24 | 24 | fossil test-simplify-name $path |
| 25 | 25 | test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"} |
| 26 | 26 | incr i |
| 27 | 27 | } |
| 28 | 28 | } |
| 29 | + | |
| 30 | +proc relative-name {testname args} { | |
| 31 | + set i 1 | |
| 32 | + foreach {subdir path result} $args { | |
| 33 | + fossil test-relative-name --chdir $subdir $path | |
| 34 | + test relative-name-$testname.$i {$::RESULT==$result} | |
| 35 | + incr i | |
| 36 | + } | |
| 37 | +} | |
| 29 | 38 | |
| 30 | 39 | simplify-name 100 . . .// . .. .. ..///// .. |
| 31 | 40 | simplify-name 101 {} {} / / ///////// / ././././ . |
| 32 | 41 | simplify-name 102 x x /x /x ///x //x |
| 33 | 42 | simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b |
| @@ -38,5 +47,16 @@ | ||
| 38 | 47 | |
| 39 | 48 | if {$::tcl_platform(os)=="Windows NT"} { |
| 40 | 49 | simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {} |
| 41 | 50 | simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {} |
| 42 | 51 | } |
| 52 | + | |
| 53 | +# Those directories are only needed for the testcase being able to "--chdir" to it. | |
| 54 | +file mkdir test1 | |
| 55 | +file mkdir test1/test2 | |
| 56 | + | |
| 57 | +relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test | |
| 58 | +relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test | |
| 59 | +relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2 | |
| 60 | + | |
| 61 | +catch {file delete test1/test2} | |
| 62 | +catch {file delete test1} | |
| 43 | 63 |
| --- test/file1.test | |
| +++ test/file1.test | |
| @@ -24,10 +24,19 @@ | |
| 24 | fossil test-simplify-name $path |
| 25 | test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"} |
| 26 | incr i |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | simplify-name 100 . . .// . .. .. ..///// .. |
| 31 | simplify-name 101 {} {} / / ///////// / ././././ . |
| 32 | simplify-name 102 x x /x /x ///x //x |
| 33 | simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b |
| @@ -38,5 +47,16 @@ | |
| 38 | |
| 39 | if {$::tcl_platform(os)=="Windows NT"} { |
| 40 | simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {} |
| 41 | simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {} |
| 42 | } |
| 43 |
| --- test/file1.test | |
| +++ test/file1.test | |
| @@ -24,10 +24,19 @@ | |
| 24 | fossil test-simplify-name $path |
| 25 | test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"} |
| 26 | incr i |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | proc relative-name {testname args} { |
| 31 | set i 1 |
| 32 | foreach {subdir path result} $args { |
| 33 | fossil test-relative-name --chdir $subdir $path |
| 34 | test relative-name-$testname.$i {$::RESULT==$result} |
| 35 | incr i |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | simplify-name 100 . . .// . .. .. ..///// .. |
| 40 | simplify-name 101 {} {} / / ///////// / ././././ . |
| 41 | simplify-name 102 x x /x /x ///x //x |
| 42 | simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b |
| @@ -38,5 +47,16 @@ | |
| 47 | |
| 48 | if {$::tcl_platform(os)=="Windows NT"} { |
| 49 | simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {} |
| 50 | simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {} |
| 51 | } |
| 52 | |
| 53 | # Those directories are only needed for the testcase being able to "--chdir" to it. |
| 54 | file mkdir test1 |
| 55 | file mkdir test1/test2 |
| 56 | |
| 57 | relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test |
| 58 | relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test |
| 59 | relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2 |
| 60 | |
| 61 | catch {file delete test1/test2} |
| 62 | catch {file delete test1} |
| 63 |
+20
| --- test/file1.test | ||
| +++ test/file1.test | ||
| @@ -24,10 +24,19 @@ | ||
| 24 | 24 | fossil test-simplify-name $path |
| 25 | 25 | test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"} |
| 26 | 26 | incr i |
| 27 | 27 | } |
| 28 | 28 | } |
| 29 | + | |
| 30 | +proc relative-name {testname args} { | |
| 31 | + set i 1 | |
| 32 | + foreach {subdir path result} $args { | |
| 33 | + fossil test-relative-name --chdir $subdir $path | |
| 34 | + test relative-name-$testname.$i {$::RESULT==$result} | |
| 35 | + incr i | |
| 36 | + } | |
| 37 | +} | |
| 29 | 38 | |
| 30 | 39 | simplify-name 100 . . .// . .. .. ..///// .. |
| 31 | 40 | simplify-name 101 {} {} / / ///////// / ././././ . |
| 32 | 41 | simplify-name 102 x x /x /x ///x //x |
| 33 | 42 | simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b |
| @@ -38,5 +47,16 @@ | ||
| 38 | 47 | |
| 39 | 48 | if {$::tcl_platform(os)=="Windows NT"} { |
| 40 | 49 | simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {} |
| 41 | 50 | simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {} |
| 42 | 51 | } |
| 52 | + | |
| 53 | +# Those directories are only needed for the testcase being able to "--chdir" to it. | |
| 54 | +file mkdir test1 | |
| 55 | +file mkdir test1/test2 | |
| 56 | + | |
| 57 | +relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test | |
| 58 | +relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test | |
| 59 | +relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2 | |
| 60 | + | |
| 61 | +catch {file delete test1/test2} | |
| 62 | +catch {file delete test1} | |
| 43 | 63 |
| --- test/file1.test | |
| +++ test/file1.test | |
| @@ -24,10 +24,19 @@ | |
| 24 | fossil test-simplify-name $path |
| 25 | test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"} |
| 26 | incr i |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | simplify-name 100 . . .// . .. .. ..///// .. |
| 31 | simplify-name 101 {} {} / / ///////// / ././././ . |
| 32 | simplify-name 102 x x /x /x ///x //x |
| 33 | simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b |
| @@ -38,5 +47,16 @@ | |
| 38 | |
| 39 | if {$::tcl_platform(os)=="Windows NT"} { |
| 40 | simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {} |
| 41 | simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {} |
| 42 | } |
| 43 |
| --- test/file1.test | |
| +++ test/file1.test | |
| @@ -24,10 +24,19 @@ | |
| 24 | fossil test-simplify-name $path |
| 25 | test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"} |
| 26 | incr i |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | proc relative-name {testname args} { |
| 31 | set i 1 |
| 32 | foreach {subdir path result} $args { |
| 33 | fossil test-relative-name --chdir $subdir $path |
| 34 | test relative-name-$testname.$i {$::RESULT==$result} |
| 35 | incr i |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | simplify-name 100 . . .// . .. .. ..///// .. |
| 40 | simplify-name 101 {} {} / / ///////// / ././././ . |
| 41 | simplify-name 102 x x /x /x ///x //x |
| 42 | simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b |
| @@ -38,5 +47,16 @@ | |
| 47 | |
| 48 | if {$::tcl_platform(os)=="Windows NT"} { |
| 49 | simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {} |
| 50 | simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {} |
| 51 | } |
| 52 | |
| 53 | # Those directories are only needed for the testcase being able to "--chdir" to it. |
| 54 | file mkdir test1 |
| 55 | file mkdir test1/test2 |
| 56 | |
| 57 | relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test |
| 58 | relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test |
| 59 | relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2 |
| 60 | |
| 61 | catch {file delete test1/test2} |
| 62 | catch {file delete test1} |
| 63 |
| --- test/merge_renames.test | ||
| +++ test/merge_renames.test | ||
| @@ -1,9 +1,16 @@ | ||
| 1 | 1 | # |
| 2 | 2 | # Tests for merging with renames |
| 3 | 3 | # |
| 4 | 4 | # |
| 5 | + | |
| 6 | +catch {exec $::fossilexe info} res | |
| 7 | +puts res=$res | |
| 8 | +if {![regexp {use --repository} $res]} { | |
| 9 | + puts stderr "Cannot run this test within an open checkout" | |
| 10 | + return | |
| 11 | +} | |
| 5 | 12 | |
| 6 | 13 | ###################################### |
| 7 | 14 | # Test 1 # |
| 8 | 15 | # Reported: Ticket [554f44ee74e3d] # |
| 9 | 16 | ###################################### |
| 10 | 17 |
| --- test/merge_renames.test | |
| +++ test/merge_renames.test | |
| @@ -1,9 +1,16 @@ | |
| 1 | # |
| 2 | # Tests for merging with renames |
| 3 | # |
| 4 | # |
| 5 | |
| 6 | ###################################### |
| 7 | # Test 1 # |
| 8 | # Reported: Ticket [554f44ee74e3d] # |
| 9 | ###################################### |
| 10 |
| --- test/merge_renames.test | |
| +++ test/merge_renames.test | |
| @@ -1,9 +1,16 @@ | |
| 1 | # |
| 2 | # Tests for merging with renames |
| 3 | # |
| 4 | # |
| 5 | |
| 6 | catch {exec $::fossilexe info} res |
| 7 | puts res=$res |
| 8 | if {![regexp {use --repository} $res]} { |
| 9 | puts stderr "Cannot run this test within an open checkout" |
| 10 | return |
| 11 | } |
| 12 | |
| 13 | ###################################### |
| 14 | # Test 1 # |
| 15 | # Reported: Ticket [554f44ee74e3d] # |
| 16 | ###################################### |
| 17 |
| --- test/merge_renames.test | ||
| +++ test/merge_renames.test | ||
| @@ -1,9 +1,16 @@ | ||
| 1 | 1 | # |
| 2 | 2 | # Tests for merging with renames |
| 3 | 3 | # |
| 4 | 4 | # |
| 5 | + | |
| 6 | +catch {exec $::fossilexe info} res | |
| 7 | +puts res=$res | |
| 8 | +if {![regexp {use --repository} $res]} { | |
| 9 | + puts stderr "Cannot run this test within an open checkout" | |
| 10 | + return | |
| 11 | +} | |
| 5 | 12 | |
| 6 | 13 | ###################################### |
| 7 | 14 | # Test 1 # |
| 8 | 15 | # Reported: Ticket [554f44ee74e3d] # |
| 9 | 16 | ###################################### |
| 10 | 17 |
| --- test/merge_renames.test | |
| +++ test/merge_renames.test | |
| @@ -1,9 +1,16 @@ | |
| 1 | # |
| 2 | # Tests for merging with renames |
| 3 | # |
| 4 | # |
| 5 | |
| 6 | ###################################### |
| 7 | # Test 1 # |
| 8 | # Reported: Ticket [554f44ee74e3d] # |
| 9 | ###################################### |
| 10 |
| --- test/merge_renames.test | |
| +++ test/merge_renames.test | |
| @@ -1,9 +1,16 @@ | |
| 1 | # |
| 2 | # Tests for merging with renames |
| 3 | # |
| 4 | # |
| 5 | |
| 6 | catch {exec $::fossilexe info} res |
| 7 | puts res=$res |
| 8 | if {![regexp {use --repository} $res]} { |
| 9 | puts stderr "Cannot run this test within an open checkout" |
| 10 | return |
| 11 | } |
| 12 | |
| 13 | ###################################### |
| 14 | # Test 1 # |
| 15 | # Reported: Ticket [554f44ee74e3d] # |
| 16 | ###################################### |
| 17 |
+7
| --- test/revert.test | ||
| +++ test/revert.test | ||
| @@ -36,10 +36,17 @@ | ||
| 36 | 36 | test revert-$testid$key $passed |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | fossil undo |
| 40 | 40 | } |
| 41 | + | |
| 42 | +catch {exec $::fossilexe info} res | |
| 43 | +puts res=$res | |
| 44 | +if {![regexp {use --repository} $res]} { | |
| 45 | + puts stderr "Cannot run this test within an open checkout" | |
| 46 | + return | |
| 47 | +} | |
| 41 | 48 | |
| 42 | 49 | repo_init |
| 43 | 50 | |
| 44 | 51 | # Prepare first commit |
| 45 | 52 | # |
| 46 | 53 |
| --- test/revert.test | |
| +++ test/revert.test | |
| @@ -36,10 +36,17 @@ | |
| 36 | test revert-$testid$key $passed |
| 37 | } |
| 38 | |
| 39 | fossil undo |
| 40 | } |
| 41 | |
| 42 | repo_init |
| 43 | |
| 44 | # Prepare first commit |
| 45 | # |
| 46 |
| --- test/revert.test | |
| +++ test/revert.test | |
| @@ -36,10 +36,17 @@ | |
| 36 | test revert-$testid$key $passed |
| 37 | } |
| 38 | |
| 39 | fossil undo |
| 40 | } |
| 41 | |
| 42 | catch {exec $::fossilexe info} res |
| 43 | puts res=$res |
| 44 | if {![regexp {use --repository} $res]} { |
| 45 | puts stderr "Cannot run this test within an open checkout" |
| 46 | return |
| 47 | } |
| 48 | |
| 49 | repo_init |
| 50 | |
| 51 | # Prepare first commit |
| 52 | # |
| 53 |
+7
| --- test/revert.test | ||
| +++ test/revert.test | ||
| @@ -36,10 +36,17 @@ | ||
| 36 | 36 | test revert-$testid$key $passed |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | fossil undo |
| 40 | 40 | } |
| 41 | + | |
| 42 | +catch {exec $::fossilexe info} res | |
| 43 | +puts res=$res | |
| 44 | +if {![regexp {use --repository} $res]} { | |
| 45 | + puts stderr "Cannot run this test within an open checkout" | |
| 46 | + return | |
| 47 | +} | |
| 41 | 48 | |
| 42 | 49 | repo_init |
| 43 | 50 | |
| 44 | 51 | # Prepare first commit |
| 45 | 52 | # |
| 46 | 53 |
| --- test/revert.test | |
| +++ test/revert.test | |
| @@ -36,10 +36,17 @@ | |
| 36 | test revert-$testid$key $passed |
| 37 | } |
| 38 | |
| 39 | fossil undo |
| 40 | } |
| 41 | |
| 42 | repo_init |
| 43 | |
| 44 | # Prepare first commit |
| 45 | # |
| 46 |
| --- test/revert.test | |
| +++ test/revert.test | |
| @@ -36,10 +36,17 @@ | |
| 36 | test revert-$testid$key $passed |
| 37 | } |
| 38 | |
| 39 | fossil undo |
| 40 | } |
| 41 | |
| 42 | catch {exec $::fossilexe info} res |
| 43 | puts res=$res |
| 44 | if {![regexp {use --repository} $res]} { |
| 45 | puts stderr "Cannot run this test within an open checkout" |
| 46 | return |
| 47 | } |
| 48 | |
| 49 | repo_init |
| 50 | |
| 51 | # Prepare first commit |
| 52 | # |
| 53 |
+113
| --- test/th1.test | ||
| +++ test/th1.test | ||
| @@ -362,5 +362,118 @@ | ||
| 362 | 362 | |
| 363 | 363 | ############################################################################### |
| 364 | 364 | |
| 365 | 365 | fossil test-th-eval "expr +2147483649.0" |
| 366 | 366 | test th1-expr-13 {$RESULT eq {2147483649.0}} |
| 367 | + | |
| 368 | +############################################################################### | |
| 369 | + | |
| 370 | +fossil test-th-eval "expr ~(-1)" | |
| 371 | +test th1-expr-14 {$RESULT eq {0}} | |
| 372 | + | |
| 373 | +############################################################################### | |
| 374 | + | |
| 375 | +fossil test-th-eval "expr ~-1" | |
| 376 | +test th1-expr-15 {$RESULT eq {0}} | |
| 377 | + | |
| 378 | +############################################################################### | |
| 379 | + | |
| 380 | +fossil test-th-eval "expr ~0" | |
| 381 | +test th1-expr-16 {$RESULT eq {-1}} | |
| 382 | + | |
| 383 | +############################################################################### | |
| 384 | + | |
| 385 | +fossil test-th-eval "expr ~+0" | |
| 386 | +test th1-expr-17 {$RESULT eq {-1}} | |
| 387 | + | |
| 388 | +############################################################################### | |
| 389 | + | |
| 390 | +fossil test-th-eval "expr ~-0" | |
| 391 | +test th1-expr-18 {$RESULT eq {-1}} | |
| 392 | + | |
| 393 | +############################################################################### | |
| 394 | + | |
| 395 | +fossil test-th-eval "expr ~(+0)" | |
| 396 | +test th1-expr-19 {$RESULT eq {-1}} | |
| 397 | + | |
| 398 | +############################################################################### | |
| 399 | + | |
| 400 | +fossil test-th-eval "expr ~(-0)" | |
| 401 | +test th1-expr-20 {$RESULT eq {-1}} | |
| 402 | + | |
| 403 | +############################################################################### | |
| 404 | + | |
| 405 | +fossil test-th-eval "expr ~1" | |
| 406 | +test th1-expr-21 {$RESULT eq {-2}} | |
| 407 | + | |
| 408 | +############################################################################### | |
| 409 | + | |
| 410 | +fossil test-th-eval "expr ~+1" | |
| 411 | +test th1-expr-22 {$RESULT eq {-2}} | |
| 412 | + | |
| 413 | +############################################################################### | |
| 414 | + | |
| 415 | +fossil test-th-eval "expr ~(+1)" | |
| 416 | +test th1-expr-23 {$RESULT eq {-2}} | |
| 417 | + | |
| 418 | +############################################################################### | |
| 419 | + | |
| 420 | +fossil test-th-eval "expr 0+0b11" | |
| 421 | +test th1-expr-24 {$RESULT eq 3} | |
| 422 | + | |
| 423 | +############################################################################### | |
| 424 | + | |
| 425 | +fossil test-th-eval "expr 0+0o15" | |
| 426 | +test th1-expr-25 {$RESULT eq 13} | |
| 427 | + | |
| 428 | +############################################################################### | |
| 429 | + | |
| 430 | +fossil test-th-eval "expr 0+0x15" | |
| 431 | +test th1-expr-26 {$RESULT eq 21} | |
| 432 | + | |
| 433 | +############################################################################### | |
| 434 | + | |
| 435 | +fossil test-th-eval "expr 0+0b2" | |
| 436 | +test th1-expr-27 {$RESULT eq {TH_ERROR: expected number, got: "0b2"}} | |
| 437 | + | |
| 438 | +############################################################################### | |
| 439 | + | |
| 440 | +fossil test-th-eval "expr 0+0o8" | |
| 441 | +test th1-expr-28 {$RESULT eq {TH_ERROR: expected number, got: "0o8"}} | |
| 442 | + | |
| 443 | +############################################################################### | |
| 444 | + | |
| 445 | +fossil test-th-eval "expr 0+0xg" | |
| 446 | +test th1-expr-29 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0xg"}} | |
| 447 | + | |
| 448 | +############################################################################### | |
| 449 | + | |
| 450 | +fossil test-th-eval "expr 0+0b1." | |
| 451 | +test th1-expr-30 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0b1."}} | |
| 452 | + | |
| 453 | +############################################################################### | |
| 454 | + | |
| 455 | +fossil test-th-eval "expr 0+0o1." | |
| 456 | +test th1-expr-31 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0o1."}} | |
| 457 | + | |
| 458 | +############################################################################### | |
| 459 | + | |
| 460 | +fossil test-th-eval "expr 0+0x1." | |
| 461 | +test th1-expr-32 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0x1."}} | |
| 462 | + | |
| 463 | +############################################################################### | |
| 464 | + | |
| 465 | +fossil test-th-eval "expr 0ne5" | |
| 466 | +test th1-expr-33 {$RESULT eq {1}} | |
| 467 | + | |
| 468 | +############################################################################### | |
| 469 | + | |
| 470 | +fossil test-th-eval "expr 0b1+5" | |
| 471 | +test th1-expr-34 {$RESULT eq {6}} | |
| 472 | + | |
| 473 | + | |
| 474 | +############################################################################### | |
| 475 | + | |
| 476 | +fossil test-th-eval "expr 0+0b" | |
| 477 | +test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} | |
| 478 | + | |
| 479 | + | |
| 367 | 480 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -362,5 +362,118 @@ | |
| 362 | |
| 363 | ############################################################################### |
| 364 | |
| 365 | fossil test-th-eval "expr +2147483649.0" |
| 366 | test th1-expr-13 {$RESULT eq {2147483649.0}} |
| 367 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -362,5 +362,118 @@ | |
| 362 | |
| 363 | ############################################################################### |
| 364 | |
| 365 | fossil test-th-eval "expr +2147483649.0" |
| 366 | test th1-expr-13 {$RESULT eq {2147483649.0}} |
| 367 | |
| 368 | ############################################################################### |
| 369 | |
| 370 | fossil test-th-eval "expr ~(-1)" |
| 371 | test th1-expr-14 {$RESULT eq {0}} |
| 372 | |
| 373 | ############################################################################### |
| 374 | |
| 375 | fossil test-th-eval "expr ~-1" |
| 376 | test th1-expr-15 {$RESULT eq {0}} |
| 377 | |
| 378 | ############################################################################### |
| 379 | |
| 380 | fossil test-th-eval "expr ~0" |
| 381 | test th1-expr-16 {$RESULT eq {-1}} |
| 382 | |
| 383 | ############################################################################### |
| 384 | |
| 385 | fossil test-th-eval "expr ~+0" |
| 386 | test th1-expr-17 {$RESULT eq {-1}} |
| 387 | |
| 388 | ############################################################################### |
| 389 | |
| 390 | fossil test-th-eval "expr ~-0" |
| 391 | test th1-expr-18 {$RESULT eq {-1}} |
| 392 | |
| 393 | ############################################################################### |
| 394 | |
| 395 | fossil test-th-eval "expr ~(+0)" |
| 396 | test th1-expr-19 {$RESULT eq {-1}} |
| 397 | |
| 398 | ############################################################################### |
| 399 | |
| 400 | fossil test-th-eval "expr ~(-0)" |
| 401 | test th1-expr-20 {$RESULT eq {-1}} |
| 402 | |
| 403 | ############################################################################### |
| 404 | |
| 405 | fossil test-th-eval "expr ~1" |
| 406 | test th1-expr-21 {$RESULT eq {-2}} |
| 407 | |
| 408 | ############################################################################### |
| 409 | |
| 410 | fossil test-th-eval "expr ~+1" |
| 411 | test th1-expr-22 {$RESULT eq {-2}} |
| 412 | |
| 413 | ############################################################################### |
| 414 | |
| 415 | fossil test-th-eval "expr ~(+1)" |
| 416 | test th1-expr-23 {$RESULT eq {-2}} |
| 417 | |
| 418 | ############################################################################### |
| 419 | |
| 420 | fossil test-th-eval "expr 0+0b11" |
| 421 | test th1-expr-24 {$RESULT eq 3} |
| 422 | |
| 423 | ############################################################################### |
| 424 | |
| 425 | fossil test-th-eval "expr 0+0o15" |
| 426 | test th1-expr-25 {$RESULT eq 13} |
| 427 | |
| 428 | ############################################################################### |
| 429 | |
| 430 | fossil test-th-eval "expr 0+0x15" |
| 431 | test th1-expr-26 {$RESULT eq 21} |
| 432 | |
| 433 | ############################################################################### |
| 434 | |
| 435 | fossil test-th-eval "expr 0+0b2" |
| 436 | test th1-expr-27 {$RESULT eq {TH_ERROR: expected number, got: "0b2"}} |
| 437 | |
| 438 | ############################################################################### |
| 439 | |
| 440 | fossil test-th-eval "expr 0+0o8" |
| 441 | test th1-expr-28 {$RESULT eq {TH_ERROR: expected number, got: "0o8"}} |
| 442 | |
| 443 | ############################################################################### |
| 444 | |
| 445 | fossil test-th-eval "expr 0+0xg" |
| 446 | test th1-expr-29 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0xg"}} |
| 447 | |
| 448 | ############################################################################### |
| 449 | |
| 450 | fossil test-th-eval "expr 0+0b1." |
| 451 | test th1-expr-30 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0b1."}} |
| 452 | |
| 453 | ############################################################################### |
| 454 | |
| 455 | fossil test-th-eval "expr 0+0o1." |
| 456 | test th1-expr-31 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0o1."}} |
| 457 | |
| 458 | ############################################################################### |
| 459 | |
| 460 | fossil test-th-eval "expr 0+0x1." |
| 461 | test th1-expr-32 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0x1."}} |
| 462 | |
| 463 | ############################################################################### |
| 464 | |
| 465 | fossil test-th-eval "expr 0ne5" |
| 466 | test th1-expr-33 {$RESULT eq {1}} |
| 467 | |
| 468 | ############################################################################### |
| 469 | |
| 470 | fossil test-th-eval "expr 0b1+5" |
| 471 | test th1-expr-34 {$RESULT eq {6}} |
| 472 | |
| 473 | |
| 474 | ############################################################################### |
| 475 | |
| 476 | fossil test-th-eval "expr 0+0b" |
| 477 | test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} |
| 478 | |
| 479 | |
| 480 |
+113
| --- test/th1.test | ||
| +++ test/th1.test | ||
| @@ -362,5 +362,118 @@ | ||
| 362 | 362 | |
| 363 | 363 | ############################################################################### |
| 364 | 364 | |
| 365 | 365 | fossil test-th-eval "expr +2147483649.0" |
| 366 | 366 | test th1-expr-13 {$RESULT eq {2147483649.0}} |
| 367 | + | |
| 368 | +############################################################################### | |
| 369 | + | |
| 370 | +fossil test-th-eval "expr ~(-1)" | |
| 371 | +test th1-expr-14 {$RESULT eq {0}} | |
| 372 | + | |
| 373 | +############################################################################### | |
| 374 | + | |
| 375 | +fossil test-th-eval "expr ~-1" | |
| 376 | +test th1-expr-15 {$RESULT eq {0}} | |
| 377 | + | |
| 378 | +############################################################################### | |
| 379 | + | |
| 380 | +fossil test-th-eval "expr ~0" | |
| 381 | +test th1-expr-16 {$RESULT eq {-1}} | |
| 382 | + | |
| 383 | +############################################################################### | |
| 384 | + | |
| 385 | +fossil test-th-eval "expr ~+0" | |
| 386 | +test th1-expr-17 {$RESULT eq {-1}} | |
| 387 | + | |
| 388 | +############################################################################### | |
| 389 | + | |
| 390 | +fossil test-th-eval "expr ~-0" | |
| 391 | +test th1-expr-18 {$RESULT eq {-1}} | |
| 392 | + | |
| 393 | +############################################################################### | |
| 394 | + | |
| 395 | +fossil test-th-eval "expr ~(+0)" | |
| 396 | +test th1-expr-19 {$RESULT eq {-1}} | |
| 397 | + | |
| 398 | +############################################################################### | |
| 399 | + | |
| 400 | +fossil test-th-eval "expr ~(-0)" | |
| 401 | +test th1-expr-20 {$RESULT eq {-1}} | |
| 402 | + | |
| 403 | +############################################################################### | |
| 404 | + | |
| 405 | +fossil test-th-eval "expr ~1" | |
| 406 | +test th1-expr-21 {$RESULT eq {-2}} | |
| 407 | + | |
| 408 | +############################################################################### | |
| 409 | + | |
| 410 | +fossil test-th-eval "expr ~+1" | |
| 411 | +test th1-expr-22 {$RESULT eq {-2}} | |
| 412 | + | |
| 413 | +############################################################################### | |
| 414 | + | |
| 415 | +fossil test-th-eval "expr ~(+1)" | |
| 416 | +test th1-expr-23 {$RESULT eq {-2}} | |
| 417 | + | |
| 418 | +############################################################################### | |
| 419 | + | |
| 420 | +fossil test-th-eval "expr 0+0b11" | |
| 421 | +test th1-expr-24 {$RESULT eq 3} | |
| 422 | + | |
| 423 | +############################################################################### | |
| 424 | + | |
| 425 | +fossil test-th-eval "expr 0+0o15" | |
| 426 | +test th1-expr-25 {$RESULT eq 13} | |
| 427 | + | |
| 428 | +############################################################################### | |
| 429 | + | |
| 430 | +fossil test-th-eval "expr 0+0x15" | |
| 431 | +test th1-expr-26 {$RESULT eq 21} | |
| 432 | + | |
| 433 | +############################################################################### | |
| 434 | + | |
| 435 | +fossil test-th-eval "expr 0+0b2" | |
| 436 | +test th1-expr-27 {$RESULT eq {TH_ERROR: expected number, got: "0b2"}} | |
| 437 | + | |
| 438 | +############################################################################### | |
| 439 | + | |
| 440 | +fossil test-th-eval "expr 0+0o8" | |
| 441 | +test th1-expr-28 {$RESULT eq {TH_ERROR: expected number, got: "0o8"}} | |
| 442 | + | |
| 443 | +############################################################################### | |
| 444 | + | |
| 445 | +fossil test-th-eval "expr 0+0xg" | |
| 446 | +test th1-expr-29 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0xg"}} | |
| 447 | + | |
| 448 | +############################################################################### | |
| 449 | + | |
| 450 | +fossil test-th-eval "expr 0+0b1." | |
| 451 | +test th1-expr-30 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0b1."}} | |
| 452 | + | |
| 453 | +############################################################################### | |
| 454 | + | |
| 455 | +fossil test-th-eval "expr 0+0o1." | |
| 456 | +test th1-expr-31 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0o1."}} | |
| 457 | + | |
| 458 | +############################################################################### | |
| 459 | + | |
| 460 | +fossil test-th-eval "expr 0+0x1." | |
| 461 | +test th1-expr-32 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0x1."}} | |
| 462 | + | |
| 463 | +############################################################################### | |
| 464 | + | |
| 465 | +fossil test-th-eval "expr 0ne5" | |
| 466 | +test th1-expr-33 {$RESULT eq {1}} | |
| 467 | + | |
| 468 | +############################################################################### | |
| 469 | + | |
| 470 | +fossil test-th-eval "expr 0b1+5" | |
| 471 | +test th1-expr-34 {$RESULT eq {6}} | |
| 472 | + | |
| 473 | + | |
| 474 | +############################################################################### | |
| 475 | + | |
| 476 | +fossil test-th-eval "expr 0+0b" | |
| 477 | +test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} | |
| 478 | + | |
| 479 | + | |
| 367 | 480 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -362,5 +362,118 @@ | |
| 362 | |
| 363 | ############################################################################### |
| 364 | |
| 365 | fossil test-th-eval "expr +2147483649.0" |
| 366 | test th1-expr-13 {$RESULT eq {2147483649.0}} |
| 367 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -362,5 +362,118 @@ | |
| 362 | |
| 363 | ############################################################################### |
| 364 | |
| 365 | fossil test-th-eval "expr +2147483649.0" |
| 366 | test th1-expr-13 {$RESULT eq {2147483649.0}} |
| 367 | |
| 368 | ############################################################################### |
| 369 | |
| 370 | fossil test-th-eval "expr ~(-1)" |
| 371 | test th1-expr-14 {$RESULT eq {0}} |
| 372 | |
| 373 | ############################################################################### |
| 374 | |
| 375 | fossil test-th-eval "expr ~-1" |
| 376 | test th1-expr-15 {$RESULT eq {0}} |
| 377 | |
| 378 | ############################################################################### |
| 379 | |
| 380 | fossil test-th-eval "expr ~0" |
| 381 | test th1-expr-16 {$RESULT eq {-1}} |
| 382 | |
| 383 | ############################################################################### |
| 384 | |
| 385 | fossil test-th-eval "expr ~+0" |
| 386 | test th1-expr-17 {$RESULT eq {-1}} |
| 387 | |
| 388 | ############################################################################### |
| 389 | |
| 390 | fossil test-th-eval "expr ~-0" |
| 391 | test th1-expr-18 {$RESULT eq {-1}} |
| 392 | |
| 393 | ############################################################################### |
| 394 | |
| 395 | fossil test-th-eval "expr ~(+0)" |
| 396 | test th1-expr-19 {$RESULT eq {-1}} |
| 397 | |
| 398 | ############################################################################### |
| 399 | |
| 400 | fossil test-th-eval "expr ~(-0)" |
| 401 | test th1-expr-20 {$RESULT eq {-1}} |
| 402 | |
| 403 | ############################################################################### |
| 404 | |
| 405 | fossil test-th-eval "expr ~1" |
| 406 | test th1-expr-21 {$RESULT eq {-2}} |
| 407 | |
| 408 | ############################################################################### |
| 409 | |
| 410 | fossil test-th-eval "expr ~+1" |
| 411 | test th1-expr-22 {$RESULT eq {-2}} |
| 412 | |
| 413 | ############################################################################### |
| 414 | |
| 415 | fossil test-th-eval "expr ~(+1)" |
| 416 | test th1-expr-23 {$RESULT eq {-2}} |
| 417 | |
| 418 | ############################################################################### |
| 419 | |
| 420 | fossil test-th-eval "expr 0+0b11" |
| 421 | test th1-expr-24 {$RESULT eq 3} |
| 422 | |
| 423 | ############################################################################### |
| 424 | |
| 425 | fossil test-th-eval "expr 0+0o15" |
| 426 | test th1-expr-25 {$RESULT eq 13} |
| 427 | |
| 428 | ############################################################################### |
| 429 | |
| 430 | fossil test-th-eval "expr 0+0x15" |
| 431 | test th1-expr-26 {$RESULT eq 21} |
| 432 | |
| 433 | ############################################################################### |
| 434 | |
| 435 | fossil test-th-eval "expr 0+0b2" |
| 436 | test th1-expr-27 {$RESULT eq {TH_ERROR: expected number, got: "0b2"}} |
| 437 | |
| 438 | ############################################################################### |
| 439 | |
| 440 | fossil test-th-eval "expr 0+0o8" |
| 441 | test th1-expr-28 {$RESULT eq {TH_ERROR: expected number, got: "0o8"}} |
| 442 | |
| 443 | ############################################################################### |
| 444 | |
| 445 | fossil test-th-eval "expr 0+0xg" |
| 446 | test th1-expr-29 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0xg"}} |
| 447 | |
| 448 | ############################################################################### |
| 449 | |
| 450 | fossil test-th-eval "expr 0+0b1." |
| 451 | test th1-expr-30 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0b1."}} |
| 452 | |
| 453 | ############################################################################### |
| 454 | |
| 455 | fossil test-th-eval "expr 0+0o1." |
| 456 | test th1-expr-31 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0o1."}} |
| 457 | |
| 458 | ############################################################################### |
| 459 | |
| 460 | fossil test-th-eval "expr 0+0x1." |
| 461 | test th1-expr-32 {$RESULT eq {TH_ERROR: syntax error in expression: "0+0x1."}} |
| 462 | |
| 463 | ############################################################################### |
| 464 | |
| 465 | fossil test-th-eval "expr 0ne5" |
| 466 | test th1-expr-33 {$RESULT eq {1}} |
| 467 | |
| 468 | ############################################################################### |
| 469 | |
| 470 | fossil test-th-eval "expr 0b1+5" |
| 471 | test th1-expr-34 {$RESULT eq {6}} |
| 472 | |
| 473 | |
| 474 | ############################################################################### |
| 475 | |
| 476 | fossil test-th-eval "expr 0+0b" |
| 477 | test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} |
| 478 | |
| 479 | |
| 480 |
+4
-9
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -84,12 +84,12 @@ | ||
| 84 | 84 | #### The directories where the OpenSSL include and library files are located. |
| 85 | 85 | # The recommended usage here is to use the Sysinternals junction tool |
| 86 | 86 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 87 | 87 | # Fossil source code directory and the target OpenSSL source directory. |
| 88 | 88 | # |
| 89 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1f/include | |
| 90 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1f | |
| 89 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1g/include | |
| 90 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1g | |
| 91 | 91 | |
| 92 | 92 | #### Either the directory where the Tcl library is installed or the Tcl |
| 93 | 93 | # source code directory resides (depending on the value of the macro |
| 94 | 94 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 95 | 95 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -669,15 +669,11 @@ | ||
| 669 | 669 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 670 | 670 | |
| 671 | 671 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 672 | 672 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 673 | 673 | |
| 674 | -EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/cson_amalgamation.o | |
| 675 | - | |
| 676 | -ifdef FOSSIL_ENABLE_TCL | |
| 677 | -EXTRAOBJ += $(OBJDIR)/th_tcl.o | |
| 678 | -endif | |
| 674 | +EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o | |
| 679 | 675 | |
| 680 | 676 | zlib: |
| 681 | 677 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 682 | 678 | |
| 683 | 679 | clean-zlib: |
| @@ -1745,9 +1741,8 @@ | ||
| 1745 | 1741 | $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1746 | 1742 | |
| 1747 | 1743 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1748 | 1744 | $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1749 | 1745 | |
| 1750 | -ifdef FOSSIL_ENABLE_TCL | |
| 1751 | 1746 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1752 | 1747 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1753 | -endif | |
| 1748 | + | |
| 1754 | 1749 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -84,12 +84,12 @@ | |
| 84 | #### The directories where the OpenSSL include and library files are located. |
| 85 | # The recommended usage here is to use the Sysinternals junction tool |
| 86 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 87 | # Fossil source code directory and the target OpenSSL source directory. |
| 88 | # |
| 89 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1f/include |
| 90 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1f |
| 91 | |
| 92 | #### Either the directory where the Tcl library is installed or the Tcl |
| 93 | # source code directory resides (depending on the value of the macro |
| 94 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 95 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -669,15 +669,11 @@ | |
| 669 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 670 | |
| 671 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 672 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 673 | |
| 674 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/cson_amalgamation.o |
| 675 | |
| 676 | ifdef FOSSIL_ENABLE_TCL |
| 677 | EXTRAOBJ += $(OBJDIR)/th_tcl.o |
| 678 | endif |
| 679 | |
| 680 | zlib: |
| 681 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 682 | |
| 683 | clean-zlib: |
| @@ -1745,9 +1741,8 @@ | |
| 1745 | $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1746 | |
| 1747 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1748 | $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1749 | |
| 1750 | ifdef FOSSIL_ENABLE_TCL |
| 1751 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1752 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1753 | endif |
| 1754 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -84,12 +84,12 @@ | |
| 84 | #### The directories where the OpenSSL include and library files are located. |
| 85 | # The recommended usage here is to use the Sysinternals junction tool |
| 86 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 87 | # Fossil source code directory and the target OpenSSL source directory. |
| 88 | # |
| 89 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1g/include |
| 90 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1g |
| 91 | |
| 92 | #### Either the directory where the Tcl library is installed or the Tcl |
| 93 | # source code directory resides (depending on the value of the macro |
| 94 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 95 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -669,15 +669,11 @@ | |
| 669 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 670 | |
| 671 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 672 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 673 | |
| 674 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o |
| 675 | |
| 676 | zlib: |
| 677 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 678 | |
| 679 | clean-zlib: |
| @@ -1745,9 +1741,8 @@ | |
| 1741 | $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1742 | |
| 1743 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1744 | $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1745 | |
| 1746 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1747 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1748 | |
| 1749 |
+3
-9
| --- win/Makefile.mingw.mistachkin | ||
| +++ win/Makefile.mingw.mistachkin | ||
| @@ -84,12 +84,12 @@ | ||
| 84 | 84 | #### The directories where the OpenSSL include and library files are located. |
| 85 | 85 | # The recommended usage here is to use the Sysinternals junction tool |
| 86 | 86 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 87 | 87 | # Fossil source code directory and the target OpenSSL source directory. |
| 88 | 88 | # |
| 89 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1f/include | |
| 90 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1f | |
| 89 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1g/include | |
| 90 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1g | |
| 91 | 91 | |
| 92 | 92 | #### Either the directory where the Tcl library is installed or the Tcl |
| 93 | 93 | # source code directory resides (depending on the value of the macro |
| 94 | 94 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 95 | 95 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -669,15 +669,11 @@ | ||
| 669 | 669 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 670 | 670 | |
| 671 | 671 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 672 | 672 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 673 | 673 | |
| 674 | -EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/cson_amalgamation.o | |
| 675 | - | |
| 676 | -ifdef FOSSIL_ENABLE_TCL | |
| 677 | -EXTRAOBJ += $(OBJDIR)/th_tcl.o | |
| 678 | -endif | |
| 674 | +EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o | |
| 679 | 675 | |
| 680 | 676 | zlib: |
| 681 | 677 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 682 | 678 | |
| 683 | 679 | clean-zlib: |
| @@ -1745,9 +1741,7 @@ | ||
| 1745 | 1741 | $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1746 | 1742 | |
| 1747 | 1743 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1748 | 1744 | $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1749 | 1745 | |
| 1750 | -ifdef FOSSIL_ENABLE_TCL | |
| 1751 | 1746 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1752 | 1747 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1753 | -endif | |
| 1754 | 1748 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -84,12 +84,12 @@ | |
| 84 | #### The directories where the OpenSSL include and library files are located. |
| 85 | # The recommended usage here is to use the Sysinternals junction tool |
| 86 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 87 | # Fossil source code directory and the target OpenSSL source directory. |
| 88 | # |
| 89 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1f/include |
| 90 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1f |
| 91 | |
| 92 | #### Either the directory where the Tcl library is installed or the Tcl |
| 93 | # source code directory resides (depending on the value of the macro |
| 94 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 95 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -669,15 +669,11 @@ | |
| 669 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 670 | |
| 671 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 672 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 673 | |
| 674 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/cson_amalgamation.o |
| 675 | |
| 676 | ifdef FOSSIL_ENABLE_TCL |
| 677 | EXTRAOBJ += $(OBJDIR)/th_tcl.o |
| 678 | endif |
| 679 | |
| 680 | zlib: |
| 681 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 682 | |
| 683 | clean-zlib: |
| @@ -1745,9 +1741,7 @@ | |
| 1745 | $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1746 | |
| 1747 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1748 | $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1749 | |
| 1750 | ifdef FOSSIL_ENABLE_TCL |
| 1751 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1752 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1753 | endif |
| 1754 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -84,12 +84,12 @@ | |
| 84 | #### The directories where the OpenSSL include and library files are located. |
| 85 | # The recommended usage here is to use the Sysinternals junction tool |
| 86 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 87 | # Fossil source code directory and the target OpenSSL source directory. |
| 88 | # |
| 89 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1g/include |
| 90 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1g |
| 91 | |
| 92 | #### Either the directory where the Tcl library is installed or the Tcl |
| 93 | # source code directory resides (depending on the value of the macro |
| 94 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 95 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -669,15 +669,11 @@ | |
| 669 | $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) |
| 670 | |
| 671 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 672 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 673 | |
| 674 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/th_tcl.o $(OBJDIR)/cson_amalgamation.o |
| 675 | |
| 676 | zlib: |
| 677 | $(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a |
| 678 | |
| 679 | clean-zlib: |
| @@ -1745,9 +1741,7 @@ | |
| 1741 | $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1742 | |
| 1743 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1744 | $(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1745 | |
| 1746 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1747 | $(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1748 |
+4
-10
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -26,12 +26,12 @@ | ||
| 26 | 26 | |
| 27 | 27 | # Uncomment to enable Tcl support |
| 28 | 28 | # FOSSIL_ENABLE_TCL = 1 |
| 29 | 29 | |
| 30 | 30 | !ifdef FOSSIL_ENABLE_SSL |
| 31 | -SSLINCDIR = $(B)\compat\openssl-1.0.1f\include | |
| 32 | -SSLLIBDIR = $(B)\compat\openssl-1.0.1f\out32 | |
| 31 | +SSLINCDIR = $(B)\compat\openssl-1.0.1g\include | |
| 32 | +SSLLIBDIR = $(B)\compat\openssl-1.0.1g\out32 | |
| 33 | 33 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 34 | 34 | !endif |
| 35 | 35 | |
| 36 | 36 | !ifdef FOSSIL_ENABLE_TCL |
| 37 | 37 | TCLDIR = $(B)\compat\tcl-8.6 |
| @@ -310,10 +310,11 @@ | ||
| 310 | 310 | $(OX)\tag$O \ |
| 311 | 311 | $(OX)\tar$O \ |
| 312 | 312 | $(OX)\th$O \ |
| 313 | 313 | $(OX)\th_lang$O \ |
| 314 | 314 | $(OX)\th_main$O \ |
| 315 | + $(OX)\th_tcl$O \ | |
| 315 | 316 | $(OX)\timeline$O \ |
| 316 | 317 | $(OX)\tkt$O \ |
| 317 | 318 | $(OX)\tktsetup$O \ |
| 318 | 319 | $(OX)\undo$O \ |
| 319 | 320 | $(OX)\unicode$O \ |
| @@ -332,13 +333,10 @@ | ||
| 332 | 333 | $(OX)\xfer$O \ |
| 333 | 334 | $(OX)\xfersetup$O \ |
| 334 | 335 | $(OX)\zip$O \ |
| 335 | 336 | $(OX)\fossil.res |
| 336 | 337 | |
| 337 | -!ifdef FOSSIL_ENABLE_TCL | |
| 338 | -OBJ = $(OBJ) $(OX)\th_tcl$O | |
| 339 | -!endif | |
| 340 | 338 | |
| 341 | 339 | APPNAME = $(OX)\fossil$(E) |
| 342 | 340 | PDBNAME = $(OX)\fossil$(P) |
| 343 | 341 | |
| 344 | 342 | all: $(OX) $(APPNAME) |
| @@ -444,10 +442,11 @@ | ||
| 444 | 442 | echo $(OX)\tag.obj >> $@ |
| 445 | 443 | echo $(OX)\tar.obj >> $@ |
| 446 | 444 | echo $(OX)\th.obj >> $@ |
| 447 | 445 | echo $(OX)\th_lang.obj >> $@ |
| 448 | 446 | echo $(OX)\th_main.obj >> $@ |
| 447 | + echo $(OX)\th_tcl.obj >> $@ | |
| 449 | 448 | echo $(OX)\timeline.obj >> $@ |
| 450 | 449 | echo $(OX)\tkt.obj >> $@ |
| 451 | 450 | echo $(OX)\tktsetup.obj >> $@ |
| 452 | 451 | echo $(OX)\undo.obj >> $@ |
| 453 | 452 | echo $(OX)\unicode.obj >> $@ |
| @@ -464,13 +463,10 @@ | ||
| 464 | 463 | echo $(OX)\winhttp.obj >> $@ |
| 465 | 464 | echo $(OX)\wysiwyg.obj >> $@ |
| 466 | 465 | echo $(OX)\xfer.obj >> $@ |
| 467 | 466 | echo $(OX)\xfersetup.obj >> $@ |
| 468 | 467 | echo $(OX)\zip.obj >> $@ |
| 469 | -!ifdef FOSSIL_ENABLE_TCL | |
| 470 | - echo $(OX)\th_tcl.obj >> $@ | |
| 471 | -!endif | |
| 472 | 468 | echo $(LIBS) >> $@ |
| 473 | 469 | |
| 474 | 470 | $(OX): |
| 475 | 471 | @-mkdir $@ |
| 476 | 472 | |
| @@ -496,14 +492,12 @@ | ||
| 496 | 492 | $(TCC) /Fo$@ -c $** |
| 497 | 493 | |
| 498 | 494 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 499 | 495 | $(TCC) /Fo$@ -c $** |
| 500 | 496 | |
| 501 | -!ifdef FOSSIL_ENABLE_TCL | |
| 502 | 497 | $(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c |
| 503 | 498 | $(TCC) /Fo$@ -c $** |
| 504 | -!endif | |
| 505 | 499 | |
| 506 | 500 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 507 | 501 | $** > $@ |
| 508 | 502 | $(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c |
| 509 | 503 | $(TCC) /Fo$@ /c $** |
| 510 | 504 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -26,12 +26,12 @@ | |
| 26 | |
| 27 | # Uncomment to enable Tcl support |
| 28 | # FOSSIL_ENABLE_TCL = 1 |
| 29 | |
| 30 | !ifdef FOSSIL_ENABLE_SSL |
| 31 | SSLINCDIR = $(B)\compat\openssl-1.0.1f\include |
| 32 | SSLLIBDIR = $(B)\compat\openssl-1.0.1f\out32 |
| 33 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 34 | !endif |
| 35 | |
| 36 | !ifdef FOSSIL_ENABLE_TCL |
| 37 | TCLDIR = $(B)\compat\tcl-8.6 |
| @@ -310,10 +310,11 @@ | |
| 310 | $(OX)\tag$O \ |
| 311 | $(OX)\tar$O \ |
| 312 | $(OX)\th$O \ |
| 313 | $(OX)\th_lang$O \ |
| 314 | $(OX)\th_main$O \ |
| 315 | $(OX)\timeline$O \ |
| 316 | $(OX)\tkt$O \ |
| 317 | $(OX)\tktsetup$O \ |
| 318 | $(OX)\undo$O \ |
| 319 | $(OX)\unicode$O \ |
| @@ -332,13 +333,10 @@ | |
| 332 | $(OX)\xfer$O \ |
| 333 | $(OX)\xfersetup$O \ |
| 334 | $(OX)\zip$O \ |
| 335 | $(OX)\fossil.res |
| 336 | |
| 337 | !ifdef FOSSIL_ENABLE_TCL |
| 338 | OBJ = $(OBJ) $(OX)\th_tcl$O |
| 339 | !endif |
| 340 | |
| 341 | APPNAME = $(OX)\fossil$(E) |
| 342 | PDBNAME = $(OX)\fossil$(P) |
| 343 | |
| 344 | all: $(OX) $(APPNAME) |
| @@ -444,10 +442,11 @@ | |
| 444 | echo $(OX)\tag.obj >> $@ |
| 445 | echo $(OX)\tar.obj >> $@ |
| 446 | echo $(OX)\th.obj >> $@ |
| 447 | echo $(OX)\th_lang.obj >> $@ |
| 448 | echo $(OX)\th_main.obj >> $@ |
| 449 | echo $(OX)\timeline.obj >> $@ |
| 450 | echo $(OX)\tkt.obj >> $@ |
| 451 | echo $(OX)\tktsetup.obj >> $@ |
| 452 | echo $(OX)\undo.obj >> $@ |
| 453 | echo $(OX)\unicode.obj >> $@ |
| @@ -464,13 +463,10 @@ | |
| 464 | echo $(OX)\winhttp.obj >> $@ |
| 465 | echo $(OX)\wysiwyg.obj >> $@ |
| 466 | echo $(OX)\xfer.obj >> $@ |
| 467 | echo $(OX)\xfersetup.obj >> $@ |
| 468 | echo $(OX)\zip.obj >> $@ |
| 469 | !ifdef FOSSIL_ENABLE_TCL |
| 470 | echo $(OX)\th_tcl.obj >> $@ |
| 471 | !endif |
| 472 | echo $(LIBS) >> $@ |
| 473 | |
| 474 | $(OX): |
| 475 | @-mkdir $@ |
| 476 | |
| @@ -496,14 +492,12 @@ | |
| 496 | $(TCC) /Fo$@ -c $** |
| 497 | |
| 498 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 499 | $(TCC) /Fo$@ -c $** |
| 500 | |
| 501 | !ifdef FOSSIL_ENABLE_TCL |
| 502 | $(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c |
| 503 | $(TCC) /Fo$@ -c $** |
| 504 | !endif |
| 505 | |
| 506 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 507 | $** > $@ |
| 508 | $(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c |
| 509 | $(TCC) /Fo$@ /c $** |
| 510 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -26,12 +26,12 @@ | |
| 26 | |
| 27 | # Uncomment to enable Tcl support |
| 28 | # FOSSIL_ENABLE_TCL = 1 |
| 29 | |
| 30 | !ifdef FOSSIL_ENABLE_SSL |
| 31 | SSLINCDIR = $(B)\compat\openssl-1.0.1g\include |
| 32 | SSLLIBDIR = $(B)\compat\openssl-1.0.1g\out32 |
| 33 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 34 | !endif |
| 35 | |
| 36 | !ifdef FOSSIL_ENABLE_TCL |
| 37 | TCLDIR = $(B)\compat\tcl-8.6 |
| @@ -310,10 +310,11 @@ | |
| 310 | $(OX)\tag$O \ |
| 311 | $(OX)\tar$O \ |
| 312 | $(OX)\th$O \ |
| 313 | $(OX)\th_lang$O \ |
| 314 | $(OX)\th_main$O \ |
| 315 | $(OX)\th_tcl$O \ |
| 316 | $(OX)\timeline$O \ |
| 317 | $(OX)\tkt$O \ |
| 318 | $(OX)\tktsetup$O \ |
| 319 | $(OX)\undo$O \ |
| 320 | $(OX)\unicode$O \ |
| @@ -332,13 +333,10 @@ | |
| 333 | $(OX)\xfer$O \ |
| 334 | $(OX)\xfersetup$O \ |
| 335 | $(OX)\zip$O \ |
| 336 | $(OX)\fossil.res |
| 337 | |
| 338 | |
| 339 | APPNAME = $(OX)\fossil$(E) |
| 340 | PDBNAME = $(OX)\fossil$(P) |
| 341 | |
| 342 | all: $(OX) $(APPNAME) |
| @@ -444,10 +442,11 @@ | |
| 442 | echo $(OX)\tag.obj >> $@ |
| 443 | echo $(OX)\tar.obj >> $@ |
| 444 | echo $(OX)\th.obj >> $@ |
| 445 | echo $(OX)\th_lang.obj >> $@ |
| 446 | echo $(OX)\th_main.obj >> $@ |
| 447 | echo $(OX)\th_tcl.obj >> $@ |
| 448 | echo $(OX)\timeline.obj >> $@ |
| 449 | echo $(OX)\tkt.obj >> $@ |
| 450 | echo $(OX)\tktsetup.obj >> $@ |
| 451 | echo $(OX)\undo.obj >> $@ |
| 452 | echo $(OX)\unicode.obj >> $@ |
| @@ -464,13 +463,10 @@ | |
| 463 | echo $(OX)\winhttp.obj >> $@ |
| 464 | echo $(OX)\wysiwyg.obj >> $@ |
| 465 | echo $(OX)\xfer.obj >> $@ |
| 466 | echo $(OX)\xfersetup.obj >> $@ |
| 467 | echo $(OX)\zip.obj >> $@ |
| 468 | echo $(LIBS) >> $@ |
| 469 | |
| 470 | $(OX): |
| 471 | @-mkdir $@ |
| 472 | |
| @@ -496,14 +492,12 @@ | |
| 492 | $(TCC) /Fo$@ -c $** |
| 493 | |
| 494 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 495 | $(TCC) /Fo$@ -c $** |
| 496 | |
| 497 | $(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c |
| 498 | $(TCC) /Fo$@ -c $** |
| 499 | |
| 500 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 501 | $** > $@ |
| 502 | $(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c |
| 503 | $(TCC) /Fo$@ /c $** |
| 504 |
+3
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -14,12 +14,15 @@ | ||
| 14 | 14 | * Add option --empty to the "[/help?cmd=open | fossil open]" command. |
| 15 | 15 | * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter. |
| 16 | 16 | * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to |
| 17 | 17 | [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame], |
| 18 | 18 | [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff]. |
| 19 | + * Add --strip-trailing-cr option to [/help?cmd=diff|fossil (g)diff] and | |
| 20 | + [/help?cmd=stash|fossil stash diff]. | |
| 19 | 21 | * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff |
| 20 | 22 | and /vdiff UI pages. |
| 23 | + * Enhanced [/reports?view=byweekday|/reports] with a "byweekday" view. | |
| 21 | 24 | |
| 22 | 25 | <h2>Changes For Version 1.28 (2014-01-27)</h2> |
| 23 | 26 | * Enhance [/help?cmd=/reports | /reports] to support event type filtering. |
| 24 | 27 | * When cloning a repository, the user name passed via the URL (if any) |
| 25 | 28 | is now used as the default local admin user's name. |
| 26 | 29 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -14,12 +14,15 @@ | |
| 14 | * Add option --empty to the "[/help?cmd=open | fossil open]" command. |
| 15 | * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter. |
| 16 | * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to |
| 17 | [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame], |
| 18 | [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff]. |
| 19 | * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff |
| 20 | and /vdiff UI pages. |
| 21 | |
| 22 | <h2>Changes For Version 1.28 (2014-01-27)</h2> |
| 23 | * Enhance [/help?cmd=/reports | /reports] to support event type filtering. |
| 24 | * When cloning a repository, the user name passed via the URL (if any) |
| 25 | is now used as the default local admin user's name. |
| 26 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -14,12 +14,15 @@ | |
| 14 | * Add option --empty to the "[/help?cmd=open | fossil open]" command. |
| 15 | * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter. |
| 16 | * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to |
| 17 | [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame], |
| 18 | [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff]. |
| 19 | * Add --strip-trailing-cr option to [/help?cmd=diff|fossil (g)diff] and |
| 20 | [/help?cmd=stash|fossil stash diff]. |
| 21 | * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff |
| 22 | and /vdiff UI pages. |
| 23 | * Enhanced [/reports?view=byweekday|/reports] with a "byweekday" view. |
| 24 | |
| 25 | <h2>Changes For Version 1.28 (2014-01-27)</h2> |
| 26 | * Enhance [/help?cmd=/reports | /reports] to support event type filtering. |
| 27 | * When cloning a repository, the user name passed via the URL (if any) |
| 28 | is now used as the default local admin user's name. |
| 29 |
+23
| --- www/quickstart.wiki | ||
| +++ www/quickstart.wiki | ||
| @@ -119,10 +119,24 @@ | ||
| 119 | 119 | |
| 120 | 120 | <p>Note that Fossil allows you to make multiple check-outs in |
| 121 | 121 | separate directories from the same repository. This enables you, |
| 122 | 122 | for example, to do builds from multiple branches or versions at |
| 123 | 123 | the same time without having to generate extra clones.</p> |
| 124 | + | |
| 125 | + <p>To switch a checkout between different versions and branches, | |
| 126 | + use:</p> | |
| 127 | + | |
| 128 | + <blockquote> | |
| 129 | + <b>[/help/update | fossil update]</b><br> | |
| 130 | + <b>[/help/checkout | fossil checkout]</b><br> | |
| 131 | + </blockquote> | |
| 132 | + | |
| 133 | + <p>[/help/update | update] honors the "autosync" option and | |
| 134 | + does a "soft" switch, merging any local changes into the target | |
| 135 | + version, whereas [/help/checkout | checkout] does not | |
| 136 | + automatically sync and does a "hard" switch, overwriting local | |
| 137 | + changes if told to do so.</p> | |
| 124 | 138 | |
| 125 | 139 | <h2>Configuring Your Local Repository</h2> |
| 126 | 140 | |
| 127 | 141 | <p>When you create a new repository, either by cloning an existing |
| 128 | 142 | project or create a new project of your own, you usually want to do some |
| @@ -227,10 +241,19 @@ | ||
| 227 | 241 | when you run [/help/update|update] and a [/help/push|push] happens |
| 228 | 242 | automatically after you [/help/commit|commit]. So in normal practice, |
| 229 | 243 | the push, pull, and sync commands are rarely used. But it is important |
| 230 | 244 | to know about them, all the same.</p> |
| 231 | 245 | |
| 246 | + <blockquote> | |
| 247 | + <b>[/help/checkout | fossil checkout]</b> <i>VERSION</i> | |
| 248 | + </blockquote> | |
| 249 | + | |
| 250 | + <p>Is similar to update except that it does not honor the autosync | |
| 251 | + setting, nor does it merge in local changes - it prefers to overwrite | |
| 252 | + them and fails if local changes exist unless the <tt>--force</tt> | |
| 253 | + flag is used.</p> | |
| 254 | + | |
| 232 | 255 | <h2>Branching And Merging</h2> |
| 233 | 256 | |
| 234 | 257 | <p>Use the --branch option to the [/help/commit | commit] command |
| 235 | 258 | to start a new branch. Note that in Fossil, branches are normally |
| 236 | 259 | created when you commit, not before you start editing. You can |
| 237 | 260 |
| --- www/quickstart.wiki | |
| +++ www/quickstart.wiki | |
| @@ -119,10 +119,24 @@ | |
| 119 | |
| 120 | <p>Note that Fossil allows you to make multiple check-outs in |
| 121 | separate directories from the same repository. This enables you, |
| 122 | for example, to do builds from multiple branches or versions at |
| 123 | the same time without having to generate extra clones.</p> |
| 124 | |
| 125 | <h2>Configuring Your Local Repository</h2> |
| 126 | |
| 127 | <p>When you create a new repository, either by cloning an existing |
| 128 | project or create a new project of your own, you usually want to do some |
| @@ -227,10 +241,19 @@ | |
| 227 | when you run [/help/update|update] and a [/help/push|push] happens |
| 228 | automatically after you [/help/commit|commit]. So in normal practice, |
| 229 | the push, pull, and sync commands are rarely used. But it is important |
| 230 | to know about them, all the same.</p> |
| 231 | |
| 232 | <h2>Branching And Merging</h2> |
| 233 | |
| 234 | <p>Use the --branch option to the [/help/commit | commit] command |
| 235 | to start a new branch. Note that in Fossil, branches are normally |
| 236 | created when you commit, not before you start editing. You can |
| 237 |
| --- www/quickstart.wiki | |
| +++ www/quickstart.wiki | |
| @@ -119,10 +119,24 @@ | |
| 119 | |
| 120 | <p>Note that Fossil allows you to make multiple check-outs in |
| 121 | separate directories from the same repository. This enables you, |
| 122 | for example, to do builds from multiple branches or versions at |
| 123 | the same time without having to generate extra clones.</p> |
| 124 | |
| 125 | <p>To switch a checkout between different versions and branches, |
| 126 | use:</p> |
| 127 | |
| 128 | <blockquote> |
| 129 | <b>[/help/update | fossil update]</b><br> |
| 130 | <b>[/help/checkout | fossil checkout]</b><br> |
| 131 | </blockquote> |
| 132 | |
| 133 | <p>[/help/update | update] honors the "autosync" option and |
| 134 | does a "soft" switch, merging any local changes into the target |
| 135 | version, whereas [/help/checkout | checkout] does not |
| 136 | automatically sync and does a "hard" switch, overwriting local |
| 137 | changes if told to do so.</p> |
| 138 | |
| 139 | <h2>Configuring Your Local Repository</h2> |
| 140 | |
| 141 | <p>When you create a new repository, either by cloning an existing |
| 142 | project or create a new project of your own, you usually want to do some |
| @@ -227,10 +241,19 @@ | |
| 241 | when you run [/help/update|update] and a [/help/push|push] happens |
| 242 | automatically after you [/help/commit|commit]. So in normal practice, |
| 243 | the push, pull, and sync commands are rarely used. But it is important |
| 244 | to know about them, all the same.</p> |
| 245 | |
| 246 | <blockquote> |
| 247 | <b>[/help/checkout | fossil checkout]</b> <i>VERSION</i> |
| 248 | </blockquote> |
| 249 | |
| 250 | <p>Is similar to update except that it does not honor the autosync |
| 251 | setting, nor does it merge in local changes - it prefers to overwrite |
| 252 | them and fails if local changes exist unless the <tt>--force</tt> |
| 253 | flag is used.</p> |
| 254 | |
| 255 | <h2>Branching And Merging</h2> |
| 256 | |
| 257 | <p>Use the --branch option to the [/help/commit | commit] command |
| 258 | to start a new branch. Note that in Fossil, branches are normally |
| 259 | created when you commit, not before you start editing. You can |
| 260 |