Fossil SCM

New format for JSON diff output. Promote the "test-diff" command to "xdiff", retaining the older spelling as a backup for compatibility.

drh 2021-09-02 19:38 diff-color-enhancements
Commit b0511022724d7bf02169a54ae9e2c846f7b32a35f402ce262f155c82f5560901
3 files changed +23 +105 -187 +4 -4
+23
--- src/blob.c
+++ src/blob.c
@@ -356,10 +356,33 @@
356356
*/
357357
void blob_append_xfer(Blob *pTo, Blob *pFrom){
358358
blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
359359
blob_reset(pFrom);
360360
}
361
+
362
+/*
363
+** Write into pOut, a string literal representation for the first n bytes
364
+** of z[]. The string literal representation is compatible with C, TCL,
365
+** and JSON. Double-quotes are added to both ends. Double-quote and
366
+** backslash characters are escaped.
367
+*/
368
+void blob_append_string_literal(Blob *pOut, const char *z, int n){
369
+ int i;
370
+ blob_append_char(pOut, '"');
371
+ for(i=0; i<n; i++){
372
+ switch( z[i] ){
373
+ case '"':
374
+ case '\\':
375
+ blob_append_char(pOut, '\\');
376
+ /* Fall thru */
377
+ default:
378
+ blob_append_char(pOut, z[i]);
379
+ }
380
+ }
381
+ blob_append_char(pOut, '"');
382
+}
383
+
361384
362385
/*
363386
** Return a pointer to a null-terminated string for a blob.
364387
*/
365388
char *blob_str(Blob *p){
366389
--- src/blob.c
+++ src/blob.c
@@ -356,10 +356,33 @@
356 */
357 void blob_append_xfer(Blob *pTo, Blob *pFrom){
358 blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
359 blob_reset(pFrom);
360 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
362 /*
363 ** Return a pointer to a null-terminated string for a blob.
364 */
365 char *blob_str(Blob *p){
366
--- src/blob.c
+++ src/blob.c
@@ -356,10 +356,33 @@
356 */
357 void blob_append_xfer(Blob *pTo, Blob *pFrom){
358 blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
359 blob_reset(pFrom);
360 }
361
362 /*
363 ** Write into pOut, a string literal representation for the first n bytes
364 ** of z[]. The string literal representation is compatible with C, TCL,
365 ** and JSON. Double-quotes are added to both ends. Double-quote and
366 ** backslash characters are escaped.
367 */
368 void blob_append_string_literal(Blob *pOut, const char *z, int n){
369 int i;
370 blob_append_char(pOut, '"');
371 for(i=0; i<n; i++){
372 switch( z[i] ){
373 case '"':
374 case '\\':
375 blob_append_char(pOut, '\\');
376 /* Fall thru */
377 default:
378 blob_append_char(pOut, z[i]);
379 }
380 }
381 blob_append_char(pOut, '"');
382 }
383
384
385 /*
386 ** Return a pointer to a null-terminated string for a blob.
387 */
388 char *blob_str(Blob *p){
389
+105 -187
--- src/diff.c
+++ src/diff.c
@@ -1742,73 +1742,54 @@
17421742
/************************* DiffBuilderTcl ********************************/
17431743
/*
17441744
** This variant outputs a description of the diff formatted as TCL, for
17451745
** use by the --tk option to "diff".
17461746
*/
1747
-
1748
-/*
1749
-** Write out a quoted TCL string
1750
-*/
1751
-void blob_append_tcl_string(Blob *pOut, const char *z, int n){
1752
- int i;
1753
- blob_append_char(pOut, '"');
1754
- for(i=0; i<n; i++){
1755
- switch( z[i] ){
1756
- case '"':
1757
- case '\\':
1758
- blob_append_char(pOut, '\\');
1759
- /* Fall thru */
1760
- default:
1761
- blob_append_char(pOut, z[i]);
1762
- }
1763
- }
1764
- blob_append_char(pOut, '"');
1765
-}
1766
-
17671747
static void dftclSkip(DiffBuilder *p, unsigned int n, int isFinal){
17681748
blob_appendf(p->pOut, "SKIP %u\n", n);
17691749
}
17701750
static void dftclCommon(DiffBuilder *p, const DLine *pLine){
17711751
blob_appendf(p->pOut, "COM ");
1772
- blob_append_tcl_string(p->pOut, pLine->z, pLine->n);
1752
+ blob_append_string_literal(p->pOut, pLine->z, pLine->n);
17731753
blob_append_char(p->pOut, '\n');
17741754
}
17751755
static void dftclInsert(DiffBuilder *p, const DLine *pLine){
17761756
blob_append(p->pOut, "INS ", -1);
1777
- blob_append_tcl_string(p->pOut, pLine->z, pLine->n);
1757
+ blob_append_string_literal(p->pOut, pLine->z, pLine->n);
17781758
blob_append_char(p->pOut, '\n');
17791759
}
17801760
static void dftclDelete(DiffBuilder *p, const DLine *pLine){
17811761
blob_append(p->pOut, "DEL ", -1);
1782
- blob_append_tcl_string(p->pOut, pLine->z, pLine->n);
1762
+ blob_append_string_literal(p->pOut, pLine->z, pLine->n);
17831763
blob_append_char(p->pOut, '\n');
17841764
}
17851765
static void dftclReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
17861766
blob_append(p->pOut, "EDIT ", -1);
1787
- blob_append_tcl_string(p->pOut, pX->z, pX->n);
1767
+ blob_append_string_literal(p->pOut, pX->z, pX->n);
17881768
blob_append_char(p->pOut, ' ');
1789
- blob_append_tcl_string(p->pOut, pY->z, pY->n);
1769
+ blob_append_string_literal(p->pOut, pY->z, pY->n);
17901770
blob_append_char(p->pOut, '\n');
17911771
}
17921772
static void dftclEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
17931773
int i, x;
17941774
ChangeSpan span;
17951775
blob_append(p->pOut, "EDIT", 4);
17961776
oneLineChange(pX, pY, &span);
17971777
for(i=x=0; i<span.n; i++){
17981778
blob_append_char(p->pOut, ' ');
1799
- blob_append_tcl_string(p->pOut, pX->z + x, span.a[i].iStart1 - x);
1779
+ blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iStart1 - x);
18001780
x = span.a[i].iStart1;
18011781
blob_append_char(p->pOut, ' ');
1802
- blob_append_tcl_string(p->pOut, pX->z + x, span.a[i].iLen1);
1782
+ blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iLen1);
18031783
x += span.a[i].iLen1;
18041784
blob_append_char(p->pOut, ' ');
1805
- blob_append_tcl_string(p->pOut, pY->z + span.a[i].iStart2,span.a[i].iLen2);
1785
+ blob_append_string_literal(p->pOut,
1786
+ pY->z + span.a[i].iStart2, span.a[i].iLen2);
18061787
}
18071788
if( x<pX->n ){
18081789
blob_append_char(p->pOut, ' ');
1809
- blob_append_tcl_string(p->pOut, pX->z + x, pX->n - x);
1790
+ blob_append_string_literal(p->pOut, pX->z + x, pX->n - x);
18101791
}
18111792
blob_append_char(p->pOut, '\n');
18121793
}
18131794
static void dftclEnd(DiffBuilder *p){
18141795
fossil_free(p);
@@ -1825,134 +1806,73 @@
18251806
p->pOut = pOut;
18261807
return p;
18271808
}
18281809
18291810
/************************* DiffBuilderJson ********************************/
1830
-
1831
-/* Convert raw text into content suitable for a JSON string. Escape
1832
-** charaters that are special to HTML and to JSON:
1833
-**
1834
-** < -> &lt;
1835
-** > -> &gt;
1836
-** & -> &amp;
1837
-** " -> &quot;
1838
-** ' -> &#39;
1839
-** \ -> &#92;
1840
-**
1841
-** In addition, TAB characters are converted into an appropriate number
1842
-** of spaces. The *piCol value is the number of prior columns in the
1843
-** current line. Update the column count before returning, so that
1844
-** subsequent invocations can figure out the right number of spaces to
1845
-** insert for each tab.
1846
-*/
1847
-static void jsonize_to_blob(Blob *p, const char *zIn, int n, int *piCol){
1848
- int c, i, x;
1849
- int iCol = *piCol;
1850
- for(i=0; i<n; i++){
1851
- c = zIn[i];
1852
- switch( c ){
1853
- case '<':
1854
- blob_append(p, "&lt;", 4);
1855
- iCol++;
1856
- break;
1857
- case '>':
1858
- blob_append(p, "&gt;", 4);
1859
- iCol++;
1860
- break;
1861
- case '&':
1862
- blob_append(p, "&amp;", 5);
1863
- iCol++;
1864
- break;
1865
- case '"':
1866
- blob_append(p, "&quot;", 6);
1867
- iCol++;
1868
- break;
1869
- case '\'':
1870
- blob_append(p, "&#39;", 5);
1871
- iCol++;
1872
- break;
1873
- case '\\':
1874
- blob_append(p, "&#92;", 5);
1875
- iCol++;
1876
- break;
1877
- case '\t':
1878
- x = 1 + (iCol+7)%8;
1879
- blob_appendf(p, "%*s", x, "");
1880
- iCol += x;
1881
- break;
1882
- default:
1883
- blob_append_char(p, c);
1884
- if( (c&0xc0)!=0x80 ) iCol++;
1885
- break;
1886
- }
1887
- }
1888
- *piCol = iCol;
1889
-}
1811
+/*
1812
+** This module generates a JSON array that describes the difference.
1813
+**
1814
+** The Json array consists of integer opcodes with each opcode followed
1815
+** by zero or more arguments:
1816
+**
1817
+** Syntax Mnemonic Description
1818
+** ----------- -------- --------------------------
1819
+** 0 END This is the end of the diff
1820
+** 1 INTEGER SKIP Skip N lines from both files
1821
+** 2 STRING COMMON The line show by STRING is in both files
1822
+** 3 STRING INSERT The line STRING is in only the right file
1823
+** 4 STRING DELETE The STRING line is in only the left file
1824
+** 5 SUBARRAY EDIT One line is different on left and right.
1825
+**
1826
+** The SUBARRAY is an array of 3*N+1 strings with N>=0. The triples
1827
+** represent common-text, left-text, and right-text. The last string
1828
+** in SUBARRAY is the common-suffix. Any string can be empty if it does
1829
+** not apply.
1830
+*/
18901831
static void dfjsonSkip(DiffBuilder *p, unsigned int n, int isFinal){
18911832
blob_appendf(p->pOut, "1,%u,\n", n);
18921833
}
18931834
static void dfjsonCommon(DiffBuilder *p, const DLine *pLine){
1894
- int iCol = 0;
1895
- blob_append(p->pOut, "2,\"",3);
1896
- jsonize_to_blob(p->pOut, pLine->z, (int)pLine->n, &iCol);
1897
- blob_append(p->pOut, "\",\n",3);
1835
+ blob_append(p->pOut, "2,",2);
1836
+ blob_append_string_literal(p->pOut, pLine->z, (int)pLine->n);
1837
+ blob_append(p->pOut, ",\n",2);
18981838
}
18991839
static void dfjsonInsert(DiffBuilder *p, const DLine *pLine){
1900
- int iCol = 0;
1901
- blob_append(p->pOut, "3,\"",3);
1902
- jsonize_to_blob(p->pOut, pLine->z, (int)pLine->n, &iCol);
1903
- blob_append(p->pOut, "\",\n",3);
1840
+ blob_append(p->pOut, "3,",2);
1841
+ blob_append_string_literal(p->pOut, pLine->z, (int)pLine->n);
1842
+ blob_append(p->pOut, ",\n",2);
19041843
}
19051844
static void dfjsonDelete(DiffBuilder *p, const DLine *pLine){
1906
- int iCol = 0;
1907
- blob_append(p->pOut, "4,\"",3);
1908
- jsonize_to_blob(p->pOut, pLine->z, (int)pLine->n, &iCol);
1909
- blob_append(p->pOut, "\",\n",3);
1845
+ blob_append(p->pOut, "4,",2);
1846
+ blob_append_string_literal(p->pOut, pLine->z, (int)pLine->n);
1847
+ blob_append(p->pOut, ",\n",2);
19101848
}
19111849
static void dfjsonReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1912
- int iCol = 0;
1913
- blob_append(p->pOut, "5,\"",3);
1914
- jsonize_to_blob(p->pOut, pX->z, (int)pX->n, &iCol);
1915
- blob_append(p->pOut, "\",\"",3);
1916
- jsonize_to_blob(p->pOut, pY->z, (int)pY->n, &iCol);
1917
- blob_append(p->pOut, "\",\n",3);
1850
+ blob_append(p->pOut, "5,[\"\",",-1);
1851
+ blob_append_string_literal(p->pOut, pX->z, (int)pX->n);
1852
+ blob_append(p->pOut, ",",1);
1853
+ blob_append_string_literal(p->pOut, pY->z, (int)pY->n);
1854
+ blob_append(p->pOut, ",\"\"],\n",-1);
19181855
}
19191856
static void dfjsonEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1920
- int i;
1921
- int x;
1922
- int iCol;
1857
+ int i, x;
19231858
ChangeSpan span;
1859
+ blob_append(p->pOut, "5,[", 3);
19241860
oneLineChange(pX, pY, &span);
1925
- blob_appendf(p->pOut, "5,\"");
1926
- for(i=x=iCol=0; i<span.n; i++){
1927
- int ofst = span.a[i].iStart1;
1928
- int len = span.a[i].iLen1;
1929
- if( len ){
1930
- jsonize_to_blob(p->pOut, pX->z+x, ofst - x, &iCol);
1931
- x = ofst;
1932
- blob_append(p->pOut, "<mark>", 6);
1933
- jsonize_to_blob(p->pOut, pX->z+x, len, &iCol);
1934
- x += len;
1935
- blob_append(p->pOut, "</mark>", 7);
1936
- }
1937
- }
1938
- if( x<pX->n ) jsonize_to_blob(p->pOut, pX->z+x, pX->n - x, &iCol);
1939
- blob_append(p->pOut, "\",\n \"", -1);
1940
- for(i=x=iCol=0; i<span.n; i++){
1941
- int ofst = span.a[i].iStart2;
1942
- int len = span.a[i].iLen2;
1943
- if( len ){
1944
- jsonize_to_blob(p->pOut, pY->z+x, ofst - x, &iCol);
1945
- x = ofst;
1946
- blob_append(p->pOut, "<mark>", 6);
1947
- jsonize_to_blob(p->pOut, pY->z+x, len, &iCol);
1948
- x += len;
1949
- blob_append(p->pOut, "</mark>", 7);
1950
- }
1951
- }
1952
- if( x<pY->n ) jsonize_to_blob(p->pOut, pY->z+x, pY->n - x, &iCol);
1953
- blob_append(p->pOut, "\",\n", -1);
1861
+ for(i=x=0; i<span.n; i++){
1862
+ blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iStart1 - x);
1863
+ x = span.a[i].iStart1;
1864
+ blob_append_char(p->pOut, ',');
1865
+ blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iLen1);
1866
+ x += span.a[i].iLen1;
1867
+ blob_append_char(p->pOut, ',');
1868
+ blob_append_string_literal(p->pOut,
1869
+ pY->z + span.a[i].iStart2, span.a[i].iLen2);
1870
+ }
1871
+ blob_append_char(p->pOut, ',');
1872
+ blob_append_string_literal(p->pOut, pX->z + x, pX->n - x);
1873
+ blob_append(p->pOut, "],\n",3);
19541874
}
19551875
static void dfjsonEnd(DiffBuilder *p){
19561876
blob_append(p->pOut, "0]", 2);
19571877
fossil_free(p);
19581878
}
@@ -1970,12 +1890,13 @@
19701890
blob_append_char(pOut, '[');
19711891
return p;
19721892
}
19731893
19741894
/************************* DiffBuilderUnified********************************/
1975
-
1976
-/* Accumulator strategy:
1895
+/* This module generates a unified diff for HTML
1896
+**
1897
+** Accumulator strategy:
19771898
**
19781899
** * Delete line numbers are output directly to p->pOut
19791900
** * Insert line numbers accumulate in p->aCol[0].
19801901
** * Separator marks accumulate in p->aCol[1].
19811902
** * Change text accumulates in p->aCol[2].
@@ -2039,34 +1960,31 @@
20391960
}
20401961
p->lnLeft += n;
20411962
p->lnRight += n;
20421963
}
20431964
static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
2044
- int iCol = 0;
20451965
dfunifiedStartRow(p);
20461966
dfunifiedFinishDelete(p);
20471967
dfunifiedFinishInsert(p);
20481968
p->lnLeft++;
20491969
p->lnRight++;
20501970
blob_appendf(p->pOut,"%d\n", p->lnLeft);
20511971
blob_appendf(&p->aCol[0],"%d\n",p->lnRight);
20521972
blob_append_char(&p->aCol[1], '\n');
2053
- jsonize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n, &iCol);
1973
+ htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
20541974
blob_append_char(&p->aCol[2], '\n');
20551975
}
20561976
static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
2057
- int iCol = 0;
20581977
dfunifiedStartRow(p);
20591978
p->lnRight++;
20601979
blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
20611980
blob_append(&p->aCol[4], "<ins>", 5);
2062
- jsonize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n, &iCol);
1981
+ htmlize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n);
20631982
blob_append(&p->aCol[4], "</ins>\n", 7);
20641983
p->nPending++;
20651984
}
20661985
static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
2067
- int iCol = 0;
20681986
dfunifiedStartRow(p);
20691987
dfunifiedFinishInsert(p);
20701988
if( p->eState==0 ){
20711989
dfunifiedFinishInsert(p);
20721990
blob_append(p->pOut, "<del>", 5);
@@ -2076,15 +1994,14 @@
20761994
p->lnLeft++;
20771995
blob_appendf(p->pOut,"%d\n", p->lnLeft);
20781996
blob_append_char(&p->aCol[0],'\n');
20791997
blob_append(&p->aCol[1],"-\n",2);
20801998
blob_append(&p->aCol[2], "<del>", 5);
2081
- jsonize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n, &iCol);
1999
+ htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
20822000
blob_append(&p->aCol[2], "</del>\n", 7);
20832001
}
20842002
static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
2085
- int iCol;
20862003
dfunifiedStartRow(p);
20872004
if( p->eState==0 ){
20882005
dfunifiedFinishInsert(p);
20892006
blob_append(p->pOut, "<del>", 5);
20902007
blob_append(&p->aCol[2], "<del>", 5);
@@ -2094,25 +2011,22 @@
20942011
p->lnRight++;
20952012
blob_appendf(p->pOut,"%d\n", p->lnLeft);
20962013
blob_append_char(&p->aCol[0], '\n');
20972014
blob_append(&p->aCol[1], "-\n", 2);
20982015
2099
- iCol = 0;
2100
- jsonize_to_blob(&p->aCol[2], pX->z, pX->n, &iCol);
2016
+ htmlize_to_blob(&p->aCol[2], pX->z, pX->n);
21012017
blob_append_char(&p->aCol[2], '\n');
21022018
21032019
blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
21042020
2105
- iCol = 0;
2106
- jsonize_to_blob(&p->aCol[4], pY->z, pY->n, &iCol);
2021
+ htmlize_to_blob(&p->aCol[4], pY->z, pY->n);
21072022
blob_append_char(&p->aCol[4], '\n');
21082023
p->nPending++;
21092024
}
21102025
static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
21112026
int i;
21122027
int x;
2113
- int iCol;
21142028
ChangeSpan span;
21152029
oneLineChange(pX, pY, &span);
21162030
dfunifiedStartRow(p);
21172031
if( p->eState==0 ){
21182032
dfunifiedFinishInsert(p);
@@ -2124,39 +2038,39 @@
21242038
p->lnRight++;
21252039
blob_appendf(p->pOut,"%d\n", p->lnLeft);
21262040
blob_append_char(&p->aCol[0], '\n');
21272041
blob_append(&p->aCol[1], "-\n", 2);
21282042
2129
- for(i=x=iCol=0; i<span.n; i++){
2043
+ for(i=x=0; i<span.n; i++){
21302044
int ofst = span.a[i].iStart1;
21312045
int len = span.a[i].iLen1;
21322046
if( len ){
2133
- jsonize_to_blob(&p->aCol[2], pX->z+x, ofst - x, &iCol);
2047
+ htmlize_to_blob(&p->aCol[2], pX->z+x, ofst - x);
21342048
x = ofst;
21352049
blob_append(&p->aCol[2], "<del>", 5);
2136
- jsonize_to_blob(&p->aCol[2], pX->z+x, len, &iCol);
2050
+ htmlize_to_blob(&p->aCol[2], pX->z+x, len);
21372051
x += len;
21382052
blob_append(&p->aCol[2], "</del>", 6);
21392053
}
21402054
}
2141
- if( x<pX->n ) jsonize_to_blob(&p->aCol[2], pX->z+x, pX->n - x, &iCol);
2055
+ htmlize_to_blob(&p->aCol[2], pX->z+x, pX->n - x);
21422056
blob_append_char(&p->aCol[2], '\n');
21432057
21442058
blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
2145
- for(i=x=iCol=0; i<span.n; i++){
2059
+ for(i=x=0; i<span.n; i++){
21462060
int ofst = span.a[i].iStart2;
21472061
int len = span.a[i].iLen2;
21482062
if( len ){
2149
- jsonize_to_blob(&p->aCol[4], pY->z+x, ofst - x, &iCol);
2063
+ htmlize_to_blob(&p->aCol[4], pY->z+x, ofst - x);
21502064
x = ofst;
21512065
blob_append(&p->aCol[4], "<ins>", 5);
2152
- jsonize_to_blob(&p->aCol[4], pY->z+x, len, &iCol);
2066
+ htmlize_to_blob(&p->aCol[4], pY->z+x, len);
21532067
x += len;
21542068
blob_append(&p->aCol[4], "</ins>", 6);
21552069
}
21562070
}
2157
- if( x<pY->n ) jsonize_to_blob(&p->aCol[4], pY->z+x, pY->n - x, &iCol);
2071
+ htmlize_to_blob(&p->aCol[4], pY->z+x, pY->n - x);
21582072
blob_append_char(&p->aCol[4], '\n');
21592073
p->nPending++;
21602074
}
21612075
static void dfunifiedEnd(DiffBuilder *p){
21622076
dfunifiedFinishRow(p);
@@ -2184,12 +2098,13 @@
21842098
blob_init(&p->aCol[4], 0, 0);
21852099
return p;
21862100
}
21872101
21882102
/************************* DiffBuilderSplit ******************************/
2189
-
2190
-/* Accumulator strategy:
2103
+/* This module generates a side-by-side diff for HTML.
2104
+**
2105
+** Accumulator strategy:
21912106
**
21922107
** * Left line numbers are output directly to p->pOut
21932108
** * Left text accumulates in p->aCol[0].
21942109
** * Edit marks accumulates in p->aCol[1].
21952110
** * Right line numbers accumulate in p->aCol[2].
@@ -2251,110 +2166,103 @@
22512166
}
22522167
p->lnLeft += n;
22532168
p->lnRight += n;
22542169
}
22552170
static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
2256
- int iCol = 0;
22572171
dfsplitStartRow(p);
22582172
dfsplitChangeState(p, 0);
22592173
p->lnLeft++;
22602174
p->lnRight++;
22612175
blob_appendf(p->pOut,"%d\n", p->lnLeft);
2262
- jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
2176
+ htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
22632177
blob_append_char(&p->aCol[0], '\n');
22642178
blob_append_char(&p->aCol[1], '\n');
22652179
blob_appendf(&p->aCol[2],"%d\n",p->lnRight);
2266
- jsonize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n, &iCol);
2180
+ htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
22672181
blob_append_char(&p->aCol[3], '\n');
22682182
}
22692183
static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){
2270
- int iCol = 0;
22712184
dfsplitStartRow(p);
22722185
dfsplitChangeState(p, 2);
22732186
p->lnRight++;
22742187
blob_append_char(p->pOut, '\n');
22752188
blob_append_char(&p->aCol[0], '\n');
22762189
blob_append(&p->aCol[1], "&gt;\n", -1);
22772190
blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
22782191
blob_append(&p->aCol[3], "<ins>", 5);
2279
- jsonize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n, &iCol);
2192
+ htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
22802193
blob_append(&p->aCol[3], "</ins>\n", 7);
22812194
}
22822195
static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){
2283
- int iCol = 0;
22842196
dfsplitStartRow(p);
22852197
dfsplitChangeState(p, 1);
22862198
p->lnLeft++;
22872199
blob_appendf(p->pOut,"%d\n", p->lnLeft);
22882200
blob_append(&p->aCol[0], "<del>", 5);
2289
- jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
2201
+ htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
22902202
blob_append(&p->aCol[0], "</del>\n", 7);
22912203
blob_append(&p->aCol[1], "&lt;\n", -1);
22922204
blob_append_char(&p->aCol[2],'\n');
22932205
blob_append_char(&p->aCol[3],'\n');
22942206
}
22952207
static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
2296
- int iCol;
22972208
dfsplitStartRow(p);
22982209
dfsplitChangeState(p, 3);
22992210
p->lnLeft++;
23002211
p->lnRight++;
23012212
blob_appendf(p->pOut,"%d\n", p->lnLeft);
2302
- iCol = 0;
2303
- jsonize_to_blob(&p->aCol[0], pX->z, pX->n, &iCol);
2213
+ htmlize_to_blob(&p->aCol[0], pX->z, pX->n);
23042214
blob_append_char(&p->aCol[0], '\n');
23052215
23062216
blob_append(&p->aCol[1], "|\n", 2);
23072217
23082218
blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
23092219
2310
- iCol = 0;
2311
- jsonize_to_blob(&p->aCol[3], pY->z, pY->n, &iCol);
2220
+ htmlize_to_blob(&p->aCol[3], pY->z, pY->n);
23122221
blob_append_char(&p->aCol[3], '\n');
23132222
}
23142223
static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
23152224
int i;
23162225
int x;
2317
- int iCol;
2318
- ChangeSpan span;
2226
+ ChangeSpan span;
23192227
oneLineChange(pX, pY, &span);
23202228
dfsplitStartRow(p);
23212229
dfsplitChangeState(p, 3);
23222230
p->lnLeft++;
23232231
p->lnRight++;
23242232
blob_appendf(p->pOut,"%d\n", p->lnLeft);
2325
- for(i=x=iCol=0; i<span.n; i++){
2233
+ for(i=x=0; i<span.n; i++){
23262234
int ofst = span.a[i].iStart1;
23272235
int len = span.a[i].iLen1;
23282236
if( len ){
2329
- jsonize_to_blob(&p->aCol[0], pX->z+x, ofst - x, &iCol);
2237
+ htmlize_to_blob(&p->aCol[0], pX->z+x, ofst - x);
23302238
x = ofst;
23312239
blob_append(&p->aCol[0], "<del>", 5);
2332
- jsonize_to_blob(&p->aCol[0], pX->z+x, len, &iCol);
2240
+ htmlize_to_blob(&p->aCol[0], pX->z+x, len);
23332241
x += len;
23342242
blob_append(&p->aCol[0], "</del>", 6);
23352243
}
23362244
}
2337
- if( x<pX->n ) jsonize_to_blob(&p->aCol[0], pX->z+x, pX->n - x, &iCol);
2245
+ htmlize_to_blob(&p->aCol[0], pX->z+x, pX->n - x);
23382246
blob_append_char(&p->aCol[0], '\n');
23392247
23402248
blob_append(&p->aCol[1], "|\n", 2);
23412249
23422250
blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2343
- for(i=x=iCol=0; i<span.n; i++){
2251
+ for(i=x=0; i<span.n; i++){
23442252
int ofst = span.a[i].iStart2;
23452253
int len = span.a[i].iLen2;
23462254
if( len ){
2347
- jsonize_to_blob(&p->aCol[3], pY->z+x, ofst - x, &iCol);
2255
+ htmlize_to_blob(&p->aCol[3], pY->z+x, ofst - x);
23482256
x = ofst;
23492257
blob_append(&p->aCol[3], "<ins>", 5);
2350
- jsonize_to_blob(&p->aCol[3], pY->z+x, len, &iCol);
2258
+ htmlize_to_blob(&p->aCol[3], pY->z+x, len);
23512259
x += len;
23522260
blob_append(&p->aCol[3], "</ins>", 6);
23532261
}
23542262
}
2355
- if( x<pY->n ) jsonize_to_blob(&p->aCol[3], pY->z+x, pY->n - x, &iCol);
2263
+ htmlize_to_blob(&p->aCol[3], pY->z+x, pY->n - x);
23562264
blob_append_char(&p->aCol[3], '\n');
23572265
}
23582266
static void dfsplitEnd(DiffBuilder *p){
23592267
dfsplitFinishRow(p);
23602268
blob_append(p->pOut, "</table>\n",-1);
@@ -3212,14 +3120,24 @@
32123120
return diffFlags;
32133121
}
32143122
32153123
/*
32163124
** COMMAND: test-diff
3125
+** COMMAND: xdiff
3126
+**
3127
+** Usage: %fossil xdiff [options] FILE1 FILE2
3128
+**
3129
+** This is the "external diff" feature. By "external" here we mean a diff
3130
+** applied to files that are not under version control. See the "diff"
3131
+** command for computing differences between files that are under control.
32173132
**
3218
-** Usage: %fossil [options] FILE1 FILE2
3133
+** This command prints the differences between the two files FILE1 and FILE2.
3134
+** all of the usual diff command-line options apply. See the "diff" command
3135
+** for a full list of command-line options.
32193136
**
3220
-** Print the difference between two files. The usual diff options apply.
3137
+** This command used to be called "test-diff". The older "test-diff" spelling
3138
+** still works, for compatibility.
32213139
*/
32223140
void test_diff_cmd(void){
32233141
Blob a, b, out;
32243142
u64 diffFlag;
32253143
const char *zRe; /* Regex filter for diff output */
32263144
--- src/diff.c
+++ src/diff.c
@@ -1742,73 +1742,54 @@
1742 /************************* DiffBuilderTcl ********************************/
1743 /*
1744 ** This variant outputs a description of the diff formatted as TCL, for
1745 ** use by the --tk option to "diff".
1746 */
1747
1748 /*
1749 ** Write out a quoted TCL string
1750 */
1751 void blob_append_tcl_string(Blob *pOut, const char *z, int n){
1752 int i;
1753 blob_append_char(pOut, '"');
1754 for(i=0; i<n; i++){
1755 switch( z[i] ){
1756 case '"':
1757 case '\\':
1758 blob_append_char(pOut, '\\');
1759 /* Fall thru */
1760 default:
1761 blob_append_char(pOut, z[i]);
1762 }
1763 }
1764 blob_append_char(pOut, '"');
1765 }
1766
1767 static void dftclSkip(DiffBuilder *p, unsigned int n, int isFinal){
1768 blob_appendf(p->pOut, "SKIP %u\n", n);
1769 }
1770 static void dftclCommon(DiffBuilder *p, const DLine *pLine){
1771 blob_appendf(p->pOut, "COM ");
1772 blob_append_tcl_string(p->pOut, pLine->z, pLine->n);
1773 blob_append_char(p->pOut, '\n');
1774 }
1775 static void dftclInsert(DiffBuilder *p, const DLine *pLine){
1776 blob_append(p->pOut, "INS ", -1);
1777 blob_append_tcl_string(p->pOut, pLine->z, pLine->n);
1778 blob_append_char(p->pOut, '\n');
1779 }
1780 static void dftclDelete(DiffBuilder *p, const DLine *pLine){
1781 blob_append(p->pOut, "DEL ", -1);
1782 blob_append_tcl_string(p->pOut, pLine->z, pLine->n);
1783 blob_append_char(p->pOut, '\n');
1784 }
1785 static void dftclReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1786 blob_append(p->pOut, "EDIT ", -1);
1787 blob_append_tcl_string(p->pOut, pX->z, pX->n);
1788 blob_append_char(p->pOut, ' ');
1789 blob_append_tcl_string(p->pOut, pY->z, pY->n);
1790 blob_append_char(p->pOut, '\n');
1791 }
1792 static void dftclEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1793 int i, x;
1794 ChangeSpan span;
1795 blob_append(p->pOut, "EDIT", 4);
1796 oneLineChange(pX, pY, &span);
1797 for(i=x=0; i<span.n; i++){
1798 blob_append_char(p->pOut, ' ');
1799 blob_append_tcl_string(p->pOut, pX->z + x, span.a[i].iStart1 - x);
1800 x = span.a[i].iStart1;
1801 blob_append_char(p->pOut, ' ');
1802 blob_append_tcl_string(p->pOut, pX->z + x, span.a[i].iLen1);
1803 x += span.a[i].iLen1;
1804 blob_append_char(p->pOut, ' ');
1805 blob_append_tcl_string(p->pOut, pY->z + span.a[i].iStart2,span.a[i].iLen2);
 
1806 }
1807 if( x<pX->n ){
1808 blob_append_char(p->pOut, ' ');
1809 blob_append_tcl_string(p->pOut, pX->z + x, pX->n - x);
1810 }
1811 blob_append_char(p->pOut, '\n');
1812 }
1813 static void dftclEnd(DiffBuilder *p){
1814 fossil_free(p);
@@ -1825,134 +1806,73 @@
1825 p->pOut = pOut;
1826 return p;
1827 }
1828
1829 /************************* DiffBuilderJson ********************************/
1830
1831 /* Convert raw text into content suitable for a JSON string. Escape
1832 ** charaters that are special to HTML and to JSON:
1833 **
1834 ** < -> &lt;
1835 ** > -> &gt;
1836 ** & -> &amp;
1837 ** " -> &quot;
1838 ** ' -> &#39;
1839 ** \ -> &#92;
1840 **
1841 ** In addition, TAB characters are converted into an appropriate number
1842 ** of spaces. The *piCol value is the number of prior columns in the
1843 ** current line. Update the column count before returning, so that
1844 ** subsequent invocations can figure out the right number of spaces to
1845 ** insert for each tab.
1846 */
1847 static void jsonize_to_blob(Blob *p, const char *zIn, int n, int *piCol){
1848 int c, i, x;
1849 int iCol = *piCol;
1850 for(i=0; i<n; i++){
1851 c = zIn[i];
1852 switch( c ){
1853 case '<':
1854 blob_append(p, "&lt;", 4);
1855 iCol++;
1856 break;
1857 case '>':
1858 blob_append(p, "&gt;", 4);
1859 iCol++;
1860 break;
1861 case '&':
1862 blob_append(p, "&amp;", 5);
1863 iCol++;
1864 break;
1865 case '"':
1866 blob_append(p, "&quot;", 6);
1867 iCol++;
1868 break;
1869 case '\'':
1870 blob_append(p, "&#39;", 5);
1871 iCol++;
1872 break;
1873 case '\\':
1874 blob_append(p, "&#92;", 5);
1875 iCol++;
1876 break;
1877 case '\t':
1878 x = 1 + (iCol+7)%8;
1879 blob_appendf(p, "%*s", x, "");
1880 iCol += x;
1881 break;
1882 default:
1883 blob_append_char(p, c);
1884 if( (c&0xc0)!=0x80 ) iCol++;
1885 break;
1886 }
1887 }
1888 *piCol = iCol;
1889 }
1890 static void dfjsonSkip(DiffBuilder *p, unsigned int n, int isFinal){
1891 blob_appendf(p->pOut, "1,%u,\n", n);
1892 }
1893 static void dfjsonCommon(DiffBuilder *p, const DLine *pLine){
1894 int iCol = 0;
1895 blob_append(p->pOut, "2,\"",3);
1896 jsonize_to_blob(p->pOut, pLine->z, (int)pLine->n, &iCol);
1897 blob_append(p->pOut, "\",\n",3);
1898 }
1899 static void dfjsonInsert(DiffBuilder *p, const DLine *pLine){
1900 int iCol = 0;
1901 blob_append(p->pOut, "3,\"",3);
1902 jsonize_to_blob(p->pOut, pLine->z, (int)pLine->n, &iCol);
1903 blob_append(p->pOut, "\",\n",3);
1904 }
1905 static void dfjsonDelete(DiffBuilder *p, const DLine *pLine){
1906 int iCol = 0;
1907 blob_append(p->pOut, "4,\"",3);
1908 jsonize_to_blob(p->pOut, pLine->z, (int)pLine->n, &iCol);
1909 blob_append(p->pOut, "\",\n",3);
1910 }
1911 static void dfjsonReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1912 int iCol = 0;
1913 blob_append(p->pOut, "5,\"",3);
1914 jsonize_to_blob(p->pOut, pX->z, (int)pX->n, &iCol);
1915 blob_append(p->pOut, "\",\"",3);
1916 jsonize_to_blob(p->pOut, pY->z, (int)pY->n, &iCol);
1917 blob_append(p->pOut, "\",\n",3);
1918 }
1919 static void dfjsonEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1920 int i;
1921 int x;
1922 int iCol;
1923 ChangeSpan span;
 
1924 oneLineChange(pX, pY, &span);
1925 blob_appendf(p->pOut, "5,\"");
1926 for(i=x=iCol=0; i<span.n; i++){
1927 int ofst = span.a[i].iStart1;
1928 int len = span.a[i].iLen1;
1929 if( len ){
1930 jsonize_to_blob(p->pOut, pX->z+x, ofst - x, &iCol);
1931 x = ofst;
1932 blob_append(p->pOut, "<mark>", 6);
1933 jsonize_to_blob(p->pOut, pX->z+x, len, &iCol);
1934 x += len;
1935 blob_append(p->pOut, "</mark>", 7);
1936 }
1937 }
1938 if( x<pX->n ) jsonize_to_blob(p->pOut, pX->z+x, pX->n - x, &iCol);
1939 blob_append(p->pOut, "\",\n \"", -1);
1940 for(i=x=iCol=0; i<span.n; i++){
1941 int ofst = span.a[i].iStart2;
1942 int len = span.a[i].iLen2;
1943 if( len ){
1944 jsonize_to_blob(p->pOut, pY->z+x, ofst - x, &iCol);
1945 x = ofst;
1946 blob_append(p->pOut, "<mark>", 6);
1947 jsonize_to_blob(p->pOut, pY->z+x, len, &iCol);
1948 x += len;
1949 blob_append(p->pOut, "</mark>", 7);
1950 }
1951 }
1952 if( x<pY->n ) jsonize_to_blob(p->pOut, pY->z+x, pY->n - x, &iCol);
1953 blob_append(p->pOut, "\",\n", -1);
1954 }
1955 static void dfjsonEnd(DiffBuilder *p){
1956 blob_append(p->pOut, "0]", 2);
1957 fossil_free(p);
1958 }
@@ -1970,12 +1890,13 @@
1970 blob_append_char(pOut, '[');
1971 return p;
1972 }
1973
1974 /************************* DiffBuilderUnified********************************/
1975
1976 /* Accumulator strategy:
 
1977 **
1978 ** * Delete line numbers are output directly to p->pOut
1979 ** * Insert line numbers accumulate in p->aCol[0].
1980 ** * Separator marks accumulate in p->aCol[1].
1981 ** * Change text accumulates in p->aCol[2].
@@ -2039,34 +1960,31 @@
2039 }
2040 p->lnLeft += n;
2041 p->lnRight += n;
2042 }
2043 static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
2044 int iCol = 0;
2045 dfunifiedStartRow(p);
2046 dfunifiedFinishDelete(p);
2047 dfunifiedFinishInsert(p);
2048 p->lnLeft++;
2049 p->lnRight++;
2050 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2051 blob_appendf(&p->aCol[0],"%d\n",p->lnRight);
2052 blob_append_char(&p->aCol[1], '\n');
2053 jsonize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n, &iCol);
2054 blob_append_char(&p->aCol[2], '\n');
2055 }
2056 static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
2057 int iCol = 0;
2058 dfunifiedStartRow(p);
2059 p->lnRight++;
2060 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
2061 blob_append(&p->aCol[4], "<ins>", 5);
2062 jsonize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n, &iCol);
2063 blob_append(&p->aCol[4], "</ins>\n", 7);
2064 p->nPending++;
2065 }
2066 static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
2067 int iCol = 0;
2068 dfunifiedStartRow(p);
2069 dfunifiedFinishInsert(p);
2070 if( p->eState==0 ){
2071 dfunifiedFinishInsert(p);
2072 blob_append(p->pOut, "<del>", 5);
@@ -2076,15 +1994,14 @@
2076 p->lnLeft++;
2077 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2078 blob_append_char(&p->aCol[0],'\n');
2079 blob_append(&p->aCol[1],"-\n",2);
2080 blob_append(&p->aCol[2], "<del>", 5);
2081 jsonize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n, &iCol);
2082 blob_append(&p->aCol[2], "</del>\n", 7);
2083 }
2084 static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
2085 int iCol;
2086 dfunifiedStartRow(p);
2087 if( p->eState==0 ){
2088 dfunifiedFinishInsert(p);
2089 blob_append(p->pOut, "<del>", 5);
2090 blob_append(&p->aCol[2], "<del>", 5);
@@ -2094,25 +2011,22 @@
2094 p->lnRight++;
2095 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2096 blob_append_char(&p->aCol[0], '\n');
2097 blob_append(&p->aCol[1], "-\n", 2);
2098
2099 iCol = 0;
2100 jsonize_to_blob(&p->aCol[2], pX->z, pX->n, &iCol);
2101 blob_append_char(&p->aCol[2], '\n');
2102
2103 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
2104
2105 iCol = 0;
2106 jsonize_to_blob(&p->aCol[4], pY->z, pY->n, &iCol);
2107 blob_append_char(&p->aCol[4], '\n');
2108 p->nPending++;
2109 }
2110 static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
2111 int i;
2112 int x;
2113 int iCol;
2114 ChangeSpan span;
2115 oneLineChange(pX, pY, &span);
2116 dfunifiedStartRow(p);
2117 if( p->eState==0 ){
2118 dfunifiedFinishInsert(p);
@@ -2124,39 +2038,39 @@
2124 p->lnRight++;
2125 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2126 blob_append_char(&p->aCol[0], '\n');
2127 blob_append(&p->aCol[1], "-\n", 2);
2128
2129 for(i=x=iCol=0; i<span.n; i++){
2130 int ofst = span.a[i].iStart1;
2131 int len = span.a[i].iLen1;
2132 if( len ){
2133 jsonize_to_blob(&p->aCol[2], pX->z+x, ofst - x, &iCol);
2134 x = ofst;
2135 blob_append(&p->aCol[2], "<del>", 5);
2136 jsonize_to_blob(&p->aCol[2], pX->z+x, len, &iCol);
2137 x += len;
2138 blob_append(&p->aCol[2], "</del>", 6);
2139 }
2140 }
2141 if( x<pX->n ) jsonize_to_blob(&p->aCol[2], pX->z+x, pX->n - x, &iCol);
2142 blob_append_char(&p->aCol[2], '\n');
2143
2144 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
2145 for(i=x=iCol=0; i<span.n; i++){
2146 int ofst = span.a[i].iStart2;
2147 int len = span.a[i].iLen2;
2148 if( len ){
2149 jsonize_to_blob(&p->aCol[4], pY->z+x, ofst - x, &iCol);
2150 x = ofst;
2151 blob_append(&p->aCol[4], "<ins>", 5);
2152 jsonize_to_blob(&p->aCol[4], pY->z+x, len, &iCol);
2153 x += len;
2154 blob_append(&p->aCol[4], "</ins>", 6);
2155 }
2156 }
2157 if( x<pY->n ) jsonize_to_blob(&p->aCol[4], pY->z+x, pY->n - x, &iCol);
2158 blob_append_char(&p->aCol[4], '\n');
2159 p->nPending++;
2160 }
2161 static void dfunifiedEnd(DiffBuilder *p){
2162 dfunifiedFinishRow(p);
@@ -2184,12 +2098,13 @@
2184 blob_init(&p->aCol[4], 0, 0);
2185 return p;
2186 }
2187
2188 /************************* DiffBuilderSplit ******************************/
2189
2190 /* Accumulator strategy:
 
2191 **
2192 ** * Left line numbers are output directly to p->pOut
2193 ** * Left text accumulates in p->aCol[0].
2194 ** * Edit marks accumulates in p->aCol[1].
2195 ** * Right line numbers accumulate in p->aCol[2].
@@ -2251,110 +2166,103 @@
2251 }
2252 p->lnLeft += n;
2253 p->lnRight += n;
2254 }
2255 static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
2256 int iCol = 0;
2257 dfsplitStartRow(p);
2258 dfsplitChangeState(p, 0);
2259 p->lnLeft++;
2260 p->lnRight++;
2261 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2262 jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
2263 blob_append_char(&p->aCol[0], '\n');
2264 blob_append_char(&p->aCol[1], '\n');
2265 blob_appendf(&p->aCol[2],"%d\n",p->lnRight);
2266 jsonize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n, &iCol);
2267 blob_append_char(&p->aCol[3], '\n');
2268 }
2269 static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){
2270 int iCol = 0;
2271 dfsplitStartRow(p);
2272 dfsplitChangeState(p, 2);
2273 p->lnRight++;
2274 blob_append_char(p->pOut, '\n');
2275 blob_append_char(&p->aCol[0], '\n');
2276 blob_append(&p->aCol[1], "&gt;\n", -1);
2277 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2278 blob_append(&p->aCol[3], "<ins>", 5);
2279 jsonize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n, &iCol);
2280 blob_append(&p->aCol[3], "</ins>\n", 7);
2281 }
2282 static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){
2283 int iCol = 0;
2284 dfsplitStartRow(p);
2285 dfsplitChangeState(p, 1);
2286 p->lnLeft++;
2287 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2288 blob_append(&p->aCol[0], "<del>", 5);
2289 jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
2290 blob_append(&p->aCol[0], "</del>\n", 7);
2291 blob_append(&p->aCol[1], "&lt;\n", -1);
2292 blob_append_char(&p->aCol[2],'\n');
2293 blob_append_char(&p->aCol[3],'\n');
2294 }
2295 static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
2296 int iCol;
2297 dfsplitStartRow(p);
2298 dfsplitChangeState(p, 3);
2299 p->lnLeft++;
2300 p->lnRight++;
2301 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2302 iCol = 0;
2303 jsonize_to_blob(&p->aCol[0], pX->z, pX->n, &iCol);
2304 blob_append_char(&p->aCol[0], '\n');
2305
2306 blob_append(&p->aCol[1], "|\n", 2);
2307
2308 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2309
2310 iCol = 0;
2311 jsonize_to_blob(&p->aCol[3], pY->z, pY->n, &iCol);
2312 blob_append_char(&p->aCol[3], '\n');
2313 }
2314 static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
2315 int i;
2316 int x;
2317 int iCol;
2318 ChangeSpan span;
2319 oneLineChange(pX, pY, &span);
2320 dfsplitStartRow(p);
2321 dfsplitChangeState(p, 3);
2322 p->lnLeft++;
2323 p->lnRight++;
2324 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2325 for(i=x=iCol=0; i<span.n; i++){
2326 int ofst = span.a[i].iStart1;
2327 int len = span.a[i].iLen1;
2328 if( len ){
2329 jsonize_to_blob(&p->aCol[0], pX->z+x, ofst - x, &iCol);
2330 x = ofst;
2331 blob_append(&p->aCol[0], "<del>", 5);
2332 jsonize_to_blob(&p->aCol[0], pX->z+x, len, &iCol);
2333 x += len;
2334 blob_append(&p->aCol[0], "</del>", 6);
2335 }
2336 }
2337 if( x<pX->n ) jsonize_to_blob(&p->aCol[0], pX->z+x, pX->n - x, &iCol);
2338 blob_append_char(&p->aCol[0], '\n');
2339
2340 blob_append(&p->aCol[1], "|\n", 2);
2341
2342 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2343 for(i=x=iCol=0; i<span.n; i++){
2344 int ofst = span.a[i].iStart2;
2345 int len = span.a[i].iLen2;
2346 if( len ){
2347 jsonize_to_blob(&p->aCol[3], pY->z+x, ofst - x, &iCol);
2348 x = ofst;
2349 blob_append(&p->aCol[3], "<ins>", 5);
2350 jsonize_to_blob(&p->aCol[3], pY->z+x, len, &iCol);
2351 x += len;
2352 blob_append(&p->aCol[3], "</ins>", 6);
2353 }
2354 }
2355 if( x<pY->n ) jsonize_to_blob(&p->aCol[3], pY->z+x, pY->n - x, &iCol);
2356 blob_append_char(&p->aCol[3], '\n');
2357 }
2358 static void dfsplitEnd(DiffBuilder *p){
2359 dfsplitFinishRow(p);
2360 blob_append(p->pOut, "</table>\n",-1);
@@ -3212,14 +3120,24 @@
3212 return diffFlags;
3213 }
3214
3215 /*
3216 ** COMMAND: test-diff
 
 
 
 
 
 
 
3217 **
3218 ** Usage: %fossil [options] FILE1 FILE2
 
 
3219 **
3220 ** Print the difference between two files. The usual diff options apply.
 
3221 */
3222 void test_diff_cmd(void){
3223 Blob a, b, out;
3224 u64 diffFlag;
3225 const char *zRe; /* Regex filter for diff output */
3226
--- src/diff.c
+++ src/diff.c
@@ -1742,73 +1742,54 @@
1742 /************************* DiffBuilderTcl ********************************/
1743 /*
1744 ** This variant outputs a description of the diff formatted as TCL, for
1745 ** use by the --tk option to "diff".
1746 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1747 static void dftclSkip(DiffBuilder *p, unsigned int n, int isFinal){
1748 blob_appendf(p->pOut, "SKIP %u\n", n);
1749 }
1750 static void dftclCommon(DiffBuilder *p, const DLine *pLine){
1751 blob_appendf(p->pOut, "COM ");
1752 blob_append_string_literal(p->pOut, pLine->z, pLine->n);
1753 blob_append_char(p->pOut, '\n');
1754 }
1755 static void dftclInsert(DiffBuilder *p, const DLine *pLine){
1756 blob_append(p->pOut, "INS ", -1);
1757 blob_append_string_literal(p->pOut, pLine->z, pLine->n);
1758 blob_append_char(p->pOut, '\n');
1759 }
1760 static void dftclDelete(DiffBuilder *p, const DLine *pLine){
1761 blob_append(p->pOut, "DEL ", -1);
1762 blob_append_string_literal(p->pOut, pLine->z, pLine->n);
1763 blob_append_char(p->pOut, '\n');
1764 }
1765 static void dftclReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1766 blob_append(p->pOut, "EDIT ", -1);
1767 blob_append_string_literal(p->pOut, pX->z, pX->n);
1768 blob_append_char(p->pOut, ' ');
1769 blob_append_string_literal(p->pOut, pY->z, pY->n);
1770 blob_append_char(p->pOut, '\n');
1771 }
1772 static void dftclEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1773 int i, x;
1774 ChangeSpan span;
1775 blob_append(p->pOut, "EDIT", 4);
1776 oneLineChange(pX, pY, &span);
1777 for(i=x=0; i<span.n; i++){
1778 blob_append_char(p->pOut, ' ');
1779 blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iStart1 - x);
1780 x = span.a[i].iStart1;
1781 blob_append_char(p->pOut, ' ');
1782 blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iLen1);
1783 x += span.a[i].iLen1;
1784 blob_append_char(p->pOut, ' ');
1785 blob_append_string_literal(p->pOut,
1786 pY->z + span.a[i].iStart2, span.a[i].iLen2);
1787 }
1788 if( x<pX->n ){
1789 blob_append_char(p->pOut, ' ');
1790 blob_append_string_literal(p->pOut, pX->z + x, pX->n - x);
1791 }
1792 blob_append_char(p->pOut, '\n');
1793 }
1794 static void dftclEnd(DiffBuilder *p){
1795 fossil_free(p);
@@ -1825,134 +1806,73 @@
1806 p->pOut = pOut;
1807 return p;
1808 }
1809
1810 /************************* DiffBuilderJson ********************************/
1811 /*
1812 ** This module generates a JSON array that describes the difference.
1813 **
1814 ** The Json array consists of integer opcodes with each opcode followed
1815 ** by zero or more arguments:
1816 **
1817 ** Syntax Mnemonic Description
1818 ** ----------- -------- --------------------------
1819 ** 0 END This is the end of the diff
1820 ** 1 INTEGER SKIP Skip N lines from both files
1821 ** 2 STRING COMMON The line show by STRING is in both files
1822 ** 3 STRING INSERT The line STRING is in only the right file
1823 ** 4 STRING DELETE The STRING line is in only the left file
1824 ** 5 SUBARRAY EDIT One line is different on left and right.
1825 **
1826 ** The SUBARRAY is an array of 3*N+1 strings with N>=0. The triples
1827 ** represent common-text, left-text, and right-text. The last string
1828 ** in SUBARRAY is the common-suffix. Any string can be empty if it does
1829 ** not apply.
1830 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1831 static void dfjsonSkip(DiffBuilder *p, unsigned int n, int isFinal){
1832 blob_appendf(p->pOut, "1,%u,\n", n);
1833 }
1834 static void dfjsonCommon(DiffBuilder *p, const DLine *pLine){
1835 blob_append(p->pOut, "2,",2);
1836 blob_append_string_literal(p->pOut, pLine->z, (int)pLine->n);
1837 blob_append(p->pOut, ",\n",2);
 
1838 }
1839 static void dfjsonInsert(DiffBuilder *p, const DLine *pLine){
1840 blob_append(p->pOut, "3,",2);
1841 blob_append_string_literal(p->pOut, pLine->z, (int)pLine->n);
1842 blob_append(p->pOut, ",\n",2);
 
1843 }
1844 static void dfjsonDelete(DiffBuilder *p, const DLine *pLine){
1845 blob_append(p->pOut, "4,",2);
1846 blob_append_string_literal(p->pOut, pLine->z, (int)pLine->n);
1847 blob_append(p->pOut, ",\n",2);
 
1848 }
1849 static void dfjsonReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1850 blob_append(p->pOut, "5,[\"\",",-1);
1851 blob_append_string_literal(p->pOut, pX->z, (int)pX->n);
1852 blob_append(p->pOut, ",",1);
1853 blob_append_string_literal(p->pOut, pY->z, (int)pY->n);
1854 blob_append(p->pOut, ",\"\"],\n",-1);
 
1855 }
1856 static void dfjsonEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1857 int i, x;
 
 
1858 ChangeSpan span;
1859 blob_append(p->pOut, "5,[", 3);
1860 oneLineChange(pX, pY, &span);
1861 for(i=x=0; i<span.n; i++){
1862 blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iStart1 - x);
1863 x = span.a[i].iStart1;
1864 blob_append_char(p->pOut, ',');
1865 blob_append_string_literal(p->pOut, pX->z + x, span.a[i].iLen1);
1866 x += span.a[i].iLen1;
1867 blob_append_char(p->pOut, ',');
1868 blob_append_string_literal(p->pOut,
1869 pY->z + span.a[i].iStart2, span.a[i].iLen2);
1870 }
1871 blob_append_char(p->pOut, ',');
1872 blob_append_string_literal(p->pOut, pX->z + x, pX->n - x);
1873 blob_append(p->pOut, "],\n",3);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1874 }
1875 static void dfjsonEnd(DiffBuilder *p){
1876 blob_append(p->pOut, "0]", 2);
1877 fossil_free(p);
1878 }
@@ -1970,12 +1890,13 @@
1890 blob_append_char(pOut, '[');
1891 return p;
1892 }
1893
1894 /************************* DiffBuilderUnified********************************/
1895 /* This module generates a unified diff for HTML
1896 **
1897 ** Accumulator strategy:
1898 **
1899 ** * Delete line numbers are output directly to p->pOut
1900 ** * Insert line numbers accumulate in p->aCol[0].
1901 ** * Separator marks accumulate in p->aCol[1].
1902 ** * Change text accumulates in p->aCol[2].
@@ -2039,34 +1960,31 @@
1960 }
1961 p->lnLeft += n;
1962 p->lnRight += n;
1963 }
1964 static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
 
1965 dfunifiedStartRow(p);
1966 dfunifiedFinishDelete(p);
1967 dfunifiedFinishInsert(p);
1968 p->lnLeft++;
1969 p->lnRight++;
1970 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1971 blob_appendf(&p->aCol[0],"%d\n",p->lnRight);
1972 blob_append_char(&p->aCol[1], '\n');
1973 htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
1974 blob_append_char(&p->aCol[2], '\n');
1975 }
1976 static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
 
1977 dfunifiedStartRow(p);
1978 p->lnRight++;
1979 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1980 blob_append(&p->aCol[4], "<ins>", 5);
1981 htmlize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n);
1982 blob_append(&p->aCol[4], "</ins>\n", 7);
1983 p->nPending++;
1984 }
1985 static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
 
1986 dfunifiedStartRow(p);
1987 dfunifiedFinishInsert(p);
1988 if( p->eState==0 ){
1989 dfunifiedFinishInsert(p);
1990 blob_append(p->pOut, "<del>", 5);
@@ -2076,15 +1994,14 @@
1994 p->lnLeft++;
1995 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1996 blob_append_char(&p->aCol[0],'\n');
1997 blob_append(&p->aCol[1],"-\n",2);
1998 blob_append(&p->aCol[2], "<del>", 5);
1999 htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
2000 blob_append(&p->aCol[2], "</del>\n", 7);
2001 }
2002 static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
 
2003 dfunifiedStartRow(p);
2004 if( p->eState==0 ){
2005 dfunifiedFinishInsert(p);
2006 blob_append(p->pOut, "<del>", 5);
2007 blob_append(&p->aCol[2], "<del>", 5);
@@ -2094,25 +2011,22 @@
2011 p->lnRight++;
2012 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2013 blob_append_char(&p->aCol[0], '\n');
2014 blob_append(&p->aCol[1], "-\n", 2);
2015
2016 htmlize_to_blob(&p->aCol[2], pX->z, pX->n);
 
2017 blob_append_char(&p->aCol[2], '\n');
2018
2019 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
2020
2021 htmlize_to_blob(&p->aCol[4], pY->z, pY->n);
 
2022 blob_append_char(&p->aCol[4], '\n');
2023 p->nPending++;
2024 }
2025 static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
2026 int i;
2027 int x;
 
2028 ChangeSpan span;
2029 oneLineChange(pX, pY, &span);
2030 dfunifiedStartRow(p);
2031 if( p->eState==0 ){
2032 dfunifiedFinishInsert(p);
@@ -2124,39 +2038,39 @@
2038 p->lnRight++;
2039 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2040 blob_append_char(&p->aCol[0], '\n');
2041 blob_append(&p->aCol[1], "-\n", 2);
2042
2043 for(i=x=0; i<span.n; i++){
2044 int ofst = span.a[i].iStart1;
2045 int len = span.a[i].iLen1;
2046 if( len ){
2047 htmlize_to_blob(&p->aCol[2], pX->z+x, ofst - x);
2048 x = ofst;
2049 blob_append(&p->aCol[2], "<del>", 5);
2050 htmlize_to_blob(&p->aCol[2], pX->z+x, len);
2051 x += len;
2052 blob_append(&p->aCol[2], "</del>", 6);
2053 }
2054 }
2055 htmlize_to_blob(&p->aCol[2], pX->z+x, pX->n - x);
2056 blob_append_char(&p->aCol[2], '\n');
2057
2058 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
2059 for(i=x=0; i<span.n; i++){
2060 int ofst = span.a[i].iStart2;
2061 int len = span.a[i].iLen2;
2062 if( len ){
2063 htmlize_to_blob(&p->aCol[4], pY->z+x, ofst - x);
2064 x = ofst;
2065 blob_append(&p->aCol[4], "<ins>", 5);
2066 htmlize_to_blob(&p->aCol[4], pY->z+x, len);
2067 x += len;
2068 blob_append(&p->aCol[4], "</ins>", 6);
2069 }
2070 }
2071 htmlize_to_blob(&p->aCol[4], pY->z+x, pY->n - x);
2072 blob_append_char(&p->aCol[4], '\n');
2073 p->nPending++;
2074 }
2075 static void dfunifiedEnd(DiffBuilder *p){
2076 dfunifiedFinishRow(p);
@@ -2184,12 +2098,13 @@
2098 blob_init(&p->aCol[4], 0, 0);
2099 return p;
2100 }
2101
2102 /************************* DiffBuilderSplit ******************************/
2103 /* This module generates a side-by-side diff for HTML.
2104 **
2105 ** Accumulator strategy:
2106 **
2107 ** * Left line numbers are output directly to p->pOut
2108 ** * Left text accumulates in p->aCol[0].
2109 ** * Edit marks accumulates in p->aCol[1].
2110 ** * Right line numbers accumulate in p->aCol[2].
@@ -2251,110 +2166,103 @@
2166 }
2167 p->lnLeft += n;
2168 p->lnRight += n;
2169 }
2170 static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
 
2171 dfsplitStartRow(p);
2172 dfsplitChangeState(p, 0);
2173 p->lnLeft++;
2174 p->lnRight++;
2175 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2176 htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
2177 blob_append_char(&p->aCol[0], '\n');
2178 blob_append_char(&p->aCol[1], '\n');
2179 blob_appendf(&p->aCol[2],"%d\n",p->lnRight);
2180 htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
2181 blob_append_char(&p->aCol[3], '\n');
2182 }
2183 static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){
 
2184 dfsplitStartRow(p);
2185 dfsplitChangeState(p, 2);
2186 p->lnRight++;
2187 blob_append_char(p->pOut, '\n');
2188 blob_append_char(&p->aCol[0], '\n');
2189 blob_append(&p->aCol[1], "&gt;\n", -1);
2190 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2191 blob_append(&p->aCol[3], "<ins>", 5);
2192 htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
2193 blob_append(&p->aCol[3], "</ins>\n", 7);
2194 }
2195 static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){
 
2196 dfsplitStartRow(p);
2197 dfsplitChangeState(p, 1);
2198 p->lnLeft++;
2199 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2200 blob_append(&p->aCol[0], "<del>", 5);
2201 htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
2202 blob_append(&p->aCol[0], "</del>\n", 7);
2203 blob_append(&p->aCol[1], "&lt;\n", -1);
2204 blob_append_char(&p->aCol[2],'\n');
2205 blob_append_char(&p->aCol[3],'\n');
2206 }
2207 static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
 
2208 dfsplitStartRow(p);
2209 dfsplitChangeState(p, 3);
2210 p->lnLeft++;
2211 p->lnRight++;
2212 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2213 htmlize_to_blob(&p->aCol[0], pX->z, pX->n);
 
2214 blob_append_char(&p->aCol[0], '\n');
2215
2216 blob_append(&p->aCol[1], "|\n", 2);
2217
2218 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2219
2220 htmlize_to_blob(&p->aCol[3], pY->z, pY->n);
 
2221 blob_append_char(&p->aCol[3], '\n');
2222 }
2223 static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
2224 int i;
2225 int x;
2226 ChangeSpan span;
 
2227 oneLineChange(pX, pY, &span);
2228 dfsplitStartRow(p);
2229 dfsplitChangeState(p, 3);
2230 p->lnLeft++;
2231 p->lnRight++;
2232 blob_appendf(p->pOut,"%d\n", p->lnLeft);
2233 for(i=x=0; i<span.n; i++){
2234 int ofst = span.a[i].iStart1;
2235 int len = span.a[i].iLen1;
2236 if( len ){
2237 htmlize_to_blob(&p->aCol[0], pX->z+x, ofst - x);
2238 x = ofst;
2239 blob_append(&p->aCol[0], "<del>", 5);
2240 htmlize_to_blob(&p->aCol[0], pX->z+x, len);
2241 x += len;
2242 blob_append(&p->aCol[0], "</del>", 6);
2243 }
2244 }
2245 htmlize_to_blob(&p->aCol[0], pX->z+x, pX->n - x);
2246 blob_append_char(&p->aCol[0], '\n');
2247
2248 blob_append(&p->aCol[1], "|\n", 2);
2249
2250 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
2251 for(i=x=0; i<span.n; i++){
2252 int ofst = span.a[i].iStart2;
2253 int len = span.a[i].iLen2;
2254 if( len ){
2255 htmlize_to_blob(&p->aCol[3], pY->z+x, ofst - x);
2256 x = ofst;
2257 blob_append(&p->aCol[3], "<ins>", 5);
2258 htmlize_to_blob(&p->aCol[3], pY->z+x, len);
2259 x += len;
2260 blob_append(&p->aCol[3], "</ins>", 6);
2261 }
2262 }
2263 htmlize_to_blob(&p->aCol[3], pY->z+x, pY->n - x);
2264 blob_append_char(&p->aCol[3], '\n');
2265 }
2266 static void dfsplitEnd(DiffBuilder *p){
2267 dfsplitFinishRow(p);
2268 blob_append(p->pOut, "</table>\n",-1);
@@ -3212,14 +3120,24 @@
3120 return diffFlags;
3121 }
3122
3123 /*
3124 ** COMMAND: test-diff
3125 ** COMMAND: xdiff
3126 **
3127 ** Usage: %fossil xdiff [options] FILE1 FILE2
3128 **
3129 ** This is the "external diff" feature. By "external" here we mean a diff
3130 ** applied to files that are not under version control. See the "diff"
3131 ** command for computing differences between files that are under control.
3132 **
3133 ** This command prints the differences between the two files FILE1 and FILE2.
3134 ** all of the usual diff command-line options apply. See the "diff" command
3135 ** for a full list of command-line options.
3136 **
3137 ** This command used to be called "test-diff". The older "test-diff" spelling
3138 ** still works, for compatibility.
3139 */
3140 void test_diff_cmd(void){
3141 Blob a, b, out;
3142 u64 diffFlag;
3143 const char *zRe; /* Regex filter for diff output */
3144
+4 -4
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -114,11 +114,11 @@
114114
115115
/*
116116
** Print the "Index:" message that patches wants to see at the top of a diff.
117117
*/
118118
void diff_print_index(const char *zFile, u64 diffFlags, Blob *diffBlob){
119
- if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT|
119
+ if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT|DIFF_JSON|
120120
DIFF_WEBPAGE|DIFF_TCL))==0 ){
121121
char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
122122
if( !diffBlob ){
123123
fossil_print("%s", z);
124124
}else{
@@ -136,11 +136,11 @@
136136
const char *zRight,
137137
u64 diffFlags,
138138
Blob *diffBlob
139139
){
140140
char *z = 0;
141
- if( diffFlags & (DIFF_BRIEF|DIFF_RAW) ){
141
+ if( diffFlags & (DIFF_BRIEF|DIFF_RAW|DIFF_JSON) ){
142142
/* no-op */
143143
}else if( diffFlags & DIFF_DEBUG ){
144144
fossil_print("FILE-LEFT %s\nFILE-RIGHT %s\n",
145145
zLeft, zRight);
146146
}else if( diffFlags & DIFF_WEBPAGE ){
@@ -157,13 +157,13 @@
157157
}else{
158158
blob_init(&x, 0, 0);
159159
pOut = &x;
160160
}
161161
blob_append(pOut, "FILE ", 5);
162
- blob_append_tcl_string(pOut, zLeft, (int)strlen(zLeft));
162
+ blob_append_string_literal(pOut, zLeft, (int)strlen(zLeft));
163163
blob_append_char(pOut, ' ');
164
- blob_append_tcl_string(pOut, zRight, (int)strlen(zRight));
164
+ blob_append_string_literal(pOut, zRight, (int)strlen(zRight));
165165
blob_append_char(pOut, '\n');
166166
if( !diffBlob ){
167167
fossil_print("%s", blob_str(pOut));
168168
blob_reset(&x);
169169
}
170170
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -114,11 +114,11 @@
114
115 /*
116 ** Print the "Index:" message that patches wants to see at the top of a diff.
117 */
118 void diff_print_index(const char *zFile, u64 diffFlags, Blob *diffBlob){
119 if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT|
120 DIFF_WEBPAGE|DIFF_TCL))==0 ){
121 char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
122 if( !diffBlob ){
123 fossil_print("%s", z);
124 }else{
@@ -136,11 +136,11 @@
136 const char *zRight,
137 u64 diffFlags,
138 Blob *diffBlob
139 ){
140 char *z = 0;
141 if( diffFlags & (DIFF_BRIEF|DIFF_RAW) ){
142 /* no-op */
143 }else if( diffFlags & DIFF_DEBUG ){
144 fossil_print("FILE-LEFT %s\nFILE-RIGHT %s\n",
145 zLeft, zRight);
146 }else if( diffFlags & DIFF_WEBPAGE ){
@@ -157,13 +157,13 @@
157 }else{
158 blob_init(&x, 0, 0);
159 pOut = &x;
160 }
161 blob_append(pOut, "FILE ", 5);
162 blob_append_tcl_string(pOut, zLeft, (int)strlen(zLeft));
163 blob_append_char(pOut, ' ');
164 blob_append_tcl_string(pOut, zRight, (int)strlen(zRight));
165 blob_append_char(pOut, '\n');
166 if( !diffBlob ){
167 fossil_print("%s", blob_str(pOut));
168 blob_reset(&x);
169 }
170
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -114,11 +114,11 @@
114
115 /*
116 ** Print the "Index:" message that patches wants to see at the top of a diff.
117 */
118 void diff_print_index(const char *zFile, u64 diffFlags, Blob *diffBlob){
119 if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT|DIFF_JSON|
120 DIFF_WEBPAGE|DIFF_TCL))==0 ){
121 char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
122 if( !diffBlob ){
123 fossil_print("%s", z);
124 }else{
@@ -136,11 +136,11 @@
136 const char *zRight,
137 u64 diffFlags,
138 Blob *diffBlob
139 ){
140 char *z = 0;
141 if( diffFlags & (DIFF_BRIEF|DIFF_RAW|DIFF_JSON) ){
142 /* no-op */
143 }else if( diffFlags & DIFF_DEBUG ){
144 fossil_print("FILE-LEFT %s\nFILE-RIGHT %s\n",
145 zLeft, zRight);
146 }else if( diffFlags & DIFF_WEBPAGE ){
@@ -157,13 +157,13 @@
157 }else{
158 blob_init(&x, 0, 0);
159 pOut = &x;
160 }
161 blob_append(pOut, "FILE ", 5);
162 blob_append_string_literal(pOut, zLeft, (int)strlen(zLeft));
163 blob_append_char(pOut, ' ');
164 blob_append_string_literal(pOut, zRight, (int)strlen(zRight));
165 blob_append_char(pOut, '\n');
166 if( !diffBlob ){
167 fossil_print("%s", blob_str(pOut));
168 blob_reset(&x);
169 }
170

Keyboard Shortcuts

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