Fossil SCM
Make -w|--ignore-all-space option work the same as the GNU diff option with the same name.
Commit
a7a61cdd6f2b5a5f23f29d0872edec40f5725bd9
Parent
a915aa03b3c66f4…
13 files changed
+1
+1
-1
+43
-41
+43
-41
-1
-1
+1
-1
+4
-3
+2
-2
+174
-68
+1
-2
-13
+118
-96
+1
| --- src/comformat.c | ||
| +++ src/comformat.c | ||
| @@ -36,10 +36,11 @@ | ||
| 36 | 36 | int doIndent = 0; |
| 37 | 37 | char *zBuf; |
| 38 | 38 | char zBuffer[400]; |
| 39 | 39 | int lineCnt = 0; |
| 40 | 40 | |
| 41 | + if( zText==0 ) zText = "(NULL)"; | |
| 41 | 42 | if( tlen<=0 ){ |
| 42 | 43 | tlen = strlen(zText); |
| 43 | 44 | } |
| 44 | 45 | if( tlen >= (sizeof(zBuffer)) ){ |
| 45 | 46 | zBuf = fossil_malloc(tlen+1); |
| 46 | 47 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -36,10 +36,11 @@ | |
| 36 | int doIndent = 0; |
| 37 | char *zBuf; |
| 38 | char zBuffer[400]; |
| 39 | int lineCnt = 0; |
| 40 | |
| 41 | if( tlen<=0 ){ |
| 42 | tlen = strlen(zText); |
| 43 | } |
| 44 | if( tlen >= (sizeof(zBuffer)) ){ |
| 45 | zBuf = fossil_malloc(tlen+1); |
| 46 |
| --- src/comformat.c | |
| +++ src/comformat.c | |
| @@ -36,10 +36,11 @@ | |
| 36 | int doIndent = 0; |
| 37 | char *zBuf; |
| 38 | char zBuffer[400]; |
| 39 | int lineCnt = 0; |
| 40 | |
| 41 | if( zText==0 ) zText = "(NULL)"; |
| 42 | if( tlen<=0 ){ |
| 43 | tlen = strlen(zText); |
| 44 | } |
| 45 | if( tlen >= (sizeof(zBuffer)) ){ |
| 46 | zBuf = fossil_malloc(tlen+1); |
| 47 |
M
src/db.c
+1
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -715,11 +715,11 @@ | ||
| 715 | 715 | */ |
| 716 | 716 | LOCAL sqlite3 *db_open(const char *zDbName){ |
| 717 | 717 | int rc; |
| 718 | 718 | sqlite3 *db; |
| 719 | 719 | |
| 720 | -#if defined(__CYGWIN__) && !defined(USE_SYSTEM_SQLITE) | |
| 720 | +#if defined(__CYGWIN__) && USE_SYSTEM_SQLITE+0!=1 | |
| 721 | 721 | zDbName = fossil_utf8_to_filename(zDbName); |
| 722 | 722 | #endif |
| 723 | 723 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 724 | 724 | rc = sqlite3_open_v2( |
| 725 | 725 | zDbName, &db, |
| 726 | 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__) && !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 @@ | ||
| 29 | 29 | ** of the diff output. |
| 30 | 30 | */ |
| 31 | 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | -#define DIFF_IGNORE_WSCHG ((u64)0x02000000) /* Ignore whitespace changes */ | |
| 35 | 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 36 | 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 37 | 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 38 | 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 39 | 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -91,11 +90,11 @@ | ||
| 91 | 90 | }; |
| 92 | 91 | |
| 93 | 92 | /* |
| 94 | 93 | ** Length of a dline |
| 95 | 94 | */ |
| 96 | -#define LENGTH(X) ((X)->h & LENGTH_MASK) | |
| 95 | +#define LENGTH(X) ((X)->n) | |
| 97 | 96 | |
| 98 | 97 | /* |
| 99 | 98 | ** A context for running a raw diff. |
| 100 | 99 | ** |
| 101 | 100 | ** The aEdit[] array describes the raw diff. Each triple of integers in |
| @@ -177,16 +176,26 @@ | ||
| 177 | 176 | s = 0; |
| 178 | 177 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 179 | 178 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 180 | 179 | } |
| 181 | 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 181 | + int numws = 0; | |
| 182 | 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 | + } | |
| 183 | 195 | } |
| 184 | 196 | a[i].indent = s; |
| 185 | - for(h=0, x=s; x<k; x++){ | |
| 186 | - h = h ^ (h<<2) ^ z[x]; | |
| 187 | - } | |
| 188 | 197 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 189 | 198 | h2 = h % nLine; |
| 190 | 199 | a[i].iNext = a[h2].iHash; |
| 191 | 200 | a[h2].iHash = i+1; |
| 192 | 201 | z += j+1; |
| @@ -199,21 +208,30 @@ | ||
| 199 | 208 | |
| 200 | 209 | /* |
| 201 | 210 | ** Return true if two DLine elements are identical. |
| 202 | 211 | */ |
| 203 | 212 | 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; | |
| 205 | 214 | } |
| 206 | 215 | |
| 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 | +*/ | |
| 211 | 221 | |
| 212 | 222 | 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; | |
| 215 | 233 | } |
| 216 | 234 | |
| 217 | 235 | /* |
| 218 | 236 | ** Return true if the regular expression *pRe matches any of the |
| 219 | 237 | ** N dlines |
| @@ -1789,22 +1807,18 @@ | ||
| 1789 | 1807 | if( diffFlags & DIFF_INVERT ){ |
| 1790 | 1808 | Blob *pTemp = pA_Blob; |
| 1791 | 1809 | pA_Blob = pB_Blob; |
| 1792 | 1810 | pB_Blob = pTemp; |
| 1793 | 1811 | } |
| 1794 | - ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0; | |
| 1812 | + ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0; | |
| 1795 | 1813 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1796 | 1814 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1797 | 1815 | |
| 1798 | 1816 | /* Prepare the input files */ |
| 1799 | 1817 | 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; | |
| 1806 | 1820 | }else{ |
| 1807 | 1821 | c.same_fn = same_dline; |
| 1808 | 1822 | } |
| 1809 | 1823 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1810 | 1824 | &c.nFrom, diffFlags); |
| @@ -1868,20 +1882,19 @@ | ||
| 1868 | 1882 | |
| 1869 | 1883 | /* |
| 1870 | 1884 | ** Process diff-related command-line options and return an appropriate |
| 1871 | 1885 | ** "diffFlags" integer. |
| 1872 | 1886 | ** |
| 1873 | -** -b|--ignore-space-change Ignore space changes DIFF_IGNORE_WSCHG | |
| 1874 | 1887 | ** --brief Show filenames only DIFF_BRIEF |
| 1875 | 1888 | ** -c|--context N N lines of context. DIFF_CONTEXT_MASK |
| 1876 | 1889 | ** --html Format for HTML DIFF_HTML |
| 1877 | 1890 | ** --invert Invert the diff DIFF_INVERT |
| 1878 | 1891 | ** -n|--linenum Show line numbers DIFF_LINENO |
| 1879 | 1892 | ** --noopt Disable optimization DIFF_NOOPT |
| 1880 | 1893 | ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR |
| 1881 | 1894 | ** --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 | |
| 1883 | 1896 | ** -W|--width N N character lines. DIFF_WIDTH_MASK |
| 1884 | 1897 | ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE |
| 1885 | 1898 | ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS |
| 1886 | 1899 | */ |
| 1887 | 1900 | u64 diff_options(void){ |
| @@ -1889,15 +1902,12 @@ | ||
| 1889 | 1902 | const char *z; |
| 1890 | 1903 | int f; |
| 1891 | 1904 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1892 | 1905 | diffFlags = DIFF_IGNORE_EOLWS; |
| 1893 | 1906 | } |
| 1894 | - if( find_option("ignore-space-change","b",0)!=0 ){ | |
| 1895 | - diffFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */ | |
| 1896 | - } | |
| 1897 | 1907 | 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 */ | |
| 1899 | 1909 | } |
| 1900 | 1910 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1901 | 1911 | diffFlags |= DIFF_STRIP_EOLCR; |
| 1902 | 1912 | } |
| 1903 | 1913 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| @@ -2016,16 +2026,12 @@ | ||
| 2016 | 2026 | */ |
| 2017 | 2027 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 2018 | 2028 | int i; |
| 2019 | 2029 | |
| 2020 | 2030 | 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; | |
| 2027 | 2033 | }else{ |
| 2028 | 2034 | p->c.same_fn = same_dline; |
| 2029 | 2035 | } |
| 2030 | 2036 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 2031 | 2037 | diffFlags); |
| @@ -2390,16 +2396,15 @@ | ||
| 2390 | 2396 | ** the file was last modified. The "annotate" command shows line numbers |
| 2391 | 2397 | ** and omits the username. The "blame" and "praise" commands show the user |
| 2392 | 2398 | ** who made each checkin and omits the line number. |
| 2393 | 2399 | ** |
| 2394 | 2400 | ** 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 | |
| 2401 | 2406 | ** |
| 2402 | 2407 | ** See also: info, finfo, timeline |
| 2403 | 2408 | */ |
| 2404 | 2409 | void annotate_cmd(void){ |
| 2405 | 2410 | int fnid; /* Filename ID */ |
| @@ -2423,15 +2428,12 @@ | ||
| 2423 | 2428 | iLimit = atoi(zLimit); |
| 2424 | 2429 | showLog = find_option("log","l",0)!=0; |
| 2425 | 2430 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 2426 | 2431 | annFlags = DIFF_IGNORE_EOLWS; |
| 2427 | 2432 | } |
| 2428 | - if( find_option("ignore-space-change","b",0)!=0 ){ | |
| 2429 | - annFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */ | |
| 2430 | - } | |
| 2431 | 2433 | 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 */ | |
| 2433 | 2435 | } |
| 2434 | 2436 | fileVers = find_option("filevers",0,0)!=0; |
| 2435 | 2437 | db_must_be_within_tree(); |
| 2436 | 2438 | if( g.argc<3 ) { |
| 2437 | 2439 | usage("FILENAME"); |
| 2438 | 2440 |
| --- 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 @@ | ||
| 29 | 29 | ** of the diff output. |
| 30 | 30 | */ |
| 31 | 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | -#define DIFF_IGNORE_WSCHG ((u64)0x02000000) /* Ignore whitespace changes */ | |
| 35 | 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 36 | 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 37 | 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 38 | 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 39 | 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -91,11 +90,11 @@ | ||
| 91 | 90 | }; |
| 92 | 91 | |
| 93 | 92 | /* |
| 94 | 93 | ** Length of a dline |
| 95 | 94 | */ |
| 96 | -#define LENGTH(X) ((X)->h & LENGTH_MASK) | |
| 95 | +#define LENGTH(X) ((X)->n) | |
| 97 | 96 | |
| 98 | 97 | /* |
| 99 | 98 | ** A context for running a raw diff. |
| 100 | 99 | ** |
| 101 | 100 | ** The aEdit[] array describes the raw diff. Each triple of integers in |
| @@ -177,16 +176,26 @@ | ||
| 177 | 176 | s = 0; |
| 178 | 177 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 179 | 178 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; } |
| 180 | 179 | } |
| 181 | 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 181 | + int numws = 0; | |
| 182 | 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 | + } | |
| 183 | 195 | } |
| 184 | 196 | a[i].indent = s; |
| 185 | - for(h=0, x=s; x<k; x++){ | |
| 186 | - h = h ^ (h<<2) ^ z[x]; | |
| 187 | - } | |
| 188 | 197 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 189 | 198 | h2 = h % nLine; |
| 190 | 199 | a[i].iNext = a[h2].iHash; |
| 191 | 200 | a[h2].iHash = i+1; |
| 192 | 201 | z += j+1; |
| @@ -199,21 +208,30 @@ | ||
| 199 | 208 | |
| 200 | 209 | /* |
| 201 | 210 | ** Return true if two DLine elements are identical. |
| 202 | 211 | */ |
| 203 | 212 | 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; | |
| 205 | 214 | } |
| 206 | 215 | |
| 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 | +*/ | |
| 211 | 221 | |
| 212 | 222 | 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; | |
| 215 | 233 | } |
| 216 | 234 | |
| 217 | 235 | /* |
| 218 | 236 | ** Return true if the regular expression *pRe matches any of the |
| 219 | 237 | ** N dlines |
| @@ -1789,22 +1807,18 @@ | ||
| 1789 | 1807 | if( diffFlags & DIFF_INVERT ){ |
| 1790 | 1808 | Blob *pTemp = pA_Blob; |
| 1791 | 1809 | pA_Blob = pB_Blob; |
| 1792 | 1810 | pB_Blob = pTemp; |
| 1793 | 1811 | } |
| 1794 | - ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0; | |
| 1812 | + ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0; | |
| 1795 | 1813 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1796 | 1814 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1797 | 1815 | |
| 1798 | 1816 | /* Prepare the input files */ |
| 1799 | 1817 | 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; | |
| 1806 | 1820 | }else{ |
| 1807 | 1821 | c.same_fn = same_dline; |
| 1808 | 1822 | } |
| 1809 | 1823 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 1810 | 1824 | &c.nFrom, diffFlags); |
| @@ -1868,20 +1882,19 @@ | ||
| 1868 | 1882 | |
| 1869 | 1883 | /* |
| 1870 | 1884 | ** Process diff-related command-line options and return an appropriate |
| 1871 | 1885 | ** "diffFlags" integer. |
| 1872 | 1886 | ** |
| 1873 | -** -b|--ignore-space-change Ignore space changes DIFF_IGNORE_WSCHG | |
| 1874 | 1887 | ** --brief Show filenames only DIFF_BRIEF |
| 1875 | 1888 | ** -c|--context N N lines of context. DIFF_CONTEXT_MASK |
| 1876 | 1889 | ** --html Format for HTML DIFF_HTML |
| 1877 | 1890 | ** --invert Invert the diff DIFF_INVERT |
| 1878 | 1891 | ** -n|--linenum Show line numbers DIFF_LINENO |
| 1879 | 1892 | ** --noopt Disable optimization DIFF_NOOPT |
| 1880 | 1893 | ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR |
| 1881 | 1894 | ** --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 | |
| 1883 | 1896 | ** -W|--width N N character lines. DIFF_WIDTH_MASK |
| 1884 | 1897 | ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE |
| 1885 | 1898 | ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS |
| 1886 | 1899 | */ |
| 1887 | 1900 | u64 diff_options(void){ |
| @@ -1889,15 +1902,12 @@ | ||
| 1889 | 1902 | const char *z; |
| 1890 | 1903 | int f; |
| 1891 | 1904 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1892 | 1905 | diffFlags = DIFF_IGNORE_EOLWS; |
| 1893 | 1906 | } |
| 1894 | - if( find_option("ignore-space-change","b",0)!=0 ){ | |
| 1895 | - diffFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */ | |
| 1896 | - } | |
| 1897 | 1907 | 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 */ | |
| 1899 | 1909 | } |
| 1900 | 1910 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1901 | 1911 | diffFlags |= DIFF_STRIP_EOLCR; |
| 1902 | 1912 | } |
| 1903 | 1913 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| @@ -2016,16 +2026,12 @@ | ||
| 2016 | 2026 | */ |
| 2017 | 2027 | static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){ |
| 2018 | 2028 | int i; |
| 2019 | 2029 | |
| 2020 | 2030 | 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; | |
| 2027 | 2033 | }else{ |
| 2028 | 2034 | p->c.same_fn = same_dline; |
| 2029 | 2035 | } |
| 2030 | 2036 | p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo, |
| 2031 | 2037 | diffFlags); |
| @@ -2390,16 +2396,15 @@ | ||
| 2390 | 2396 | ** the file was last modified. The "annotate" command shows line numbers |
| 2391 | 2397 | ** and omits the username. The "blame" and "praise" commands show the user |
| 2392 | 2398 | ** who made each checkin and omits the line number. |
| 2393 | 2399 | ** |
| 2394 | 2400 | ** 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 | |
| 2401 | 2406 | ** |
| 2402 | 2407 | ** See also: info, finfo, timeline |
| 2403 | 2408 | */ |
| 2404 | 2409 | void annotate_cmd(void){ |
| 2405 | 2410 | int fnid; /* Filename ID */ |
| @@ -2423,15 +2428,12 @@ | ||
| 2423 | 2428 | iLimit = atoi(zLimit); |
| 2424 | 2429 | showLog = find_option("log","l",0)!=0; |
| 2425 | 2430 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 2426 | 2431 | annFlags = DIFF_IGNORE_EOLWS; |
| 2427 | 2432 | } |
| 2428 | - if( find_option("ignore-space-change","b",0)!=0 ){ | |
| 2429 | - annFlags = DIFF_IGNORE_WSCHG; /* stronger than DIFF_IGNORE_EOLWS */ | |
| 2430 | - } | |
| 2431 | 2433 | 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 */ | |
| 2433 | 2435 | } |
| 2434 | 2436 | fileVers = find_option("filevers",0,0)!=0; |
| 2435 | 2437 | db_must_be_within_tree(); |
| 2436 | 2438 | if( g.argc<3 ) { |
| 2437 | 2439 | usage("FILENAME"); |
| 2438 | 2440 |
| --- 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 |
-1
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -1089,11 +1089,10 @@ | ||
| 1089 | 1089 | ** The "--binary" option causes files matching the glob PATTERN to be treated |
| 1090 | 1090 | ** as binary when considering if they should be used with external diff program. |
| 1091 | 1091 | ** This option overrides the "binary-glob" setting. |
| 1092 | 1092 | ** |
| 1093 | 1093 | ** Options: |
| 1094 | -** -b|--ignore-space-change Ignore white space changes when comparing lines | |
| 1095 | 1094 | ** --binary PATTERN Treat files that match the glob PATTERN as binary |
| 1096 | 1095 | ** --branch BRANCH Show diff of all changes on BRANCH |
| 1097 | 1096 | ** --brief Show filenames only |
| 1098 | 1097 | ** --context|-c N Use N lines of context |
| 1099 | 1098 | ** --diff-binary BOOL Include binary files when using external commands |
| 1100 | 1099 |
| --- 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
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -1089,11 +1089,10 @@ | ||
| 1089 | 1089 | ** The "--binary" option causes files matching the glob PATTERN to be treated |
| 1090 | 1090 | ** as binary when considering if they should be used with external diff program. |
| 1091 | 1091 | ** This option overrides the "binary-glob" setting. |
| 1092 | 1092 | ** |
| 1093 | 1093 | ** Options: |
| 1094 | -** -b|--ignore-space-change Ignore white space changes when comparing lines | |
| 1095 | 1094 | ** --binary PATTERN Treat files that match the glob PATTERN as binary |
| 1096 | 1095 | ** --branch BRANCH Show diff of all changes on BRANCH |
| 1097 | 1096 | ** --brief Show filenames only |
| 1098 | 1097 | ** --context|-c N Use N lines of context |
| 1099 | 1098 | ** --diff-binary BOOL Include binary files when using external commands |
| 1100 | 1099 |
| --- 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 @@ | ||
| 147 | 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | 148 | */ |
| 149 | 149 | static int save_httpauth_prompt(void){ |
| 150 | 150 | Blob x; |
| 151 | 151 | char c; |
| 152 | - if( (g.urlFlags & URL_REMEMBER)==0 ) return; | |
| 152 | + if( (g.urlFlags & URL_REMEMBER)==0 ) return 0; | |
| 153 | 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | 154 | c = blob_str(&x)[0]; |
| 155 | 155 | blob_reset(&x); |
| 156 | 156 | return ( c!='n' && c!='N' ); |
| 157 | 157 | } |
| 158 | 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; |
| 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 @@ | ||
| 470 | 470 | diffFlags += x; |
| 471 | 471 | |
| 472 | 472 | /* The "noopt" parameter disables diff optimization */ |
| 473 | 473 | if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 474 | 474 | } |
| 475 | - return diffFlags; | |
| 475 | + return diffFlags|DIFF_STRIP_EOLCR; | |
| 476 | 476 | } |
| 477 | 477 | |
| 478 | 478 | /* |
| 479 | 479 | ** WEBPAGE: vinfo |
| 480 | 480 | ** WEBPAGE: ci |
| @@ -1722,11 +1722,12 @@ | ||
| 1722 | 1722 | }else{ |
| 1723 | 1723 | renderAsHtml = 1; |
| 1724 | 1724 | style_submenu_element("Text", "Text", |
| 1725 | 1725 | "%s/artifact/%s?txt=1", g.zTop, zUuid); |
| 1726 | 1726 | } |
| 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 ){ | |
| 1728 | 1729 | if( asText ){ |
| 1729 | 1730 | style_submenu_element("Wiki", "Wiki", |
| 1730 | 1731 | "%s/artifact/%s", g.zTop, zUuid); |
| 1731 | 1732 | }else{ |
| 1732 | 1733 | renderAsWiki = 1; |
| @@ -1739,11 +1740,11 @@ | ||
| 1739 | 1740 | style_submenu_element("Parsed", "Parsed", "%R/info/%s", zUuid); |
| 1740 | 1741 | } |
| 1741 | 1742 | @ <hr /> |
| 1742 | 1743 | content_get(rid, &content); |
| 1743 | 1744 | if( renderAsWiki ){ |
| 1744 | - wiki_convert(&content, 0, 0); | |
| 1745 | + wiki_render_by_mimetype(&content, zMime); | |
| 1745 | 1746 | }else if( renderAsHtml ){ |
| 1746 | 1747 | @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)" |
| 1747 | 1748 | @ width="100%%" frameborder="0" marginwidth="0" marginheight="0" |
| 1748 | 1749 | @ sandbox="allow-same-origin" |
| 1749 | 1750 | @ onload="this.height = this.contentDocument.documentElement.scrollHeight;"> |
| 1750 | 1751 |
| --- 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 @@ | ||
| 604 | 604 | #endif |
| 605 | 605 | g.mainTimerId = fossil_timer_start(); |
| 606 | 606 | g.zVfsName = find_option("vfs",0,1); |
| 607 | 607 | if( g.zVfsName==0 ){ |
| 608 | 608 | g.zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 609 | -#if defined(__CYGWIN__) | |
| 609 | +#if defined(__CYGWIN__) && USE_SYSTEM_SQLITE+0!=1 | |
| 610 | 610 | if( g.zVfsName==0 ){ |
| 611 | 611 | g.zVfsName = "win32-longpath"; |
| 612 | 612 | } |
| 613 | 613 | #endif |
| 614 | 614 | } |
| @@ -1070,11 +1070,11 @@ | ||
| 1070 | 1070 | if( j>0 ){ |
| 1071 | 1071 | @ </ul></td> |
| 1072 | 1072 | } |
| 1073 | 1073 | @ </tr></table> |
| 1074 | 1074 | |
| 1075 | - @ <h1>Available pages:</h1> | |
| 1075 | + @ <h1>Available web UI pages:</h1> | |
| 1076 | 1076 | @ (Only pages with help text are linked.) |
| 1077 | 1077 | @ <table border="0"><tr> |
| 1078 | 1078 | for(i=j=0; i<count(aCommand); i++){ |
| 1079 | 1079 | const char *z = aCommand[i].zName; |
| 1080 | 1080 | if( '/'!=*z ) continue; |
| 1081 | 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__) |
| 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 @@ | ||
| 433 | 433 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 434 | 434 | rid = 0; |
| 435 | 435 | } |
| 436 | 436 | return rid; |
| 437 | 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 | +} | |
| 438 | 581 | |
| 439 | 582 | /* |
| 440 | 583 | ** COMMAND: whatis* |
| 441 | 584 | ** Usage: %fossil whatis NAME |
| 442 | 585 | ** |
| @@ -452,78 +595,41 @@ | ||
| 452 | 595 | verboseFlag = find_option("verbose","v",0)!=0; |
| 453 | 596 | if( g.argc!=3 ) usage("whatis NAME"); |
| 454 | 597 | zName = g.argv[2]; |
| 455 | 598 | rid = symbolic_name_to_rid(zName, 0); |
| 456 | 599 | if( rid<0 ){ |
| 600 | + Stmt q; | |
| 601 | + int cnt = 0; | |
| 457 | 602 | fossil_print("Ambiguous artifact name prefix: %s\n", zName); |
| 603 | + db_prepare(&q, | |
| 604 | + "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", | |
| 605 | + zName, zName | |
| 606 | + ); | |
| 607 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 608 | + if( cnt++ ) fossil_print("%.79c\n", '-'); | |
| 609 | + whatis_rid(db_column_int(&q, 0), verboseFlag); | |
| 610 | + } | |
| 611 | + db_finalize(&q); | |
| 458 | 612 | }else if( rid==0 ){ |
| 459 | 613 | fossil_print("Unknown artifact: %s\n", zName); |
| 460 | 614 | }else{ |
| 461 | - Stmt q; | |
| 462 | - db_prepare(&q, | |
| 463 | - "SELECT uuid, size, datetime(mtime%s), ipaddr," | |
| 464 | - " (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref" | |
| 465 | - " WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid" | |
| 466 | - " AND tagxref.rid=blob.rid AND tagxref.tagtype>0)" | |
| 467 | - " FROM blob, rcvfrom" | |
| 468 | - " WHERE rid=%d" | |
| 469 | - " AND rcvfrom.rcvid=blob.rcvid", | |
| 470 | - timeline_utc(), rid); | |
| 471 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 472 | - const char *zTagList = db_column_text(&q, 4); | |
| 473 | - if( verboseFlag ){ | |
| 474 | - fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); | |
| 475 | - fossil_print("size: %d bytes\n", db_column_int(&q,1)); | |
| 476 | - fossil_print("received: %s from %s\n", | |
| 477 | - db_column_text(&q, 2), | |
| 478 | - db_column_text(&q, 3)); | |
| 479 | - }else{ | |
| 480 | - fossil_print("artifact: %s\n", db_column_text(&q,0)); | |
| 481 | - fossil_print("size: %d bytes\n", db_column_int(&q,1)); | |
| 482 | - } | |
| 483 | - if( zTagList && zTagList[0] ){ | |
| 484 | - fossil_print("tags: %s\n", zTagList); | |
| 485 | - } | |
| 486 | - } | |
| 487 | - db_finalize(&q); | |
| 488 | - db_prepare(&q, | |
| 489 | - "SELECT type, datetime(mtime%s)," | |
| 490 | - " coalesce(euser,user), coalesce(ecomment,comment)" | |
| 491 | - " FROM event WHERE objid=%d", timeline_utc(), rid); | |
| 492 | - if( db_step(&q)==SQLITE_ROW ){ | |
| 493 | - const char *zType; | |
| 494 | - switch( db_column_text(&q,0)[0] ){ | |
| 495 | - case 'c': zType = "Check-in"; break; | |
| 496 | - case 'w': zType = "Wiki-edit"; break; | |
| 497 | - case 'e': zType = "Event"; break; | |
| 498 | - case 't': zType = "Ticket-change"; break; | |
| 499 | - case 'g': zType = "Tag-change"; break; | |
| 500 | - default: zType = "Unknown"; break; | |
| 501 | - } | |
| 502 | - fossil_print("type: %s by %s on %s\n", zType, db_column_text(&q,2), | |
| 503 | - db_column_text(&q, 1)); | |
| 504 | - fossil_print("comment: "); | |
| 505 | - comment_print(db_column_text(&q,3), 10, 78); | |
| 506 | - } | |
| 507 | - db_finalize(&q); | |
| 508 | - db_prepare(&q, | |
| 509 | - "SELECT filename.name, blob.uuid, datetime(event.mtime%s)," | |
| 510 | - " coalesce(euser,user), coalesce(ecomment,comment)" | |
| 511 | - " FROM mlink, filename, blob, event" | |
| 512 | - " WHERE mlink.fid=%d" | |
| 513 | - " AND filename.fnid=mlink.fnid" | |
| 514 | - " AND event.objid=mlink.mid" | |
| 515 | - " AND blob.rid=mlink.mid" | |
| 516 | - " ORDER BY event.mtime DESC /*sort*/", | |
| 517 | - timeline_utc(), rid); | |
| 518 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 519 | - fossil_print("file: %s\n", db_column_text(&q,0)); | |
| 520 | - fossil_print(" part of [%.10s] by %s on %s\n", | |
| 521 | - db_column_text(&q, 1), | |
| 522 | - db_column_text(&q, 3), | |
| 523 | - db_column_text(&q, 2)); | |
| 524 | - fossil_print(" "); | |
| 525 | - comment_print(db_column_text(&q,4), 10, 78); | |
| 526 | - } | |
| 527 | - db_finalize(&q); | |
| 528 | - } | |
| 615 | + whatis_rid(rid, verboseFlag); | |
| 616 | + } | |
| 617 | +} | |
| 618 | + | |
| 619 | +/* | |
| 620 | +** COMMAND: test-whatis-all | |
| 621 | +** Usage: %fossil test-whatis-all | |
| 622 | +** | |
| 623 | +** Show "whatis" information about every artifact in the repository | |
| 624 | +*/ | |
| 625 | +void test_whatis_all_cmd(void){ | |
| 626 | + Stmt q; | |
| 627 | + int cnt = 0; | |
| 628 | + db_find_and_open_repository(0,0); | |
| 629 | + db_prepare(&q, "SELECT rid FROM blob ORDER BY rid"); | |
| 630 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 631 | + if( cnt++ ) fossil_print("%.79c\n", '-'); | |
| 632 | + whatis_rid(db_column_int(&q,0), 1); | |
| 633 | + } | |
| 634 | + db_finalize(&q); | |
| 529 | 635 | } |
| 530 | 636 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -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 @@ | ||
| 204 | 204 | #endif |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | 207 | /* |
| 208 | 208 | ** Close the connection to a child process previously created using |
| 209 | -** popen2(). Kill off the child process, then close the pipes. | |
| 209 | +** popen2(). | |
| 210 | 210 | */ |
| 211 | 211 | void pclose2(int fdIn, FILE *pOut, int childPid){ |
| 212 | 212 | #ifdef _WIN32 |
| 213 | 213 | /* Not implemented, yet */ |
| 214 | 214 | close(fdIn); |
| 215 | 215 | fclose(pOut); |
| 216 | 216 | #else |
| 217 | 217 | close(fdIn); |
| 218 | 218 | fclose(pOut); |
| 219 | - kill(childPid, SIGINT); | |
| 220 | 219 | while( waitpid(0, 0, WNOHANG)>0 ) {} |
| 221 | 220 | #endif |
| 222 | 221 | } |
| 223 | 222 |
| --- src/popen.c | |
| +++ src/popen.c | |
| @@ -204,19 +204,18 @@ | |
| 204 | #endif |
| 205 | } |
| 206 | |
| 207 | /* |
| 208 | ** Close the connection to a child process previously created using |
| 209 | ** popen2(). Kill off the child process, then close the pipes. |
| 210 | */ |
| 211 | void pclose2(int fdIn, FILE *pOut, int childPid){ |
| 212 | #ifdef _WIN32 |
| 213 | /* Not implemented, yet */ |
| 214 | close(fdIn); |
| 215 | fclose(pOut); |
| 216 | #else |
| 217 | close(fdIn); |
| 218 | fclose(pOut); |
| 219 | kill(childPid, SIGINT); |
| 220 | while( waitpid(0, 0, WNOHANG)>0 ) {} |
| 221 | #endif |
| 222 | } |
| 223 |
| --- src/popen.c | |
| +++ src/popen.c | |
| @@ -204,19 +204,18 @@ | |
| 204 | #endif |
| 205 | } |
| 206 | |
| 207 | /* |
| 208 | ** Close the connection to a child process previously created using |
| 209 | ** popen2(). |
| 210 | */ |
| 211 | void pclose2(int fdIn, FILE *pOut, int childPid){ |
| 212 | #ifdef _WIN32 |
| 213 | /* Not implemented, yet */ |
| 214 | close(fdIn); |
| 215 | fclose(pOut); |
| 216 | #else |
| 217 | close(fdIn); |
| 218 | fclose(pOut); |
| 219 | while( waitpid(0, 0, WNOHANG)>0 ) {} |
| 220 | #endif |
| 221 | } |
| 222 |
-13
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -612,23 +612,10 @@ | ||
| 612 | 612 | @ priority AS 'Pri', |
| 613 | 613 | @ title AS 'Title', |
| 614 | 614 | @ description AS '_Description', -- When the column name begins with '_' |
| 615 | 615 | @ remarks AS '_Remarks' -- content is rendered as wiki |
| 616 | 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 | 617 | @ </pre></blockquote> |
| 631 | 618 | @ |
| 632 | 619 | } |
| 633 | 620 | |
| 634 | 621 | /* |
| 635 | 622 |
| --- 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 @@ | ||
| 35 | 35 | |
| 36 | 36 | |
| 37 | 37 | /* |
| 38 | 38 | ** These are the only markup attributes allowed. |
| 39 | 39 | */ |
| 40 | -#define ATTR_ALIGN 1 | |
| 41 | -#define ATTR_ALT 2 | |
| 42 | -#define ATTR_BGCOLOR 3 | |
| 43 | -#define ATTR_BORDER 4 | |
| 44 | -#define ATTR_CELLPADDING 5 | |
| 45 | -#define ATTR_CELLSPACING 6 | |
| 46 | -#define ATTR_CLASS 7 | |
| 47 | -#define ATTR_CLEAR 8 | |
| 48 | -#define ATTR_COLOR 9 | |
| 49 | -#define ATTR_COLSPAN 10 | |
| 50 | -#define ATTR_COMPACT 11 | |
| 51 | -#define ATTR_FACE 12 | |
| 52 | -#define ATTR_HEIGHT 13 | |
| 53 | -#define ATTR_HREF 14 | |
| 54 | -#define ATTR_HSPACE 15 | |
| 55 | -#define ATTR_ID 16 | |
| 56 | -#define ATTR_LINKS 17 | |
| 57 | -#define ATTR_NAME 18 | |
| 58 | -#define ATTR_ROWSPAN 19 | |
| 59 | -#define ATTR_SIZE 20 | |
| 60 | -#define ATTR_SRC 21 | |
| 61 | -#define ATTR_START 22 | |
| 62 | -#define ATTR_STYLE 23 | |
| 63 | -#define ATTR_TARGET 24 | |
| 64 | -#define ATTR_TYPE 25 | |
| 65 | -#define ATTR_VALIGN 26 | |
| 66 | -#define ATTR_VALUE 27 | |
| 67 | -#define ATTR_VSPACE 28 | |
| 68 | -#define ATTR_WIDTH 29 | |
| 69 | -#define AMSK_ALIGN 0x00000001 | |
| 70 | -#define AMSK_ALT 0x00000002 | |
| 71 | -#define AMSK_BGCOLOR 0x00000004 | |
| 72 | -#define AMSK_BORDER 0x00000008 | |
| 73 | -#define AMSK_CELLPADDING 0x00000010 | |
| 74 | -#define AMSK_CELLSPACING 0x00000020 | |
| 75 | -#define AMSK_CLASS 0x00000040 | |
| 76 | -#define AMSK_CLEAR 0x00000080 | |
| 77 | -#define AMSK_COLOR 0x00000100 | |
| 78 | -#define AMSK_COLSPAN 0x00000200 | |
| 79 | -#define AMSK_COMPACT 0x00000400 | |
| 80 | -#define AMSK_FACE 0x00000800 | |
| 81 | -#define AMSK_HEIGHT 0x00001000 | |
| 82 | -#define AMSK_HREF 0x00002000 | |
| 83 | -#define AMSK_HSPACE 0x00004000 | |
| 84 | -#define AMSK_ID 0x00008000 | |
| 85 | -#define AMSK_LINKS 0x00010000 | |
| 86 | -#define AMSK_NAME 0x00020000 | |
| 87 | -#define AMSK_ROWSPAN 0x00040000 | |
| 88 | -#define AMSK_SIZE 0x00080000 | |
| 89 | -#define AMSK_SRC 0x00100000 | |
| 90 | -#define AMSK_START 0x00200000 | |
| 91 | -#define AMSK_STYLE 0x00400000 | |
| 92 | -#define AMSK_TARGET 0x00800000 | |
| 93 | -#define AMSK_TYPE 0x01000000 | |
| 94 | -#define AMSK_VALIGN 0x02000000 | |
| 95 | -#define AMSK_VALUE 0x04000000 | |
| 96 | -#define AMSK_VSPACE 0x08000000 | |
| 97 | -#define AMSK_WIDTH 0x10000000 | |
| 40 | +enum allowed_attr_t { | |
| 41 | + ATTR_ALIGN = 1, | |
| 42 | + ATTR_ALT, | |
| 43 | + ATTR_BGCOLOR, | |
| 44 | + ATTR_BORDER, | |
| 45 | + ATTR_CELLPADDING, | |
| 46 | + ATTR_CELLSPACING, | |
| 47 | + ATTR_CLASS, | |
| 48 | + ATTR_CLEAR, | |
| 49 | + ATTR_COLOR, | |
| 50 | + ATTR_COLSPAN, | |
| 51 | + ATTR_COMPACT, | |
| 52 | + ATTR_FACE, | |
| 53 | + ATTR_HEIGHT, | |
| 54 | + ATTR_HREF, | |
| 55 | + ATTR_HSPACE, | |
| 56 | + ATTR_ID, | |
| 57 | + ATTR_LINKS, | |
| 58 | + ATTR_NAME, | |
| 59 | + ATTR_ROWSPAN, | |
| 60 | + ATTR_SIZE, | |
| 61 | + ATTR_SRC, | |
| 62 | + ATTR_START, | |
| 63 | + ATTR_STYLE, | |
| 64 | + ATTR_TARGET, | |
| 65 | + ATTR_TYPE, | |
| 66 | + ATTR_VALIGN, | |
| 67 | + ATTR_VALUE, | |
| 68 | + ATTR_VSPACE, | |
| 69 | + ATTR_WIDTH | |
| 70 | +}; | |
| 71 | + | |
| 72 | +enum amsk_t { | |
| 73 | + AMSK_ALIGN = 0x00000001, | |
| 74 | + AMSK_ALT = 0x00000002, | |
| 75 | + AMSK_BGCOLOR = 0x00000004, | |
| 76 | + AMSK_BORDER = 0x00000008, | |
| 77 | + AMSK_CELLPADDING = 0x00000010, | |
| 78 | + AMSK_CELLSPACING = 0x00000020, | |
| 79 | + AMSK_CLASS = 0x00000040, | |
| 80 | + AMSK_CLEAR = 0x00000080, | |
| 81 | + AMSK_COLOR = 0x00000100, | |
| 82 | + AMSK_COLSPAN = 0x00000200, | |
| 83 | + AMSK_COMPACT = 0x00000400, | |
| 84 | + /* re-use = 0x00000800, */ | |
| 85 | + AMSK_FACE = 0x00001000, | |
| 86 | + AMSK_HEIGHT = 0x00002000, | |
| 87 | + AMSK_HREF = 0x00004000, | |
| 88 | + AMSK_HSPACE = 0x00008000, | |
| 89 | + AMSK_ID = 0x00010000, | |
| 90 | + AMSK_LINKS = 0x00020000, | |
| 91 | + AMSK_NAME = 0x00040000, | |
| 92 | + AMSK_ROWSPAN = 0x00080000, | |
| 93 | + AMSK_SIZE = 0x00100000, | |
| 94 | + AMSK_SRC = 0x00200000, | |
| 95 | + AMSK_START = 0x00400000, | |
| 96 | + AMSK_STYLE = 0x00800000, | |
| 97 | + AMSK_TARGET = 0x01000000, | |
| 98 | + AMSK_TYPE = 0x02000000, | |
| 99 | + AMSK_VALIGN = 0x04000000, | |
| 100 | + AMSK_VALUE = 0x08000000, | |
| 101 | + AMSK_VSPACE = 0x10000000, | |
| 102 | + AMSK_WIDTH = 0x20000000 | |
| 103 | +}; | |
| 98 | 104 | |
| 99 | 105 | static const struct AllowedAttribute { |
| 100 | 106 | const char *zName; |
| 101 | 107 | unsigned int iMask; |
| 102 | 108 | } aAttribute[] = { |
| 109 | + /* These indexes MUST line up with their | |
| 110 | + corresponding allowed_attr_t enum values. | |
| 111 | + */ | |
| 103 | 112 | { 0, 0 }, |
| 104 | - { "align", AMSK_ALIGN, }, | |
| 105 | - { "alt", AMSK_ALT, }, | |
| 106 | - { "bgcolor", AMSK_BGCOLOR, }, | |
| 107 | - { "border", AMSK_BORDER, }, | |
| 108 | - { "cellpadding", AMSK_CELLPADDING, }, | |
| 109 | - { "cellspacing", AMSK_CELLSPACING, }, | |
| 110 | - { "class", AMSK_CLASS, }, | |
| 111 | - { "clear", AMSK_CLEAR, }, | |
| 112 | - { "color", AMSK_COLOR, }, | |
| 113 | - { "colspan", AMSK_COLSPAN, }, | |
| 114 | - { "compact", AMSK_COMPACT, }, | |
| 115 | - { "face", AMSK_FACE, }, | |
| 116 | - { "height", AMSK_HEIGHT, }, | |
| 117 | - { "href", AMSK_HREF, }, | |
| 118 | - { "hspace", AMSK_HSPACE, }, | |
| 119 | - { "id", AMSK_ID, }, | |
| 120 | - { "links", AMSK_LINKS, }, | |
| 121 | - { "name", AMSK_NAME, }, | |
| 122 | - { "rowspan", AMSK_ROWSPAN, }, | |
| 123 | - { "size", AMSK_SIZE, }, | |
| 124 | - { "src", AMSK_SRC, }, | |
| 125 | - { "start", AMSK_START, }, | |
| 126 | - { "style", AMSK_STYLE, }, | |
| 127 | - { "target", AMSK_TARGET, }, | |
| 128 | - { "type", AMSK_TYPE, }, | |
| 129 | - { "valign", AMSK_VALIGN, }, | |
| 130 | - { "value", AMSK_VALUE, }, | |
| 131 | - { "vspace", AMSK_VSPACE, }, | |
| 132 | - { "width", AMSK_WIDTH, }, | |
| 113 | + { "align", AMSK_ALIGN }, | |
| 114 | + { "alt", AMSK_ALT }, | |
| 115 | + { "bgcolor", AMSK_BGCOLOR }, | |
| 116 | + { "border", AMSK_BORDER }, | |
| 117 | + { "cellpadding", AMSK_CELLPADDING }, | |
| 118 | + { "cellspacing", AMSK_CELLSPACING }, | |
| 119 | + { "class", AMSK_CLASS }, | |
| 120 | + { "clear", AMSK_CLEAR }, | |
| 121 | + { "color", AMSK_COLOR }, | |
| 122 | + { "colspan", AMSK_COLSPAN }, | |
| 123 | + { "compact", AMSK_COMPACT }, | |
| 124 | + { "face", AMSK_FACE }, | |
| 125 | + { "height", AMSK_HEIGHT }, | |
| 126 | + { "href", AMSK_HREF }, | |
| 127 | + { "hspace", AMSK_HSPACE }, | |
| 128 | + { "id", AMSK_ID }, | |
| 129 | + { "links", AMSK_LINKS }, | |
| 130 | + { "name", AMSK_NAME }, | |
| 131 | + { "rowspan", AMSK_ROWSPAN }, | |
| 132 | + { "size", AMSK_SIZE }, | |
| 133 | + { "src", AMSK_SRC }, | |
| 134 | + { "start", AMSK_START }, | |
| 135 | + { "style", AMSK_STYLE }, | |
| 136 | + { "target", AMSK_TARGET }, | |
| 137 | + { "type", AMSK_TYPE }, | |
| 138 | + { "valign", AMSK_VALIGN }, | |
| 139 | + { "value", AMSK_VALUE }, | |
| 140 | + { "vspace", AMSK_VSPACE }, | |
| 141 | + { "width", AMSK_WIDTH }, | |
| 133 | 142 | }; |
| 134 | 143 | |
| 135 | 144 | /* |
| 136 | 145 | ** Use binary search to locate a tag in the aAttribute[] table. |
| 137 | 146 | */ |
| @@ -216,16 +225,17 @@ | ||
| 216 | 225 | #define MARKUP_TBODY 50 |
| 217 | 226 | #define MARKUP_TD 51 |
| 218 | 227 | #define MARKUP_TFOOT 52 |
| 219 | 228 | #define MARKUP_TH 53 |
| 220 | 229 | #define MARKUP_THEAD 54 |
| 221 | -#define MARKUP_TR 55 | |
| 222 | -#define MARKUP_TT 56 | |
| 223 | -#define MARKUP_U 57 | |
| 224 | -#define MARKUP_UL 58 | |
| 225 | -#define MARKUP_VAR 59 | |
| 226 | -#define MARKUP_VERBATIM 60 | |
| 230 | +#define MARKUP_TITLE 55 | |
| 231 | +#define MARKUP_TR 56 | |
| 232 | +#define MARKUP_TT 57 | |
| 233 | +#define MARKUP_U 58 | |
| 234 | +#define MARKUP_UL 59 | |
| 235 | +#define MARKUP_VAR 60 | |
| 236 | +#define MARKUP_VERBATIM 61 | |
| 227 | 237 | |
| 228 | 238 | /* |
| 229 | 239 | ** The various markup is divided into the following types: |
| 230 | 240 | */ |
| 231 | 241 | #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ |
| @@ -348,10 +358,11 @@ | ||
| 348 | 358 | { "th", MARKUP_TH, MUTYPE_TD, |
| 349 | 359 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| |
| 350 | 360 | AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 351 | 361 | { "thead", MARKUP_THEAD, MUTYPE_BLOCK, |
| 352 | 362 | AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 363 | + { "title", MARKUP_TITLE, MUTYPE_BLOCK, 0 }, | |
| 353 | 364 | { "tr", MARKUP_TR, MUTYPE_TR, |
| 354 | 365 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 355 | 366 | { "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE }, |
| 356 | 367 | { "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE }, |
| 357 | 368 | { "ul", MARKUP_UL, MUTYPE_LIST, |
| @@ -787,11 +798,11 @@ | ||
| 787 | 798 | p->nAttr = 1; |
| 788 | 799 | if( c=='>' ) return; |
| 789 | 800 | } |
| 790 | 801 | while( fossil_isspace(z[i]) ){ i++; } |
| 791 | 802 | while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){ |
| 792 | - int attrOk; /* True to preserver attribute. False to ignore it */ | |
| 803 | + int attrOk; /* True to preserve attribute. False to ignore it */ | |
| 793 | 804 | j = 0; |
| 794 | 805 | while( fossil_isalnum(z[i]) ){ |
| 795 | 806 | if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]); |
| 796 | 807 | i++; |
| 797 | 808 | } |
| @@ -869,12 +880,14 @@ | ||
| 869 | 880 | static void unparseMarkup(ParsedMarkup *p){ |
| 870 | 881 | int i, n; |
| 871 | 882 | for(i=0; i<p->nAttr; i++){ |
| 872 | 883 | char *z = p->aAttr[i].zValue; |
| 873 | 884 | if( z==0 ) continue; |
| 874 | - n = strlen(z); | |
| 875 | - z[n] = p->aAttr[i].cTerm; | |
| 885 | + if( p->aAttr[i].cTerm ){ | |
| 886 | + n = strlen(z); | |
| 887 | + z[n] = p->aAttr[i].cTerm; | |
| 888 | + } | |
| 876 | 889 | } |
| 877 | 890 | } |
| 878 | 891 | |
| 879 | 892 | /* |
| 880 | 893 | ** Return the value of attribute attrId. Return NULL if there is no |
| @@ -1468,10 +1481,19 @@ | ||
| 1468 | 1481 | } |
| 1469 | 1482 | case TOKEN_MARKUP: { |
| 1470 | 1483 | const char *zId; |
| 1471 | 1484 | int iDiv; |
| 1472 | 1485 | parseMarkup(&markup, z); |
| 1486 | + | |
| 1487 | + /* Convert <title> to <h1 align='center'> */ | |
| 1488 | + if( markup.iCode==MARKUP_TITLE && !p->inVerbatim ){ | |
| 1489 | + markup.iCode = MARKUP_H1; | |
| 1490 | + markup.nAttr = 1; | |
| 1491 | + markup.aAttr[0].iACode = AMSK_ALIGN; | |
| 1492 | + markup.aAttr[0].zValue = "center"; | |
| 1493 | + markup.aAttr[0].cTerm = 0; | |
| 1494 | + } | |
| 1473 | 1495 | |
| 1474 | 1496 | /* Markup of the form </div id=ID> where there is a matching |
| 1475 | 1497 | ** ID somewhere on the stack. Exit any contained verbatim. |
| 1476 | 1498 | ** Pop the stack up to the matching <div>. Discard the </div> |
| 1477 | 1499 | */ |
| 1478 | 1500 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -35,103 +35,112 @@ | |
| 35 | |
| 36 | |
| 37 | /* |
| 38 | ** These are the only markup attributes allowed. |
| 39 | */ |
| 40 | #define ATTR_ALIGN 1 |
| 41 | #define ATTR_ALT 2 |
| 42 | #define ATTR_BGCOLOR 3 |
| 43 | #define ATTR_BORDER 4 |
| 44 | #define ATTR_CELLPADDING 5 |
| 45 | #define ATTR_CELLSPACING 6 |
| 46 | #define ATTR_CLASS 7 |
| 47 | #define ATTR_CLEAR 8 |
| 48 | #define ATTR_COLOR 9 |
| 49 | #define ATTR_COLSPAN 10 |
| 50 | #define ATTR_COMPACT 11 |
| 51 | #define ATTR_FACE 12 |
| 52 | #define ATTR_HEIGHT 13 |
| 53 | #define ATTR_HREF 14 |
| 54 | #define ATTR_HSPACE 15 |
| 55 | #define ATTR_ID 16 |
| 56 | #define ATTR_LINKS 17 |
| 57 | #define ATTR_NAME 18 |
| 58 | #define ATTR_ROWSPAN 19 |
| 59 | #define ATTR_SIZE 20 |
| 60 | #define ATTR_SRC 21 |
| 61 | #define ATTR_START 22 |
| 62 | #define ATTR_STYLE 23 |
| 63 | #define ATTR_TARGET 24 |
| 64 | #define ATTR_TYPE 25 |
| 65 | #define ATTR_VALIGN 26 |
| 66 | #define ATTR_VALUE 27 |
| 67 | #define ATTR_VSPACE 28 |
| 68 | #define ATTR_WIDTH 29 |
| 69 | #define AMSK_ALIGN 0x00000001 |
| 70 | #define AMSK_ALT 0x00000002 |
| 71 | #define AMSK_BGCOLOR 0x00000004 |
| 72 | #define AMSK_BORDER 0x00000008 |
| 73 | #define AMSK_CELLPADDING 0x00000010 |
| 74 | #define AMSK_CELLSPACING 0x00000020 |
| 75 | #define AMSK_CLASS 0x00000040 |
| 76 | #define AMSK_CLEAR 0x00000080 |
| 77 | #define AMSK_COLOR 0x00000100 |
| 78 | #define AMSK_COLSPAN 0x00000200 |
| 79 | #define AMSK_COMPACT 0x00000400 |
| 80 | #define AMSK_FACE 0x00000800 |
| 81 | #define AMSK_HEIGHT 0x00001000 |
| 82 | #define AMSK_HREF 0x00002000 |
| 83 | #define AMSK_HSPACE 0x00004000 |
| 84 | #define AMSK_ID 0x00008000 |
| 85 | #define AMSK_LINKS 0x00010000 |
| 86 | #define AMSK_NAME 0x00020000 |
| 87 | #define AMSK_ROWSPAN 0x00040000 |
| 88 | #define AMSK_SIZE 0x00080000 |
| 89 | #define AMSK_SRC 0x00100000 |
| 90 | #define AMSK_START 0x00200000 |
| 91 | #define AMSK_STYLE 0x00400000 |
| 92 | #define AMSK_TARGET 0x00800000 |
| 93 | #define AMSK_TYPE 0x01000000 |
| 94 | #define AMSK_VALIGN 0x02000000 |
| 95 | #define AMSK_VALUE 0x04000000 |
| 96 | #define AMSK_VSPACE 0x08000000 |
| 97 | #define AMSK_WIDTH 0x10000000 |
| 98 | |
| 99 | static const struct AllowedAttribute { |
| 100 | const char *zName; |
| 101 | unsigned int iMask; |
| 102 | } aAttribute[] = { |
| 103 | { 0, 0 }, |
| 104 | { "align", AMSK_ALIGN, }, |
| 105 | { "alt", AMSK_ALT, }, |
| 106 | { "bgcolor", AMSK_BGCOLOR, }, |
| 107 | { "border", AMSK_BORDER, }, |
| 108 | { "cellpadding", AMSK_CELLPADDING, }, |
| 109 | { "cellspacing", AMSK_CELLSPACING, }, |
| 110 | { "class", AMSK_CLASS, }, |
| 111 | { "clear", AMSK_CLEAR, }, |
| 112 | { "color", AMSK_COLOR, }, |
| 113 | { "colspan", AMSK_COLSPAN, }, |
| 114 | { "compact", AMSK_COMPACT, }, |
| 115 | { "face", AMSK_FACE, }, |
| 116 | { "height", AMSK_HEIGHT, }, |
| 117 | { "href", AMSK_HREF, }, |
| 118 | { "hspace", AMSK_HSPACE, }, |
| 119 | { "id", AMSK_ID, }, |
| 120 | { "links", AMSK_LINKS, }, |
| 121 | { "name", AMSK_NAME, }, |
| 122 | { "rowspan", AMSK_ROWSPAN, }, |
| 123 | { "size", AMSK_SIZE, }, |
| 124 | { "src", AMSK_SRC, }, |
| 125 | { "start", AMSK_START, }, |
| 126 | { "style", AMSK_STYLE, }, |
| 127 | { "target", AMSK_TARGET, }, |
| 128 | { "type", AMSK_TYPE, }, |
| 129 | { "valign", AMSK_VALIGN, }, |
| 130 | { "value", AMSK_VALUE, }, |
| 131 | { "vspace", AMSK_VSPACE, }, |
| 132 | { "width", AMSK_WIDTH, }, |
| 133 | }; |
| 134 | |
| 135 | /* |
| 136 | ** Use binary search to locate a tag in the aAttribute[] table. |
| 137 | */ |
| @@ -216,16 +225,17 @@ | |
| 216 | #define MARKUP_TBODY 50 |
| 217 | #define MARKUP_TD 51 |
| 218 | #define MARKUP_TFOOT 52 |
| 219 | #define MARKUP_TH 53 |
| 220 | #define MARKUP_THEAD 54 |
| 221 | #define MARKUP_TR 55 |
| 222 | #define MARKUP_TT 56 |
| 223 | #define MARKUP_U 57 |
| 224 | #define MARKUP_UL 58 |
| 225 | #define MARKUP_VAR 59 |
| 226 | #define MARKUP_VERBATIM 60 |
| 227 | |
| 228 | /* |
| 229 | ** The various markup is divided into the following types: |
| 230 | */ |
| 231 | #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ |
| @@ -348,10 +358,11 @@ | |
| 348 | { "th", MARKUP_TH, MUTYPE_TD, |
| 349 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| |
| 350 | AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 351 | { "thead", MARKUP_THEAD, MUTYPE_BLOCK, |
| 352 | AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 353 | { "tr", MARKUP_TR, MUTYPE_TR, |
| 354 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 355 | { "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE }, |
| 356 | { "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE }, |
| 357 | { "ul", MARKUP_UL, MUTYPE_LIST, |
| @@ -787,11 +798,11 @@ | |
| 787 | p->nAttr = 1; |
| 788 | if( c=='>' ) return; |
| 789 | } |
| 790 | while( fossil_isspace(z[i]) ){ i++; } |
| 791 | while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){ |
| 792 | int attrOk; /* True to preserver attribute. False to ignore it */ |
| 793 | j = 0; |
| 794 | while( fossil_isalnum(z[i]) ){ |
| 795 | if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]); |
| 796 | i++; |
| 797 | } |
| @@ -869,12 +880,14 @@ | |
| 869 | static void unparseMarkup(ParsedMarkup *p){ |
| 870 | int i, n; |
| 871 | for(i=0; i<p->nAttr; i++){ |
| 872 | char *z = p->aAttr[i].zValue; |
| 873 | if( z==0 ) continue; |
| 874 | n = strlen(z); |
| 875 | z[n] = p->aAttr[i].cTerm; |
| 876 | } |
| 877 | } |
| 878 | |
| 879 | /* |
| 880 | ** Return the value of attribute attrId. Return NULL if there is no |
| @@ -1468,10 +1481,19 @@ | |
| 1468 | } |
| 1469 | case TOKEN_MARKUP: { |
| 1470 | const char *zId; |
| 1471 | int iDiv; |
| 1472 | parseMarkup(&markup, z); |
| 1473 | |
| 1474 | /* Markup of the form </div id=ID> where there is a matching |
| 1475 | ** ID somewhere on the stack. Exit any contained verbatim. |
| 1476 | ** Pop the stack up to the matching <div>. Discard the </div> |
| 1477 | */ |
| 1478 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -35,103 +35,112 @@ | |
| 35 | |
| 36 | |
| 37 | /* |
| 38 | ** These are the only markup attributes allowed. |
| 39 | */ |
| 40 | enum allowed_attr_t { |
| 41 | ATTR_ALIGN = 1, |
| 42 | ATTR_ALT, |
| 43 | ATTR_BGCOLOR, |
| 44 | ATTR_BORDER, |
| 45 | ATTR_CELLPADDING, |
| 46 | ATTR_CELLSPACING, |
| 47 | ATTR_CLASS, |
| 48 | ATTR_CLEAR, |
| 49 | ATTR_COLOR, |
| 50 | ATTR_COLSPAN, |
| 51 | ATTR_COMPACT, |
| 52 | ATTR_FACE, |
| 53 | ATTR_HEIGHT, |
| 54 | ATTR_HREF, |
| 55 | ATTR_HSPACE, |
| 56 | ATTR_ID, |
| 57 | ATTR_LINKS, |
| 58 | ATTR_NAME, |
| 59 | ATTR_ROWSPAN, |
| 60 | ATTR_SIZE, |
| 61 | ATTR_SRC, |
| 62 | ATTR_START, |
| 63 | ATTR_STYLE, |
| 64 | ATTR_TARGET, |
| 65 | ATTR_TYPE, |
| 66 | ATTR_VALIGN, |
| 67 | ATTR_VALUE, |
| 68 | ATTR_VSPACE, |
| 69 | ATTR_WIDTH |
| 70 | }; |
| 71 | |
| 72 | enum amsk_t { |
| 73 | AMSK_ALIGN = 0x00000001, |
| 74 | AMSK_ALT = 0x00000002, |
| 75 | AMSK_BGCOLOR = 0x00000004, |
| 76 | AMSK_BORDER = 0x00000008, |
| 77 | AMSK_CELLPADDING = 0x00000010, |
| 78 | AMSK_CELLSPACING = 0x00000020, |
| 79 | AMSK_CLASS = 0x00000040, |
| 80 | AMSK_CLEAR = 0x00000080, |
| 81 | AMSK_COLOR = 0x00000100, |
| 82 | AMSK_COLSPAN = 0x00000200, |
| 83 | AMSK_COMPACT = 0x00000400, |
| 84 | /* re-use = 0x00000800, */ |
| 85 | AMSK_FACE = 0x00001000, |
| 86 | AMSK_HEIGHT = 0x00002000, |
| 87 | AMSK_HREF = 0x00004000, |
| 88 | AMSK_HSPACE = 0x00008000, |
| 89 | AMSK_ID = 0x00010000, |
| 90 | AMSK_LINKS = 0x00020000, |
| 91 | AMSK_NAME = 0x00040000, |
| 92 | AMSK_ROWSPAN = 0x00080000, |
| 93 | AMSK_SIZE = 0x00100000, |
| 94 | AMSK_SRC = 0x00200000, |
| 95 | AMSK_START = 0x00400000, |
| 96 | AMSK_STYLE = 0x00800000, |
| 97 | AMSK_TARGET = 0x01000000, |
| 98 | AMSK_TYPE = 0x02000000, |
| 99 | AMSK_VALIGN = 0x04000000, |
| 100 | AMSK_VALUE = 0x08000000, |
| 101 | AMSK_VSPACE = 0x10000000, |
| 102 | AMSK_WIDTH = 0x20000000 |
| 103 | }; |
| 104 | |
| 105 | static const struct AllowedAttribute { |
| 106 | const char *zName; |
| 107 | unsigned int iMask; |
| 108 | } aAttribute[] = { |
| 109 | /* These indexes MUST line up with their |
| 110 | corresponding allowed_attr_t enum values. |
| 111 | */ |
| 112 | { 0, 0 }, |
| 113 | { "align", AMSK_ALIGN }, |
| 114 | { "alt", AMSK_ALT }, |
| 115 | { "bgcolor", AMSK_BGCOLOR }, |
| 116 | { "border", AMSK_BORDER }, |
| 117 | { "cellpadding", AMSK_CELLPADDING }, |
| 118 | { "cellspacing", AMSK_CELLSPACING }, |
| 119 | { "class", AMSK_CLASS }, |
| 120 | { "clear", AMSK_CLEAR }, |
| 121 | { "color", AMSK_COLOR }, |
| 122 | { "colspan", AMSK_COLSPAN }, |
| 123 | { "compact", AMSK_COMPACT }, |
| 124 | { "face", AMSK_FACE }, |
| 125 | { "height", AMSK_HEIGHT }, |
| 126 | { "href", AMSK_HREF }, |
| 127 | { "hspace", AMSK_HSPACE }, |
| 128 | { "id", AMSK_ID }, |
| 129 | { "links", AMSK_LINKS }, |
| 130 | { "name", AMSK_NAME }, |
| 131 | { "rowspan", AMSK_ROWSPAN }, |
| 132 | { "size", AMSK_SIZE }, |
| 133 | { "src", AMSK_SRC }, |
| 134 | { "start", AMSK_START }, |
| 135 | { "style", AMSK_STYLE }, |
| 136 | { "target", AMSK_TARGET }, |
| 137 | { "type", AMSK_TYPE }, |
| 138 | { "valign", AMSK_VALIGN }, |
| 139 | { "value", AMSK_VALUE }, |
| 140 | { "vspace", AMSK_VSPACE }, |
| 141 | { "width", AMSK_WIDTH }, |
| 142 | }; |
| 143 | |
| 144 | /* |
| 145 | ** Use binary search to locate a tag in the aAttribute[] table. |
| 146 | */ |
| @@ -216,16 +225,17 @@ | |
| 225 | #define MARKUP_TBODY 50 |
| 226 | #define MARKUP_TD 51 |
| 227 | #define MARKUP_TFOOT 52 |
| 228 | #define MARKUP_TH 53 |
| 229 | #define MARKUP_THEAD 54 |
| 230 | #define MARKUP_TITLE 55 |
| 231 | #define MARKUP_TR 56 |
| 232 | #define MARKUP_TT 57 |
| 233 | #define MARKUP_U 58 |
| 234 | #define MARKUP_UL 59 |
| 235 | #define MARKUP_VAR 60 |
| 236 | #define MARKUP_VERBATIM 61 |
| 237 | |
| 238 | /* |
| 239 | ** The various markup is divided into the following types: |
| 240 | */ |
| 241 | #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ |
| @@ -348,10 +358,11 @@ | |
| 358 | { "th", MARKUP_TH, MUTYPE_TD, |
| 359 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| |
| 360 | AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 361 | { "thead", MARKUP_THEAD, MUTYPE_BLOCK, |
| 362 | AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 363 | { "title", MARKUP_TITLE, MUTYPE_BLOCK, 0 }, |
| 364 | { "tr", MARKUP_TR, MUTYPE_TR, |
| 365 | AMSK_ALIGN|AMSK_BGCOLOR|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE }, |
| 366 | { "tt", MARKUP_TT, MUTYPE_FONT, AMSK_STYLE }, |
| 367 | { "u", MARKUP_U, MUTYPE_FONT, AMSK_STYLE }, |
| 368 | { "ul", MARKUP_UL, MUTYPE_LIST, |
| @@ -787,11 +798,11 @@ | |
| 798 | p->nAttr = 1; |
| 799 | if( c=='>' ) return; |
| 800 | } |
| 801 | while( fossil_isspace(z[i]) ){ i++; } |
| 802 | while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){ |
| 803 | int attrOk; /* True to preserve attribute. False to ignore it */ |
| 804 | j = 0; |
| 805 | while( fossil_isalnum(z[i]) ){ |
| 806 | if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]); |
| 807 | i++; |
| 808 | } |
| @@ -869,12 +880,14 @@ | |
| 880 | static void unparseMarkup(ParsedMarkup *p){ |
| 881 | int i, n; |
| 882 | for(i=0; i<p->nAttr; i++){ |
| 883 | char *z = p->aAttr[i].zValue; |
| 884 | if( z==0 ) continue; |
| 885 | if( p->aAttr[i].cTerm ){ |
| 886 | n = strlen(z); |
| 887 | z[n] = p->aAttr[i].cTerm; |
| 888 | } |
| 889 | } |
| 890 | } |
| 891 | |
| 892 | /* |
| 893 | ** Return the value of attribute attrId. Return NULL if there is no |
| @@ -1468,10 +1481,19 @@ | |
| 1481 | } |
| 1482 | case TOKEN_MARKUP: { |
| 1483 | const char *zId; |
| 1484 | int iDiv; |
| 1485 | parseMarkup(&markup, z); |
| 1486 | |
| 1487 | /* Convert <title> to <h1 align='center'> */ |
| 1488 | if( markup.iCode==MARKUP_TITLE && !p->inVerbatim ){ |
| 1489 | markup.iCode = MARKUP_H1; |
| 1490 | markup.nAttr = 1; |
| 1491 | markup.aAttr[0].iACode = AMSK_ALIGN; |
| 1492 | markup.aAttr[0].zValue = "center"; |
| 1493 | markup.aAttr[0].cTerm = 0; |
| 1494 | } |
| 1495 | |
| 1496 | /* Markup of the form </div id=ID> where there is a matching |
| 1497 | ** ID somewhere on the stack. Exit any contained verbatim. |
| 1498 | ** Pop the stack up to the matching <div>. Discard the </div> |
| 1499 | */ |
| 1500 |