Fossil SCM

merge trunk. Add support for extended UNC paths as well.

jan.nijtmans 2014-04-14 13:03 win32-longpath merge
Commit 9d4a73cb408e66e39d5c3ae6f973ec225b447ea6
--- Makefile.Cygwin.in
+++ Makefile.Cygwin.in
@@ -36,17 +36,16 @@
3636
# care about testing the end result, this can be blank.
3737
#
3838
TCLSH = tclsh
3939
4040
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
4242
INSTALLDIR =$(DESTDIR)@prefix@/bin
4343
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
4847
4948
include $(SRCDIR)/main.mk
5049
5150
distclean: clean
5251
rm -f autoconfig.h config.log Makefile
5352
--- 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
--- Makefile.in
+++ Makefile.in
@@ -40,13 +40,10 @@
4040
4141
LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
4242
TCC += @EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H
4343
INSTALLDIR = $(DESTDIR)@prefix@/bin
4444
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@
4845
4946
include $(SRCDIR)/main.mk
5047
5148
distclean: clean
5249
rm -f autoconfig.h config.log Makefile
5350
--- 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
+5
--- auto.def
+++ auto.def
@@ -248,10 +248,15 @@
248248
if {[string match *mingw* [get-define host]]} {
249249
define-append LIBS -lwsock32
250250
}
251251
}
252252
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
+}
253258
254259
# Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars
255260
if {![cc-check-functions getpassphrase]} {
256261
# Haiku needs this
257262
cc-check-function-in-lib getpass bsd
258263
--- 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 @@
2525
#include "cygsup.h"
2626
2727
/*
2828
** This routine returns the names of files in a working checkout that
2929
** 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.
3131
**
3232
** Return the N-th name. The first name has N==0. When all names have
3333
** been used, return 0.
3434
*/
3535
const char *fossil_reserved_name(int N, int omitRepo){
@@ -461,11 +461,11 @@
461461
**
462462
** Do all necessary "add" and "rm" commands to synchronize the repository
463463
** with the content of the working checkout:
464464
**
465465
** * 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
467467
** if by the "add" command.
468468
**
469469
** * All files in the repository but missing from the checkout (that is,
470470
** all files that show as MISSING with the "status" command) are
471471
** removed as if by the "rm" command.
472472
--- 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 @@
7676
7777
7878
/*
7979
** COMMAND: all
8080
**
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)
8282
**
8383
** The ~/.fossil file records the location of all repositories for a
8484
** user. This command performs certain operations on all repositories
8585
** that can be useful before or after a period of disconnected operation.
8686
**
@@ -99,16 +99,16 @@
9999
** and the --whatif option to carefully review the files to
100100
** be deleted beforehand is highly recommended. The command
101101
** line options supported by the clean command itself, if any
102102
** are present, are passed along verbatim.
103103
**
104
-** extra Shows extra files from all local checkouts. The command
104
+** extras Shows "extra" files from all local checkouts. The command
105105
** line options supported by the extra command itself, if any
106106
** are present, are passed along verbatim.
107107
**
108108
** 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
110110
** sync operations. The -c|--ckout option causes the listed
111111
** local checkouts to be ignored instead.
112112
**
113113
** list | ls Display the location of all repositories. The -c|--ckout
114114
** option causes all local checkouts to be listed instead.
@@ -136,10 +136,11 @@
136136
** when one of the following commands are run against the repository:
137137
** clone, info, pull, push, or sync. Even previously ignored repositories
138138
** are added back to the list of repositories by these commands.
139139
**
140140
** Options:
141
+** --showfile Show the repository or checkout being operated upon.
141142
** --dontstop Continue with other repositories even after an error.
142143
** --dry-run If given, display instead of run actions.
143144
*/
144145
void all_cmd(void){
145146
int n;
@@ -150,10 +151,11 @@
150151
char *zQFilename;
151152
Blob extra;
152153
int useCheckouts = 0;
153154
int quiet = 0;
154155
int dryRunFlag = 0;
156
+ int showFile = find_option("showfile",0,0)!=0;
155157
int stopOnError = find_option("dontstop",0,0)==0;
156158
int rc;
157159
int nToDel = 0;
158160
159161
dryRunFlag = find_option("dry-run","n",0)!=0;
@@ -160,11 +162,11 @@
160162
if( !dryRunFlag ){
161163
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
162164
}
163165
164166
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");
166168
}
167169
n = strlen(g.argv[2]);
168170
db_open_config(1);
169171
blob_zero(&extra);
170172
zCmd = g.argv[2];
@@ -185,12 +187,16 @@
185187
collect_argument_value(&extra, "keep");
186188
collect_argument(&extra, "temp",0);
187189
collect_argument(&extra, "verbose","v");
188190
collect_argument(&extra, "whatif",0);
189191
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
+ }
192198
collect_argument(&extra, "abs-paths",0);
193199
collect_argument_value(&extra, "case-sensitive");
194200
collect_argument(&extra, "dotfiles",0);
195201
collect_argument_value(&extra, "ignore");
196202
collect_argument(&extra, "rel-paths",0);
@@ -254,11 +260,11 @@
254260
}
255261
db_end_transaction(0);
256262
return;
257263
}else{
258264
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");
260266
}
261267
verify_all_options();
262268
zFossil = quoteFilename(g.nameOfExe);
263269
if( useCheckouts ){
264270
db_prepare(&q,
@@ -287,10 +293,13 @@
287293
continue;
288294
}
289295
if( zCmd[0]=='l' ){
290296
fossil_print("%s\n", zFilename);
291297
continue;
298
+ }else if( showFile ){
299
+ fossil_print("%s: %s\n", useCheckouts ? "checkout" : "repository",
300
+ zFilename);
292301
}
293302
zQFilename = quoteFilename(zFilename);
294303
zSyscmd = mprintf("%s %s %s%s",
295304
zFossil, zCmd, zQFilename, blob_str(&extra));
296305
if( !quiet || dryRunFlag ){
297306
--- 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 @@
258258
zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag"
259259
" WHERE tagname GLOB 'tkt-%q*'", zTkt);
260260
if( zTkt==0 ) fossil_redirect_home();
261261
}
262262
zTarget = zTkt;
263
- zTargetType = mprintf("Ticket <a href=\"%s/tktview/%S\">%S</a>",
263
+ zTargetType = mprintf("Ticket <a href=\"%s/tktview/%s\">%S</a>",
264264
g.zTop, zTkt, zTkt);
265265
}
266266
if( zFrom==0 ) zFrom = mprintf("%s/home", g.zTop);
267267
if( P("cancel") ){
268268
cgi_redirect(zFrom);
@@ -463,11 +463,11 @@
463463
if( strcmp(zModAction,"approve")==0 ){
464464
moderation_approve(rid);
465465
}
466466
}
467467
style_header("Attachment Details");
468
- style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
468
+ style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid);
469469
470470
@ <div class="section">Overview</div>
471471
@ <p><table class="label-value">
472472
@ <tr><th>Artifact&nbsp;ID:</th>
473473
@ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
@@ -531,12 +531,12 @@
531531
@ <pre>
532532
@ %h(z)
533533
@ </pre>
534534
}
535535
}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);
538538
}else{
539539
int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
540540
@ <i>(file is %d(sz) bytes of binary data)</i>
541541
}
542542
@ </blockquote>
543543
--- 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&nbsp;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&nbsp;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 @@
8585
8686
for(i=0; zPath[i]; i=j){
8787
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
8888
if( zPath[j] && g.perm.Hyperlink ){
8989
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);
9191
blob_appendf(pOut, "%s%z%#h</a>",
9292
zSep, zLink, j-i, &zPath[i]);
9393
}else{
9494
char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx);
9595
blob_appendf(pOut, "%s%z%#h</a>",
@@ -179,18 +179,15 @@
179179
if( linkTip ){
180180
style_submenu_element("Tip", "Tip", "%s",
181181
url_render(&sURI, "ci", "tip", 0, 0));
182182
}
183183
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>]
188185
@ %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);
190187
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",
192189
zUuid);
193190
}
194191
}else{
195192
@ <h2>The union of all files from all check-ins
196193
@ %s(blob_str(&dirname))</h2>
@@ -490,11 +487,11 @@
490487
}
491488
if( zCI ){
492489
style_submenu_element("All", "All", "%s",
493490
url_render(&sURI, "ci", 0, 0, 0));
494491
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",
496493
zUuid);
497494
}
498495
}
499496
if( linkTrunk ){
500497
style_submenu_element("Trunk", "Trunk", "%s",
@@ -574,11 +571,11 @@
574571
if( zCI ){
575572
@ <h2>%d(nFile) %s(zObjType) of check-in
576573
if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
577574
@ "%h(zCI)"
578575
}
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>
580577
}else{
581578
int n = db_int(0, "SELECT count(*) FROM plink");
582579
@ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins
583580
@ %s(blob_str(&dirname))</h2>
584581
}
@@ -617,11 +614,11 @@
617614
nDir++;
618615
}else if( !showDirOnly ){
619616
const char *zFileClass = fileext_class(p->zName);
620617
char *zLink;
621618
if( zCI ){
622
- zLink = href("%R/artifact/%S",p->zUuid);
619
+ zLink = href("%R/artifact/%s",p->zUuid);
623620
}else{
624621
zLink = href("%R/finfo?name=%T",p->zFullName);
625622
}
626623
@ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a>
627624
}
@@ -875,14 +872,14 @@
875872
zAge[0] = 0;
876873
}
877874
@ <tr>
878875
@ <td>%s(zAge)
879876
@ <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>
881878
@ </tr>
882879
@
883880
}
884881
@ <tr><td colspan=3><hr></tr>
885882
@ </table>
886883
db_finalize(&q);
887884
style_footer();
888885
}
889886
--- 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 @@
874874
char *z;
875875
const char *zType;
876876
int len;
877877
const char *zRequestUri = cgi_parameter("REQUEST_URI",0);
878878
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);
880880
881881
#ifdef FOSSIL_ENABLE_JSON
882882
json_main_bootstrap();
883883
#endif
884884
g.isHTTP = 1;
885885
--- 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 @@
179179
** --sha1sum Verify file status using SHA1 hashing rather
180180
** than relying on file mtimes.
181181
** --header Identify the repository if there are changes
182182
** -v|--verbose Say "(none)" if there are no changes
183183
**
184
-** See also: extra, ls, status
184
+** See also: extras, ls, status
185185
*/
186186
void changes_cmd(void){
187187
Blob report;
188188
int vid;
189189
int useSha1sum = find_option("sha1sum", 0, 0)!=0;
@@ -223,11 +223,11 @@
223223
** --rel-paths Display pathnames relative to the current working
224224
** directory.
225225
** --sha1sum Verify file status using SHA1 hashing rather
226226
** than relying on file mtimes.
227227
**
228
-** See also: changes, extra, ls
228
+** See also: changes, extras, ls
229229
*/
230230
void status_cmd(void){
231231
int vid;
232232
db_must_be_within_tree();
233233
/* 012345678901234 */
@@ -255,11 +255,11 @@
255255
**
256256
** Options:
257257
** --age Show when each file was committed
258258
** -v|--verbose Provide extra information about each file.
259259
**
260
-** See also: changes, extra, status
260
+** See also: changes, extras, status
261261
*/
262262
void ls_cmd(void){
263263
int vid;
264264
Stmt q;
265265
int verboseFlag;
@@ -433,20 +433,22 @@
433433
**
434434
** Options:
435435
** --abs-paths Display absolute pathnames.
436436
** --case-sensitive <BOOL> override case-sensitive setting
437437
** --dotfiles include files beginning with a dot (".")
438
+** --header Identify the repository if there are extras
438439
** --ignore <CSG> ignore files matching patterns from the argument
439440
** --rel-paths Display pathnames relative to the current working
440441
** directory.
441442
**
442443
** See also: changes, clean, status
443444
*/
444
-void extra_cmd(void){
445
+void extras_cmd(void){
445446
Stmt q;
446447
const char *zIgnoreFlag = find_option("ignore",0,1);
447448
unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
449
+ int showHdr = find_option("header",0,0)!=0;
448450
int cwdRelative = 0;
449451
Glob *pIgnore;
450452
Blob rewrittenPathname;
451453
const char *zPathname, *zDisplayName;
452454
@@ -477,10 +479,15 @@
477479
zDisplayName = blob_str(&rewrittenPathname);
478480
if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
479481
zDisplayName += 2; /* no unnecessary ./ prefix */
480482
}
481483
}
484
+ if( showHdr ){
485
+ showHdr = 0;
486
+ fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
487
+ g.zLocalRoot);
488
+ }
482489
fossil_print("%s\n", zDisplayName);
483490
}
484491
blob_reset(&rewrittenPathname);
485492
db_finalize(&q);
486493
}
@@ -536,11 +543,11 @@
536543
** list of glob patterns.
537544
** -n|--dry-run If given, display instead of run actions.
538545
** --temp Remove only Fossil-generated temporary files.
539546
** -v|--verbose Show all files as they are removed.
540547
**
541
-** See also: addremove, extra, status
548
+** See also: addremove, extras, status
542549
*/
543550
void clean_cmd(void){
544551
int allFileFlag, allDirFlag, dryRunFlag, verboseFlag;
545552
int emptyDirsFlag, dirsOnlyFlag;
546553
unsigned scanFlags = 0;
@@ -1301,21 +1308,25 @@
13011308
char *zOrig = file_newname(zFilename, "original", 1);
13021309
FILE *f;
13031310
blob_write_to_file(p, zOrig);
13041311
fossil_free(zOrig);
13051312
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
+ }
13171328
return 1;
13181329
}else if( cReply!='y' && cReply!='Y' ){
13191330
fossil_fatal("Abandoning commit due to %s in %s",
13201331
zWarning, blob_str(&fname));
13211332
}
@@ -1408,11 +1419,11 @@
14081419
** --private do not sync changes and their descendants
14091420
** --sha1sum verify file status using SHA1 hashing rather
14101421
** than relying on file mtimes
14111422
** --tag TAG-NAME assign given tag TAG-NAME to the checkin
14121423
**
1413
-** See also: branch, changes, checkout, extra, sync
1424
+** See also: branch, changes, checkout, extras, sync
14141425
*/
14151426
void commit_cmd(void){
14161427
int hasChanges; /* True if unsaved changes exist */
14171428
int vid; /* blob-id of parent version */
14181429
int nrid; /* blob-id of a modified file */
14191430
--- 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 @@
136136
if( file_size(g.argv[3])>0 ){
137137
fossil_fatal("file already exists: %s", g.argv[3]);
138138
}
139139
140140
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]);
144144
db_close(1);
145145
db_open_repository(g.argv[3]);
146146
db_record_repository_filename(g.argv[3]);
147147
url_remember();
148148
if( !bPrivate ) delete_private_content();
@@ -211,11 +211,11 @@
211211
void remember_or_get_http_auth(
212212
const char *zHttpAuth, /* Credentials in the form "user:password" */
213213
int fRemember, /* True to remember credentials for later reuse */
214214
const char *zUrl /* URL for which these credentials apply */
215215
){
216
- char *zKey = mprintf("http-auth:%s", g.urlCanonical);
216
+ char *zKey = mprintf("http-auth:%s", g.url.canonical);
217217
if( zHttpAuth && zHttpAuth[0] ){
218218
g.zHttpAuth = mprintf("%s", zHttpAuth);
219219
}
220220
if( fRemember ){
221221
if( g.zHttpAuth && g.zHttpAuth[0] ){
@@ -233,20 +233,20 @@
233233
234234
/*
235235
** Get the HTTP Authorization preference from db.
236236
*/
237237
char *get_httpauth(void){
238
- char *zKey = mprintf("http-auth:%s", g.urlCanonical);
238
+ char *zKey = mprintf("http-auth:%s", g.url.canonical);
239239
return unobscure(db_get(zKey, 0));
240240
free(zKey);
241241
}
242242
243243
/*
244244
** Set the HTTP Authorization preference in db.
245245
*/
246246
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);
248248
db_set(zKey, obscure(zHttpAuth), 0);
249249
free(zKey);
250250
}
251251
252252
/*
253253
--- 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
--- src/comformat.c
+++ src/comformat.c
@@ -36,10 +36,11 @@
3636
int doIndent = 0;
3737
char *zBuf;
3838
char zBuffer[400];
3939
int lineCnt = 0;
4040
41
+ if( zText==0 ) zText = "(NULL)";
4142
if( tlen<=0 ){
4243
tlen = strlen(zText);
4344
}
4445
if( tlen >= (sizeof(zBuffer)) ){
4546
zBuf = fossil_malloc(tlen+1);
4647
--- 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 @@
924924
mask = configure_name_to_mask(g.argv[3], 1);
925925
if( g.argc==5 ){
926926
zServer = g.argv[4];
927927
}
928928
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");
930930
user_select();
931931
url_enable_proxy("via proxy: ");
932932
if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT;
933933
if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
934934
if( strncmp(zMethod, "push", n)==0 ){
935935
--- 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
+1 -5
--- src/db.c
+++ src/db.c
@@ -715,11 +715,11 @@
715715
*/
716716
LOCAL sqlite3 *db_open(const char *zDbName){
717717
int rc;
718718
sqlite3 *db;
719719
720
-#if defined(__CYGWIN__) && !defined(USE_SYSTEM_SQLITE)
720
+#if defined(__CYGWIN__) && USE_SYSTEM_SQLITE+0!=1
721721
zDbName = fossil_utf8_to_filename(zDbName);
722722
#endif
723723
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
724724
rc = sqlite3_open_v2(
725725
zDbName, &db,
@@ -1022,15 +1022,11 @@
10221022
g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
10231023
#endif
10241024
fossil_panic("not a valid repository: %s", zDbName);
10251025
}
10261026
}
1027
-#if defined(__CYGWIN__)
1028
- g.zRepositoryName = fossil_utf8_to_filename(zDbName);
1029
-#else
10301027
g.zRepositoryName = mprintf("%s", zDbName);
1031
-#endif
10321028
db_open_or_attach(g.zRepositoryName, "repository", 0);
10331029
g.repositoryOpen = 1;
10341030
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
10351031
g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
10361032
}
10371033
--- 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 @@
467467
zDelta += lenOut-base;
468468
}
469469
/* Output the final checksum record. */
470470
putInt(checksum(zOut, lenOut), &zDelta);
471471
*(zDelta++) = ';';
472
- free(collide);
472
+ fossil_free(collide);
473473
return zDelta - zOrigDelta;
474474
}
475475
476476
/*
477477
** Return the size (in bytes) of the output from applying
478478
--- 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 @@
3232
#define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
3333
#define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */
3434
#define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
3535
#define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
3636
#define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
37
-#define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
3837
#define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
3938
#define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
4039
#define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
4140
#define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
4241
#define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
4342
#define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
4443
#define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
44
+#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
4545
4646
/*
4747
** These error messages are shared in multiple locations. They are defined
4848
** here for consistency.
4949
*/
@@ -89,11 +89,11 @@
8989
};
9090
9191
/*
9292
** Length of a dline
9393
*/
94
-#define LENGTH(X) ((X)->h & LENGTH_MASK)
94
+#define LENGTH(X) ((X)->n)
9595
9696
/*
9797
** A context for running a raw diff.
9898
**
9999
** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -113,10 +113,11 @@
113113
int nEditAlloc; /* Space allocated for aEdit[] */
114114
DLine *aFrom; /* File on left side of the diff */
115115
int nFrom; /* Number of lines in aFrom[] */
116116
DLine *aTo; /* File on right side of the diff */
117117
int nTo; /* Number of lines in aTo[] */
118
+ int (*same_fn)(const DLine *, const DLine *); /* Function to be used for comparing */
118119
};
119120
120121
/*
121122
** Return an array of DLine objects containing a pointer to the
122123
** start of each line and a hash of that line. The lower
@@ -165,22 +166,36 @@
165166
166167
/* Fill in the array */
167168
for(i=0; i<nLine; i++){
168169
for(j=0; z[j] && z[j]!='\n'; j++){}
169170
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;
171176
s = 0;
172177
if( diffFlags & DIFF_IGNORE_EOLWS ){
173178
while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174179
}
175180
if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
181
+ int numws = 0;
176182
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
+ }
177195
}
178196
a[i].indent = s;
179
- for(h=0, x=s; x<k; x++){
180
- h = h ^ (h<<2) ^ z[x];
181
- }
182197
a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
183198
h2 = h % nLine;
184199
a[i].iNext = a[h2].iHash;
185200
a[h2].iHash = i+1;
186201
z += j+1;
@@ -192,13 +207,31 @@
192207
}
193208
194209
/*
195210
** Return true if two DLine elements are identical.
196211
*/
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;
200233
}
201234
202235
/*
203236
** Return true if the regular expression *pRe matches any of the
204237
** N dlines
@@ -733,13 +766,13 @@
733766
int aLCS[4]; /* Bounds of common middle segment */
734767
static const char zClassRm[] = "<span class=\"diffrm\">";
735768
static const char zClassAdd[] = "<span class=\"diffadd\">";
736769
static const char zClassChng[] = "<span class=\"diffchng\">";
737770
738
- nLeft = pLeft->h & LENGTH_MASK;
771
+ nLeft = pLeft->n;
739772
zLeft = pLeft->z;
740
- nRight = pRight->h & LENGTH_MASK;
773
+ nRight = pRight->n;
741774
zRight = pRight->z;
742775
nShort = nLeft<nRight ? nLeft : nRight;
743776
744777
nPrefix = 0;
745778
while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){
@@ -881,12 +914,12 @@
881914
unsigned char aFirst[256]; /* aFirst[X] = index in zB[] of first char X */
882915
unsigned char aNext[252]; /* aNext[i] = index in zB[] of next zB[i] char */
883916
884917
zA = pA->z;
885918
zB = pB->z;
886
- nA = pA->h & LENGTH_MASK;
887
- nB = pB->h & LENGTH_MASK;
919
+ nA = pA->n;
920
+ nB = pB->n;
888921
while( nA>0 && fossil_isspace(zA[0]) ){ nA--; zA++; }
889922
while( nA>0 && fossil_isspace(zA[nA-1]) ){ nA--; }
890923
while( nB>0 && fossil_isspace(zB[0]) ){ nB--; zB++; }
891924
while( nB>0 && fossil_isspace(zB[nB-1]) ){ nB--; }
892925
if( nA>250 ) nA = 250;
@@ -1350,16 +1383,16 @@
13501383
int iSXb = iS1; /* Best match so far */
13511384
int iSYb = iS2; /* Best match so far */
13521385
13531386
for(i=iS1; i<iE1-mxLength; i++){
13541387
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]) ){
13571390
continue;
13581391
}
13591392
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]) ){
13611394
k++;
13621395
}
13631396
if( k>mxLength ){
13641397
iSXb = i;
13651398
iSYb = j;
@@ -1421,11 +1454,11 @@
14211454
mid = (iE1 + iS1)/2;
14221455
for(i=iS1; i<iE1; i++){
14231456
int limit = 0;
14241457
j = p->aTo[p->aFrom[i].h % p->nTo].iHash;
14251458
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]))
14271460
){
14281461
if( limit++ > 10 ){
14291462
j = 0;
14301463
break;
14311464
}
@@ -1438,19 +1471,19 @@
14381471
iSX = i;
14391472
iSY = j-1;
14401473
pA = &p->aFrom[iSX-1];
14411474
pB = &p->aTo[iSY-1];
14421475
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--){}
14441477
iSX -= k;
14451478
iSY -= k;
14461479
iEX = i+1;
14471480
iEY = j;
14481481
pA = &p->aFrom[iEX];
14491482
pB = &p->aTo[iEY];
14501483
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++){}
14521485
iEX += k;
14531486
iEY += k;
14541487
skew = (iSX-iS1) - (iSY-iS2);
14551488
if( skew<0 ) skew = -skew;
14561489
dist = (iSX+iEX)/2 - mid;
@@ -1587,16 +1620,16 @@
15871620
int mnE, iS, iE1, iE2;
15881621
15891622
/* Carve off the common header and footer */
15901623
iE1 = p->nFrom;
15911624
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]) ){
15931626
iE1--;
15941627
iE2--;
15951628
}
15961629
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++){}
15981631
15991632
/* do the difference */
16001633
if( iS>0 ){
16011634
appendTriple(p, iS, 0, 0);
16021635
}
@@ -1661,11 +1694,11 @@
16611694
16621695
/* Shift insertions toward the beginning of the file */
16631696
while( cpy>0 && del==0 && ins>0 ){
16641697
DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of insert */
16651698
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;
16671700
if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break;
16681701
lnFrom--;
16691702
lnTo--;
16701703
p->aEdit[r]--;
16711704
p->aEdit[r+3]++;
@@ -1674,11 +1707,11 @@
16741707
16751708
/* Shift insertions toward the end of the file */
16761709
while( r+3<p->nEdit && p->aEdit[r+3]>0 && del==0 && ins>0 ){
16771710
DLine *pTop = &p->aTo[lnTo]; /* First line inserted */
16781711
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;
16801713
if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop+1)+LENGTH(pBtm) ) break;
16811714
lnFrom++;
16821715
lnTo++;
16831716
p->aEdit[r]++;
16841717
p->aEdit[r+3]--;
@@ -1687,11 +1720,11 @@
16871720
16881721
/* Shift deletions toward the beginning of the file */
16891722
while( cpy>0 && del>0 && ins==0 ){
16901723
DLine *pTop = &p->aFrom[lnFrom-1]; /* Line before start of delete */
16911724
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;
16931726
if( LENGTH(pTop+1)+LENGTH(pBtm)<=LENGTH(pTop)+LENGTH(pBtm-1) ) break;
16941727
lnFrom--;
16951728
lnTo--;
16961729
p->aEdit[r]--;
16971730
p->aEdit[r+3]++;
@@ -1700,11 +1733,11 @@
17001733
17011734
/* Shift deletions toward the end of the file */
17021735
while( r+3<p->nEdit && p->aEdit[r+3]>0 && del>0 && ins==0 ){
17031736
DLine *pTop = &p->aFrom[lnFrom]; /* First line deleted */
17041737
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;
17061739
if( LENGTH(pTop)+LENGTH(pBtm-1)<=LENGTH(pTop)+LENGTH(pBtm) ) break;
17071740
lnFrom++;
17081741
lnTo++;
17091742
p->aEdit[r]++;
17101743
p->aEdit[r+3]--;
@@ -1780,10 +1813,15 @@
17801813
blob_to_utf8_no_bom(pA_Blob, 0);
17811814
blob_to_utf8_no_bom(pB_Blob, 0);
17821815
17831816
/* Prepare the input files */
17841817
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
+ }
17851823
c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
17861824
&c.nFrom, diffFlags);
17871825
c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
17881826
&c.nTo, diffFlags);
17891827
if( c.aFrom==0 || c.aTo==0 ){
@@ -1850,20 +1888,30 @@
18501888
** -c|--context N N lines of context. DIFF_CONTEXT_MASK
18511889
** --html Format for HTML DIFF_HTML
18521890
** --invert Invert the diff DIFF_INVERT
18531891
** -n|--linenum Show line numbers DIFF_LINENO
18541892
** --noopt Disable optimization DIFF_NOOPT
1893
+** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
18551894
** --unified Unified diff. ~DIFF_SIDEBYSIDE
18561895
** -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
18581897
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
18591898
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
18601899
*/
18611900
u64 diff_options(void){
18621901
u64 diffFlags = 0;
18631902
const char *z;
18641903
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
+ }
18651913
if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
18661914
if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
18671915
if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
18681916
if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
18691917
diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1872,12 +1920,10 @@
18721920
f *= DIFF_CONTEXT_MASK+1;
18731921
if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
18741922
diffFlags |= f;
18751923
}
18761924
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;
18791925
if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
18801926
if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
18811927
if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
18821928
if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
18831929
return diffFlags;
@@ -1954,11 +2000,11 @@
19542000
typedef struct Annotator Annotator;
19552001
struct Annotator {
19562002
DContext c; /* The diff-engine context */
19572003
struct AnnLine { /* Lines of the original files... */
19582004
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) */
19602006
short int iVers; /* Level at which tag was set */
19612007
} *aOrig;
19622008
int nOrig; /* Number of elements in aOrig[] */
19632009
int nVers; /* Number of versions analyzed */
19642010
int bLimit; /* True if the iLimit was reached */
@@ -1980,10 +2026,15 @@
19802026
*/
19812027
static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
19822028
int i;
19832029
19842030
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
+ }
19852036
p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
19862037
diffFlags);
19872038
if( p->c.aTo==0 ){
19882039
return 1;
19892040
}
@@ -2138,10 +2189,11 @@
21382189
*/
21392190
unsigned gradient_color(unsigned c1, unsigned c2, int n, int i){
21402191
unsigned c; /* Result color */
21412192
unsigned x1, x2;
21422193
if( i==0 || n==0 ) return c1;
2194
+ else if(i>=n) return c2;
21432195
x1 = (c1>>16)&0xff;
21442196
x2 = (c2>>16)&0xff;
21452197
c = (x1*(n-i) + x2*i)/n<<16 & 0xff0000;
21462198
x1 = (c1>>8)&0xff;
21472199
x2 = (c2>>8)&0xff;
@@ -2168,11 +2220,11 @@
21682220
void annotation_page(void){
21692221
int mid;
21702222
int fnid;
21712223
int i;
21722224
int iLimit; /* Depth limit */
2173
- u64 annFlags = ANN_FILE_ANCEST;
2225
+ u64 annFlags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR);
21742226
int showLog = 0; /* True to display the log */
21752227
int ignoreWs = 0; /* Ignore whitespace */
21762228
const char *zFilename; /* Name of file to annotate */
21772229
const char *zCI; /* The check-in containing zFilename */
21782230
Annotator ann;
@@ -2255,17 +2307,17 @@
22552307
clr = gradient_color(clr1, clr2, ann.nVers-1, i);
22562308
ann.aVers[i].zBgColor = mprintf("#%06x", clr);
22572309
}
22582310
22592311
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);
22612313
@ <h2>Ancestors of %z(zLink)%h(zFilename)</a> analyzed:</h2>
22622314
@ <ol>
22632315
for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
22642316
@ <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>
22672319
@ </span>
22682320
#if 0
22692321
if( i>0 ){
22702322
char *zLink = xhref("target='infowindow'",
22712323
"%R/fdiff?v1=%S&v2=%S&sbs=1",
@@ -2283,17 +2335,17 @@
22832335
@ </ol>
22842336
@ <hr>
22852337
}
22862338
if( !ann.bLimit ){
22872339
@ <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>
22902342
iLimit = ann.nVers+10;
22912343
}else{
22922344
@ <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>
22952347
}
22962348
@ <pre>
22972349
for(i=0; i<ann.nOrig; i++){
22982350
int iVers = ann.aOrig[i].iVers;
22992351
char *z = (char*)ann.aOrig[i].z;
@@ -2303,11 +2355,11 @@
23032355
if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1;
23042356
23052357
if( bBlame ){
23062358
if( iVers>=0 ){
23072359
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);
23092361
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
23102362
"<span style='background-color:%s'>"
23112363
"%s%.10s</a> %s</span> %13.13s:",
23122364
p->zBgColor, zLink, p->zMUuid, p->zDate, p->zUser);
23132365
fossil_free(zLink);
@@ -2315,11 +2367,11 @@
23152367
sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%36s", "");
23162368
}
23172369
}else{
23182370
if( iVers>=0 ){
23192371
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);
23212373
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
23222374
"<span style='background-color:%s'>"
23232375
"%s%.10s</a> %s</span> %4d:",
23242376
p->zBgColor, zLink, p->zMUuid, p->zDate, i+1);
23252377
fossil_free(zLink);
@@ -2348,12 +2400,12 @@
23482400
**
23492401
** Options:
23502402
** --filevers Show file version numbers rather than check-in versions
23512403
** -l|--log List all versions analyzed
23522404
** -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
23552407
**
23562408
** See also: info, finfo, timeline
23572409
*/
23582410
void annotate_cmd(void){
23592411
int fnid; /* Filename ID */
@@ -2374,12 +2426,16 @@
23742426
bBlame = g.argv[1][0]!='a';
23752427
zLimit = find_option("limit","n",1);
23762428
if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
23772429
iLimit = atoi(zLimit);
23782430
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
+ }
23812437
fileVers = find_option("filevers",0,0)!=0;
23822438
db_must_be_within_tree();
23832439
if( g.argc<3 ) {
23842440
usage("FILENAME");
23852441
}
@@ -2404,11 +2460,11 @@
24042460
" ORDER BY ancestor.generation ASC LIMIT 1",
24052461
fid, fnid);
24062462
if( mid==0 ){
24072463
fossil_fatal("unable to find manifest");
24082464
}
2409
- annFlags |= ANN_FILE_ANCEST;
2465
+ annFlags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR);
24102466
annotate_file(&ann, fnid, mid, iLimit, annFlags);
24112467
if( showLog ){
24122468
struct AnnVers *p;
24132469
for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
24142470
fossil_print("version %3d: %s %.10s file %.10s\n",
24152471
--- 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 @@
943943
@ foreach e $::difftxt {puts $out [list $e]}
944944
@ puts $out "\175"
945945
@ puts $out "eval \$prog"
946946
@ close $out
947947
@ }
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
+@ }
948973
@ ::ttk::button .bb.quit -text {Quit} -command exit
974
+@ ::ttk::button .bb.invert -text {Invert} -command invertDiff
949975
@ ::ttk::button .bb.save -text {Save As...} -command saveDiff
950
-@ pack .bb.quit -side left
976
+@ pack .bb.quit .bb.invert -side left
951977
@ if {$fossilcmd!=""} {pack .bb.save -side left}
952978
@ pack .bb.files -side left
953979
@ grid rowconfigure . 1 -weight 1
954980
@ grid columnconfigure . 1 -weight 1
955981
@ grid columnconfigure . 4 -weight 1
@@ -998,12 +1024,17 @@
9981024
i++;
9991025
zTempFile = g.argv[i];
10001026
continue;
10011027
}
10021028
}
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
+ }
10051036
}
10061037
blob_appendf(&script, "}\n%s", zDiffScript);
10071038
if( zTempFile ){
10081039
blob_write_to_file(&script, zTempFile);
10091040
fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
@@ -1097,17 +1128,17 @@
10971128
** --context|-c N Use N lines of context
10981129
** --diff-binary BOOL Include binary files when using external commands
10991130
** --from|-r VERSION select VERSION as source for the diff
11001131
** --internal|-i use internal diff logic
11011132
** --side-by-side|-y side-by-side diff
1133
+** --strip-trailing-cr Strip trailing CR
11021134
** --tk Launch a Tcl/Tk GUI for display
11031135
** --to VERSION select VERSION as target for the diff
11041136
** --unified unified diff
11051137
** -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
11091140
** -Z|--ignore-trailing-space Ignore changes to end-of-line whitespace
11101141
*/
11111142
void diff_cmd(void){
11121143
int isGDiff; /* True for gdiff. False for normal diff */
11131144
int isInternDiff; /* True for internal diff */
11141145
--- 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 @@
977977
for(j=i+1; zPwd[j]; j++){
978978
if( zPwd[j]=='/' ){
979979
blob_append(pOut, "/..", 3);
980980
}
981981
}
982
+ while( i>0 && (zPwd[i]!='/')) --i;
983
+ blob_append(pOut, zPath+i, j-i);
982984
}
983985
if( slash && i>0 && zPath[strlen(zPath)-1]=='/'){
984986
blob_append(pOut, "/", 1);
985987
}
986988
blob_reset(&tmp);
@@ -1044,11 +1046,14 @@
10441046
int nFull;
10451047
char *zFull;
10461048
int (*xCmp)(const char*,const char*,int);
10471049
10481050
blob_zero(pOut);
1049
- db_must_be_within_tree();
1051
+ if( !g.localOpen ){
1052
+ blob_appendf(pOut, "%s", zOrigName);
1053
+ return 1;
1054
+ }
10501055
file_canonical_name(g.zLocalRoot, &localRoot, 1);
10511056
nLocalRoot = blob_size(&localRoot);
10521057
zLocalRoot = blob_buffer(&localRoot);
10531058
assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' );
10541059
file_canonical_name(zOrigName, &full, 0);
@@ -1093,10 +1098,11 @@
10931098
** a boolean: "yes", "no", "true", "false", etc.
10941099
*/
10951100
void cmd_test_tree_name(void){
10961101
int i;
10971102
Blob x;
1103
+ db_find_and_open_repository(0,0);
10981104
blob_zero(&x);
10991105
capture_case_sensitive_option();
11001106
for(i=2; i<g.argc; i++){
11011107
if( file_tree_name(g.argv[i], &x, 1) ){
11021108
fossil_print("%s\n", blob_buffer(&x));
11031109
--- 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 @@
374374
}
375375
blob_reset(&sql);
376376
blob_zero(&title);
377377
if( baseCheckin ){
378378
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);
380380
blob_appendf(&title, "Ancestors of file ");
381381
hyperlinked_path(zFilename, &title, zUuid, "tree", "");
382382
blob_appendf(&title, " from check-in %z%.10s</a>", zLink, zUuid);
383383
fossil_free(zUuid);
384384
}else{
@@ -404,12 +404,10 @@
404404
const char *zBr = db_column_text(&q, 9);
405405
int fmid = db_column_int(&q, 10);
406406
int pfnid = db_column_int(&q, 11);
407407
int gidx;
408408
char zTime[10];
409
- char zShort[20];
410
- char zShortCkin[20];
411409
if( zBr==0 ) zBr = "trunk";
412410
if( uBg ){
413411
zBgClr = hash_color(zUser);
414412
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
415413
zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
@@ -430,12 +428,10 @@
430428
if( zBgClr && zBgClr[0] ){
431429
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
432430
}else{
433431
@ <td class="timelineTableCell">
434432
}
435
- sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
436
- sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin);
437433
if( zUuid ){
438434
if( fpid==0 ){
439435
@ <b>Added</b>
440436
}else if( pfnid ){
441437
char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d",
@@ -458,23 +454,23 @@
458454
fossil_free(zNewName);
459455
}else{
460456
@ <b>Deleted</b> by check-in
461457
}
462458
}
463
- hyperlink_to_uuid(zShortCkin);
459
+ hyperlink_to_uuid(zCkin);
464460
@ %w(zCom) (user:
465461
hyperlink_to_user(zUser, zDate, "");
466462
@ branch: %h(zBr))
467463
if( g.perm.Hyperlink && zUuid ){
468464
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))
470466
@ [annotate]</a>
471
- @ %z(href("%R/blame?checkin=%S&filename=%h",zCkin,z))
467
+ @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
472468
@ [blame]</a>
473
- @ %z(href("%R/timeline?n=200&uf=%S",zUuid))[checkins&nbsp;using]</a>
469
+ @ %z(href("%R/timeline?n=200&uf=%s",zUuid))[checkins&nbsp;using]</a>
474470
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>
476472
}
477473
}
478474
if( fDebug & FINFO_DEBUG_MLINK ){
479475
int srcid = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", frid);
480476
int sz = db_int(0, "SELECT length(content) FROM blob WHERE rid=%d", frid);
481477
--- 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&nbsp;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&nbsp;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 @@
5555
const char *zPw; /* The user password */
5656
Blob pw; /* The nonce with user password appended */
5757
Blob sig; /* The signature field */
5858
5959
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 ){
6161
return; /* If no login card for users "nobody" and "anonymous" */
6262
}
63
- if( g.urlIsSsh ){
63
+ if( g.url.isSsh ){
6464
return; /* If no login card for SSH: */
6565
}
6666
blob_zero(&nonce);
6767
blob_zero(&pw);
6868
sha1sum_blob(pPayload, &nonce);
6969
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;
7373
}else if( g.cgiOutput ){
7474
/* Password failure while doing a sync from the web interface */
7575
cgi_printf("*** incorrect or missing password for user %h\n", zLogin);
7676
zPw = 0;
7777
}else{
7878
/* Password failure while doing a sync from the command-line interface */
7979
url_prompt_for_password();
80
- zPw = g.urlPasswd;
80
+ zPw = g.url.passwd;
8181
}
8282
8383
/* The login card wants the SHA1 hash of the password, so convert the
8484
** password to its SHA1 hash it it isn't already a SHA1 hash.
8585
*/
@@ -102,29 +102,29 @@
102102
static void http_build_header(Blob *pPayload, Blob *pHdr){
103103
int i;
104104
const char *zSep;
105105
106106
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]=='/' ){
109109
zSep = "";
110110
}else{
111111
zSep = "/";
112112
}
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);
116116
}
117117
if( g.zHttpAuth && g.zHttpAuth[0] ){
118118
const char *zCredentials = g.zHttpAuth;
119119
char *zEncoded = encode64(zCredentials, -1);
120120
blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
121121
fossil_free(zEncoded);
122122
}
123
- blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
123
+ blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname);
124124
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");
126126
if( g.fHttpTrace ){
127127
blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
128128
}else{
129129
blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
130130
}
@@ -147,11 +147,11 @@
147147
** Prompt to save HTTP Basic Authorization information
148148
*/
149149
static int save_httpauth_prompt(void){
150150
Blob x;
151151
char c;
152
- if( (g.urlFlags & URL_REMEMBER)==0 ) return;
152
+ if( (g.url.flags & URL_REMEMBER)==0 ) return 0;
153153
prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x);
154154
c = blob_str(&x)[0];
155155
blob_reset(&x);
156156
return ( c!='n' && c!='N' );
157157
}
@@ -166,15 +166,15 @@
166166
char *zPw;
167167
char *zPrompt;
168168
char *zHttpAuth = 0;
169169
if( !isatty(fileno(stdin)) ) return 0;
170170
zPrompt = mprintf("\n%s authorization required by\n%s\n",
171
- g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical);
171
+ g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172172
fossil_print(zPrompt);
173173
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);
176176
}else{
177177
prompt_user("Basic Authorization user: ", &x);
178178
zUser = mprintf("%b", &x);
179179
zPrompt = mprintf("HTTP password for %b: ", &x);
180180
blob_reset(&x);
@@ -213,12 +213,12 @@
213213
char *zLine; /* A single line of the reply header */
214214
int i; /* Loop counter */
215215
int isError = 0; /* True if the reply is an error message */
216216
int isCompressed = 1; /* True if the reply is compressed */
217217
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));
220220
return 1;
221221
}
222222
223223
/* Construct the login card and prepare the complete payload */
224224
blob_zero(&login);
@@ -260,32 +260,32 @@
260260
}
261261
262262
/*
263263
** Send the request to the server.
264264
*/
265
- transport_send(GLOBAL_URL(), &hdr);
266
- transport_send(GLOBAL_URL(), &payload);
265
+ transport_send(&g.url, &hdr);
266
+ transport_send(&g.url, &payload);
267267
blob_reset(&hdr);
268268
blob_reset(&payload);
269
- transport_flip(GLOBAL_URL());
269
+ transport_flip(&g.url);
270270
271271
/*
272272
** Read and interpret the server reply
273273
*/
274274
closeConnection = 1;
275275
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 ){
277277
/* printf("[%s]\n", zLine); fflush(stdout); */
278278
if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
279279
if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
280280
if( rc==401 ){
281281
if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){
282282
if( g.zHttpAuth ){
283283
if( g.zHttpAuth ) free(g.zHttpAuth);
284284
}
285285
g.zHttpAuth = prompt_for_httpauth_creds();
286
- transport_close(GLOBAL_URL());
286
+ transport_close(&g.url);
287287
return http_exchange(pSend, pReply, useLogin, maxRedirect);
288288
}
289289
}
290290
if( rc!=200 && rc!=302 ){
291291
int ii;
@@ -297,11 +297,11 @@
297297
if( iHttpVersion==0 ){
298298
closeConnection = 1;
299299
}else{
300300
closeConnection = 0;
301301
}
302
- }else if( g.urlIsSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
302
+ }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
303303
if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
304304
if( rc!=200 && rc!=302 ){
305305
int ii;
306306
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
307307
while( zLine[ii]==' ' ) ii++;
@@ -337,11 +337,11 @@
337337
fossil_print("redirect to %s\n", &zLine[i]);
338338
url_parse(&zLine[i], 0);
339339
fSeenHttpAuth = 0;
340340
if( g.zHttpAuth ) free(g.zHttpAuth);
341341
g.zHttpAuth = get_httpauth();
342
- transport_close(GLOBAL_URL());
342
+ transport_close(&g.url);
343343
return http_exchange(pSend, pReply, useLogin, maxRedirect);
344344
}else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
345345
if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
346346
isCompressed = 0;
347347
}else if( fossil_strnicmp(&zLine[14],
@@ -364,11 +364,11 @@
364364
/*
365365
** Extract the reply payload that follows the header
366366
*/
367367
blob_zero(pReply);
368368
blob_resize(pReply, iLength);
369
- iLength = transport_receive(GLOBAL_URL(), blob_buffer(pReply), iLength);
369
+ iLength = transport_receive(&g.url, blob_buffer(pReply), iLength);
370370
blob_resize(pReply, iLength);
371371
if( isError ){
372372
char *z;
373373
int i, j;
374374
z = blob_str(pReply);
@@ -391,20 +391,20 @@
391391
** connection from remaining open. The easiest fix for now is to
392392
** simply close and restart the connection for each round-trip.
393393
**
394394
** For SSH we will leave the connection open.
395395
*/
396
- if( ! g.urlIsSsh ) closeConnection = 1; /* FIX ME */
396
+ if( ! g.url.isSsh ) closeConnection = 1; /* FIX ME */
397397
if( closeConnection ){
398
- transport_close(GLOBAL_URL());
398
+ transport_close(&g.url);
399399
}else{
400
- transport_rewind(GLOBAL_URL());
400
+ transport_rewind(&g.url);
401401
}
402402
return 0;
403403
404404
/*
405405
** Jump to here if an error is seen.
406406
*/
407407
write_err:
408
- transport_close(GLOBAL_URL());
408
+ transport_close(&g.url);
409409
return 1;
410410
}
411411
--- 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
--- src/http_socket.c
+++ src/http_socket.c
@@ -124,14 +124,14 @@
124124
}
125125
}
126126
127127
/*
128128
** Open a socket connection. The identify of the server is determined
129
-** by global variables that are set using url_parse():
129
+** by pUrlData
130130
**
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
133133
**
134134
** Return the number of errors.
135135
*/
136136
int socket_open(UrlData *pUrlData){
137137
static struct sockaddr_in addr; /* The server address */
@@ -212,13 +212,14 @@
212212
}
213213
return total;
214214
}
215215
216216
/*
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.
220221
*/
221222
void socket_ssh_resolve_addr(UrlData *pUrlData){
222223
struct hostent *pHost; /* Used to make best effort for rcvfrom */
223224
struct sockaddr_in addr;
224225
225226
--- 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 @@
224224
return rc;
225225
}
226226
227227
/*
228228
** Open an SSL connection. The identify of the server is determined
229
-** by variables that are set using url_parse():
229
+** as follows:
230230
**
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
232232
** pUrlData->port TCP/IP port to use. Ex: 80
233233
**
234234
** Return the number of errors.
235235
*/
236236
int ssl_open(UrlData *pUrlData){
@@ -253,11 +253,11 @@
253253
254254
if( pUrlData->useProxy ){
255255
int rc;
256256
BIO *sBio;
257257
char *connStr;
258
- connStr = mprintf("%s:%d", g.urlName, pUrlData->port);
258
+ connStr = mprintf("%s:%d", g.url.name, pUrlData->port);
259259
sBio = BIO_new_connect(connStr);
260260
free(connStr);
261261
if( BIO_do_connect(sBio)<=0 ){
262262
ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)",
263263
pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error()));
@@ -417,26 +417,28 @@
417417
free(zHost);
418418
BIO_free(mem);
419419
}
420420
421421
/*
422
-** Get certificate for g.urlName from global config.
422
+** Get certificate for pUrlData->urlName from global config.
423423
** Return NULL if no certificate found.
424424
*/
425425
X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){
426426
char *zHost, *zCert;
427427
BIO *mem;
428428
X509 *cert;
429429
430
- zHost = mprintf("cert:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name);
430
+ zHost = mprintf("cert:%s",
431
+ pUrlData->useProxy ? pUrlData->hostname : pUrlData->name);
431432
zCert = db_get(zHost, NULL);
432433
free(zHost);
433434
if ( zCert==NULL )
434435
return NULL;
435436
436437
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);
438440
*pTrusted = db_get_int(zHost, 0);
439441
free(zHost);
440442
}
441443
442444
mem = BIO_new(BIO_s_mem());
443445
--- 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
--- src/http_transport.c
+++ src/http_transport.c
@@ -138,15 +138,15 @@
138138
return sshPid==0;
139139
}
140140
141141
/*
142142
** Open a connection to the server. The server is defined by the following
143
-** global variables:
143
+** variables:
144144
**
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
148148
**
149149
** Return the number of errors.
150150
*/
151151
int transport_open(UrlData *pUrlData){
152152
int rc = 0;
153153
--- 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 @@
399399
}
400400
if( diffFlags ){
401401
append_diff(zOld, zNew, diffFlags, pRe);
402402
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
403403
@ &nbsp;&nbsp;
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>
405405
}
406406
}
407407
}
408408
409409
/*
@@ -443,24 +443,20 @@
443443
/*
444444
** Construct an appropriate diffFlag for text_diff() based on query
445445
** parameters and the to boolean arguments.
446446
*/
447447
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 ){
452450
int x;
453451
if( sideBySide ){
454452
diffFlags = DIFF_SIDEBYSIDE;
455453
456454
/* "dw" query parameter determines width of each column */
457455
x = atoi(PD("dw","80"))*(DIFF_CONTEXT_MASK+1);
458456
if( x<0 || x>DIFF_WIDTH_MASK ) x = DIFF_WIDTH_MASK;
459457
diffFlags += x;
460
- }else{
461
- diffFlags = DIFF_INLINE;
462458
}
463459
464460
if( P("w") ){
465461
diffFlags |= DIFF_IGNORE_ALLWS;
466462
}
@@ -469,10 +465,11 @@
469465
if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470466
diffFlags += x;
471467
472468
/* The "noopt" parameter disables diff optimization */
473469
if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT;
470
+ diffFlags |= DIFF_STRIP_EOLCR;
474471
}
475472
return diffFlags;
476473
}
477474
478475
/*
@@ -615,19 +612,19 @@
615612
if( (zPJ[jj]>0 && zPJ[jj]<' ') || strchr("\"*/:<>?\\|", zPJ[jj]) ){
616613
zPJ[jj] = '_';
617614
}
618615
}
619616
@ <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>
621618
if( zParent ){
622
- @ | %z(href("%R/timeline?p=%S&unhide",zUuid))ancestors</a>
619
+ @ | %z(href("%R/timeline?p=%s&unhide",zUuid))ancestors</a>
623620
}
624621
if( !isLeaf ){
625
- @ | %z(href("%R/timeline?d=%S&unhide",zUuid))descendants</a>
622
+ @ | %z(href("%R/timeline?d=%s&unhide",zUuid))descendants</a>
626623
}
627624
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>
629626
}
630627
db_prepare(&q2,"SELECT substr(tag.tagname,5) FROM tagxref, tag "
631628
" WHERE rid=%d AND tagtype>0 "
632629
" AND tag.tagid=tagxref.tagid "
633630
" AND +tag.tagname GLOB 'sym-*'", rid);
@@ -650,16 +647,16 @@
650647
fossil_free(zUrl);
651648
}
652649
@ </td></tr>
653650
@ <tr><th>Other&nbsp;Links:</th>
654651
@ <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>
659656
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>
661658
}
662659
@ </td>
663660
@ </tr>
664661
blob_reset(&projName);
665662
}
@@ -702,11 +699,11 @@
702699
@ Show&nbsp;Unified&nbsp;Diffs</a>
703700
@ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName))
704701
@ Show&nbsp;Side-by-Side&nbsp;Diffs</a>
705702
}
706703
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))
708705
@ Patch</a>
709706
}
710707
@</div>
711708
if( pRe ){
712709
@ <p><b>Only differences that match regular expression "%h(zRe)"
@@ -773,11 +770,11 @@
773770
}
774771
}
775772
style_header("Update of \"%h\"", pWiki->zWikiTitle);
776773
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
777774
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);
779776
style_submenu_element("History", "History", "whistory?name=%t",
780777
pWiki->zWikiTitle);
781778
style_submenu_element("Page", "Page", "wiki?name=%t",
782779
pWiki->zWikiTitle);
783780
login_anonymous_available();
@@ -801,11 +798,11 @@
801798
if( pWiki->nParent>0 ){
802799
int i;
803800
@ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
804801
for(i=0; i<pWiki->nParent; i++){
805802
char *zParent = pWiki->azParent[i];
806
- @ %z(href("info/%S",zParent))%s(zParent)</a>
803
+ @ %z(href("info/%s",zParent))%s(zParent)</a>
807804
}
808805
@ </td></tr>
809806
}
810807
@ </table>
811808
@@ -1191,14 +1188,14 @@
11911188
@ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
11921189
}
11931190
@ - %!w(zCom) (user:
11941191
hyperlink_to_user(zUser,zDate,")");
11951192
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))
11981195
@ [annotate]</a>
1199
- @ %z(href("%R/blame?checkin=%S&filename=%T",zVers,zName))
1196
+ @ %z(href("%R/blame?filename=%T&checkin=%s",zName,zVers))
12001197
@ [blame]</a>
12011198
}
12021199
cnt++;
12031200
if( pDownloadName && blob_size(pDownloadName)==0 ){
12041201
blob_append(pDownloadName, zName, -1);
@@ -1305,11 +1302,11 @@
13051302
@ Attachment "%h(zFilename)" to
13061303
}
13071304
objType |= OBJTYPE_ATTACHMENT;
13081305
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
13091306
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>]
13111308
}else{
13121309
@ ticket [%S(zTarget)]
13131310
}
13141311
}else{
13151312
if( g.perm.Hyperlink && g.perm.RdWiki ){
@@ -1331,11 +1328,11 @@
13311328
@ Control artifact.
13321329
if( pDownloadName && blob_size(pDownloadName)==0 ){
13331330
blob_appendf(pDownloadName, "%.10s.txt", zUuid);
13341331
}
13351332
}else if( linkToView && g.perm.Hyperlink ){
1336
- @ %z(href("%R/artifact/%S",zUuid))[view]</a>
1333
+ @ %z(href("%R/artifact/%s",zUuid))[view]</a>
13371334
}
13381335
return objType;
13391336
}
13401337
13411338
@@ -1407,17 +1404,17 @@
14071404
g.zTop, P("v1"), P("v2"), zW);
14081405
}
14091406
14101407
if( P("smhdr")!=0 ){
14111408
@ <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>
14141411
}else{
14151412
@ <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>
14171414
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>
14191416
object_description(v2, 0, 0);
14201417
}
14211418
if( pRe ){
14221419
@ <b>Only differences that match regular expression "%h(zRe)"
14231420
@ are shown.</b>
@@ -1722,11 +1719,12 @@
17221719
}else{
17231720
renderAsHtml = 1;
17241721
style_submenu_element("Text", "Text",
17251722
"%s/artifact/%s?txt=1", g.zTop, zUuid);
17261723
}
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 ){
17281726
if( asText ){
17291727
style_submenu_element("Wiki", "Wiki",
17301728
"%s/artifact/%s", g.zTop, zUuid);
17311729
}else{
17321730
renderAsWiki = 1;
@@ -1739,11 +1737,11 @@
17391737
style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid);
17401738
}
17411739
@ <hr />
17421740
content_get(rid, &content);
17431741
if( renderAsWiki ){
1744
- wiki_convert(&content, 0, 0);
1742
+ wiki_render_by_mimetype(&content, zMime);
17451743
}else if( renderAsHtml ){
17461744
@ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
17471745
@ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
17481746
@ sandbox="allow-same-origin"
17491747
@ onload="this.height = this.contentDocument.documentElement.scrollHeight;">
@@ -1763,13 +1761,13 @@
17631761
@ <pre>
17641762
@ %h(z)
17651763
@ </pre>
17661764
}
17671765
}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)" />
17691767
style_submenu_element("Image", "Image",
1770
- "%R/raw/%S?m=%s", zUuid, zMime);
1768
+ "%R/raw/%s?m=%s", zUuid, zMime);
17711769
}else{
17721770
@ <i>(file is %d(blob_size(&content)) bytes of binary data)</i>
17731771
}
17741772
@ </blockquote>
17751773
}
@@ -1821,19 +1819,19 @@
18211819
}
18221820
zTktTitle = db_table_has_column( "ticket", "title" )
18231821
? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
18241822
: 0;
18251823
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);
18271825
style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
18281826
style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
18291827
style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
18301828
if( P("plaintext") ){
1831
- style_submenu_element("Formatted", "Formatted", "%R/info/%S", zUuid);
1829
+ style_submenu_element("Formatted", "Formatted", "%R/info/%s", zUuid);
18321830
}else{
18331831
style_submenu_element("Plaintext", "Plaintext",
1834
- "%R/info/%S?plaintext", zUuid);
1832
+ "%R/info/%s?plaintext", zUuid);
18351833
}
18361834
18371835
@ <div class="section">Overview</div>
18381836
@ <p><table class="label-value">
18391837
@ <tr><th>Artifact&nbsp;ID:</th>
@@ -2343,11 +2341,11 @@
23432341
}
23442342
@ <p>Make changes to attributes of check-in
23452343
@ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p>
23462344
form_begin(0, "%R/ci_edit");
23472345
login_insert_csrf_secret();
2348
- @ <div><input type="hidden" name="r" value="%S(zUuid)" />
2346
+ @ <div><input type="hidden" name="r" value="%s(zUuid)" />
23492347
@ <table border="0" cellspacing="10">
23502348
23512349
@ <tr><th align="right" valign="top">User:</th>
23522350
@ <td valign="top">
23532351
@ <input type="text" name="u" size="20" value="%h(zNewUser)" />
23542352
--- 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 @ &nbsp;&nbsp;
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&nbsp;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&nbsp;Unified&nbsp;Diffs</a>
703 @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName))
704 @ Show&nbsp;Side-by-Side&nbsp;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&nbsp;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 @ &nbsp;&nbsp;
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&nbsp;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&nbsp;Unified&nbsp;Diffs</a>
700 @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName))
701 @ Show&nbsp;Side-by-Side&nbsp;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&nbsp;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 @@
12751275
INT(g, xlinkClusterOnly);
12761276
INT(g, fTimeFormat);
12771277
INT(g, markPrivate);
12781278
INT(g, clockSkewSeen);
12791279
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);
12851285
INT(g, useLocalauth);
12861286
INT(g, noPswd);
12871287
INT(g, userUid);
12881288
INT(g, rcvid);
12891289
INT(g, okCsrf);
@@ -1299,19 +1299,19 @@
12991299
CSTR(g, zExtra);
13001300
CSTR(g, zBaseURL);
13011301
CSTR(g, zTop);
13021302
CSTR(g, zContentType);
13031303
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);
13131313
CSTR(g, zLogin);
13141314
CSTR(g, zSSLIdentity);
13151315
CSTR(g, zIpAddr);
13161316
CSTR(g, zNonce);
13171317
CSTR(g, zCsrfToken);
13181318
--- 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 @@
542542
543543
blob_init(&w1, pW1->zWiki, -1);
544544
blob_zero(&w2);
545545
blob_init(&w2, pW2->zWiki, -1);
546546
blob_zero(&d);
547
- diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE;
547
+ diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR;
548548
text_diff(&w2, &w1, &d, 0, diffFlags);
549549
blob_reset(&w1);
550550
blob_reset(&w2);
551551
552552
pay = cson_new_object();
553553
--- 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 @@
112112
void *xPostEval; /* Optional, called after Tcl_Eval*(). */
113113
void *pPostContext; /* Optional, provided to xPostEval(). */
114114
};
115115
#endif
116116
117
-/*
118
-** All global variables are in this structure.
119
-*/
120
-#define GLOBAL_URL() ((UrlData *)(&g.urlIsFile))
121
-
122117
struct Global {
123118
int argc; char **argv; /* Command-line arguments to the program */
124119
char *nameOfExe; /* Full path of executable. */
125120
const char *zErrlog; /* Log errors to this file, if not NULL */
126121
int isConst; /* True if the output is unchanging & cacheable */
@@ -171,11 +166,12 @@
171166
int clockSkewSeen; /* True if clocks on client and server out of sync */
172167
int wikiFlags; /* Wiki conversion flags applied to %w and %W */
173168
char isHTTP; /* True if server/CGI modes, else assume CLI. */
174169
char javascriptHyperlink; /* If true, set href= using script, not HTML */
175170
Blob httpHeader; /* Complete text of the HTTP request header */
176
-
171
+ UrlData url; /* Information about current URL */
172
+#if 0
177173
/*
178174
** NOTE: These members MUST be kept in sync with those in the "UrlData"
179175
** structure defined in "url.c".
180176
*/
181177
int urlIsFile; /* True if a "file:" url */
@@ -194,10 +190,12 @@
194190
char *urlFossil; /* The fossil query parameter on ssh: */
195191
unsigned urlFlags; /* Boolean flags controlling URL processing */
196192
int useProxy; /* Used to remember that a proxy is in use */
197193
char *proxyUrlPath;
198194
int proxyOrigPort; /* Tunneled port number for https through proxy */
195
+#endif
196
+
199197
const char *zLogin; /* Login name. NULL or "" if not logged in. */
200198
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of
201199
** SSL client identity */
202200
int useLocalauth; /* No login required if from 127.0.0.1 */
203201
int noPswd; /* Logged in without password (on 127.0.0.1) */
@@ -604,15 +602,10 @@
604602
#endif
605603
g.mainTimerId = fossil_timer_start();
606604
g.zVfsName = find_option("vfs",0,1);
607605
if( g.zVfsName==0 ){
608606
g.zVfsName = fossil_getenv("FOSSIL_VFS");
609
-#if defined(__CYGWIN__)
610
- if( g.zVfsName==0 ){
611
- g.zVfsName = "win32-longpath";
612
- }
613
-#endif
614607
}
615608
if( g.zVfsName ){
616609
sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName);
617610
if( pVfs ){
618611
sqlite3_vfs_register(pVfs, 1);
@@ -1070,11 +1063,11 @@
10701063
if( j>0 ){
10711064
@ </ul></td>
10721065
}
10731066
@ </tr></table>
10741067
1075
- @ <h1>Available pages:</h1>
1068
+ @ <h1>Available web UI pages:</h1>
10761069
@ (Only pages with help text are linked.)
10771070
@ <table border="0"><tr>
10781071
for(i=j=0; i<count(aCommand); i++){
10791072
const char *z = aCommand[i].zName;
10801073
if( '/'!=*z ) continue;
10811074
--- 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 @@
400400
# using -lsqlite3.
401401
SQLITE3_OBJ.1 =
402402
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o
403403
SQLITE3_OBJ. = $(SQLITE3_OBJ.0)
404404
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
413406
414407
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
415408
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
416409
417410
# This rule prevents make from using its default rules to try build
418411
--- 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 @@
268268
# using -lsqlite3.
269269
SQLITE3_OBJ.1 =
270270
SQLITE3_OBJ.0 = $(OBJDIR)/sqlite3.o
271271
SQLITE3_OBJ. = $(SQLITE3_OBJ.0)
272272
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
-
280273
EXTRAOBJ = \
281274
$(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
282275
$(OBJDIR)/shell.o \
283276
$(OBJDIR)/th.o \
284277
$(OBJDIR)/th_lang.o \
285
- $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \
278
+ $(OBJDIR)/th_tcl.o \
286279
$(OBJDIR)/cson_amalgamation.o
287280
288281
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
289282
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
290283
@@ -451,12 +444,12 @@
451444
#### The directories where the OpenSSL include and library files are located.
452445
# The recommended usage here is to use the Sysinternals junction tool
453446
# to create a hard link between an "openssl-1.x" sub-directory of the
454447
# Fossil source code directory and the target OpenSSL source directory.
455448
#
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
458451
459452
#### Either the directory where the Tcl library is installed or the Tcl
460453
# source code directory resides (depending on the value of the macro
461454
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
462455
# this directory must have "include" and "lib" sub-directories. If
@@ -724,16 +717,13 @@
724717
EXTRAOBJ = \
725718
$(OBJDIR)/sqlite3.o \
726719
$(OBJDIR)/shell.o \
727720
$(OBJDIR)/th.o \
728721
$(OBJDIR)/th_lang.o \
722
+ $(OBJDIR)/th_tcl.o \
729723
$(OBJDIR)/cson_amalgamation.o
730724
731
-ifdef FOSSIL_ENABLE_TCL
732
-EXTRAOBJ += $(OBJDIR)/th_tcl.o
733
-endif
734
-
735725
zlib:
736726
$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a
737727
738728
clean-zlib:
739729
$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc clean
@@ -824,14 +814,12 @@
824814
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
825815
826816
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
827817
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
828818
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"
833821
834822
close $output_file
835823
#
836824
# End of the win/Makefile.mingw output
837825
##############################################################################
@@ -1024,12 +1012,12 @@
10241012
10251013
# Uncomment to enable Tcl support
10261014
# FOSSIL_ENABLE_TCL = 1
10271015
10281016
!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
10311019
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
10321020
!endif
10331021
10341022
!ifdef FOSSIL_ENABLE_TCL
10351023
TCLDIR = $(B)\compat\tcl-8.6
@@ -1107,11 +1095,11 @@
11071095
writeln -nonewline " "
11081096
}
11091097
writeln -nonewline "${s}_.c"; incr i
11101098
}
11111099
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]
11131101
writeln -nonewline "OBJ = "
11141102
set i 0
11151103
foreach s [lsort [concat $src $AdditionalObj]] {
11161104
if {$i > 0} {
11171105
writeln " \\"
@@ -1119,13 +1107,10 @@
11191107
}
11201108
writeln -nonewline "\$(OX)\\$s\$O"; incr i
11211109
}
11221110
writeln " \\"
11231111
writeln -nonewline " \$(OX)\\fossil.res\n\n"
1124
-writeln "!ifdef FOSSIL_ENABLE_TCL"
1125
-writeln "OBJ = \$(OBJ) \$(OX)\\th_tcl\$O"
1126
-writeln "!endif"
11271112
writeln {
11281113
APPNAME = $(OX)\fossil$(E)
11291114
PDBNAME = $(OX)\fossil$(P)
11301115
11311116
all: $(OX) $(APPNAME)
@@ -1142,14 +1127,11 @@
11421127
set redir {>}
11431128
foreach s [lsort [concat $src $AdditionalObj]] {
11441129
writeln "\techo \$(OX)\\$s.obj $redir \$@"
11451130
set redir {>>}
11461131
}
1147
-writeln "!ifdef FOSSIL_ENABLE_TCL"
1148
-writeln "\techo \$(OX)\\th_tcl.obj $redir \$@"
11491132
set redir {>>}
1150
-writeln "!endif"
11511133
writeln "\techo \$(LIBS) $redir \$@"
11521134
writeln {
11531135
$(OX):
11541136
@-mkdir $@
11551137
@@ -1175,14 +1157,12 @@
11751157
$(TCC) /Fo$@ -c $**
11761158
11771159
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
11781160
$(TCC) /Fo$@ -c $**
11791161
1180
-!ifdef FOSSIL_ENABLE_TCL
11811162
$(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c
11821163
$(TCC) /Fo$@ -c $**
1183
-!endif
11841164
11851165
VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
11861166
$** > $@
11871167
$(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c
11881168
$(TCC) /Fo$@ /c $**
11891169
--- 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 @@
135135
** Clear the memory allocated in a manifest object
136136
*/
137137
void manifest_destroy(Manifest *p){
138138
if( p ){
139139
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);
146146
if( p->pBaseline ) manifest_destroy(p->pBaseline);
147147
memset(p, 0, sizeof(*p));
148148
fossil_free(p);
149149
}
150150
}
@@ -1589,42 +1589,43 @@
15891589
if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
15901590
zNewStatus = pManifest->aField[i].zValue;
15911591
}
15921592
}
15931593
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
15961596
);
15971597
if( pManifest->nField>1 ){
15981598
blob_appendf(&comment, " plus %d other change%s",
15991599
pManifest->nField-1, pManifest->nField==2 ? "" : "s");
16001600
}
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);
16031603
}else{
16041604
zNewStatus = db_text("unknown",
16051605
"SELECT %s FROM ticket WHERE tkt_uuid='%s'",
16061606
zStatusColumn, pManifest->zTicketUuid
16071607
);
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 "
16091609
"%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"
16121612
);
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,
16161616
pManifest->nField==1 ? "" : "s"
16171617
);
16181618
}
16191619
}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
16221622
);
1623
- blob_appendf(&brief, "New ticket [%.10s].", pManifest->zTicketUuid);
1623
+ blob_appendf(&brief, "New ticket [%s|%.10s].", pManifest->zTicketUuid,
1624
+ pManifest->zTicketUuid);
16241625
}
1625
- free(zTitle);
1626
+ fossil_free(zTitle);
16261627
db_multi_exec(
16271628
"REPLACE INTO event(type,tagid,mtime,objid,user,comment,brief)"
16281629
"VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)",
16291630
tktTagId, pManifest->rDate, rid, pManifest->zUser,
16301631
blob_str(&comment), blob_str(&brief)
@@ -1752,11 +1753,11 @@
17521753
TAG_COMMENT, rid, p->rDate
17531754
);
17541755
zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event"
17551756
" WHERE rowid=last_insert_rowid()");
17561757
wiki_extract_links(zCom, rid, 0, p->rDate, 1, WIKI_INLINE);
1757
- free(zCom);
1758
+ fossil_free(zCom);
17581759
17591760
/* If this is a delta-manifest, record the fact that this repository
17601761
** contains delta manifests, to free the "commit" logic to generate
17611762
** new delta manifests.
17621763
*/
@@ -1821,11 +1822,11 @@
18211822
char zLength[40];
18221823
while( fossil_isspace(p->zWiki[0]) ) p->zWiki++;
18231824
nWiki = strlen(p->zWiki);
18241825
sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki);
18251826
tag_insert(zTag, 1, zLength, rid, p->rDate, rid);
1826
- free(zTag);
1827
+ fossil_free(zTag);
18271828
prior = db_int(0,
18281829
"SELECT rid FROM tagxref"
18291830
" WHERE tagid=%d AND mtime<%.17g"
18301831
" ORDER BY mtime DESC",
18311832
tagid, p->rDate
@@ -1849,11 +1850,11 @@
18491850
TAG_BGCOLOR, rid,
18501851
TAG_BGCOLOR, rid,
18511852
TAG_USER, rid,
18521853
TAG_COMMENT, rid
18531854
);
1854
- free(zComment);
1855
+ fossil_free(zComment);
18551856
}
18561857
if( p->type==CFTYPE_EVENT ){
18571858
char *zTag = mprintf("event-%s", p->zEventId);
18581859
int tagid = tag_findid(zTag, 1);
18591860
int prior, subsequent;
@@ -1861,11 +1862,11 @@
18611862
char zLength[40];
18621863
while( fossil_isspace(p->zWiki[0]) ) p->zWiki++;
18631864
nWiki = strlen(p->zWiki);
18641865
sqlite3_snprintf(sizeof(zLength), zLength, "%d", nWiki);
18651866
tag_insert(zTag, 1, zLength, rid, p->rDate, rid);
1866
- free(zTag);
1867
+ fossil_free(zTag);
18671868
prior = db_int(0,
18681869
"SELECT rid FROM tagxref"
18691870
" WHERE tagid=%d AND mtime<%.17g AND rid!=%d"
18701871
" ORDER BY mtime DESC",
18711872
tagid, p->rDate, rid
@@ -1900,22 +1901,26 @@
19001901
);
19011902
}
19021903
}
19031904
if( p->type==CFTYPE_TICKET ){
19041905
char *zTag;
1905
-
19061906
assert( manifest_crosslink_busy==1 );
19071907
zTag = mprintf("tkt-%s", p->zTicketUuid);
19081908
tag_insert(zTag, 1, 0, rid, p->rDate, rid);
1909
- free(zTag);
1909
+ fossil_free(zTag);
19101910
db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",
19111911
p->zTicketUuid);
19121912
}
19131913
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 */;
19141919
db_multi_exec(
19151920
"INSERT INTO attachment(attachid, mtime, src, target,"
1916
- "filename, comment, user)"
1921
+ "filename, comment, user)"
19171922
"VALUES(%d,%.17g,%Q,%Q,%Q,%Q,%Q);",
19181923
rid, p->rDate, p->zAttachSrc, p->zAttachTarget, p->zAttachName,
19191924
(p->zComment ? p->zComment : ""), p->zUser
19201925
);
19211926
db_multi_exec(
@@ -1924,45 +1929,35 @@
19241929
" WHERE target=%Q AND filename=%Q))"
19251930
" WHERE target=%Q AND filename=%Q",
19261931
p->zAttachTarget, p->zAttachName,
19271932
p->zAttachTarget, p->zAttachName
19281933
);
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 ){
19341936
zComment = mprintf(
1935
- "Add attachment [/artifact/%S|%h] to wiki page [%h]",
1937
+ "Add attachment [/artifact/%s|%h] to wiki page [%h]",
19361938
p->zAttachSrc, p->zAttachName, p->zAttachTarget);
19371939
}else{
19381940
zComment = mprintf("Delete attachment \"%h\" from wiki page [%h]",
19391941
p->zAttachName, p->zAttachTarget);
19401942
}
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);
19641959
}
19651960
if( p->type==CFTYPE_CONTROL ){
19661961
Blob comment;
19671962
int i;
19681963
const char *zName;
@@ -1978,12 +1973,12 @@
19781973
for(i=0; i<p->nTag; i++){
19791974
zTagUuid = p->aTag[i].zUuid;
19801975
if( !zTagUuid ) continue;
19811976
if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){
19821977
blob_appendf(&comment,
1983
- " Edit [%S]:",
1984
- zTagUuid);
1978
+ " Edit [%s|%.10s]:",
1979
+ zTagUuid, zTagUuid);
19851980
branchMove = 0;
19861981
if( permitHooks && db_exists("SELECT 1 FROM event, blob"
19871982
" WHERE event.type='ci' AND event.objid=blob.rid"
19881983
" AND blob.uuid='%s'", zTagUuid) ){
19891984
zScript = xfer_commit_code();
@@ -1992,11 +1987,11 @@
19921987
}
19931988
zName = p->aTag[i].zName;
19941989
zValue = p->aTag[i].zValue;
19951990
if( strcmp(zName, "*branch")==0 ){
19961991
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].",
19981993
zValue, zTagUuid, zValue);
19991994
branchMove = 1;
20001995
continue;
20011996
}else if( strcmp(zName, "*bgcolor")==0 ){
20021997
blob_appendf(&comment,
20031998
--- 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 @@
402402
canonical16(z, strlen(z));
403403
db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z);
404404
while( db_step(&q)==SQLITE_ROW ){
405405
const char *zUuid = db_column_text(&q, 0);
406406
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> -
409409
object_description(rid, 0, 0);
410410
@ </p></li>
411411
}
412412
@ </ol>
413
+ db_finalize(&q);
413414
style_footer();
414415
}
415416
416417
/*
417418
** Convert the name in CGI parameter zParamName into a rid and return that
@@ -433,10 +434,152 @@
433434
cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath);
434435
rid = 0;
435436
}
436437
return rid;
437438
}
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
+}
438581
439582
/*
440583
** COMMAND: whatis*
441584
** Usage: %fossil whatis NAME
442585
**
@@ -452,78 +595,41 @@
452595
verboseFlag = find_option("verbose","v",0)!=0;
453596
if( g.argc!=3 ) usage("whatis NAME");
454597
zName = g.argv[2];
455598
rid = symbolic_name_to_rid(zName, 0);
456599
if( rid<0 ){
600
+ Stmt q;
601
+ int cnt = 0;
457602
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);
458612
}else if( rid==0 ){
459613
fossil_print("Unknown artifact: %s\n", zName);
460614
}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);
529635
}
530636
--- 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 @@
204204
#endif
205205
}
206206
207207
/*
208208
** Close the connection to a child process previously created using
209
-** popen2(). Kill off the child process, then close the pipes.
209
+** popen2().
210210
*/
211211
void pclose2(int fdIn, FILE *pOut, int childPid){
212212
#ifdef _WIN32
213213
/* Not implemented, yet */
214214
close(fdIn);
215215
fclose(pOut);
216216
#else
217217
close(fdIn);
218218
fclose(pOut);
219
- kill(childPid, SIGINT);
220219
while( waitpid(0, 0, WNOHANG)>0 ) {}
221220
#endif
222221
}
223222
--- 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 @@
302302
"FROM reportfmt WHERE rn=%d",rn);
303303
style_header("SQL For Report Format Number %d", rn);
304304
if( db_step(&q)!=SQLITE_ROW ){
305305
@ <p>Unknown report number: %d(rn)</p>
306306
style_footer();
307
+ db_finalize(&q);
307308
return;
308309
}
309310
zTitle = db_column_text(&q, 0);
310311
zSQL = db_column_text(&q, 1);
311312
zOwner = db_column_text(&q, 2);
@@ -323,10 +324,11 @@
323324
output_color_key(zClrKey, 0, "border=0 cellspacing=0 cellpadding=3");
324325
@ </td>
325326
@ </tr></table>
326327
report_format_hints();
327328
style_footer();
329
+ db_finalize(&q);
328330
}
329331
330332
/*
331333
** WEBPAGE: /rptnew
332334
** WEBPAGE: /rptedit
@@ -612,23 +614,10 @@
612614
@ priority AS 'Pri',
613615
@ title AS 'Title',
614616
@ description AS '_Description', -- When the column name begins with '_'
615617
@ remarks AS '_Remarks' -- content is rendered as wiki
616618
@ 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
630619
@ </pre></blockquote>
631620
@
632621
}
633622
634623
/*
@@ -1039,10 +1028,11 @@
10391028
/* view_add_functions(tabs); */
10401029
db_prepare(&q,
10411030
"SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn);
10421031
if( db_step(&q)!=SQLITE_ROW ){
10431032
cgi_redirect("reportlist");
1033
+ db_finalize(&q);
10441034
return;
10451035
}
10461036
zTitle = db_column_malloc(&q, 0);
10471037
zSql = db_column_malloc(&q, 1);
10481038
zOwner = db_column_malloc(&q, 2);
10491039
--- 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
--- src/setup.c
+++ src/setup.c
@@ -277,10 +277,11 @@
277277
@ </p></li>
278278
@
279279
@ </ol>
280280
@ </td></tr></table>
281281
style_footer();
282
+ db_finalize(&s);
282283
}
283284
284285
/*
285286
** Return true if zPw is a valid password string. A valid
286287
** password string is:
287288
--- 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 @@
11931193
const char *z; /* Used to check if this is an EXPLAIN */
11941194
int *abYield = 0; /* True if op is an OP_Yield */
11951195
int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
11961196
int iOp; /* Index of operation in p->aiIndent[] */
11971197
1198
- const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
1198
+ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1199
+ "NextIfOpen", "PrevIfOpen", 0 };
11991200
const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 };
12001201
const char *azGoto[] = { "Goto", 0 };
12011202
12021203
/* Try to figure out if this is really an EXPLAIN statement. If this
12031204
** cannot be verified, return early. */
12041205
--- 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 @@
11
/******************************************************************************
22
** 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
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -220,13 +220,13 @@
220220
**
221221
** See also: [sqlite3_libversion()],
222222
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
223223
** [sqlite_version()] and [sqlite_source_id()].
224224
*/
225
-#define SQLITE_VERSION "3.8.4.1"
225
+#define SQLITE_VERSION "3.8.4.3"
226226
#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"
228228
229229
/*
230230
** CAPI3REF: Run-Time Library Version Numbers
231231
** KEYWORDS: sqlite3_version, sqlite3_sourceid
232232
**
@@ -35489,25 +35489,31 @@
3548935489
3549035490
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
3549135491
if( nChar==0 ){
3549235492
return 0;
3549335493
}
35494
- zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+8 );
35494
+ zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 );
3549535495
if( zWideFilename==0 ){
3549635496
return 0;
3549735497
}
3549835498
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1,
35499
- zWideFilename+4, nChar);
35499
+ zWideFilename, nChar);
3550035500
if( nChar==0 ){
3550135501
sqlite3_free(zWideFilename);
3550235502
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
+ }
3550935515
}
3551035516
zConverted = zWideFilename;
3551135517
}
3551235518
#ifdef SQLITE_WIN32_HAS_ANSI
3551335519
else{
@@ -64803,10 +64809,11 @@
6480364809
i = 1;
6480464810
pRhs++;
6480564811
}else{
6480664812
idx1 = getVarint32(aKey1, szHdr1);
6480764813
d1 = szHdr1;
64814
+ if( d1>(unsigned)nKey1 ) return 1; /* Corruption */
6480864815
i = 0;
6480964816
}
6481064817
6481164818
VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
6481264819
assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
@@ -115289,11 +115296,11 @@
115289115296
k = pLevel->addrBody;
115290115297
pOp = sqlite3VdbeGetOp(v, k);
115291115298
for(; k<last; k++, pOp++){
115292115299
if( pOp->p1!=pLevel->iTabCur ) continue;
115293115300
if( pOp->opcode==OP_Column ){
115294
- pOp->opcode = OP_SCopy;
115301
+ pOp->opcode = OP_Copy;
115295115302
pOp->p1 = pOp->p2 + pTabItem->regResult;
115296115303
pOp->p2 = pOp->p3;
115297115304
pOp->p3 = 0;
115298115305
}else if( pOp->opcode==OP_Rowid ){
115299115306
pOp->opcode = OP_Null;
115300115307
--- 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 @@
11
/******************************************************************************
22
** 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
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -220,13 +220,13 @@
220220
**
221221
** See also: [sqlite3_libversion()],
222222
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
223223
** [sqlite_version()] and [sqlite_source_id()].
224224
*/
225
-#define SQLITE_VERSION "3.8.4.1"
225
+#define SQLITE_VERSION "3.8.4.3"
226226
#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"
228228
229229
/*
230230
** CAPI3REF: Run-Time Library Version Numbers
231231
** KEYWORDS: sqlite3_version, sqlite3_sourceid
232232
**
@@ -35489,25 +35489,31 @@
3548935489
3549035490
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
3549135491
if( nChar==0 ){
3549235492
return 0;
3549335493
}
35494
- zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+8 );
35494
+ zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 );
3549535495
if( zWideFilename==0 ){
3549635496
return 0;
3549735497
}
3549835498
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1,
35499
- zWideFilename+4, nChar);
35499
+ zWideFilename, nChar);
3550035500
if( nChar==0 ){
3550135501
sqlite3_free(zWideFilename);
3550235502
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
+ }
3550935515
}
3551035516
zConverted = zWideFilename;
3551135517
}
3551235518
#ifdef SQLITE_WIN32_HAS_ANSI
3551335519
else{
@@ -64803,10 +64809,11 @@
6480364809
i = 1;
6480464810
pRhs++;
6480564811
}else{
6480664812
idx1 = getVarint32(aKey1, szHdr1);
6480764813
d1 = szHdr1;
64814
+ if( d1>(unsigned)nKey1 ) return 1; /* Corruption */
6480864815
i = 0;
6480964816
}
6481064817
6481164818
VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
6481264819
assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
@@ -115289,11 +115296,11 @@
115289115296
k = pLevel->addrBody;
115290115297
pOp = sqlite3VdbeGetOp(v, k);
115291115298
for(; k<last; k++, pOp++){
115292115299
if( pOp->p1!=pLevel->iTabCur ) continue;
115293115300
if( pOp->opcode==OP_Column ){
115294
- pOp->opcode = OP_SCopy;
115301
+ pOp->opcode = OP_Copy;
115295115302
pOp->p1 = pOp->p2 + pTabItem->regResult;
115296115303
pOp->p2 = pOp->p3;
115297115304
pOp->p3 = 0;
115298115305
}else if( pOp->opcode==OP_Rowid ){
115299115306
pOp->opcode = OP_Null;
115300115307
--- 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 @@
105105
**
106106
** See also: [sqlite3_libversion()],
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110
-#define SQLITE_VERSION "3.8.4.1"
110
+#define SQLITE_VERSION "3.8.4.3"
111111
#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"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.8.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 @@
4848
}
4949
}else{
5050
/* Autosync defaults on. To make it default off, "return" here. */
5151
}
5252
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;
5757
url_prompt_for_password();
5858
}
5959
g.zHttpAuth = get_httpauth();
6060
url_remember();
6161
#if 0 /* Disabled for now */
@@ -69,11 +69,11 @@
6969
*/
7070
configSync = CONFIGSET_SHUN;
7171
}
7272
#endif
7373
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);
7575
url_enable_proxy("via proxy: ");
7676
rc = client_sync(flags, configSync, 0);
7777
if( rc ) fossil_warning("Autosync failed");
7878
return rc;
7979
}
@@ -121,22 +121,22 @@
121121
clone_ssh_db_set_options();
122122
}
123123
url_parse(zUrl, urlFlags);
124124
remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
125125
url_remember();
126
- if( g.urlProtocol==0 ){
126
+ if( g.url.protocol==0 ){
127127
if( urlOptional ) fossil_exit(0);
128128
usage("URL");
129129
}
130130
user_select();
131131
if( g.argc==2 ){
132132
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);
134134
}else if( (*pSyncFlags) & SYNC_PUSH ){
135
- fossil_print("Push to %s\n", g.urlCanonical);
135
+ fossil_print("Push to %s\n", g.url.canonical);
136136
}else if( (*pSyncFlags) & SYNC_PULL ){
137
- fossil_print("Pull from %s\n", g.urlCanonical);
137
+ fossil_print("Pull from %s\n", g.url.canonical);
138138
}
139139
}
140140
url_enable_proxy("via proxy: ");
141141
*pConfigFlags |= configSync;
142142
}
@@ -278,8 +278,8 @@
278278
if( zUrl==0 ){
279279
fossil_print("off\n");
280280
return;
281281
}else{
282282
url_parse(zUrl, 0);
283
- fossil_print("%s\n", g.urlCanonical);
283
+ fossil_print("%s\n", g.url.canonical);
284284
}
285285
}
286286
--- 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 @@
571571
** WEBPAGE: tarball
572572
** URL: /tarball/RID.tar.gz
573573
**
574574
** Generate a compressed tarball for a checkin.
575575
** 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
+**
576585
*/
577586
void tarball_page(void){
578587
int rid;
579588
char *zName, *zRid;
580589
int nName, nRid;
581590
--- 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
+90 -10
--- src/th.c
+++ src/th.c
@@ -128,10 +128,11 @@
128128
*/
129129
static int thNextCommand(Th_Interp*, const char *z, int n, int *pN);
130130
static int thNextEscape (Th_Interp*, const char *z, int n, int *pN);
131131
static int thNextVarname(Th_Interp*, const char *z, int n, int *pN);
132132
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);
133134
static int thNextSpace (Th_Interp*, const char *z, int n, int *pN);
134135
135136
/*
136137
** Given that the input string (z, n) contains a language construct of
137138
** the relevant type (a command enclosed in [], an escape sequence
@@ -1866,10 +1867,43 @@
18661867
{"^", OP_BITWISE_XOR, 9, ARG_INTEGER},
18671868
{"|", OP_BITWISE_OR, 10, ARG_INTEGER},
18681869
18691870
{0,0,0,0}
18701871
};
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
+}
18711905
18721906
/*
18731907
** The first part of the string (zInput,nInput) contains a number.
18741908
** Set *pnVarname to the number of bytes in the numeric string.
18751909
*/
@@ -1877,13 +1911,13 @@
18771911
Th_Interp *interp,
18781912
const char *zInput,
18791913
int nInput,
18801914
int *pnLiteral
18811915
){
1882
- int i;
1916
+ int i = 0;
18831917
int seenDot = 0;
1884
- for(i=0; i<nInput; i++){
1918
+ for(; i<nInput; i++){
18851919
char c = zInput[i];
18861920
if( (seenDot || c!='.') && !th_isdigit(c) ) break;
18871921
if( c=='.' ) seenDot = 1;
18881922
}
18891923
*pnLiteral = i;
@@ -1996,10 +2030,11 @@
19962030
case OP_BITWISE_OR: iRes = iLeft|iRight; break;
19972031
case OP_LOGICAL_AND: iRes = iLeft&&iRight; break;
19982032
case OP_LOGICAL_OR: iRes = iLeft||iRight; break;
19992033
case OP_UNARY_MINUS: iRes = -iLeft; break;
20002034
case OP_UNARY_PLUS: iRes = +iLeft; break;
2035
+ case OP_BITWISE_NOT: iRes = ~iLeft; break;
20012036
case OP_LOGICAL_NOT: iRes = !iLeft; break;
20022037
default: assert(!"Internal error");
20032038
}
20042039
Th_SetResultInt(interp, iRes);
20052040
}else if( rc==TH_OK && eArgType==ARG_NUMBER ){
@@ -2154,12 +2189,17 @@
21542189
}else{
21552190
Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr));
21562191
const char *z = &zExpr[i];
21572192
21582193
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':
21612201
thNextNumber(interp, z, nExpr-i, &pNew->nValue);
21622202
break;
21632203
21642204
case '$':
21652205
thNextVarname(interp, z, nExpr-i, &pNew->nValue);
@@ -2410,11 +2450,12 @@
24102450
** '\f' 0x0C
24112451
** '\r' 0x0D
24122452
**
24132453
** Whitespace characters have the 0x01 flag set. Decimal digits have the
24142454
** 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.
24162457
**
24172458
** The special list characters have the 0x10 flag set
24182459
**
24192460
** { } [ ] \ ; ' "
24202461
**
@@ -2423,14 +2464,14 @@
24232464
*/
24242465
static unsigned char aCharProp[256] = {
24252466
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, /* 0x0. */
24262467
0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1. */
24272468
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. */
24302471
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. */
24322473
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 4, 20, 4, 4, /* 0x7. */
24332474
24342475
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8. */
24352476
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9. */
24362477
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA. */
@@ -2454,10 +2495,22 @@
24542495
return (aCharProp[(unsigned char)c] & 0x11);
24552496
}
24562497
int th_isalnum(char c){
24572498
return (aCharProp[(unsigned char)c] & 0x0A);
24582499
}
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
+}
24592512
24602513
#ifndef LONGDOUBLE_TYPE
24612514
# define LONGDOUBLE_TYPE long double
24622515
#endif
24632516
@@ -2570,24 +2623,51 @@
25702623
** interpreter result too.
25712624
*/
25722625
int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){
25732626
int i = 0;
25742627
int iOut = 0;
2628
+ int base = 10;
2629
+ int (*isdigit)(char) = th_isdigit;
25752630
25762631
if( n<0 ){
25772632
n = th_strlen(z);
25782633
}
25792634
25802635
if( n>0 && (z[0]=='-' || z[0]=='+') ){
25812636
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
+ }
25822654
}
25832655
for(; i<n; i++){
2584
- if( !th_isdigit(z[i]) ){
2656
+ char c = z[i];
2657
+ if( !isdigit(c) ){
25852658
Th_ErrorMessage(interp, "expected integer, got: \"", z, n);
25862659
return TH_ERROR;
25872660
}
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;
25892669
}
25902670
25912671
if( n>0 && z[0]=='-' ){
25922672
iOut *= -1;
25932673
}
25942674
--- 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
+4
--- src/th.h
+++ src/th.h
@@ -145,11 +145,15 @@
145145
*/
146146
int th_strlen(const char *);
147147
int th_isdigit(char);
148148
int th_isspace(char);
149149
int th_isalnum(char);
150
+int th_isalpha(char);
150151
int th_isspecial(char);
152
+int th_ishexdig(char);
153
+int th_isoctdig(char);
154
+int th_isbindig(char);
151155
char *th_strdup(Th_Interp *interp, const char *z, int n);
152156
153157
/*
154158
** Interfaces to register the language extensions.
155159
*/
156160
--- 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 @@
4848
*/
4949
void hyperlink_to_uuid(const char *zUuid){
5050
char z[UUID_SIZE+1];
5151
shorten_uuid(z, zUuid);
5252
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>
5454
}else{
5555
@ <span class="timelineHistDsp">[%s(z)]</span>
5656
}
5757
}
5858
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
-
7259
/*
7360
** Generate a hyperlink to a date & time.
7461
*/
7562
void hyperlink_to_date(const char *zDate, const char *zSuffix){
7663
if( zSuffix==0 ) zSuffix = "";
@@ -448,11 +435,11 @@
448435
@ (user: %h(zDispUser)%s(zTagList?",":"\051")
449436
}
450437
451438
/* Generate a "detail" link for tags. */
452439
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>]
454441
}
455442
456443
/* Generate the "tags: TAGLIST" at the end of the comment, together
457444
** with hyperlinks to the tag list.
458445
*/
@@ -527,23 +514,23 @@
527514
}
528515
continue;
529516
}
530517
if( isNew ){
531518
@ <li> %h(zFilename) (new file) &nbsp;
532
- @ %z(href("%R/artifact/%S",zNew))[view]</a></li>
519
+ @ %z(href("%R/artifact/%s",zNew))[view]</a></li>
533520
}else if( isDel ){
534521
@ <li> %h(zFilename) (deleted)</li>
535522
}else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
536523
@ <li> %h(zOldName) &rarr; %h(zFilename)
537
- @ %z(href("%R/artifact/%S",zNew))[view]</a></li>
524
+ @ %z(href("%R/artifact/%s",zNew))[view]</a></li>
538525
}else{
539526
if( zOldName!=0 ){
540527
@ <li> %h(zOldName) &rarr; %h(zFilename)
541528
}else{
542529
@ <li> %h(zFilename) &nbsp;
543530
}
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>
545532
}
546533
}
547534
db_reset(&fchngQuery);
548535
if( inUl ){
549536
@ </ul>
@@ -1442,11 +1429,11 @@
14421429
blob_appendf(&desc, "%d %ss", n, zEType);
14431430
}
14441431
if( zUses ){
14451432
char *zFilenames = names_of_file(zUses);
14461433
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);
14481435
tmFlags |= TIMELINE_DISJOINT;
14491436
}
14501437
if( renameOnly ){
14511438
blob_appendf(&desc, " that contain filename changes");
14521439
tmFlags |= TIMELINE_DISJOINT|TIMELINE_FRENAMES;
@@ -1963,11 +1950,11 @@
19631950
" AND blob.rid=c.cid"
19641951
);
19651952
while( db_step(&q)==SQLITE_ROW ){
19661953
const char *zUuid = db_column_text(&q, 0);
19671954
@ <li>
1968
- @ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&amp;d=%S(zUuid)&amp;unhide">%S(zUuid)</a>
1955
+ @ <a href="%s(g.zTop)/timeline?p=%s(zUuid)&amp;d=%s(zUuid)&amp;unhide">%S(zUuid)</a>
19691956
}
19701957
db_finalize(&q);
19711958
style_footer();
19721959
}
19731960
@@ -2384,10 +2371,79 @@
23842371
@ </tbody></table>
23852372
db_finalize(&query);
23862373
output_table_sorting_javascript("statsTable","tnx");
23872374
}
23882375
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)%%;'>&nbsp;</div>
2437
+ @ </td>
2438
+ @</tr>
2439
+ }
2440
+ @ </tbody></table>
2441
+ db_finalize(&query);
2442
+ output_table_sorting_javascript("statsTable","ntnx");
2443
+}
2444
+
23892445
23902446
/*
23912447
** Helper for stats_report_by_month_year(), which generates a list of
23922448
** week numbers. zTimeframe should be either a timeframe in the form YYYY
23932449
** or YYYY-MM.
@@ -2554,10 +2610,11 @@
25542610
timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user");
25552611
}
25562612
timeline_submenu(&url, "By Year", "view", "byyear", 0);
25572613
timeline_submenu(&url, "By Month", "view", "bymonth", 0);
25582614
timeline_submenu(&url, "By Week", "view", "byweek", 0);
2615
+ timeline_submenu(&url, "By Weekday", "view", "byweekday", 0);
25592616
timeline_submenu(&url, "By User", "view", "byuser", "user");
25602617
url_reset(&url);
25612618
style_header("Activity Reports");
25622619
if(0==fossil_strcmp(zView,"byyear")){
25632620
stats_report_by_month_year(0, 0, zUserName);
@@ -2565,17 +2622,20 @@
25652622
stats_report_by_month_year(1, 0, zUserName);
25662623
}else if(0==fossil_strcmp(zView,"byweek")){
25672624
stats_report_year_weeks(zUserName);
25682625
}else if(0==fossil_strcmp(zView,"byuser")){
25692626
stats_report_by_user();
2627
+ }else if(0==fossil_strcmp(zView,"byweekday")){
2628
+ stats_report_day_of_week();
25702629
}else{
25712630
@ <h1>Select a report to show:</h1>
25722631
@ <ul>
25732632
@ <li><a href='?view=byyear'>Events by year</a></li>
25742633
@ <li><a href='?view=bymonth'>Events by month</a></li>
25752634
@ <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>
25762636
@ <li><a href='?view=byuser'>Events by user</a></li>
25772637
@ </ul>
25782638
}
25792639
25802640
style_footer();
25812641
}
25822642
--- 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) &nbsp;
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) &rarr; %h(zFilename)
537 @ %z(href("%R/artifact/%S",zNew))[view]</a></li>
538 }else{
539 if( zOldName!=0 ){
540 @ <li> %h(zOldName) &rarr; %h(zFilename)
541 }else{
542 @ <li> %h(zFilename) &nbsp;
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)&amp;d=%S(zUuid)&amp;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) &nbsp;
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) &rarr; %h(zFilename)
524 @ %z(href("%R/artifact/%s",zNew))[view]</a></li>
525 }else{
526 if( zOldName!=0 ){
527 @ <li> %h(zOldName) &rarr; %h(zFilename)
528 }else{
529 @ <li> %h(zFilename) &nbsp;
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)&amp;d=%s(zUuid)&amp;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)%%;'>&nbsp;</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 @@
446446
style_submenu_element("Attach", "Add An Attachment",
447447
"%s/attachadd?tkt=%T&from=%s/tktview/%t",
448448
g.zTop, zUuid, g.zTop, zUuid);
449449
}
450450
if( P("plaintext") ){
451
- style_submenu_element("Formatted", "Formatted", "%R/tktview/%S", zUuid);
451
+ style_submenu_element("Formatted", "Formatted", "%R/tktview/%s", zUuid);
452452
}else{
453453
style_submenu_element("Plaintext", "Plaintext",
454
- "%R/tktview/%S?plaintext", zUuid);
454
+ "%R/tktview/%s?plaintext", zUuid);
455455
}
456456
style_header("View Ticket");
457457
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
458458
ticket_init();
459459
initializeVariablesFromCGI();
@@ -895,14 +895,14 @@
895895
"%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid);
896896
style_submenu_element("Timeline", "Timeline",
897897
"%s/tkttimeline?name=%s", g.zTop, zUuid);
898898
if( P("plaintext")!=0 ){
899899
style_submenu_element("Formatted", "Formatted",
900
- "%R/tkthistory/%S", zUuid);
900
+ "%R/tkthistory/%s", zUuid);
901901
}else{
902902
style_submenu_element("Plaintext", "Plaintext",
903
- "%R/tkthistory/%S?plaintext", zUuid);
903
+ "%R/tkthistory/%s?plaintext", zUuid);
904904
}
905905
style_header(zTitle);
906906
free(zTitle);
907907
908908
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
@@ -924,17 +924,14 @@
924924
" ORDER BY 1",
925925
timeline_utc(), tagid, timeline_utc(), tagid
926926
);
927927
while( db_step(&q)==SQLITE_ROW ){
928928
Manifest *pTicket;
929
- char zShort[12];
930929
const char *zDate = db_column_text(&q, 0);
931930
int rid = db_column_int(&q, 1);
932931
const char *zChngUuid = db_column_text(&q, 2);
933932
const char *zFile = db_column_text(&q, 4);
934
- memcpy(zShort, zChngUuid, 10);
935
- zShort[10] = 0;
936933
if( nChng==0 ){
937934
@ <ol>
938935
}
939936
nChng++;
940937
if( zFile!=0 ){
@@ -944,22 +941,22 @@
944941
@
945942
@ <li><p>Delete attachment "%h(zFile)"
946943
}else{
947944
@
948945
@ <li><p>Add attachment
949
- @ "%z(href("%R/artifact/%S",zSrc))%s(zFile)</a>"
946
+ @ "%z(href("%R/artifact/%s",zSrc))%s(zFile)</a>"
950947
}
951
- @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
948
+ @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>]
952949
@ (rid %d(rid)) by
953950
hyperlink_to_user(zUser,zDate," on");
954951
hyperlink_to_date(zDate, ".</p>");
955952
}else{
956953
pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
957954
if( pTicket ){
958955
@
959956
@ <li><p>Ticket change
960
- @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
957
+ @ [%z(href("%R/artifact/%s",zChngUuid))%.10s(zChngUuid)</a>]
961958
@ (rid %d(rid)) by
962959
hyperlink_to_user(pTicket->zUser,zDate," on");
963960
hyperlink_to_date(zDate, ":");
964961
@ </p>
965962
ticket_output_change_artifact(pTicket, "a");
@@ -1219,35 +1216,31 @@
12191216
zTktUuid);
12201217
if( tagid==0 ){
12211218
fossil_fatal("no such ticket %h", zTktUuid);
12221219
}
12231220
db_prepare(&q,
1224
- "SELECT datetime(mtime%s), objid, uuid, NULL, NULL, NULL"
1221
+ "SELECT datetime(mtime%s), objid, NULL, NULL, NULL"
12251222
" FROM event, blob"
12261223
" WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)"
12271224
" AND blob.rid=event.objid"
12281225
" UNION "
1229
- "SELECT datetime(mtime%s), attachid, uuid, src, "
1230
- " filename, user"
1226
+ "SELECT datetime(mtime%s), attachid, filename, "
1227
+ " src, user"
12311228
" FROM attachment, blob"
12321229
" WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
12331230
" AND blob.rid=attachid"
12341231
" ORDER BY 1 DESC",
12351232
timeline_utc(), tagid, timeline_utc(), tagid
12361233
);
12371234
while( db_step(&q)==SQLITE_ROW ){
12381235
Manifest *pTicket;
1239
- char zShort[12];
12401236
const char *zDate = db_column_text(&q, 0);
12411237
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);
12461239
if( zFile!=0 ){
12471240
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);
12491242
if( zSrc==0 || zSrc[0]==0 ){
12501243
fossil_print("Delete attachment %s\n", zFile);
12511244
}else{
12521245
fossil_print("Add attachment %s\n", zFile);
12531246
}
12541247
--- 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
--- src/update.c
+++ src/update.c
@@ -625,10 +625,12 @@
625625
ManifestFile *pFile;
626626
int rid=0;
627627
628628
if( revision ){
629629
rid = name_to_typed_rid(revision,"ci");
630
+ }else if( !g.localOpen ){
631
+ rid = name_to_typed_rid(db_get("main-branch","trunk"),"ci");
630632
}else{
631633
rid = db_lget_int("checkout", 0);
632634
}
633635
if( !is_a_version(rid) ){
634636
if( errCode>0 ) return errCode;
635637
--- 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 @@
275275
276276
/*
277277
** Parse the given URL, which describes a sync server. Populate variables
278278
** in the global "g" structure as follows:
279279
**
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
292292
**
293293
** HTTP url format as follows (HTTPS is the same with a different scheme):
294294
**
295295
** http://userid:password@host:port/path
296296
**
@@ -298,11 +298,11 @@
298298
**
299299
** ssh://userid@host:port/path?fossil=path/to/fossil.exe
300300
**
301301
*/
302302
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);
304304
}
305305
306306
/*
307307
** COMMAND: test-urlparser
308308
**
@@ -323,25 +323,25 @@
323323
if( g.argc!=3 && g.argc!=4 ){
324324
usage("URL");
325325
}
326326
url_parse(g.argv[2], fg);
327327
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;
343343
if( i==0 ){
344344
fossil_print("********\n");
345345
url_enable_proxy("Using proxy: ");
346346
}
347347
}
@@ -385,38 +385,38 @@
385385
if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){
386386
zProxy = fossil_getenv("http_proxy");
387387
}
388388
}
389389
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 = "";
401401
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);
407407
char *zCredentials2 = encode64(zCredentials1, -1);
408
- g.urlProxyAuth = mprintf("Basic %z", zCredentials2);
408
+ g.url.proxyAuth = mprintf("Basic %z", zCredentials2);
409409
free(zCredentials1);
410410
}
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;
418418
}
419419
}
420420
421421
#if INTERFACE
422422
/*
@@ -529,35 +529,35 @@
529529
pUrlData->user);
530530
}
531531
}
532532
533533
/*
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.
536536
*/
537537
void url_prompt_for_password(void){
538
- url_prompt_for_password_local(GLOBAL_URL());
538
+ url_prompt_for_password_local(&g.url);
539539
}
540540
541541
/*
542542
** Remember the URL and password if requested.
543543
*/
544544
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);
549549
}
550550
}
551551
}
552552
553553
/* Preemptively prompt for a password if a username is given in the
554554
** URL but no password.
555555
*/
556556
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)
559559
&& isatty(fileno(stdin))
560560
){
561561
url_prompt_for_password();
562562
}
563563
}
564564
--- 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 @@
375375
if( attempt_user(fossil_getenv("LOGNAME")) ) return;
376376
377377
if( attempt_user(fossil_getenv("USERNAME")) ) return;
378378
379379
url_parse(0, 0);
380
- if( g.urlUser && attempt_user(g.urlUser) ) return;
380
+ if( g.url.user && attempt_user(g.url.user) ) return;
381381
382382
fossil_print(
383383
"Cannot figure out who you are! Consider using the --user\n"
384384
"command line option, setting your USER environment variable,\n"
385385
"or setting a default user with \"fossil user default USER\".\n"
386386
--- 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 @@
312312
return 1;
313313
#else
314314
return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF;
315315
#endif
316316
}
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
+}
317327
--- 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 @@
241241
if( rid ){
242242
style_submenu_element("Diff", "Last change",
243243
"%R/wdiff?name=%T&a=%d", zPageName, rid);
244244
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
245245
style_submenu_element("Details", "Details",
246
- "%R/info/%S", zUuid);
246
+ "%R/info/%s", zUuid);
247247
}
248248
if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
249249
if( db_get_boolean("wysiwyg-wiki", 0) ){
250250
style_submenu_element("Edit", "Edit Wiki Page",
251251
"%s/wikiedit?name=%T&wysiwyg=1",
252252
--- 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 @@
3535
3636
3737
/*
3838
** These are the only markup attributes allowed.
3939
*/
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
+};
98104
99105
static const struct AllowedAttribute {
100106
const char *zName;
101107
unsigned int iMask;
102108
} aAttribute[] = {
109
+ /* These indexes MUST line up with their
110
+ corresponding allowed_attr_t enum values.
111
+ */
103112
{ 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 },
133142
};
134143
135144
/*
136145
** Use binary search to locate a tag in the aAttribute[] table.
137146
*/
@@ -216,16 +225,17 @@
216225
#define MARKUP_TBODY 50
217226
#define MARKUP_TD 51
218227
#define MARKUP_TFOOT 52
219228
#define MARKUP_TH 53
220229
#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
227237
228238
/*
229239
** The various markup is divided into the following types:
230240
*/
231241
#define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -348,10 +358,11 @@
348358
{ "th", MARKUP_TH, MUTYPE_TD,
349359
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
350360
AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
351361
{ "thead", MARKUP_THEAD, MUTYPE_BLOCK,
352362
AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
363
+ { "title", MARKUP_TITLE, MUTYPE_BLOCK, 0 },
353364
{ "tr", MARKUP_TR, MUTYPE_TR,
354365
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
355366
{ "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE },
356367
{ "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE },
357368
{ "ul", MARKUP_UL, MUTYPE_LIST,
@@ -787,11 +798,11 @@
787798
p->nAttr = 1;
788799
if( c=='>' ) return;
789800
}
790801
while( fossil_isspace(z[i]) ){ i++; }
791802
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 */
793804
j = 0;
794805
while( fossil_isalnum(z[i]) ){
795806
if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]);
796807
i++;
797808
}
@@ -869,12 +880,14 @@
869880
static void unparseMarkup(ParsedMarkup *p){
870881
int i, n;
871882
for(i=0; i<p->nAttr; i++){
872883
char *z = p->aAttr[i].zValue;
873884
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
+ }
876889
}
877890
}
878891
879892
/*
880893
** Return the value of attribute attrId. Return NULL if there is no
@@ -1468,10 +1481,19 @@
14681481
}
14691482
case TOKEN_MARKUP: {
14701483
const char *zId;
14711484
int iDiv;
14721485
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
+ }
14731495
14741496
/* Markup of the form </div id=ID> where there is a matching
14751497
** ID somewhere on the stack. Exit any contained verbatim.
14761498
** Pop the stack up to the matching <div>. Discard the </div>
14771499
*/
14781500
--- 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 @@
13751375
static double fossil_fabs(double x){
13761376
return x>0.0 ? x : -x;
13771377
}
13781378
13791379
/*
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
13811381
** routine is called by the client.
13821382
**
13831383
** Records are pushed to the server if pushFlag is true. Records
13841384
** are pulled if pullFlag is true. A full sync occurs if both are
13851385
** true.
@@ -1823,15 +1823,15 @@
18231823
defossilize(zMsg);
18241824
fossil_force_newline();
18251825
fossil_print("Error: %s\n", zMsg);
18261826
if( fossil_strcmp(zMsg, "login failed")==0 ){
18271827
if( nCycle<2 ){
1828
- g.urlPasswd = 0;
1828
+ g.url.passwd = 0;
18291829
go = 1;
18301830
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;
18331833
url_prompt_for_password();
18341834
url_remember();
18351835
}
18361836
}
18371837
}else{
@@ -1926,13 +1926,13 @@
19261926
19271927
fossil_force_newline();
19281928
fossil_print(
19291929
"%s finished with %lld bytes sent, %lld bytes received\n",
19301930
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);
19331933
db_multi_exec("DROP TABLE onremote");
19341934
manifest_crosslink_end(MC_PERMIT_HOOKS);
19351935
content_enable_dephantomize(1);
19361936
db_end_transaction(0);
19371937
return nErr;
19381938
}
19391939
--- 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 @@
4444
setup_menu_entry("Ticket", "xfersetup_ticket",
4545
"Specific TH1 code to run after processing a ticket change.");
4646
@ </table>
4747
4848
url_parse(0, 0);
49
- if( g.urlProtocol ){
49
+ if( g.url.protocol ){
5050
unsigned syncFlags;
5151
const char *zButton;
5252
char *zWarning;
5353
5454
if( db_get_boolean("dont-push", 0) ){
@@ -57,19 +57,19 @@
5757
zWarning = 0;
5858
}else{
5959
syncFlags = SYNC_PUSH | SYNC_PULL;
6060
zButton = "Synchronize";
6161
zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.",
62
- g.urlCanonical);
62
+ g.url.canonical);
6363
}
6464
if( P("sync") ){
6565
user_select();
6666
url_enable_proxy(0);
6767
client_sync(syncFlags, 0, 0);
6868
}
6969
@ <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
7171
@ testing the various transfer scripts.</p>
7272
@ <p>You can use the "http -async" command in your scripts, but
7373
@ make sure the "th1-uri-regexp" setting is set first.</p>
7474
if( zWarning ){
7575
@
7676
--- 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 @@
418418
** WEBPAGE: zip
419419
** URL: /zip/RID.zip
420420
**
421421
** Generate a ZIP archive for the baseline.
422422
** 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
+**
423432
*/
424433
void baseline_zip_page(void){
425434
int rid;
426435
char *zName, *zRid;
427436
int nName, nRid;
428437
--- 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
--- test/file1.test
+++ test/file1.test
@@ -24,10 +24,19 @@
2424
fossil test-simplify-name $path
2525
test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"}
2626
incr i
2727
}
2828
}
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
+}
2938
3039
simplify-name 100 . . .// . .. .. ..///// ..
3140
simplify-name 101 {} {} / / ///////// / ././././ .
3241
simplify-name 102 x x /x /x ///x //x
3342
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
@@ -38,5 +47,16 @@
3847
3948
if {$::tcl_platform(os)=="Windows NT"} {
4049
simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {}
4150
simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {}
4251
}
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}
4363
--- 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/file1.test
+++ test/file1.test
@@ -24,10 +24,19 @@
2424
fossil test-simplify-name $path
2525
test simplify-name-$testname.$i {$::RESULT=="\[$path\] -> \[$result\]"}
2626
incr i
2727
}
2828
}
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
+}
2938
3039
simplify-name 100 . . .// . .. .. ..///// ..
3140
simplify-name 101 {} {} / / ///////// / ././././ .
3241
simplify-name 102 x x /x /x ///x //x
3342
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
@@ -38,5 +47,16 @@
3847
3948
if {$::tcl_platform(os)=="Windows NT"} {
4049
simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {}
4150
simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {}
4251
}
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}
4363
--- 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 @@
11
#
22
# Tests for merging with renames
33
#
44
#
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
+}
512
613
######################################
714
# Test 1 #
815
# Reported: Ticket [554f44ee74e3d] #
916
######################################
1017
--- 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 @@
11
#
22
# Tests for merging with renames
33
#
44
#
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
+}
512
613
######################################
714
# Test 1 #
815
# Reported: Ticket [554f44ee74e3d] #
916
######################################
1017
--- 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/revert.test
+++ test/revert.test
@@ -36,10 +36,17 @@
3636
test revert-$testid$key $passed
3737
}
3838
3939
fossil undo
4040
}
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
+}
4148
4249
repo_init
4350
4451
# Prepare first commit
4552
#
4653
--- 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
--- test/revert.test
+++ test/revert.test
@@ -36,10 +36,17 @@
3636
test revert-$testid$key $passed
3737
}
3838
3939
fossil undo
4040
}
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
+}
4148
4249
repo_init
4350
4451
# Prepare first commit
4552
#
4653
--- 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 @@
362362
363363
###############################################################################
364364
365365
fossil test-th-eval "expr +2147483649.0"
366366
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
+
367480
--- 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 @@
362362
363363
###############################################################################
364364
365365
fossil test-th-eval "expr +2147483649.0"
366366
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
+
367480
--- 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
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -84,12 +84,12 @@
8484
#### The directories where the OpenSSL include and library files are located.
8585
# The recommended usage here is to use the Sysinternals junction tool
8686
# to create a hard link between an "openssl-1.x" sub-directory of the
8787
# Fossil source code directory and the target OpenSSL source directory.
8888
#
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
9191
9292
#### Either the directory where the Tcl library is installed or the Tcl
9393
# source code directory resides (depending on the value of the macro
9494
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
9595
# this directory must have "include" and "lib" sub-directories. If
@@ -669,15 +669,11 @@
669669
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
670670
671671
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
672672
$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
673673
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
679675
680676
zlib:
681677
$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a
682678
683679
clean-zlib:
@@ -1745,9 +1741,8 @@
17451741
$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
17461742
17471743
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
17481744
$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
17491745
1750
-ifdef FOSSIL_ENABLE_TCL
17511746
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
17521747
$(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
1753
-endif
1748
+
17541749
--- 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
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -84,12 +84,12 @@
8484
#### The directories where the OpenSSL include and library files are located.
8585
# The recommended usage here is to use the Sysinternals junction tool
8686
# to create a hard link between an "openssl-1.x" sub-directory of the
8787
# Fossil source code directory and the target OpenSSL source directory.
8888
#
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
9191
9292
#### Either the directory where the Tcl library is installed or the Tcl
9393
# source code directory resides (depending on the value of the macro
9494
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
9595
# this directory must have "include" and "lib" sub-directories. If
@@ -669,15 +669,11 @@
669669
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
670670
671671
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
672672
$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
673673
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
679675
680676
zlib:
681677
$(MAKE) -C $(ZLIBDIR) PREFIX=$(PREFIX) -f win32/Makefile.gcc libz.a
682678
683679
clean-zlib:
@@ -1745,9 +1741,7 @@
17451741
$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
17461742
17471743
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
17481744
$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
17491745
1750
-ifdef FOSSIL_ENABLE_TCL
17511746
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
17521747
$(XTCC) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
1753
-endif
17541748
--- 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 @@
2626
2727
# Uncomment to enable Tcl support
2828
# FOSSIL_ENABLE_TCL = 1
2929
3030
!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
3333
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
3434
!endif
3535
3636
!ifdef FOSSIL_ENABLE_TCL
3737
TCLDIR = $(B)\compat\tcl-8.6
@@ -310,10 +310,11 @@
310310
$(OX)\tag$O \
311311
$(OX)\tar$O \
312312
$(OX)\th$O \
313313
$(OX)\th_lang$O \
314314
$(OX)\th_main$O \
315
+ $(OX)\th_tcl$O \
315316
$(OX)\timeline$O \
316317
$(OX)\tkt$O \
317318
$(OX)\tktsetup$O \
318319
$(OX)\undo$O \
319320
$(OX)\unicode$O \
@@ -332,13 +333,10 @@
332333
$(OX)\xfer$O \
333334
$(OX)\xfersetup$O \
334335
$(OX)\zip$O \
335336
$(OX)\fossil.res
336337
337
-!ifdef FOSSIL_ENABLE_TCL
338
-OBJ = $(OBJ) $(OX)\th_tcl$O
339
-!endif
340338
341339
APPNAME = $(OX)\fossil$(E)
342340
PDBNAME = $(OX)\fossil$(P)
343341
344342
all: $(OX) $(APPNAME)
@@ -444,10 +442,11 @@
444442
echo $(OX)\tag.obj >> $@
445443
echo $(OX)\tar.obj >> $@
446444
echo $(OX)\th.obj >> $@
447445
echo $(OX)\th_lang.obj >> $@
448446
echo $(OX)\th_main.obj >> $@
447
+ echo $(OX)\th_tcl.obj >> $@
449448
echo $(OX)\timeline.obj >> $@
450449
echo $(OX)\tkt.obj >> $@
451450
echo $(OX)\tktsetup.obj >> $@
452451
echo $(OX)\undo.obj >> $@
453452
echo $(OX)\unicode.obj >> $@
@@ -464,13 +463,10 @@
464463
echo $(OX)\winhttp.obj >> $@
465464
echo $(OX)\wysiwyg.obj >> $@
466465
echo $(OX)\xfer.obj >> $@
467466
echo $(OX)\xfersetup.obj >> $@
468467
echo $(OX)\zip.obj >> $@
469
-!ifdef FOSSIL_ENABLE_TCL
470
- echo $(OX)\th_tcl.obj >> $@
471
-!endif
472468
echo $(LIBS) >> $@
473469
474470
$(OX):
475471
@-mkdir $@
476472
@@ -496,14 +492,12 @@
496492
$(TCC) /Fo$@ -c $**
497493
498494
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
499495
$(TCC) /Fo$@ -c $**
500496
501
-!ifdef FOSSIL_ENABLE_TCL
502497
$(OX)\th_tcl$O : $(SRCDIR)\th_tcl.c
503498
$(TCC) /Fo$@ -c $**
504
-!endif
505499
506500
VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
507501
$** > $@
508502
$(OX)\cson_amalgamation$O : $(SRCDIR)\cson_amalgamation.c
509503
$(TCC) /Fo$@ /c $**
510504
--- 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
--- www/changes.wiki
+++ www/changes.wiki
@@ -14,12 +14,15 @@
1414
* Add option --empty to the "[/help?cmd=open | fossil open]" command.
1515
* Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
1616
* Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to
1717
[/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame],
1818
[/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].
1921
* Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff
2022
and /vdiff UI pages.
23
+ * Enhanced [/reports?view=byweekday|/reports] with a "byweekday" view.
2124
2225
<h2>Changes For Version 1.28 (2014-01-27)</h2>
2326
* Enhance [/help?cmd=/reports | /reports] to support event type filtering.
2427
* When cloning a repository, the user name passed via the URL (if any)
2528
is now used as the default local admin user's name.
2629
--- 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
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -119,10 +119,24 @@
119119
120120
<p>Note that Fossil allows you to make multiple check-outs in
121121
separate directories from the same repository. This enables you,
122122
for example, to do builds from multiple branches or versions at
123123
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>
124138
125139
<h2>Configuring Your Local Repository</h2>
126140
127141
<p>When you create a new repository, either by cloning an existing
128142
project or create a new project of your own, you usually want to do some
@@ -227,10 +241,19 @@
227241
when you run [/help/update|update] and a [/help/push|push] happens
228242
automatically after you [/help/commit|commit]. So in normal practice,
229243
the push, pull, and sync commands are rarely used. But it is important
230244
to know about them, all the same.</p>
231245
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
+
232255
<h2>Branching And Merging</h2>
233256
234257
<p>Use the --branch option to the [/help/commit | commit] command
235258
to start a new branch. Note that in Fossil, branches are normally
236259
created when you commit, not before you start editing. You can
237260
--- 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

Keyboard Shortcuts

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