Fossil SCM

Make -w|--ignore-all-space option work the same as the GNU diff option with the same name.

jan.nijtmans 2014-03-17 11:34 UTC pending-review merge
Commit a7a61cdd6f2b5a5f23f29d0872edec40f5725bd9
--- 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/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,
726726
--- 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,
726
--- 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,
726
+43 -41
--- src/diff.c
+++ src/diff.c
@@ -29,11 +29,10 @@
2929
** of the diff output.
3030
*/
3131
#define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
3232
#define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
3333
#define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */
34
-#define DIFF_IGNORE_WSCHG ((u64)0x02000000) /* Ignore whitespace changes */
3534
#define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
3635
#define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
3736
#define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
3837
#define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
3938
#define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
@@ -91,11 +90,11 @@
9190
};
9291
9392
/*
9493
** Length of a dline
9594
*/
96
-#define LENGTH(X) ((X)->h & LENGTH_MASK)
95
+#define LENGTH(X) ((X)->n)
9796
9897
/*
9998
** A context for running a raw diff.
10099
**
101100
** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -177,16 +176,26 @@
177176
s = 0;
178177
if( diffFlags & DIFF_IGNORE_EOLWS ){
179178
while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
180179
}
181180
if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
181
+ int numws = 0;
182182
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
+ }
183195
}
184196
a[i].indent = s;
185
- for(h=0, x=s; x<k; x++){
186
- h = h ^ (h<<2) ^ z[x];
187
- }
188197
a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
189198
h2 = h % nLine;
190199
a[i].iNext = a[h2].iHash;
191200
a[h2].iHash = i+1;
192201
z += j+1;
@@ -199,21 +208,30 @@
199208
200209
/*
201210
** Return true if two DLine elements are identical.
202211
*/
203212
static int same_dline(DLine *pA, DLine *pB){
204
- return pA->h==pB->h && memcmp(pA->z,pB->z, pA->n)==0;
213
+ return pA->h==pB->h && memcmp(pA->z,pB->z, pA->h&LENGTH_MASK)==0;
205214
}
206215
207
-static int same_dline_ignore_wschg(DLine *pA, DLine *pB){
208
- return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
209
- pA->h & LENGTH_MASK)==0;
210
-}
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
+*/
211221
212222
static int same_dline_ignore_allws(DLine *pA, DLine *pB){
213
- return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
214
- pA->h & LENGTH_MASK)==0;
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 == b<pB->n-b;
231
+ }
232
+ return 0;
215233
}
216234
217235
/*
218236
** Return true if the regular expression *pRe matches any of the
219237
** N dlines
@@ -1789,22 +1807,18 @@
17891807
if( diffFlags & DIFF_INVERT ){
17901808
Blob *pTemp = pA_Blob;
17911809
pA_Blob = pB_Blob;
17921810
pB_Blob = pTemp;
17931811
}
1794
- ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0;
1812
+ ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0;
17951813
blob_to_utf8_no_bom(pA_Blob, 0);
17961814
blob_to_utf8_no_bom(pB_Blob, 0);
17971815
17981816
/* Prepare the input files */
17991817
memset(&c, 0, sizeof(c));
1800
- if( diffFlags & DIFF_IGNORE_WSCHG ){
1801
- if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
1802
- c.same_fn = same_dline_ignore_allws;
1803
- }else{
1804
- c.same_fn = same_dline_ignore_wschg;
1805
- }
1818
+ if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
1819
+ c.same_fn = same_dline_ignore_allws;
18061820
}else{
18071821
c.same_fn = same_dline;
18081822
}
18091823
c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
18101824
&c.nFrom, diffFlags);
@@ -1868,20 +1882,19 @@
18681882
18691883
/*
18701884
** Process diff-related command-line options and return an appropriate
18711885
** "diffFlags" integer.
18721886
**
1873
-** -b|--ignore-space-change Ignore space changes DIFF_IGNORE_WSCHG
18741887
** --brief Show filenames only DIFF_BRIEF
18751888
** -c|--context N N lines of context. DIFF_CONTEXT_MASK
18761889
** --html Format for HTML DIFF_HTML
18771890
** --invert Invert the diff DIFF_INVERT
18781891
** -n|--linenum Show line numbers DIFF_LINENO
18791892
** --noopt Disable optimization DIFF_NOOPT
18801893
** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
18811894
** --unified Unified diff. ~DIFF_SIDEBYSIDE
1882
-** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1895
+** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
18831896
** -W|--width N N character lines. DIFF_WIDTH_MASK
18841897
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
18851898
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
18861899
*/
18871900
u64 diff_options(void){
@@ -1889,15 +1902,12 @@
18891902
const char *z;
18901903
int f;
18911904
if( find_option("ignore-trailing-space","Z",0)!=0 ){
18921905
diffFlags = DIFF_IGNORE_EOLWS;
18931906
}
1894
- if( find_option("ignore-space-change","b",0)!=0 ){
1895
- diffFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
1896
- }
18971907
if( find_option("ignore-all-space","w",0)!=0 ){
1898
- diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
1908
+ diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
18991909
}
19001910
if( find_option("strip-trailing-cr",0,0)!=0 ){
19011911
diffFlags |= DIFF_STRIP_EOLCR;
19021912
}
19031913
if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
@@ -2016,16 +2026,12 @@
20162026
*/
20172027
static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
20182028
int i;
20192029
20202030
memset(p, 0, sizeof(*p));
2021
- if( diffFlags & DIFF_IGNORE_WSCHG ){
2022
- if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2023
- p->c.same_fn = same_dline_ignore_allws;
2024
- }else{
2025
- p->c.same_fn = same_dline_ignore_wschg;
2026
- }
2031
+ if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2032
+ p->c.same_fn = same_dline_ignore_allws;
20272033
}else{
20282034
p->c.same_fn = same_dline;
20292035
}
20302036
p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
20312037
diffFlags);
@@ -2390,16 +2396,15 @@
23902396
** the file was last modified. The "annotate" command shows line numbers
23912397
** and omits the username. The "blame" and "praise" commands show the user
23922398
** who made each checkin and omits the line number.
23932399
**
23942400
** Options:
2395
-** -b|--ignore-space-change Ignore white space changes when comparing lines
2396
-** --filevers Show file version numbers rather than check-in versions
2397
-** -l|--log List all versions analyzed
2398
-** -n|--limit N Only look backwards in time by N versions
2399
-** -w|--ignore-all-space Ignore white space when comparing lines
2400
-** -Z|--ignore-trailing-space Ignore whitespace at line end
2401
+** --filevers Show file version numbers rather than check-in versions
2402
+** -l|--log List all versions analyzed
2403
+** -n|--limit N Only look backwards in time by N versions
2404
+** -w|--ignore-all-space Ignore white space when comparing lines
2405
+** -Z|--ignore-trailing-space Ignore whitespace at line end
24012406
**
24022407
** See also: info, finfo, timeline
24032408
*/
24042409
void annotate_cmd(void){
24052410
int fnid; /* Filename ID */
@@ -2423,15 +2428,12 @@
24232428
iLimit = atoi(zLimit);
24242429
showLog = find_option("log","l",0)!=0;
24252430
if( find_option("ignore-trailing-space","Z",0)!=0 ){
24262431
annFlags = DIFF_IGNORE_EOLWS;
24272432
}
2428
- if( find_option("ignore-space-change","b",0)!=0 ){
2429
- annFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
2430
- }
24312433
if( find_option("ignore-all-space","w",0)!=0 ){
2432
- annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
2434
+ annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
24332435
}
24342436
fileVers = find_option("filevers",0,0)!=0;
24352437
db_must_be_within_tree();
24362438
if( g.argc<3 ) {
24372439
usage("FILENAME");
24382440
--- src/diff.c
+++ src/diff.c
@@ -29,11 +29,10 @@
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
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_WSCHG ((u64)0x02000000) /* Ignore whitespace changes */
35 #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
36 #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
37 #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
38 #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
39 #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
@@ -91,11 +90,11 @@
91 };
92
93 /*
94 ** Length of a dline
95 */
96 #define LENGTH(X) ((X)->h & LENGTH_MASK)
97
98 /*
99 ** A context for running a raw diff.
100 **
101 ** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -177,16 +176,26 @@
177 s = 0;
178 if( diffFlags & DIFF_IGNORE_EOLWS ){
179 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
180 }
181 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
 
182 while( s<k && fossil_isspace(z[s]) ){ s++; }
 
 
 
 
 
 
 
 
 
 
 
 
183 }
184 a[i].indent = s;
185 for(h=0, x=s; x<k; x++){
186 h = h ^ (h<<2) ^ z[x];
187 }
188 a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
189 h2 = h % nLine;
190 a[i].iNext = a[h2].iHash;
191 a[h2].iHash = i+1;
192 z += j+1;
@@ -199,21 +208,30 @@
199
200 /*
201 ** Return true if two DLine elements are identical.
202 */
203 static int same_dline(DLine *pA, DLine *pB){
204 return pA->h==pB->h && memcmp(pA->z,pB->z, pA->n)==0;
205 }
206
207 static int same_dline_ignore_wschg(DLine *pA, DLine *pB){
208 return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
209 pA->h & LENGTH_MASK)==0;
210 }
 
211
212 static int same_dline_ignore_allws(DLine *pA, DLine *pB){
213 return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
214 pA->h & LENGTH_MASK)==0;
 
 
 
 
 
 
 
 
215 }
216
217 /*
218 ** Return true if the regular expression *pRe matches any of the
219 ** N dlines
@@ -1789,22 +1807,18 @@
1789 if( diffFlags & DIFF_INVERT ){
1790 Blob *pTemp = pA_Blob;
1791 pA_Blob = pB_Blob;
1792 pB_Blob = pTemp;
1793 }
1794 ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0;
1795 blob_to_utf8_no_bom(pA_Blob, 0);
1796 blob_to_utf8_no_bom(pB_Blob, 0);
1797
1798 /* Prepare the input files */
1799 memset(&c, 0, sizeof(c));
1800 if( diffFlags & DIFF_IGNORE_WSCHG ){
1801 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
1802 c.same_fn = same_dline_ignore_allws;
1803 }else{
1804 c.same_fn = same_dline_ignore_wschg;
1805 }
1806 }else{
1807 c.same_fn = same_dline;
1808 }
1809 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
1810 &c.nFrom, diffFlags);
@@ -1868,20 +1882,19 @@
1868
1869 /*
1870 ** Process diff-related command-line options and return an appropriate
1871 ** "diffFlags" integer.
1872 **
1873 ** -b|--ignore-space-change Ignore space changes DIFF_IGNORE_WSCHG
1874 ** --brief Show filenames only DIFF_BRIEF
1875 ** -c|--context N N lines of context. DIFF_CONTEXT_MASK
1876 ** --html Format for HTML DIFF_HTML
1877 ** --invert Invert the diff DIFF_INVERT
1878 ** -n|--linenum Show line numbers DIFF_LINENO
1879 ** --noopt Disable optimization DIFF_NOOPT
1880 ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
1881 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1882 ** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1883 ** -W|--width N N character lines. DIFF_WIDTH_MASK
1884 ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
1885 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
1886 */
1887 u64 diff_options(void){
@@ -1889,15 +1902,12 @@
1889 const char *z;
1890 int f;
1891 if( find_option("ignore-trailing-space","Z",0)!=0 ){
1892 diffFlags = DIFF_IGNORE_EOLWS;
1893 }
1894 if( find_option("ignore-space-change","b",0)!=0 ){
1895 diffFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
1896 }
1897 if( find_option("ignore-all-space","w",0)!=0 ){
1898 diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
1899 }
1900 if( find_option("strip-trailing-cr",0,0)!=0 ){
1901 diffFlags |= DIFF_STRIP_EOLCR;
1902 }
1903 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
@@ -2016,16 +2026,12 @@
2016 */
2017 static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
2018 int i;
2019
2020 memset(p, 0, sizeof(*p));
2021 if( diffFlags & DIFF_IGNORE_WSCHG ){
2022 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2023 p->c.same_fn = same_dline_ignore_allws;
2024 }else{
2025 p->c.same_fn = same_dline_ignore_wschg;
2026 }
2027 }else{
2028 p->c.same_fn = same_dline;
2029 }
2030 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2031 diffFlags);
@@ -2390,16 +2396,15 @@
2390 ** the file was last modified. The "annotate" command shows line numbers
2391 ** and omits the username. The "blame" and "praise" commands show the user
2392 ** who made each checkin and omits the line number.
2393 **
2394 ** Options:
2395 ** -b|--ignore-space-change Ignore white space changes when comparing lines
2396 ** --filevers Show file version numbers rather than check-in versions
2397 ** -l|--log List all versions analyzed
2398 ** -n|--limit N Only look backwards in time by N versions
2399 ** -w|--ignore-all-space Ignore white space when comparing lines
2400 ** -Z|--ignore-trailing-space Ignore whitespace at line end
2401 **
2402 ** See also: info, finfo, timeline
2403 */
2404 void annotate_cmd(void){
2405 int fnid; /* Filename ID */
@@ -2423,15 +2428,12 @@
2423 iLimit = atoi(zLimit);
2424 showLog = find_option("log","l",0)!=0;
2425 if( find_option("ignore-trailing-space","Z",0)!=0 ){
2426 annFlags = DIFF_IGNORE_EOLWS;
2427 }
2428 if( find_option("ignore-space-change","b",0)!=0 ){
2429 annFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
2430 }
2431 if( find_option("ignore-all-space","w",0)!=0 ){
2432 annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
2433 }
2434 fileVers = find_option("filevers",0,0)!=0;
2435 db_must_be_within_tree();
2436 if( g.argc<3 ) {
2437 usage("FILENAME");
2438
--- src/diff.c
+++ src/diff.c
@@ -29,11 +29,10 @@
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
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 */
@@ -91,11 +90,11 @@
90 };
91
92 /*
93 ** Length of a dline
94 */
95 #define LENGTH(X) ((X)->n)
96
97 /*
98 ** A context for running a raw diff.
99 **
100 ** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -177,16 +176,26 @@
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;
@@ -199,21 +208,30 @@
208
209 /*
210 ** Return true if two DLine elements are identical.
211 */
212 static int same_dline(DLine *pA, 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(DLine *pA, 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 == b<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
@@ -1789,22 +1807,18 @@
1807 if( diffFlags & DIFF_INVERT ){
1808 Blob *pTemp = pA_Blob;
1809 pA_Blob = pB_Blob;
1810 pB_Blob = pTemp;
1811 }
1812 ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0;
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);
@@ -1868,20 +1882,19 @@
1882
1883 /*
1884 ** Process diff-related command-line options and return an appropriate
1885 ** "diffFlags" integer.
1886 **
 
1887 ** --brief Show filenames only DIFF_BRIEF
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){
@@ -1889,15 +1902,12 @@
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;
@@ -2016,16 +2026,12 @@
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);
@@ -2390,16 +2396,15 @@
2396 ** the file was last modified. The "annotate" command shows line numbers
2397 ** and omits the username. The "blame" and "praise" commands show the user
2398 ** who made each checkin and omits the line number.
2399 **
2400 ** Options:
2401 ** --filevers Show file version numbers rather than check-in versions
2402 ** -l|--log List all versions analyzed
2403 ** -n|--limit N Only look backwards in time by N versions
2404 ** -w|--ignore-all-space Ignore white space when comparing lines
2405 ** -Z|--ignore-trailing-space Ignore whitespace at line end
 
2406 **
2407 ** See also: info, finfo, timeline
2408 */
2409 void annotate_cmd(void){
2410 int fnid; /* Filename ID */
@@ -2423,15 +2428,12 @@
2428 iLimit = atoi(zLimit);
2429 showLog = find_option("log","l",0)!=0;
2430 if( find_option("ignore-trailing-space","Z",0)!=0 ){
2431 annFlags = DIFF_IGNORE_EOLWS;
2432 }
 
 
 
2433 if( find_option("ignore-all-space","w",0)!=0 ){
2434 annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
2435 }
2436 fileVers = find_option("filevers",0,0)!=0;
2437 db_must_be_within_tree();
2438 if( g.argc<3 ) {
2439 usage("FILENAME");
2440
+43 -41
--- src/diff.c
+++ src/diff.c
@@ -29,11 +29,10 @@
2929
** of the diff output.
3030
*/
3131
#define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
3232
#define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
3333
#define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */
34
-#define DIFF_IGNORE_WSCHG ((u64)0x02000000) /* Ignore whitespace changes */
3534
#define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
3635
#define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
3736
#define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
3837
#define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
3938
#define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
@@ -91,11 +90,11 @@
9190
};
9291
9392
/*
9493
** Length of a dline
9594
*/
96
-#define LENGTH(X) ((X)->h & LENGTH_MASK)
95
+#define LENGTH(X) ((X)->n)
9796
9897
/*
9998
** A context for running a raw diff.
10099
**
101100
** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -177,16 +176,26 @@
177176
s = 0;
178177
if( diffFlags & DIFF_IGNORE_EOLWS ){
179178
while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
180179
}
181180
if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
181
+ int numws = 0;
182182
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
+ }
183195
}
184196
a[i].indent = s;
185
- for(h=0, x=s; x<k; x++){
186
- h = h ^ (h<<2) ^ z[x];
187
- }
188197
a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
189198
h2 = h % nLine;
190199
a[i].iNext = a[h2].iHash;
191200
a[h2].iHash = i+1;
192201
z += j+1;
@@ -199,21 +208,30 @@
199208
200209
/*
201210
** Return true if two DLine elements are identical.
202211
*/
203212
static int same_dline(DLine *pA, DLine *pB){
204
- return pA->h==pB->h && memcmp(pA->z,pB->z, pA->n)==0;
213
+ return pA->h==pB->h && memcmp(pA->z,pB->z, pA->h&LENGTH_MASK)==0;
205214
}
206215
207
-static int same_dline_ignore_wschg(DLine *pA, DLine *pB){
208
- return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
209
- pA->h & LENGTH_MASK)==0;
210
-}
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
+*/
211221
212222
static int same_dline_ignore_allws(DLine *pA, DLine *pB){
213
- return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
214
- pA->h & LENGTH_MASK)==0;
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 == b<pB->n-b;
231
+ }
232
+ return 0;
215233
}
216234
217235
/*
218236
** Return true if the regular expression *pRe matches any of the
219237
** N dlines
@@ -1789,22 +1807,18 @@
17891807
if( diffFlags & DIFF_INVERT ){
17901808
Blob *pTemp = pA_Blob;
17911809
pA_Blob = pB_Blob;
17921810
pB_Blob = pTemp;
17931811
}
1794
- ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0;
1812
+ ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0;
17951813
blob_to_utf8_no_bom(pA_Blob, 0);
17961814
blob_to_utf8_no_bom(pB_Blob, 0);
17971815
17981816
/* Prepare the input files */
17991817
memset(&c, 0, sizeof(c));
1800
- if( diffFlags & DIFF_IGNORE_WSCHG ){
1801
- if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
1802
- c.same_fn = same_dline_ignore_allws;
1803
- }else{
1804
- c.same_fn = same_dline_ignore_wschg;
1805
- }
1818
+ if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
1819
+ c.same_fn = same_dline_ignore_allws;
18061820
}else{
18071821
c.same_fn = same_dline;
18081822
}
18091823
c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
18101824
&c.nFrom, diffFlags);
@@ -1868,20 +1882,19 @@
18681882
18691883
/*
18701884
** Process diff-related command-line options and return an appropriate
18711885
** "diffFlags" integer.
18721886
**
1873
-** -b|--ignore-space-change Ignore space changes DIFF_IGNORE_WSCHG
18741887
** --brief Show filenames only DIFF_BRIEF
18751888
** -c|--context N N lines of context. DIFF_CONTEXT_MASK
18761889
** --html Format for HTML DIFF_HTML
18771890
** --invert Invert the diff DIFF_INVERT
18781891
** -n|--linenum Show line numbers DIFF_LINENO
18791892
** --noopt Disable optimization DIFF_NOOPT
18801893
** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
18811894
** --unified Unified diff. ~DIFF_SIDEBYSIDE
1882
-** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1895
+** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
18831896
** -W|--width N N character lines. DIFF_WIDTH_MASK
18841897
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
18851898
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
18861899
*/
18871900
u64 diff_options(void){
@@ -1889,15 +1902,12 @@
18891902
const char *z;
18901903
int f;
18911904
if( find_option("ignore-trailing-space","Z",0)!=0 ){
18921905
diffFlags = DIFF_IGNORE_EOLWS;
18931906
}
1894
- if( find_option("ignore-space-change","b",0)!=0 ){
1895
- diffFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
1896
- }
18971907
if( find_option("ignore-all-space","w",0)!=0 ){
1898
- diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
1908
+ diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
18991909
}
19001910
if( find_option("strip-trailing-cr",0,0)!=0 ){
19011911
diffFlags |= DIFF_STRIP_EOLCR;
19021912
}
19031913
if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
@@ -2016,16 +2026,12 @@
20162026
*/
20172027
static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
20182028
int i;
20192029
20202030
memset(p, 0, sizeof(*p));
2021
- if( diffFlags & DIFF_IGNORE_WSCHG ){
2022
- if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2023
- p->c.same_fn = same_dline_ignore_allws;
2024
- }else{
2025
- p->c.same_fn = same_dline_ignore_wschg;
2026
- }
2031
+ if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2032
+ p->c.same_fn = same_dline_ignore_allws;
20272033
}else{
20282034
p->c.same_fn = same_dline;
20292035
}
20302036
p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
20312037
diffFlags);
@@ -2390,16 +2396,15 @@
23902396
** the file was last modified. The "annotate" command shows line numbers
23912397
** and omits the username. The "blame" and "praise" commands show the user
23922398
** who made each checkin and omits the line number.
23932399
**
23942400
** Options:
2395
-** -b|--ignore-space-change Ignore white space changes when comparing lines
2396
-** --filevers Show file version numbers rather than check-in versions
2397
-** -l|--log List all versions analyzed
2398
-** -n|--limit N Only look backwards in time by N versions
2399
-** -w|--ignore-all-space Ignore white space when comparing lines
2400
-** -Z|--ignore-trailing-space Ignore whitespace at line end
2401
+** --filevers Show file version numbers rather than check-in versions
2402
+** -l|--log List all versions analyzed
2403
+** -n|--limit N Only look backwards in time by N versions
2404
+** -w|--ignore-all-space Ignore white space when comparing lines
2405
+** -Z|--ignore-trailing-space Ignore whitespace at line end
24012406
**
24022407
** See also: info, finfo, timeline
24032408
*/
24042409
void annotate_cmd(void){
24052410
int fnid; /* Filename ID */
@@ -2423,15 +2428,12 @@
24232428
iLimit = atoi(zLimit);
24242429
showLog = find_option("log","l",0)!=0;
24252430
if( find_option("ignore-trailing-space","Z",0)!=0 ){
24262431
annFlags = DIFF_IGNORE_EOLWS;
24272432
}
2428
- if( find_option("ignore-space-change","b",0)!=0 ){
2429
- annFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
2430
- }
24312433
if( find_option("ignore-all-space","w",0)!=0 ){
2432
- annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
2434
+ annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
24332435
}
24342436
fileVers = find_option("filevers",0,0)!=0;
24352437
db_must_be_within_tree();
24362438
if( g.argc<3 ) {
24372439
usage("FILENAME");
24382440
--- src/diff.c
+++ src/diff.c
@@ -29,11 +29,10 @@
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
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_WSCHG ((u64)0x02000000) /* Ignore whitespace changes */
35 #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
36 #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
37 #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
38 #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
39 #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
@@ -91,11 +90,11 @@
91 };
92
93 /*
94 ** Length of a dline
95 */
96 #define LENGTH(X) ((X)->h & LENGTH_MASK)
97
98 /*
99 ** A context for running a raw diff.
100 **
101 ** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -177,16 +176,26 @@
177 s = 0;
178 if( diffFlags & DIFF_IGNORE_EOLWS ){
179 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
180 }
181 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
 
182 while( s<k && fossil_isspace(z[s]) ){ s++; }
 
 
 
 
 
 
 
 
 
 
 
 
183 }
184 a[i].indent = s;
185 for(h=0, x=s; x<k; x++){
186 h = h ^ (h<<2) ^ z[x];
187 }
188 a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s);
189 h2 = h % nLine;
190 a[i].iNext = a[h2].iHash;
191 a[h2].iHash = i+1;
192 z += j+1;
@@ -199,21 +208,30 @@
199
200 /*
201 ** Return true if two DLine elements are identical.
202 */
203 static int same_dline(DLine *pA, DLine *pB){
204 return pA->h==pB->h && memcmp(pA->z,pB->z, pA->n)==0;
205 }
206
207 static int same_dline_ignore_wschg(DLine *pA, DLine *pB){
208 return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
209 pA->h & LENGTH_MASK)==0;
210 }
 
211
212 static int same_dline_ignore_allws(DLine *pA, DLine *pB){
213 return pA->h==pB->h && memcmp(pA->z+pA->indent,pB->z+pB->indent,
214 pA->h & LENGTH_MASK)==0;
 
 
 
 
 
 
 
 
215 }
216
217 /*
218 ** Return true if the regular expression *pRe matches any of the
219 ** N dlines
@@ -1789,22 +1807,18 @@
1789 if( diffFlags & DIFF_INVERT ){
1790 Blob *pTemp = pA_Blob;
1791 pA_Blob = pB_Blob;
1792 pB_Blob = pTemp;
1793 }
1794 ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0;
1795 blob_to_utf8_no_bom(pA_Blob, 0);
1796 blob_to_utf8_no_bom(pB_Blob, 0);
1797
1798 /* Prepare the input files */
1799 memset(&c, 0, sizeof(c));
1800 if( diffFlags & DIFF_IGNORE_WSCHG ){
1801 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
1802 c.same_fn = same_dline_ignore_allws;
1803 }else{
1804 c.same_fn = same_dline_ignore_wschg;
1805 }
1806 }else{
1807 c.same_fn = same_dline;
1808 }
1809 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
1810 &c.nFrom, diffFlags);
@@ -1868,20 +1882,19 @@
1868
1869 /*
1870 ** Process diff-related command-line options and return an appropriate
1871 ** "diffFlags" integer.
1872 **
1873 ** -b|--ignore-space-change Ignore space changes DIFF_IGNORE_WSCHG
1874 ** --brief Show filenames only DIFF_BRIEF
1875 ** -c|--context N N lines of context. DIFF_CONTEXT_MASK
1876 ** --html Format for HTML DIFF_HTML
1877 ** --invert Invert the diff DIFF_INVERT
1878 ** -n|--linenum Show line numbers DIFF_LINENO
1879 ** --noopt Disable optimization DIFF_NOOPT
1880 ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
1881 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1882 ** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1883 ** -W|--width N N character lines. DIFF_WIDTH_MASK
1884 ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
1885 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
1886 */
1887 u64 diff_options(void){
@@ -1889,15 +1902,12 @@
1889 const char *z;
1890 int f;
1891 if( find_option("ignore-trailing-space","Z",0)!=0 ){
1892 diffFlags = DIFF_IGNORE_EOLWS;
1893 }
1894 if( find_option("ignore-space-change","b",0)!=0 ){
1895 diffFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
1896 }
1897 if( find_option("ignore-all-space","w",0)!=0 ){
1898 diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
1899 }
1900 if( find_option("strip-trailing-cr",0,0)!=0 ){
1901 diffFlags |= DIFF_STRIP_EOLCR;
1902 }
1903 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
@@ -2016,16 +2026,12 @@
2016 */
2017 static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
2018 int i;
2019
2020 memset(p, 0, sizeof(*p));
2021 if( diffFlags & DIFF_IGNORE_WSCHG ){
2022 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2023 p->c.same_fn = same_dline_ignore_allws;
2024 }else{
2025 p->c.same_fn = same_dline_ignore_wschg;
2026 }
2027 }else{
2028 p->c.same_fn = same_dline;
2029 }
2030 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2031 diffFlags);
@@ -2390,16 +2396,15 @@
2390 ** the file was last modified. The "annotate" command shows line numbers
2391 ** and omits the username. The "blame" and "praise" commands show the user
2392 ** who made each checkin and omits the line number.
2393 **
2394 ** Options:
2395 ** -b|--ignore-space-change Ignore white space changes when comparing lines
2396 ** --filevers Show file version numbers rather than check-in versions
2397 ** -l|--log List all versions analyzed
2398 ** -n|--limit N Only look backwards in time by N versions
2399 ** -w|--ignore-all-space Ignore white space when comparing lines
2400 ** -Z|--ignore-trailing-space Ignore whitespace at line end
2401 **
2402 ** See also: info, finfo, timeline
2403 */
2404 void annotate_cmd(void){
2405 int fnid; /* Filename ID */
@@ -2423,15 +2428,12 @@
2423 iLimit = atoi(zLimit);
2424 showLog = find_option("log","l",0)!=0;
2425 if( find_option("ignore-trailing-space","Z",0)!=0 ){
2426 annFlags = DIFF_IGNORE_EOLWS;
2427 }
2428 if( find_option("ignore-space-change","b",0)!=0 ){
2429 annFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */
2430 }
2431 if( find_option("ignore-all-space","w",0)!=0 ){
2432 annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_WSCHG */
2433 }
2434 fileVers = find_option("filevers",0,0)!=0;
2435 db_must_be_within_tree();
2436 if( g.argc<3 ) {
2437 usage("FILENAME");
2438
--- src/diff.c
+++ src/diff.c
@@ -29,11 +29,10 @@
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
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 */
@@ -91,11 +90,11 @@
90 };
91
92 /*
93 ** Length of a dline
94 */
95 #define LENGTH(X) ((X)->n)
96
97 /*
98 ** A context for running a raw diff.
99 **
100 ** The aEdit[] array describes the raw diff. Each triple of integers in
@@ -177,16 +176,26 @@
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;
@@ -199,21 +208,30 @@
208
209 /*
210 ** Return true if two DLine elements are identical.
211 */
212 static int same_dline(DLine *pA, 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(DLine *pA, 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 == b<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
@@ -1789,22 +1807,18 @@
1807 if( diffFlags & DIFF_INVERT ){
1808 Blob *pTemp = pA_Blob;
1809 pA_Blob = pB_Blob;
1810 pB_Blob = pTemp;
1811 }
1812 ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0;
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);
@@ -1868,20 +1882,19 @@
1882
1883 /*
1884 ** Process diff-related command-line options and return an appropriate
1885 ** "diffFlags" integer.
1886 **
 
1887 ** --brief Show filenames only DIFF_BRIEF
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){
@@ -1889,15 +1902,12 @@
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;
@@ -2016,16 +2026,12 @@
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);
@@ -2390,16 +2396,15 @@
2396 ** the file was last modified. The "annotate" command shows line numbers
2397 ** and omits the username. The "blame" and "praise" commands show the user
2398 ** who made each checkin and omits the line number.
2399 **
2400 ** Options:
2401 ** --filevers Show file version numbers rather than check-in versions
2402 ** -l|--log List all versions analyzed
2403 ** -n|--limit N Only look backwards in time by N versions
2404 ** -w|--ignore-all-space Ignore white space when comparing lines
2405 ** -Z|--ignore-trailing-space Ignore whitespace at line end
 
2406 **
2407 ** See also: info, finfo, timeline
2408 */
2409 void annotate_cmd(void){
2410 int fnid; /* Filename ID */
@@ -2423,15 +2428,12 @@
2428 iLimit = atoi(zLimit);
2429 showLog = find_option("log","l",0)!=0;
2430 if( find_option("ignore-trailing-space","Z",0)!=0 ){
2431 annFlags = DIFF_IGNORE_EOLWS;
2432 }
 
 
 
2433 if( find_option("ignore-all-space","w",0)!=0 ){
2434 annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
2435 }
2436 fileVers = find_option("filevers",0,0)!=0;
2437 db_must_be_within_tree();
2438 if( g.argc<3 ) {
2439 usage("FILENAME");
2440
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,11 +1089,10 @@
10891089
** The "--binary" option causes files matching the glob PATTERN to be treated
10901090
** as binary when considering if they should be used with external diff program.
10911091
** This option overrides the "binary-glob" setting.
10921092
**
10931093
** Options:
1094
-** -b|--ignore-space-change Ignore white space changes when comparing lines
10951094
** --binary PATTERN Treat files that match the glob PATTERN as binary
10961095
** --branch BRANCH Show diff of all changes on BRANCH
10971096
** --brief Show filenames only
10981097
** --context|-c N Use N lines of context
10991098
** --diff-binary BOOL Include binary files when using external commands
11001099
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,11 +1089,10 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
1094 ** -b|--ignore-space-change Ignore white space changes when comparing lines
1095 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1096 ** --branch BRANCH Show diff of all changes on BRANCH
1097 ** --brief Show filenames only
1098 ** --context|-c N Use N lines of context
1099 ** --diff-binary BOOL Include binary files when using external commands
1100
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,11 +1089,10 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
 
1094 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1095 ** --branch BRANCH Show diff of all changes on BRANCH
1096 ** --brief Show filenames only
1097 ** --context|-c N Use N lines of context
1098 ** --diff-binary BOOL Include binary files when using external commands
1099
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,11 +1089,10 @@
10891089
** The "--binary" option causes files matching the glob PATTERN to be treated
10901090
** as binary when considering if they should be used with external diff program.
10911091
** This option overrides the "binary-glob" setting.
10921092
**
10931093
** Options:
1094
-** -b|--ignore-space-change Ignore white space changes when comparing lines
10951094
** --binary PATTERN Treat files that match the glob PATTERN as binary
10961095
** --branch BRANCH Show diff of all changes on BRANCH
10971096
** --brief Show filenames only
10981097
** --context|-c N Use N lines of context
10991098
** --diff-binary BOOL Include binary files when using external commands
11001099
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,11 +1089,10 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
1094 ** -b|--ignore-space-change Ignore white space changes when comparing lines
1095 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1096 ** --branch BRANCH Show diff of all changes on BRANCH
1097 ** --brief Show filenames only
1098 ** --context|-c N Use N lines of context
1099 ** --diff-binary BOOL Include binary files when using external commands
1100
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,11 +1089,10 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
 
1094 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1095 ** --branch BRANCH Show diff of all changes on BRANCH
1096 ** --brief Show filenames only
1097 ** --context|-c N Use N lines of context
1098 ** --diff-binary BOOL Include binary files when using external commands
1099
+1 -1
--- src/http.c
+++ src/http.c
@@ -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.urlFlags & 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
}
158158
--- src/http.c
+++ src/http.c
@@ -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 }
158
--- src/http.c
+++ src/http.c
@@ -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 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 }
158
+4 -3
--- src/info.c
+++ src/info.c
@@ -470,11 +470,11 @@
470470
diffFlags += x;
471471
472472
/* The "noopt" parameter disables diff optimization */
473473
if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT;
474474
}
475
- return diffFlags;
475
+ return diffFlags|DIFF_STRIP_EOLCR;
476476
}
477477
478478
/*
479479
** WEBPAGE: vinfo
480480
** WEBPAGE: ci
@@ -1722,11 +1722,12 @@
17221722
}else{
17231723
renderAsHtml = 1;
17241724
style_submenu_element("Text", "Text",
17251725
"%s/artifact/%s?txt=1", g.zTop, zUuid);
17261726
}
1727
- }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
1727
+ }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0
1728
+ || fossil_strcmp(zMime, "text/x-markdown")==0 ){
17281729
if( asText ){
17291730
style_submenu_element("Wiki", "Wiki",
17301731
"%s/artifact/%s", g.zTop, zUuid);
17311732
}else{
17321733
renderAsWiki = 1;
@@ -1739,11 +1740,11 @@
17391740
style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid);
17401741
}
17411742
@ <hr />
17421743
content_get(rid, &content);
17431744
if( renderAsWiki ){
1744
- wiki_convert(&content, 0, 0);
1745
+ wiki_render_by_mimetype(&content, zMime);
17451746
}else if( renderAsHtml ){
17461747
@ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
17471748
@ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
17481749
@ sandbox="allow-same-origin"
17491750
@ onload="this.height = this.contentDocument.documentElement.scrollHeight;">
17501751
--- src/info.c
+++ src/info.c
@@ -470,11 +470,11 @@
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 /*
479 ** WEBPAGE: vinfo
480 ** WEBPAGE: ci
@@ -1722,11 +1722,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 +1740,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;">
1750
--- src/info.c
+++ src/info.c
@@ -470,11 +470,11 @@
470 diffFlags += x;
471
472 /* The "noopt" parameter disables diff optimization */
473 if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT;
474 }
475 return diffFlags|DIFF_STRIP_EOLCR;
476 }
477
478 /*
479 ** WEBPAGE: vinfo
480 ** WEBPAGE: ci
@@ -1722,11 +1722,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 || fossil_strcmp(zMime, "text/x-markdown")==0 ){
1729 if( asText ){
1730 style_submenu_element("Wiki", "Wiki",
1731 "%s/artifact/%s", g.zTop, zUuid);
1732 }else{
1733 renderAsWiki = 1;
@@ -1739,11 +1740,11 @@
1740 style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid);
1741 }
1742 @ <hr />
1743 content_get(rid, &content);
1744 if( renderAsWiki ){
1745 wiki_render_by_mimetype(&content, zMime);
1746 }else if( renderAsHtml ){
1747 @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
1748 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
1749 @ sandbox="allow-same-origin"
1750 @ onload="this.height = this.contentDocument.documentElement.scrollHeight;">
1751
+2 -2
--- src/main.c
+++ src/main.c
@@ -604,11 +604,11 @@
604604
#endif
605605
g.mainTimerId = fossil_timer_start();
606606
g.zVfsName = find_option("vfs",0,1);
607607
if( g.zVfsName==0 ){
608608
g.zVfsName = fossil_getenv("FOSSIL_VFS");
609
-#if defined(__CYGWIN__)
609
+#if defined(__CYGWIN__) && USE_SYSTEM_SQLITE+0!=1
610610
if( g.zVfsName==0 ){
611611
g.zVfsName = "win32-longpath";
612612
}
613613
#endif
614614
}
@@ -1070,11 +1070,11 @@
10701070
if( j>0 ){
10711071
@ </ul></td>
10721072
}
10731073
@ </tr></table>
10741074
1075
- @ <h1>Available pages:</h1>
1075
+ @ <h1>Available web UI pages:</h1>
10761076
@ (Only pages with help text are linked.)
10771077
@ <table border="0"><tr>
10781078
for(i=j=0; i<count(aCommand); i++){
10791079
const char *z = aCommand[i].zName;
10801080
if( '/'!=*z ) continue;
10811081
--- src/main.c
+++ src/main.c
@@ -604,11 +604,11 @@
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 }
@@ -1070,11 +1070,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
@@ -604,11 +604,11 @@
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__) && USE_SYSTEM_SQLITE+0!=1
610 if( g.zVfsName==0 ){
611 g.zVfsName = "win32-longpath";
612 }
613 #endif
614 }
@@ -1070,11 +1070,11 @@
1070 if( j>0 ){
1071 @ </ul></td>
1072 }
1073 @ </tr></table>
1074
1075 @ <h1>Available web UI 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
+174 -68
--- src/name.c
+++ src/name.c
@@ -433,10 +433,153 @@
433433
cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath);
434434
rid = 0;
435435
}
436436
return rid;
437437
}
438
+
439
+/*
440
+** Generate a description of artifact "rid"
441
+*/
442
+static void whatis_rid(int rid, int verboseFlag){
443
+ Stmt q;
444
+ int cnt;
445
+
446
+ /* Basic information about the object. */
447
+ db_prepare(&q,
448
+ "SELECT uuid, size, datetime(mtime%s), ipaddr"
449
+ " FROM blob, rcvfrom"
450
+ " WHERE rid=%d"
451
+ " AND rcvfrom.rcvid=blob.rcvid",
452
+ timeline_utc(), rid);
453
+ if( db_step(&q)==SQLITE_ROW ){
454
+ const char *zTagList = db_column_text(&q, 4);
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
@@ -433,10 +433,153 @@
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
@@ -433,10 +433,153 @@
433 cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath);
434 rid = 0;
435 }
436 return rid;
437 }
438
439 /*
440 ** Generate a description of artifact "rid"
441 */
442 static void whatis_rid(int rid, int verboseFlag){
443 Stmt q;
444 int cnt;
445
446 /* Basic information about the object. */
447 db_prepare(&q,
448 "SELECT uuid, size, datetime(mtime%s), ipaddr"
449 " FROM blob, rcvfrom"
450 " WHERE rid=%d"
451 " AND rcvfrom.rcvid=blob.rcvid",
452 timeline_utc(), rid);
453 if( db_step(&q)==SQLITE_ROW ){
454 const char *zTagList = db_column_text(&q, 4);
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
-13
--- src/report.c
+++ src/report.c
@@ -612,23 +612,10 @@
612612
@ priority AS 'Pri',
613613
@ title AS 'Title',
614614
@ description AS '_Description', -- When the column name begins with '_'
615615
@ remarks AS '_Remarks' -- content is rendered as wiki
616616
@ 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
630617
@ </pre></blockquote>
631618
@
632619
}
633620
634621
/*
635622
--- src/report.c
+++ src/report.c
@@ -612,23 +612,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 /*
635
--- src/report.c
+++ src/report.c
@@ -612,23 +612,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 }
620
621 /*
622
+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

Keyboard Shortcuts

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