Fossil SCM

Create the new DiffConfig object used to pass around information about a file difference computation. Begin integrating this new object into various interfaces. Lots more work to be done.

drh 2021-09-06 18:14 trunk
Commit 8601fb13d6115f57d8201602d92809d4dda732ceec3976106e9e80832fe70e97
+3 -1
--- src/ajax.c
+++ src/ajax.c
@@ -152,12 +152,14 @@
152152
** and pContent is the locally-edited (v2) content. diffFlags is any
153153
** set of flags suitable for passing to text_diff().
154154
*/
155155
void ajax_render_diff(Blob * pOrig, Blob *pContent, u64 diffFlags){
156156
Blob out = empty_blob;
157
+ DiffConfig DCfg;
157158
158
- text_diff(pOrig, pContent, &out, 0, diffFlags);
159
+ diff_config_init(&DCfg, diffFlags);
160
+ text_diff(pOrig, pContent, &out, 0, &DCfg);
159161
if(blob_size(&out)==0){
160162
/* nothing to do */
161163
}else if(DIFF_SIDEBYSIDE & diffFlags){
162164
CX("%b",&out);
163165
}else{
164166
--- src/ajax.c
+++ src/ajax.c
@@ -152,12 +152,14 @@
152 ** and pContent is the locally-edited (v2) content. diffFlags is any
153 ** set of flags suitable for passing to text_diff().
154 */
155 void ajax_render_diff(Blob * pOrig, Blob *pContent, u64 diffFlags){
156 Blob out = empty_blob;
 
157
158 text_diff(pOrig, pContent, &out, 0, diffFlags);
 
159 if(blob_size(&out)==0){
160 /* nothing to do */
161 }else if(DIFF_SIDEBYSIDE & diffFlags){
162 CX("%b",&out);
163 }else{
164
--- src/ajax.c
+++ src/ajax.c
@@ -152,12 +152,14 @@
152 ** and pContent is the locally-edited (v2) content. diffFlags is any
153 ** set of flags suitable for passing to text_diff().
154 */
155 void ajax_render_diff(Blob * pOrig, Blob *pContent, u64 diffFlags){
156 Blob out = empty_blob;
157 DiffConfig DCfg;
158
159 diff_config_init(&DCfg, diffFlags);
160 text_diff(pOrig, pContent, &out, 0, &DCfg);
161 if(blob_size(&out)==0){
162 /* nothing to do */
163 }else if(DIFF_SIDEBYSIDE & diffFlags){
164 CX("%b",&out);
165 }else{
166
+69 -46
--- src/diff.c
+++ src/diff.c
@@ -70,12 +70,28 @@
7070
/*
7171
** Maximum length of a line in a text file, in bytes. (2**15 = 32768 bytes)
7272
*/
7373
#define LENGTH_MASK_SZ 15
7474
#define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
75
+
76
+/*
77
+** Configuration options for a diff operation
78
+*/
79
+struct DiffConfig {
80
+ u64 diffFlags; /* Legacy diff flags */
81
+};
7582
7683
#endif /* INTERFACE */
84
+
85
+/*
86
+** Initialize memory for a DiffConfig based on just a diffFlags integer.
87
+*/
88
+DiffConfig *diff_config_init(DiffConfig *pCfg, u64 diffFlags){
89
+ memset(pCfg, 0, sizeof(*pCfg));
90
+ pCfg->diffFlags = diffFlags;
91
+ return pCfg;
92
+}
7793
7894
/*
7995
** Information about each line of a file being diffed.
8096
**
8197
** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -332,11 +348,11 @@
332348
** Output a patch-style text diff.
333349
*/
334350
static void contextDiff(
335351
DContext *p, /* The difference */
336352
Blob *pOut, /* Output a context diff to here */
337
- u64 diffFlags /* Flags controlling the diff format */
353
+ DiffConfig *pCfg /* Configuration options */
338354
){
339355
DLine *A; /* Left side of the diff */
340356
DLine *B; /* Right side of the diff */
341357
int a = 0; /* Index of next line in A[] */
342358
int b = 0; /* Index of next line in B[] */
@@ -351,12 +367,12 @@
351367
static int nChunk = 0; /* Number of diff chunks seen so far */
352368
int nContext; /* Number of lines of context */
353369
int showLn; /* Show line numbers */
354370
int showDivider = 0; /* True to show the divider between diff blocks */
355371
356
- nContext = diff_context_lines(diffFlags);
357
- showLn = (diffFlags & DIFF_LINENO)!=0;
372
+ nContext = diff_context_lines(pCfg);
373
+ showLn = (pCfg->diffFlags & DIFF_LINENO)!=0;
358374
A = p->aFrom;
359375
B = p->aTo;
360376
R = p->aEdit;
361377
mxr = p->nEdit;
362378
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -1631,21 +1647,21 @@
16311647
blob_append_char(p->pOut, '\n');
16321648
}
16331649
static void dfsbsEnd(DiffBuilder *p){
16341650
fossil_free(p);
16351651
}
1636
-static DiffBuilder *dfsbsNew(Blob *pOut, u64 diffFlags){
1652
+static DiffBuilder *dfsbsNew(Blob *pOut, DiffConfig *pCfg){
16371653
DiffBuilder *p = fossil_malloc(sizeof(*p));
16381654
p->xSkip = dfsbsSkip;
16391655
p->xCommon = dfsbsCommon;
16401656
p->xInsert = dfsbsInsert;
16411657
p->xDelete = dfsbsDelete;
16421658
p->xReplace = dfsbsEdit;
16431659
p->xEdit = dfsbsEdit;
16441660
p->xEnd = dfsbsEnd;
16451661
p->lnLeft = p->lnRight = 0;
1646
- p->width = diff_width(diffFlags);
1662
+ p->width = diff_width(pCfg);
16471663
p->pOut = pOut;
16481664
return p;
16491665
}
16501666
/****************************************************************************/
16511667
/*
@@ -1767,11 +1783,11 @@
17671783
** mismatch.
17681784
*/
17691785
static unsigned char *diffBlockAlignment(
17701786
const DLine *aLeft, int nLeft, /* Text on the left */
17711787
const DLine *aRight, int nRight, /* Text on the right */
1772
- u64 diffFlags, /* Flags passed into the original diff */
1788
+ DiffConfig *pCfg, /* Configuration options */
17731789
int *pNResult /* OUTPUT: Bytes of result */
17741790
){
17751791
int i, j, k; /* Loop counters */
17761792
int *a; /* One row of the Wagner matrix */
17771793
int *pToFree; /* Space that needs to be freed */
@@ -1795,11 +1811,11 @@
17951811
/* For large alignments, use a divide and conquer algorithm that is
17961812
** O(NlogN). The result is not as precise, but this whole thing is an
17971813
** approximation anyhow, and the faster response time is an acceptable
17981814
** trade-off for reduced precision.
17991815
*/
1800
- if( nLeft*nRight>DIFF_ALIGN_MX && (diffFlags & DIFF_SLOW_SBS)==0 ){
1816
+ if( nLeft*nRight>DIFF_ALIGN_MX && (pCfg->diffFlags & DIFF_SLOW_SBS)==0 ){
18011817
const DLine *aSmall; /* The smaller of aLeft and aRight */
18021818
const DLine *aBig; /* The larger of aLeft and aRight */
18031819
int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
18041820
int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
18051821
int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
@@ -1832,14 +1848,14 @@
18321848
iDivLeft = iDivBig;
18331849
}else{
18341850
iDivRight = iDivBig;
18351851
iDivLeft = iDivSmall;
18361852
}
1837
- a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,diffFlags,&n1);
1853
+ a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,pCfg,&n1);
18381854
a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
18391855
aRight+iDivRight, nRight-iDivRight,
1840
- diffFlags, &n2);
1856
+ pCfg, &n2);
18411857
a1 = fossil_realloc(a1, n1+n2 );
18421858
memcpy(a1+n1,a2,n2);
18431859
fossil_free(a2);
18441860
*pNResult = n1+n2;
18451861
return a1;
@@ -1939,11 +1955,11 @@
19391955
** Format a diff using a DiffBuilder object
19401956
*/
19411957
static void formatDiff(
19421958
DContext *p, /* The computed diff */
19431959
ReCompiled *pRe, /* Only show changes that match this regex */
1944
- u64 diffFlags, /* Flags controlling the diff */
1960
+ DiffConfig *pCfg, /* Configuration options */
19451961
DiffBuilder *pBuilder /* The formatter object */
19461962
){
19471963
const DLine *A; /* Left side of the diff */
19481964
const DLine *B; /* Right side of the diff */
19491965
unsigned int a = 0; /* Index of next line in A[] */
@@ -1956,11 +1972,11 @@
19561972
unsigned int i, j; /* Loop counters */
19571973
unsigned int m, ma, mb;/* Number of lines to output */
19581974
signed int skip = 0; /* Number of lines to skip */
19591975
unsigned int nContext; /* Lines of context above and below each change */
19601976
1961
- nContext = diff_context_lines(diffFlags);
1977
+ nContext = diff_context_lines(pCfg);
19621978
A = p->aFrom;
19631979
B = p->aTo;
19641980
R = p->aEdit;
19651981
mxr = p->nEdit;
19661982
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -2050,11 +2066,11 @@
20502066
ma += R[r+i*3+1] + m;
20512067
mb += R[r+i*3+2] + m;
20522068
}
20532069
20542070
/* Try to find an alignment for the lines within this one block */
2055
- alignment = diffBlockAlignment(&A[a], ma, &B[b], mb, diffFlags, &nAlign);
2071
+ alignment = diffBlockAlignment(&A[a], ma, &B[b], mb, pCfg, &nAlign);
20562072
20572073
for(j=0; ma+mb>0; j++){
20582074
assert( j<nAlign );
20592075
switch( alignment[j] ){
20602076
case 1: {
@@ -2511,13 +2527,13 @@
25112527
25122528
/*
25132529
** Extract the number of lines of context from diffFlags. Supply an
25142530
** appropriate default if no context width is specified.
25152531
*/
2516
-int diff_context_lines(u64 diffFlags){
2517
- int n = diffFlags & DIFF_CONTEXT_MASK;
2518
- if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
2532
+int diff_context_lines(DiffConfig *pCfg){
2533
+ int n = pCfg->diffFlags & DIFF_CONTEXT_MASK;
2534
+ if( n==0 && (pCfg->diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
25192535
return n;
25202536
}
25212537
25222538
/*
25232539
** Extract the width of columns for side-by-side diff. Supply an
@@ -2527,12 +2543,12 @@
25272543
** term-width = 2*diff-col + diff-marker + 1
25282544
** diff-col = lineno + lmargin + text-width + rmargin
25292545
**
25302546
** text-width = (term-width - diff-marker - 1)/2 - lineno - lmargin - rmargin
25312547
*/
2532
-int diff_width(u64 diffFlags){
2533
- int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
2548
+int diff_width(DiffConfig *pCfg){
2549
+ int w = (pCfg->diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
25342550
if( w==0 ){
25352551
static struct {
25362552
unsigned int lineno, lmargin, text, rmargin, marker;
25372553
} sbsW = { 5, 2, 0, 0, 3 };
25382554
const unsigned int wMin = 24, wMax = 132;
@@ -2590,40 +2606,40 @@
25902606
int *text_diff(
25912607
Blob *pA_Blob, /* FROM file */
25922608
Blob *pB_Blob, /* TO file */
25932609
Blob *pOut, /* Write diff here if not NULL */
25942610
ReCompiled *pRe, /* Only output changes where this Regexp matches */
2595
- u64 diffFlags /* DIFF_* flags defined above */
2611
+ DiffConfig *pCfg /* Configuration options */
25962612
){
25972613
int ignoreWs; /* Ignore whitespace */
25982614
DContext c;
25992615
2600
- if( diffFlags & DIFF_INVERT ){
2616
+ if( pCfg->diffFlags & DIFF_INVERT ){
26012617
Blob *pTemp = pA_Blob;
26022618
pA_Blob = pB_Blob;
26032619
pB_Blob = pTemp;
26042620
}
2605
- ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0;
2621
+ ignoreWs = (pCfg->diffFlags & DIFF_IGNORE_ALLWS)!=0;
26062622
blob_to_utf8_no_bom(pA_Blob, 0);
26072623
blob_to_utf8_no_bom(pB_Blob, 0);
26082624
26092625
/* Prepare the input files */
26102626
memset(&c, 0, sizeof(c));
2611
- if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2627
+ if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
26122628
c.xDiffer = compare_dline_ignore_allws;
26132629
}else{
26142630
c.xDiffer = compare_dline;
26152631
}
26162632
c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
2617
- &c.nFrom, diffFlags);
2633
+ &c.nFrom, pCfg->diffFlags);
26182634
c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
2619
- &c.nTo, diffFlags);
2635
+ &c.nTo, pCfg->diffFlags);
26202636
if( c.aFrom==0 || c.aTo==0 ){
26212637
fossil_free(c.aFrom);
26222638
fossil_free(c.aTo);
26232639
if( pOut ){
2624
- diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, diffFlags);
2640
+ diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, pCfg->diffFlags);
26252641
}
26262642
return 0;
26272643
}
26282644
26292645
/* Compute the difference */
@@ -2630,32 +2646,32 @@
26302646
diff_all(&c);
26312647
if( ignoreWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){
26322648
fossil_free(c.aFrom);
26332649
fossil_free(c.aTo);
26342650
fossil_free(c.aEdit);
2635
- if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, diffFlags);
2651
+ if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, pCfg->diffFlags);
26362652
return 0;
26372653
}
2638
- if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
2654
+ if( (pCfg->diffFlags & DIFF_NOTTOOBIG)!=0 ){
26392655
int i, m, n;
26402656
int *a = c.aEdit;
26412657
int mx = c.nEdit;
26422658
for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
26432659
if( n>10000 ){
26442660
fossil_free(c.aFrom);
26452661
fossil_free(c.aTo);
26462662
fossil_free(c.aEdit);
2647
- if( pOut ) diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, diffFlags);
2663
+ if( pOut ) diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, pCfg->diffFlags);
26482664
return 0;
26492665
}
26502666
}
2651
- if( (diffFlags & DIFF_NOOPT)==0 ){
2667
+ if( (pCfg->diffFlags & DIFF_NOOPT)==0 ){
26522668
diff_optimize(&c);
26532669
}
26542670
26552671
if( pOut ){
2656
- if( diffFlags & DIFF_NUMSTAT ){
2672
+ if( pCfg->diffFlags & DIFF_NUMSTAT ){
26572673
int nDel = 0, nIns = 0, i;
26582674
for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
26592675
nDel += c.aEdit[i+1];
26602676
nIns += c.aEdit[i+2];
26612677
}
@@ -2663,40 +2679,40 @@
26632679
g.diffCnt[2] += nDel;
26642680
if( nIns+nDel ){
26652681
g.diffCnt[0]++;
26662682
blob_appendf(pOut, "%10d %10d", nIns, nDel);
26672683
}
2668
- }else if( diffFlags & DIFF_RAW ){
2684
+ }else if( pCfg->diffFlags & DIFF_RAW ){
26692685
const int *R = c.aEdit;
26702686
unsigned int r;
26712687
for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
26722688
blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
26732689
R[r], R[r+1], R[r+2]);
26742690
}
2675
- }else if( diffFlags & DIFF_JSON ){
2691
+ }else if( pCfg->diffFlags & DIFF_JSON ){
26762692
DiffBuilder *pBuilder = dfjsonNew(pOut);
2677
- formatDiff(&c, pRe, diffFlags, pBuilder);
2693
+ formatDiff(&c, pRe, pCfg, pBuilder);
26782694
blob_append_char(pOut, '\n');
2679
- }else if( diffFlags & DIFF_TCL ){
2695
+ }else if( pCfg->diffFlags & DIFF_TCL ){
26802696
DiffBuilder *pBuilder = dftclNew(pOut);
2681
- formatDiff(&c, pRe, diffFlags, pBuilder);
2682
- }else if( diffFlags & DIFF_SIDEBYSIDE ){
2697
+ formatDiff(&c, pRe, pCfg, pBuilder);
2698
+ }else if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
26832699
DiffBuilder *pBuilder;
2684
- if( diffFlags & DIFF_HTML ){
2700
+ if( pCfg->diffFlags & DIFF_HTML ){
26852701
pBuilder = dfsplitNew(pOut);
26862702
}else{
2687
- pBuilder = dfsbsNew(pOut, diffFlags);
2703
+ pBuilder = dfsbsNew(pOut, pCfg);
26882704
}
2689
- formatDiff(&c, pRe, diffFlags, pBuilder);
2690
- }else if( diffFlags & DIFF_DEBUG ){
2705
+ formatDiff(&c, pRe, pCfg, pBuilder);
2706
+ }else if( pCfg->diffFlags & DIFF_DEBUG ){
26912707
DiffBuilder *pBuilder = dfdebugNew(pOut);
2692
- formatDiff(&c, pRe, diffFlags, pBuilder);
2693
- }else if( diffFlags & DIFF_HTML ){
2708
+ formatDiff(&c, pRe, pCfg, pBuilder);
2709
+ }else if( pCfg->diffFlags & DIFF_HTML ){
26942710
DiffBuilder *pBuilder = dfunifiedNew(pOut);
2695
- formatDiff(&c, pRe, diffFlags, pBuilder);
2711
+ formatDiff(&c, pRe, pCfg, pBuilder);
26962712
}else{
2697
- contextDiff(&c, pOut, diffFlags);
2713
+ contextDiff(&c, pOut, pCfg);
26982714
}
26992715
fossil_free(c.aFrom);
27002716
fossil_free(c.aTo);
27012717
fossil_free(c.aEdit);
27022718
return 0;
@@ -2726,14 +2742,17 @@
27262742
** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
27272743
** -W|--width N N character lines. DIFF_WIDTH_MASK
27282744
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
27292745
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
27302746
*/
2731
-u64 diff_options(void){
2747
+u64 diff_options(DiffConfig *pCfg){
27322748
u64 diffFlags = 0;
27332749
const char *z;
27342750
int f;
2751
+ if( pCfg ){
2752
+ memset(pCfg, 0, sizeof(*pCfg));
2753
+ }
27352754
if( find_option("ignore-trailing-space","Z",0)!=0 ){
27362755
diffFlags = DIFF_IGNORE_EOLWS;
27372756
}
27382757
if( find_option("ignore-all-space","w",0)!=0 ){
27392758
diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
@@ -2780,10 +2799,13 @@
27802799
27812800
/* Undocumented and unsupported flags used for development
27822801
** debugging and analysis: */
27832802
if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
27842803
if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
2804
+ if( pCfg ){
2805
+ pCfg->diffFlags = diffFlags;
2806
+ }
27852807
return diffFlags;
27862808
}
27872809
27882810
/*
27892811
** COMMAND: test-diff
@@ -2807,10 +2829,11 @@
28072829
void test_diff_cmd(void){
28082830
Blob a, b, out;
28092831
u64 diffFlag;
28102832
const char *zRe; /* Regex filter for diff output */
28112833
ReCompiled *pRe = 0; /* Regex filter for diff output */
2834
+ DiffConfig DCfg;
28122835
28132836
if( find_option("tk",0,0)!=0 ){
28142837
diff_tk("test-diff", 2);
28152838
return;
28162839
}
@@ -2819,19 +2842,19 @@
28192842
zRe = find_option("regexp","e",1);
28202843
if( zRe ){
28212844
const char *zErr = re_compile(&pRe, zRe, 0);
28222845
if( zErr ) fossil_fatal("regex error: %s", zErr);
28232846
}
2824
- diffFlag = diff_options();
2847
+ diffFlag = diff_options(&DCfg);
28252848
verify_all_options();
28262849
if( g.argc!=4 ) usage("FILE1 FILE2");
28272850
blob_zero(&out);
28282851
diff_begin(diffFlag);
28292852
diff_print_filenames(g.argv[2], g.argv[3], diffFlag, &out);
28302853
blob_read_from_file(&a, g.argv[2], ExtFILE);
28312854
blob_read_from_file(&b, g.argv[3], ExtFILE);
2832
- text_diff(&a, &b, &out, pRe, diffFlag);
2855
+ text_diff(&a, &b, &out, pRe, &DCfg);
28332856
blob_write_to_file(&out, "-");
28342857
diff_end(diffFlag, 0);
28352858
re_free(pRe);
28362859
}
28372860
28382861
--- src/diff.c
+++ src/diff.c
@@ -70,12 +70,28 @@
70 /*
71 ** Maximum length of a line in a text file, in bytes. (2**15 = 32768 bytes)
72 */
73 #define LENGTH_MASK_SZ 15
74 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
 
 
 
 
 
 
 
75
76 #endif /* INTERFACE */
 
 
 
 
 
 
 
 
 
77
78 /*
79 ** Information about each line of a file being diffed.
80 **
81 ** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -332,11 +348,11 @@
332 ** Output a patch-style text diff.
333 */
334 static void contextDiff(
335 DContext *p, /* The difference */
336 Blob *pOut, /* Output a context diff to here */
337 u64 diffFlags /* Flags controlling the diff format */
338 ){
339 DLine *A; /* Left side of the diff */
340 DLine *B; /* Right side of the diff */
341 int a = 0; /* Index of next line in A[] */
342 int b = 0; /* Index of next line in B[] */
@@ -351,12 +367,12 @@
351 static int nChunk = 0; /* Number of diff chunks seen so far */
352 int nContext; /* Number of lines of context */
353 int showLn; /* Show line numbers */
354 int showDivider = 0; /* True to show the divider between diff blocks */
355
356 nContext = diff_context_lines(diffFlags);
357 showLn = (diffFlags & DIFF_LINENO)!=0;
358 A = p->aFrom;
359 B = p->aTo;
360 R = p->aEdit;
361 mxr = p->nEdit;
362 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -1631,21 +1647,21 @@
1631 blob_append_char(p->pOut, '\n');
1632 }
1633 static void dfsbsEnd(DiffBuilder *p){
1634 fossil_free(p);
1635 }
1636 static DiffBuilder *dfsbsNew(Blob *pOut, u64 diffFlags){
1637 DiffBuilder *p = fossil_malloc(sizeof(*p));
1638 p->xSkip = dfsbsSkip;
1639 p->xCommon = dfsbsCommon;
1640 p->xInsert = dfsbsInsert;
1641 p->xDelete = dfsbsDelete;
1642 p->xReplace = dfsbsEdit;
1643 p->xEdit = dfsbsEdit;
1644 p->xEnd = dfsbsEnd;
1645 p->lnLeft = p->lnRight = 0;
1646 p->width = diff_width(diffFlags);
1647 p->pOut = pOut;
1648 return p;
1649 }
1650 /****************************************************************************/
1651 /*
@@ -1767,11 +1783,11 @@
1767 ** mismatch.
1768 */
1769 static unsigned char *diffBlockAlignment(
1770 const DLine *aLeft, int nLeft, /* Text on the left */
1771 const DLine *aRight, int nRight, /* Text on the right */
1772 u64 diffFlags, /* Flags passed into the original diff */
1773 int *pNResult /* OUTPUT: Bytes of result */
1774 ){
1775 int i, j, k; /* Loop counters */
1776 int *a; /* One row of the Wagner matrix */
1777 int *pToFree; /* Space that needs to be freed */
@@ -1795,11 +1811,11 @@
1795 /* For large alignments, use a divide and conquer algorithm that is
1796 ** O(NlogN). The result is not as precise, but this whole thing is an
1797 ** approximation anyhow, and the faster response time is an acceptable
1798 ** trade-off for reduced precision.
1799 */
1800 if( nLeft*nRight>DIFF_ALIGN_MX && (diffFlags & DIFF_SLOW_SBS)==0 ){
1801 const DLine *aSmall; /* The smaller of aLeft and aRight */
1802 const DLine *aBig; /* The larger of aLeft and aRight */
1803 int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
1804 int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
1805 int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
@@ -1832,14 +1848,14 @@
1832 iDivLeft = iDivBig;
1833 }else{
1834 iDivRight = iDivBig;
1835 iDivLeft = iDivSmall;
1836 }
1837 a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,diffFlags,&n1);
1838 a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
1839 aRight+iDivRight, nRight-iDivRight,
1840 diffFlags, &n2);
1841 a1 = fossil_realloc(a1, n1+n2 );
1842 memcpy(a1+n1,a2,n2);
1843 fossil_free(a2);
1844 *pNResult = n1+n2;
1845 return a1;
@@ -1939,11 +1955,11 @@
1939 ** Format a diff using a DiffBuilder object
1940 */
1941 static void formatDiff(
1942 DContext *p, /* The computed diff */
1943 ReCompiled *pRe, /* Only show changes that match this regex */
1944 u64 diffFlags, /* Flags controlling the diff */
1945 DiffBuilder *pBuilder /* The formatter object */
1946 ){
1947 const DLine *A; /* Left side of the diff */
1948 const DLine *B; /* Right side of the diff */
1949 unsigned int a = 0; /* Index of next line in A[] */
@@ -1956,11 +1972,11 @@
1956 unsigned int i, j; /* Loop counters */
1957 unsigned int m, ma, mb;/* Number of lines to output */
1958 signed int skip = 0; /* Number of lines to skip */
1959 unsigned int nContext; /* Lines of context above and below each change */
1960
1961 nContext = diff_context_lines(diffFlags);
1962 A = p->aFrom;
1963 B = p->aTo;
1964 R = p->aEdit;
1965 mxr = p->nEdit;
1966 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -2050,11 +2066,11 @@
2050 ma += R[r+i*3+1] + m;
2051 mb += R[r+i*3+2] + m;
2052 }
2053
2054 /* Try to find an alignment for the lines within this one block */
2055 alignment = diffBlockAlignment(&A[a], ma, &B[b], mb, diffFlags, &nAlign);
2056
2057 for(j=0; ma+mb>0; j++){
2058 assert( j<nAlign );
2059 switch( alignment[j] ){
2060 case 1: {
@@ -2511,13 +2527,13 @@
2511
2512 /*
2513 ** Extract the number of lines of context from diffFlags. Supply an
2514 ** appropriate default if no context width is specified.
2515 */
2516 int diff_context_lines(u64 diffFlags){
2517 int n = diffFlags & DIFF_CONTEXT_MASK;
2518 if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
2519 return n;
2520 }
2521
2522 /*
2523 ** Extract the width of columns for side-by-side diff. Supply an
@@ -2527,12 +2543,12 @@
2527 ** term-width = 2*diff-col + diff-marker + 1
2528 ** diff-col = lineno + lmargin + text-width + rmargin
2529 **
2530 ** text-width = (term-width - diff-marker - 1)/2 - lineno - lmargin - rmargin
2531 */
2532 int diff_width(u64 diffFlags){
2533 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
2534 if( w==0 ){
2535 static struct {
2536 unsigned int lineno, lmargin, text, rmargin, marker;
2537 } sbsW = { 5, 2, 0, 0, 3 };
2538 const unsigned int wMin = 24, wMax = 132;
@@ -2590,40 +2606,40 @@
2590 int *text_diff(
2591 Blob *pA_Blob, /* FROM file */
2592 Blob *pB_Blob, /* TO file */
2593 Blob *pOut, /* Write diff here if not NULL */
2594 ReCompiled *pRe, /* Only output changes where this Regexp matches */
2595 u64 diffFlags /* DIFF_* flags defined above */
2596 ){
2597 int ignoreWs; /* Ignore whitespace */
2598 DContext c;
2599
2600 if( diffFlags & DIFF_INVERT ){
2601 Blob *pTemp = pA_Blob;
2602 pA_Blob = pB_Blob;
2603 pB_Blob = pTemp;
2604 }
2605 ignoreWs = (diffFlags & DIFF_IGNORE_ALLWS)!=0;
2606 blob_to_utf8_no_bom(pA_Blob, 0);
2607 blob_to_utf8_no_bom(pB_Blob, 0);
2608
2609 /* Prepare the input files */
2610 memset(&c, 0, sizeof(c));
2611 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2612 c.xDiffer = compare_dline_ignore_allws;
2613 }else{
2614 c.xDiffer = compare_dline;
2615 }
2616 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
2617 &c.nFrom, diffFlags);
2618 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
2619 &c.nTo, diffFlags);
2620 if( c.aFrom==0 || c.aTo==0 ){
2621 fossil_free(c.aFrom);
2622 fossil_free(c.aTo);
2623 if( pOut ){
2624 diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, diffFlags);
2625 }
2626 return 0;
2627 }
2628
2629 /* Compute the difference */
@@ -2630,32 +2646,32 @@
2630 diff_all(&c);
2631 if( ignoreWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){
2632 fossil_free(c.aFrom);
2633 fossil_free(c.aTo);
2634 fossil_free(c.aEdit);
2635 if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, diffFlags);
2636 return 0;
2637 }
2638 if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
2639 int i, m, n;
2640 int *a = c.aEdit;
2641 int mx = c.nEdit;
2642 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
2643 if( n>10000 ){
2644 fossil_free(c.aFrom);
2645 fossil_free(c.aTo);
2646 fossil_free(c.aEdit);
2647 if( pOut ) diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, diffFlags);
2648 return 0;
2649 }
2650 }
2651 if( (diffFlags & DIFF_NOOPT)==0 ){
2652 diff_optimize(&c);
2653 }
2654
2655 if( pOut ){
2656 if( diffFlags & DIFF_NUMSTAT ){
2657 int nDel = 0, nIns = 0, i;
2658 for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
2659 nDel += c.aEdit[i+1];
2660 nIns += c.aEdit[i+2];
2661 }
@@ -2663,40 +2679,40 @@
2663 g.diffCnt[2] += nDel;
2664 if( nIns+nDel ){
2665 g.diffCnt[0]++;
2666 blob_appendf(pOut, "%10d %10d", nIns, nDel);
2667 }
2668 }else if( diffFlags & DIFF_RAW ){
2669 const int *R = c.aEdit;
2670 unsigned int r;
2671 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2672 blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
2673 R[r], R[r+1], R[r+2]);
2674 }
2675 }else if( diffFlags & DIFF_JSON ){
2676 DiffBuilder *pBuilder = dfjsonNew(pOut);
2677 formatDiff(&c, pRe, diffFlags, pBuilder);
2678 blob_append_char(pOut, '\n');
2679 }else if( diffFlags & DIFF_TCL ){
2680 DiffBuilder *pBuilder = dftclNew(pOut);
2681 formatDiff(&c, pRe, diffFlags, pBuilder);
2682 }else if( diffFlags & DIFF_SIDEBYSIDE ){
2683 DiffBuilder *pBuilder;
2684 if( diffFlags & DIFF_HTML ){
2685 pBuilder = dfsplitNew(pOut);
2686 }else{
2687 pBuilder = dfsbsNew(pOut, diffFlags);
2688 }
2689 formatDiff(&c, pRe, diffFlags, pBuilder);
2690 }else if( diffFlags & DIFF_DEBUG ){
2691 DiffBuilder *pBuilder = dfdebugNew(pOut);
2692 formatDiff(&c, pRe, diffFlags, pBuilder);
2693 }else if( diffFlags & DIFF_HTML ){
2694 DiffBuilder *pBuilder = dfunifiedNew(pOut);
2695 formatDiff(&c, pRe, diffFlags, pBuilder);
2696 }else{
2697 contextDiff(&c, pOut, diffFlags);
2698 }
2699 fossil_free(c.aFrom);
2700 fossil_free(c.aTo);
2701 fossil_free(c.aEdit);
2702 return 0;
@@ -2726,14 +2742,17 @@
2726 ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
2727 ** -W|--width N N character lines. DIFF_WIDTH_MASK
2728 ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
2729 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
2730 */
2731 u64 diff_options(void){
2732 u64 diffFlags = 0;
2733 const char *z;
2734 int f;
 
 
 
2735 if( find_option("ignore-trailing-space","Z",0)!=0 ){
2736 diffFlags = DIFF_IGNORE_EOLWS;
2737 }
2738 if( find_option("ignore-all-space","w",0)!=0 ){
2739 diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
@@ -2780,10 +2799,13 @@
2780
2781 /* Undocumented and unsupported flags used for development
2782 ** debugging and analysis: */
2783 if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
2784 if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
 
 
 
2785 return diffFlags;
2786 }
2787
2788 /*
2789 ** COMMAND: test-diff
@@ -2807,10 +2829,11 @@
2807 void test_diff_cmd(void){
2808 Blob a, b, out;
2809 u64 diffFlag;
2810 const char *zRe; /* Regex filter for diff output */
2811 ReCompiled *pRe = 0; /* Regex filter for diff output */
 
2812
2813 if( find_option("tk",0,0)!=0 ){
2814 diff_tk("test-diff", 2);
2815 return;
2816 }
@@ -2819,19 +2842,19 @@
2819 zRe = find_option("regexp","e",1);
2820 if( zRe ){
2821 const char *zErr = re_compile(&pRe, zRe, 0);
2822 if( zErr ) fossil_fatal("regex error: %s", zErr);
2823 }
2824 diffFlag = diff_options();
2825 verify_all_options();
2826 if( g.argc!=4 ) usage("FILE1 FILE2");
2827 blob_zero(&out);
2828 diff_begin(diffFlag);
2829 diff_print_filenames(g.argv[2], g.argv[3], diffFlag, &out);
2830 blob_read_from_file(&a, g.argv[2], ExtFILE);
2831 blob_read_from_file(&b, g.argv[3], ExtFILE);
2832 text_diff(&a, &b, &out, pRe, diffFlag);
2833 blob_write_to_file(&out, "-");
2834 diff_end(diffFlag, 0);
2835 re_free(pRe);
2836 }
2837
2838
--- src/diff.c
+++ src/diff.c
@@ -70,12 +70,28 @@
70 /*
71 ** Maximum length of a line in a text file, in bytes. (2**15 = 32768 bytes)
72 */
73 #define LENGTH_MASK_SZ 15
74 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
75
76 /*
77 ** Configuration options for a diff operation
78 */
79 struct DiffConfig {
80 u64 diffFlags; /* Legacy diff flags */
81 };
82
83 #endif /* INTERFACE */
84
85 /*
86 ** Initialize memory for a DiffConfig based on just a diffFlags integer.
87 */
88 DiffConfig *diff_config_init(DiffConfig *pCfg, u64 diffFlags){
89 memset(pCfg, 0, sizeof(*pCfg));
90 pCfg->diffFlags = diffFlags;
91 return pCfg;
92 }
93
94 /*
95 ** Information about each line of a file being diffed.
96 **
97 ** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -332,11 +348,11 @@
348 ** Output a patch-style text diff.
349 */
350 static void contextDiff(
351 DContext *p, /* The difference */
352 Blob *pOut, /* Output a context diff to here */
353 DiffConfig *pCfg /* Configuration options */
354 ){
355 DLine *A; /* Left side of the diff */
356 DLine *B; /* Right side of the diff */
357 int a = 0; /* Index of next line in A[] */
358 int b = 0; /* Index of next line in B[] */
@@ -351,12 +367,12 @@
367 static int nChunk = 0; /* Number of diff chunks seen so far */
368 int nContext; /* Number of lines of context */
369 int showLn; /* Show line numbers */
370 int showDivider = 0; /* True to show the divider between diff blocks */
371
372 nContext = diff_context_lines(pCfg);
373 showLn = (pCfg->diffFlags & DIFF_LINENO)!=0;
374 A = p->aFrom;
375 B = p->aTo;
376 R = p->aEdit;
377 mxr = p->nEdit;
378 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -1631,21 +1647,21 @@
1647 blob_append_char(p->pOut, '\n');
1648 }
1649 static void dfsbsEnd(DiffBuilder *p){
1650 fossil_free(p);
1651 }
1652 static DiffBuilder *dfsbsNew(Blob *pOut, DiffConfig *pCfg){
1653 DiffBuilder *p = fossil_malloc(sizeof(*p));
1654 p->xSkip = dfsbsSkip;
1655 p->xCommon = dfsbsCommon;
1656 p->xInsert = dfsbsInsert;
1657 p->xDelete = dfsbsDelete;
1658 p->xReplace = dfsbsEdit;
1659 p->xEdit = dfsbsEdit;
1660 p->xEnd = dfsbsEnd;
1661 p->lnLeft = p->lnRight = 0;
1662 p->width = diff_width(pCfg);
1663 p->pOut = pOut;
1664 return p;
1665 }
1666 /****************************************************************************/
1667 /*
@@ -1767,11 +1783,11 @@
1783 ** mismatch.
1784 */
1785 static unsigned char *diffBlockAlignment(
1786 const DLine *aLeft, int nLeft, /* Text on the left */
1787 const DLine *aRight, int nRight, /* Text on the right */
1788 DiffConfig *pCfg, /* Configuration options */
1789 int *pNResult /* OUTPUT: Bytes of result */
1790 ){
1791 int i, j, k; /* Loop counters */
1792 int *a; /* One row of the Wagner matrix */
1793 int *pToFree; /* Space that needs to be freed */
@@ -1795,11 +1811,11 @@
1811 /* For large alignments, use a divide and conquer algorithm that is
1812 ** O(NlogN). The result is not as precise, but this whole thing is an
1813 ** approximation anyhow, and the faster response time is an acceptable
1814 ** trade-off for reduced precision.
1815 */
1816 if( nLeft*nRight>DIFF_ALIGN_MX && (pCfg->diffFlags & DIFF_SLOW_SBS)==0 ){
1817 const DLine *aSmall; /* The smaller of aLeft and aRight */
1818 const DLine *aBig; /* The larger of aLeft and aRight */
1819 int nSmall, nBig; /* Size of aSmall and aBig. nSmall<=nBig */
1820 int iDivSmall, iDivBig; /* Divider point for aSmall and aBig */
1821 int iDivLeft, iDivRight; /* Divider point for aLeft and aRight */
@@ -1832,14 +1848,14 @@
1848 iDivLeft = iDivBig;
1849 }else{
1850 iDivRight = iDivBig;
1851 iDivLeft = iDivSmall;
1852 }
1853 a1 = diffBlockAlignment(aLeft,iDivLeft,aRight,iDivRight,pCfg,&n1);
1854 a2 = diffBlockAlignment(aLeft+iDivLeft, nLeft-iDivLeft,
1855 aRight+iDivRight, nRight-iDivRight,
1856 pCfg, &n2);
1857 a1 = fossil_realloc(a1, n1+n2 );
1858 memcpy(a1+n1,a2,n2);
1859 fossil_free(a2);
1860 *pNResult = n1+n2;
1861 return a1;
@@ -1939,11 +1955,11 @@
1955 ** Format a diff using a DiffBuilder object
1956 */
1957 static void formatDiff(
1958 DContext *p, /* The computed diff */
1959 ReCompiled *pRe, /* Only show changes that match this regex */
1960 DiffConfig *pCfg, /* Configuration options */
1961 DiffBuilder *pBuilder /* The formatter object */
1962 ){
1963 const DLine *A; /* Left side of the diff */
1964 const DLine *B; /* Right side of the diff */
1965 unsigned int a = 0; /* Index of next line in A[] */
@@ -1956,11 +1972,11 @@
1972 unsigned int i, j; /* Loop counters */
1973 unsigned int m, ma, mb;/* Number of lines to output */
1974 signed int skip = 0; /* Number of lines to skip */
1975 unsigned int nContext; /* Lines of context above and below each change */
1976
1977 nContext = diff_context_lines(pCfg);
1978 A = p->aFrom;
1979 B = p->aTo;
1980 R = p->aEdit;
1981 mxr = p->nEdit;
1982 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -2050,11 +2066,11 @@
2066 ma += R[r+i*3+1] + m;
2067 mb += R[r+i*3+2] + m;
2068 }
2069
2070 /* Try to find an alignment for the lines within this one block */
2071 alignment = diffBlockAlignment(&A[a], ma, &B[b], mb, pCfg, &nAlign);
2072
2073 for(j=0; ma+mb>0; j++){
2074 assert( j<nAlign );
2075 switch( alignment[j] ){
2076 case 1: {
@@ -2511,13 +2527,13 @@
2527
2528 /*
2529 ** Extract the number of lines of context from diffFlags. Supply an
2530 ** appropriate default if no context width is specified.
2531 */
2532 int diff_context_lines(DiffConfig *pCfg){
2533 int n = pCfg->diffFlags & DIFF_CONTEXT_MASK;
2534 if( n==0 && (pCfg->diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
2535 return n;
2536 }
2537
2538 /*
2539 ** Extract the width of columns for side-by-side diff. Supply an
@@ -2527,12 +2543,12 @@
2543 ** term-width = 2*diff-col + diff-marker + 1
2544 ** diff-col = lineno + lmargin + text-width + rmargin
2545 **
2546 ** text-width = (term-width - diff-marker - 1)/2 - lineno - lmargin - rmargin
2547 */
2548 int diff_width(DiffConfig *pCfg){
2549 int w = (pCfg->diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
2550 if( w==0 ){
2551 static struct {
2552 unsigned int lineno, lmargin, text, rmargin, marker;
2553 } sbsW = { 5, 2, 0, 0, 3 };
2554 const unsigned int wMin = 24, wMax = 132;
@@ -2590,40 +2606,40 @@
2606 int *text_diff(
2607 Blob *pA_Blob, /* FROM file */
2608 Blob *pB_Blob, /* TO file */
2609 Blob *pOut, /* Write diff here if not NULL */
2610 ReCompiled *pRe, /* Only output changes where this Regexp matches */
2611 DiffConfig *pCfg /* Configuration options */
2612 ){
2613 int ignoreWs; /* Ignore whitespace */
2614 DContext c;
2615
2616 if( pCfg->diffFlags & DIFF_INVERT ){
2617 Blob *pTemp = pA_Blob;
2618 pA_Blob = pB_Blob;
2619 pB_Blob = pTemp;
2620 }
2621 ignoreWs = (pCfg->diffFlags & DIFF_IGNORE_ALLWS)!=0;
2622 blob_to_utf8_no_bom(pA_Blob, 0);
2623 blob_to_utf8_no_bom(pB_Blob, 0);
2624
2625 /* Prepare the input files */
2626 memset(&c, 0, sizeof(c));
2627 if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2628 c.xDiffer = compare_dline_ignore_allws;
2629 }else{
2630 c.xDiffer = compare_dline;
2631 }
2632 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
2633 &c.nFrom, pCfg->diffFlags);
2634 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
2635 &c.nTo, pCfg->diffFlags);
2636 if( c.aFrom==0 || c.aTo==0 ){
2637 fossil_free(c.aFrom);
2638 fossil_free(c.aTo);
2639 if( pOut ){
2640 diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, pCfg->diffFlags);
2641 }
2642 return 0;
2643 }
2644
2645 /* Compute the difference */
@@ -2630,32 +2646,32 @@
2646 diff_all(&c);
2647 if( ignoreWs && c.nEdit==6 && c.aEdit[1]==0 && c.aEdit[2]==0 ){
2648 fossil_free(c.aFrom);
2649 fossil_free(c.aTo);
2650 fossil_free(c.aEdit);
2651 if( pOut ) diff_errmsg(pOut, DIFF_WHITESPACE_ONLY, pCfg->diffFlags);
2652 return 0;
2653 }
2654 if( (pCfg->diffFlags & DIFF_NOTTOOBIG)!=0 ){
2655 int i, m, n;
2656 int *a = c.aEdit;
2657 int mx = c.nEdit;
2658 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
2659 if( n>10000 ){
2660 fossil_free(c.aFrom);
2661 fossil_free(c.aTo);
2662 fossil_free(c.aEdit);
2663 if( pOut ) diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, pCfg->diffFlags);
2664 return 0;
2665 }
2666 }
2667 if( (pCfg->diffFlags & DIFF_NOOPT)==0 ){
2668 diff_optimize(&c);
2669 }
2670
2671 if( pOut ){
2672 if( pCfg->diffFlags & DIFF_NUMSTAT ){
2673 int nDel = 0, nIns = 0, i;
2674 for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
2675 nDel += c.aEdit[i+1];
2676 nIns += c.aEdit[i+2];
2677 }
@@ -2663,40 +2679,40 @@
2679 g.diffCnt[2] += nDel;
2680 if( nIns+nDel ){
2681 g.diffCnt[0]++;
2682 blob_appendf(pOut, "%10d %10d", nIns, nDel);
2683 }
2684 }else if( pCfg->diffFlags & DIFF_RAW ){
2685 const int *R = c.aEdit;
2686 unsigned int r;
2687 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2688 blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
2689 R[r], R[r+1], R[r+2]);
2690 }
2691 }else if( pCfg->diffFlags & DIFF_JSON ){
2692 DiffBuilder *pBuilder = dfjsonNew(pOut);
2693 formatDiff(&c, pRe, pCfg, pBuilder);
2694 blob_append_char(pOut, '\n');
2695 }else if( pCfg->diffFlags & DIFF_TCL ){
2696 DiffBuilder *pBuilder = dftclNew(pOut);
2697 formatDiff(&c, pRe, pCfg, pBuilder);
2698 }else if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
2699 DiffBuilder *pBuilder;
2700 if( pCfg->diffFlags & DIFF_HTML ){
2701 pBuilder = dfsplitNew(pOut);
2702 }else{
2703 pBuilder = dfsbsNew(pOut, pCfg);
2704 }
2705 formatDiff(&c, pRe, pCfg, pBuilder);
2706 }else if( pCfg->diffFlags & DIFF_DEBUG ){
2707 DiffBuilder *pBuilder = dfdebugNew(pOut);
2708 formatDiff(&c, pRe, pCfg, pBuilder);
2709 }else if( pCfg->diffFlags & DIFF_HTML ){
2710 DiffBuilder *pBuilder = dfunifiedNew(pOut);
2711 formatDiff(&c, pRe, pCfg, pBuilder);
2712 }else{
2713 contextDiff(&c, pOut, pCfg);
2714 }
2715 fossil_free(c.aFrom);
2716 fossil_free(c.aTo);
2717 fossil_free(c.aEdit);
2718 return 0;
@@ -2726,14 +2742,17 @@
2742 ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
2743 ** -W|--width N N character lines. DIFF_WIDTH_MASK
2744 ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
2745 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
2746 */
2747 u64 diff_options(DiffConfig *pCfg){
2748 u64 diffFlags = 0;
2749 const char *z;
2750 int f;
2751 if( pCfg ){
2752 memset(pCfg, 0, sizeof(*pCfg));
2753 }
2754 if( find_option("ignore-trailing-space","Z",0)!=0 ){
2755 diffFlags = DIFF_IGNORE_EOLWS;
2756 }
2757 if( find_option("ignore-all-space","w",0)!=0 ){
2758 diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
@@ -2780,10 +2799,13 @@
2799
2800 /* Undocumented and unsupported flags used for development
2801 ** debugging and analysis: */
2802 if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
2803 if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
2804 if( pCfg ){
2805 pCfg->diffFlags = diffFlags;
2806 }
2807 return diffFlags;
2808 }
2809
2810 /*
2811 ** COMMAND: test-diff
@@ -2807,10 +2829,11 @@
2829 void test_diff_cmd(void){
2830 Blob a, b, out;
2831 u64 diffFlag;
2832 const char *zRe; /* Regex filter for diff output */
2833 ReCompiled *pRe = 0; /* Regex filter for diff output */
2834 DiffConfig DCfg;
2835
2836 if( find_option("tk",0,0)!=0 ){
2837 diff_tk("test-diff", 2);
2838 return;
2839 }
@@ -2819,19 +2842,19 @@
2842 zRe = find_option("regexp","e",1);
2843 if( zRe ){
2844 const char *zErr = re_compile(&pRe, zRe, 0);
2845 if( zErr ) fossil_fatal("regex error: %s", zErr);
2846 }
2847 diffFlag = diff_options(&DCfg);
2848 verify_all_options();
2849 if( g.argc!=4 ) usage("FILE1 FILE2");
2850 blob_zero(&out);
2851 diff_begin(diffFlag);
2852 diff_print_filenames(g.argv[2], g.argv[3], diffFlag, &out);
2853 blob_read_from_file(&a, g.argv[2], ExtFILE);
2854 blob_read_from_file(&b, g.argv[3], ExtFILE);
2855 text_diff(&a, &b, &out, pRe, &DCfg);
2856 blob_write_to_file(&out, "-");
2857 diff_end(diffFlag, 0);
2858 re_free(pRe);
2859 }
2860
2861
+11 -5
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -167,11 +167,12 @@
167167
fossil_print("%s", blob_str(pOut));
168168
blob_reset(&x);
169169
}
170170
return;
171171
}else if( diffFlags & DIFF_SIDEBYSIDE ){
172
- int w = diff_width(diffFlags);
172
+ DiffConfig DCfg;
173
+ int w = diff_width(diff_config_init(&DCfg,diffFlags));
173174
int n1 = strlen(zLeft);
174175
int n2 = strlen(zRight);
175176
int x;
176177
if( n1==n2 && fossil_strcmp(zLeft,zRight)==0 ){
177178
if( n1>w*2 ) n1 = w*2;
@@ -422,15 +423,17 @@
422423
if( diffFlags & DIFF_BRIEF ){
423424
if( blob_compare(pFile1, &file2) ){
424425
fossil_print("CHANGED %s\n", zName);
425426
}
426427
}else{
428
+ DiffConfig DCfg;
429
+ diff_config_init(&DCfg, diffFlags);
427430
blob_zero(&out);
428431
if( fSwapDiff ){
429
- text_diff(&file2, pFile1, &out, 0, diffFlags);
432
+ text_diff(&file2, pFile1, &out, 0, &DCfg);
430433
}else{
431
- text_diff(pFile1, &file2, &out, 0, diffFlags);
434
+ text_diff(pFile1, &file2, &out, 0, &DCfg);
432435
}
433436
if( blob_size(&out) ){
434437
if( diffFlags & DIFF_NUMSTAT ){
435438
if( !diffBlob ){
436439
fossil_print("%s %s\n", blob_str(&out), zName);
@@ -534,13 +537,15 @@
534537
u64 diffFlags /* Diff flags */
535538
){
536539
if( diffFlags & DIFF_BRIEF ) return;
537540
if( zDiffCmd==0 ){
538541
Blob out; /* Diff output text */
542
+ DiffConfig DCfg;
539543
544
+ diff_config_init(&DCfg, diffFlags);
540545
blob_zero(&out);
541
- text_diff(pFile1, pFile2, &out, 0, diffFlags);
546
+ text_diff(pFile1, pFile2, &out, 0, &DCfg);
542547
if( diffFlags & DIFF_NUMSTAT ){
543548
fossil_print("%s %s\n", blob_str(&out), zName);
544549
}else{
545550
diff_print_filenames(zName, zName, diffFlags, 0);
546551
fossil_print("%s\n", blob_str(&out));
@@ -1109,10 +1114,11 @@
11091114
const char *zBinGlob = 0; /* Treat file names matching this as binary */
11101115
int fIncludeBinary = 0; /* Include binary files for external diff */
11111116
int againstUndo = 0; /* Diff against files in the undo buffer */
11121117
u64 diffFlags = 0; /* Flags to control the DIFF */
11131118
FileDirList *pFileDir = 0; /* Restrict the diff to these files */
1119
+ DiffConfig DCfg; /* Diff configuration object */
11141120
11151121
if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
11161122
diff_tk("diff", 2);
11171123
return;
11181124
}
@@ -1121,11 +1127,11 @@
11211127
zFrom = find_option("from", "r", 1);
11221128
zTo = find_option("to", 0, 1);
11231129
zCheckin = find_option("checkin", 0, 1);
11241130
zBranch = find_option("branch", 0, 1);
11251131
againstUndo = find_option("undo",0,0)!=0;
1126
- diffFlags = diff_options();
1132
+ diffFlags = diff_options(&DCfg);
11271133
verboseFlag = find_option("verbose","v",0)!=0;
11281134
if( !verboseFlag ){
11291135
verboseFlag = find_option("new-file","N",0)!=0; /* deprecated */
11301136
}
11311137
if( verboseFlag ) diffFlags |= DIFF_VERBOSE;
11321138
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -167,11 +167,12 @@
167 fossil_print("%s", blob_str(pOut));
168 blob_reset(&x);
169 }
170 return;
171 }else if( diffFlags & DIFF_SIDEBYSIDE ){
172 int w = diff_width(diffFlags);
 
173 int n1 = strlen(zLeft);
174 int n2 = strlen(zRight);
175 int x;
176 if( n1==n2 && fossil_strcmp(zLeft,zRight)==0 ){
177 if( n1>w*2 ) n1 = w*2;
@@ -422,15 +423,17 @@
422 if( diffFlags & DIFF_BRIEF ){
423 if( blob_compare(pFile1, &file2) ){
424 fossil_print("CHANGED %s\n", zName);
425 }
426 }else{
 
 
427 blob_zero(&out);
428 if( fSwapDiff ){
429 text_diff(&file2, pFile1, &out, 0, diffFlags);
430 }else{
431 text_diff(pFile1, &file2, &out, 0, diffFlags);
432 }
433 if( blob_size(&out) ){
434 if( diffFlags & DIFF_NUMSTAT ){
435 if( !diffBlob ){
436 fossil_print("%s %s\n", blob_str(&out), zName);
@@ -534,13 +537,15 @@
534 u64 diffFlags /* Diff flags */
535 ){
536 if( diffFlags & DIFF_BRIEF ) return;
537 if( zDiffCmd==0 ){
538 Blob out; /* Diff output text */
 
539
 
540 blob_zero(&out);
541 text_diff(pFile1, pFile2, &out, 0, diffFlags);
542 if( diffFlags & DIFF_NUMSTAT ){
543 fossil_print("%s %s\n", blob_str(&out), zName);
544 }else{
545 diff_print_filenames(zName, zName, diffFlags, 0);
546 fossil_print("%s\n", blob_str(&out));
@@ -1109,10 +1114,11 @@
1109 const char *zBinGlob = 0; /* Treat file names matching this as binary */
1110 int fIncludeBinary = 0; /* Include binary files for external diff */
1111 int againstUndo = 0; /* Diff against files in the undo buffer */
1112 u64 diffFlags = 0; /* Flags to control the DIFF */
1113 FileDirList *pFileDir = 0; /* Restrict the diff to these files */
 
1114
1115 if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
1116 diff_tk("diff", 2);
1117 return;
1118 }
@@ -1121,11 +1127,11 @@
1121 zFrom = find_option("from", "r", 1);
1122 zTo = find_option("to", 0, 1);
1123 zCheckin = find_option("checkin", 0, 1);
1124 zBranch = find_option("branch", 0, 1);
1125 againstUndo = find_option("undo",0,0)!=0;
1126 diffFlags = diff_options();
1127 verboseFlag = find_option("verbose","v",0)!=0;
1128 if( !verboseFlag ){
1129 verboseFlag = find_option("new-file","N",0)!=0; /* deprecated */
1130 }
1131 if( verboseFlag ) diffFlags |= DIFF_VERBOSE;
1132
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -167,11 +167,12 @@
167 fossil_print("%s", blob_str(pOut));
168 blob_reset(&x);
169 }
170 return;
171 }else if( diffFlags & DIFF_SIDEBYSIDE ){
172 DiffConfig DCfg;
173 int w = diff_width(diff_config_init(&DCfg,diffFlags));
174 int n1 = strlen(zLeft);
175 int n2 = strlen(zRight);
176 int x;
177 if( n1==n2 && fossil_strcmp(zLeft,zRight)==0 ){
178 if( n1>w*2 ) n1 = w*2;
@@ -422,15 +423,17 @@
423 if( diffFlags & DIFF_BRIEF ){
424 if( blob_compare(pFile1, &file2) ){
425 fossil_print("CHANGED %s\n", zName);
426 }
427 }else{
428 DiffConfig DCfg;
429 diff_config_init(&DCfg, diffFlags);
430 blob_zero(&out);
431 if( fSwapDiff ){
432 text_diff(&file2, pFile1, &out, 0, &DCfg);
433 }else{
434 text_diff(pFile1, &file2, &out, 0, &DCfg);
435 }
436 if( blob_size(&out) ){
437 if( diffFlags & DIFF_NUMSTAT ){
438 if( !diffBlob ){
439 fossil_print("%s %s\n", blob_str(&out), zName);
@@ -534,13 +537,15 @@
537 u64 diffFlags /* Diff flags */
538 ){
539 if( diffFlags & DIFF_BRIEF ) return;
540 if( zDiffCmd==0 ){
541 Blob out; /* Diff output text */
542 DiffConfig DCfg;
543
544 diff_config_init(&DCfg, diffFlags);
545 blob_zero(&out);
546 text_diff(pFile1, pFile2, &out, 0, &DCfg);
547 if( diffFlags & DIFF_NUMSTAT ){
548 fossil_print("%s %s\n", blob_str(&out), zName);
549 }else{
550 diff_print_filenames(zName, zName, diffFlags, 0);
551 fossil_print("%s\n", blob_str(&out));
@@ -1109,10 +1114,11 @@
1114 const char *zBinGlob = 0; /* Treat file names matching this as binary */
1115 int fIncludeBinary = 0; /* Include binary files for external diff */
1116 int againstUndo = 0; /* Diff against files in the undo buffer */
1117 u64 diffFlags = 0; /* Flags to control the DIFF */
1118 FileDirList *pFileDir = 0; /* Restrict the diff to these files */
1119 DiffConfig DCfg; /* Diff configuration object */
1120
1121 if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
1122 diff_tk("diff", 2);
1123 return;
1124 }
@@ -1121,11 +1127,11 @@
1127 zFrom = find_option("from", "r", 1);
1128 zTo = find_option("to", 0, 1);
1129 zCheckin = find_option("checkin", 0, 1);
1130 zBranch = find_option("branch", 0, 1);
1131 againstUndo = find_option("undo",0,0)!=0;
1132 diffFlags = diff_options(&DCfg);
1133 verboseFlag = find_option("verbose","v",0)!=0;
1134 if( !verboseFlag ){
1135 verboseFlag = find_option("new-file","N",0)!=0; /* deprecated */
1136 }
1137 if( verboseFlag ) diffFlags |= DIFF_VERBOSE;
1138
+6 -2
--- src/info.c
+++ src/info.c
@@ -336,10 +336,11 @@
336336
ReCompiled *pRe /* Only show change matching this regex */
337337
){
338338
int fromid;
339339
int toid;
340340
Blob from, to;
341
+ DiffConfig DCfg;
341342
if( zFrom ){
342343
fromid = uuid_to_rid(zFrom, 0);
343344
content_get(fromid, &from);
344345
}else{
345346
blob_zero(&from);
@@ -353,11 +354,12 @@
353354
if( diffFlags & DIFF_SIDEBYSIDE ){
354355
diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
355356
}else{
356357
diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
357358
}
358
- text_diff(&from, &to, cgi_output_blob(), pRe, diffFlags);
359
+ diff_config_init(&DCfg, diffFlags);
360
+ text_diff(&from, &to, cgi_output_blob(), pRe, &DCfg);
359361
blob_reset(&from);
360362
blob_reset(&to);
361363
}
362364
363365
/*
@@ -1768,16 +1770,18 @@
17681770
zRe = P("regex");
17691771
if( zRe ) re_compile(&pRe, zRe, 0);
17701772
if( verbose ) objdescFlags |= OBJDESC_DETAIL;
17711773
if( isPatch ){
17721774
Blob c1, c2, *pOut;
1775
+ DiffConfig DCfg;
17731776
pOut = cgi_output_blob();
17741777
cgi_set_content_type("text/plain");
17751778
diffFlags = 4;
17761779
content_get(v1, &c1);
17771780
content_get(v2, &c2);
1778
- text_diff(&c1, &c2, pOut, pRe, diffFlags);
1781
+ diff_config_init(&DCfg, diffFlags);
1782
+ text_diff(&c1, &c2, pOut, pRe, &DCfg);
17791783
blob_reset(&c1);
17801784
blob_reset(&c2);
17811785
return;
17821786
}
17831787
17841788
--- src/info.c
+++ src/info.c
@@ -336,10 +336,11 @@
336 ReCompiled *pRe /* Only show change matching this regex */
337 ){
338 int fromid;
339 int toid;
340 Blob from, to;
 
341 if( zFrom ){
342 fromid = uuid_to_rid(zFrom, 0);
343 content_get(fromid, &from);
344 }else{
345 blob_zero(&from);
@@ -353,11 +354,12 @@
353 if( diffFlags & DIFF_SIDEBYSIDE ){
354 diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
355 }else{
356 diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
357 }
358 text_diff(&from, &to, cgi_output_blob(), pRe, diffFlags);
 
359 blob_reset(&from);
360 blob_reset(&to);
361 }
362
363 /*
@@ -1768,16 +1770,18 @@
1768 zRe = P("regex");
1769 if( zRe ) re_compile(&pRe, zRe, 0);
1770 if( verbose ) objdescFlags |= OBJDESC_DETAIL;
1771 if( isPatch ){
1772 Blob c1, c2, *pOut;
 
1773 pOut = cgi_output_blob();
1774 cgi_set_content_type("text/plain");
1775 diffFlags = 4;
1776 content_get(v1, &c1);
1777 content_get(v2, &c2);
1778 text_diff(&c1, &c2, pOut, pRe, diffFlags);
 
1779 blob_reset(&c1);
1780 blob_reset(&c2);
1781 return;
1782 }
1783
1784
--- src/info.c
+++ src/info.c
@@ -336,10 +336,11 @@
336 ReCompiled *pRe /* Only show change matching this regex */
337 ){
338 int fromid;
339 int toid;
340 Blob from, to;
341 DiffConfig DCfg;
342 if( zFrom ){
343 fromid = uuid_to_rid(zFrom, 0);
344 content_get(fromid, &from);
345 }else{
346 blob_zero(&from);
@@ -353,11 +354,12 @@
354 if( diffFlags & DIFF_SIDEBYSIDE ){
355 diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
356 }else{
357 diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
358 }
359 diff_config_init(&DCfg, diffFlags);
360 text_diff(&from, &to, cgi_output_blob(), pRe, &DCfg);
361 blob_reset(&from);
362 blob_reset(&to);
363 }
364
365 /*
@@ -1768,16 +1770,18 @@
1770 zRe = P("regex");
1771 if( zRe ) re_compile(&pRe, zRe, 0);
1772 if( verbose ) objdescFlags |= OBJDESC_DETAIL;
1773 if( isPatch ){
1774 Blob c1, c2, *pOut;
1775 DiffConfig DCfg;
1776 pOut = cgi_output_blob();
1777 cgi_set_content_type("text/plain");
1778 diffFlags = 4;
1779 content_get(v1, &c1);
1780 content_get(v2, &c2);
1781 diff_config_init(&DCfg, diffFlags);
1782 text_diff(&c1, &c2, pOut, pRe, &DCfg);
1783 blob_reset(&c1);
1784 blob_reset(&c2);
1785 return;
1786 }
1787
1788
+2 -1
--- src/patch.c
+++ src/patch.c
@@ -952,17 +952,18 @@
952952
const char *zBinGlob = 0;
953953
int fIncludeBinary = 0;
954954
u64 diffFlags;
955955
char *zIn;
956956
unsigned flags = 0;
957
+ DiffConfig DCfg;
957958
958959
if( find_option("tk",0,0)!=0 ){
959960
db_close(0);
960961
diff_tk("patch diff", 3);
961962
return;
962963
}
963
- diffFlags = diff_options();
964
+ diffFlags = diff_options(&DCfg);
964965
if( find_option("internal","i",0)==0
965966
&& (diffFlags & DIFF_HTML)==0
966967
){
967968
zDiffCmd = diff_command_external(zCmd[0]=='g');
968969
}
969970
--- src/patch.c
+++ src/patch.c
@@ -952,17 +952,18 @@
952 const char *zBinGlob = 0;
953 int fIncludeBinary = 0;
954 u64 diffFlags;
955 char *zIn;
956 unsigned flags = 0;
 
957
958 if( find_option("tk",0,0)!=0 ){
959 db_close(0);
960 diff_tk("patch diff", 3);
961 return;
962 }
963 diffFlags = diff_options();
964 if( find_option("internal","i",0)==0
965 && (diffFlags & DIFF_HTML)==0
966 ){
967 zDiffCmd = diff_command_external(zCmd[0]=='g');
968 }
969
--- src/patch.c
+++ src/patch.c
@@ -952,17 +952,18 @@
952 const char *zBinGlob = 0;
953 int fIncludeBinary = 0;
954 u64 diffFlags;
955 char *zIn;
956 unsigned flags = 0;
957 DiffConfig DCfg;
958
959 if( find_option("tk",0,0)!=0 ){
960 db_close(0);
961 diff_tk("patch diff", 3);
962 return;
963 }
964 diffFlags = diff_options(&DCfg);
965 if( find_option("internal","i",0)==0
966 && (diffFlags & DIFF_HTML)==0
967 ){
968 zDiffCmd = diff_command_external(zCmd[0]=='g');
969 }
970
+5 -3
--- src/skins.c
+++ src/skins.c
@@ -869,20 +869,22 @@
869869
@ <input type="submit" name="diff" value="Unified Diff" />
870870
@ <input type="submit" name="sbsdiff" value="Side-by-Side Diff" />
871871
if( P("diff")!=0 || P("sbsdiff")!=0 ){
872872
u64 diffFlags = construct_diff_flags(1) | DIFF_STRIP_EOLCR;
873873
Blob from, to, out;
874
+ DiffConfig DCfg;
874875
if( P("sbsdiff")!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
875876
blob_init(&to, zContent, -1);
876877
blob_init(&from, skin_file_content(zBasis, zFile), -1);
877878
blob_zero(&out);
879
+ diff_config_init(&DCfg, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
878880
if( diffFlags & DIFF_SIDEBYSIDE ){
879
- text_diff(&from, &to, &out, 0, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
881
+ text_diff(&from, &to, &out, 0, &DCfg );
880882
@ %s(blob_str(&out))
881883
}else{
882
- text_diff(&from, &to, &out, 0,
883
- diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
884
+ DCfg.diffFlags |= DIFF_LINENO;
885
+ text_diff(&from, &to, &out, 0, &DCfg);
884886
@ <pre class="udiff">
885887
@ %s(blob_str(&out))
886888
@ </pre>
887889
}
888890
blob_reset(&from);
889891
--- src/skins.c
+++ src/skins.c
@@ -869,20 +869,22 @@
869 @ <input type="submit" name="diff" value="Unified Diff" />
870 @ <input type="submit" name="sbsdiff" value="Side-by-Side Diff" />
871 if( P("diff")!=0 || P("sbsdiff")!=0 ){
872 u64 diffFlags = construct_diff_flags(1) | DIFF_STRIP_EOLCR;
873 Blob from, to, out;
 
874 if( P("sbsdiff")!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
875 blob_init(&to, zContent, -1);
876 blob_init(&from, skin_file_content(zBasis, zFile), -1);
877 blob_zero(&out);
 
878 if( diffFlags & DIFF_SIDEBYSIDE ){
879 text_diff(&from, &to, &out, 0, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
880 @ %s(blob_str(&out))
881 }else{
882 text_diff(&from, &to, &out, 0,
883 diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
884 @ <pre class="udiff">
885 @ %s(blob_str(&out))
886 @ </pre>
887 }
888 blob_reset(&from);
889
--- src/skins.c
+++ src/skins.c
@@ -869,20 +869,22 @@
869 @ <input type="submit" name="diff" value="Unified Diff" />
870 @ <input type="submit" name="sbsdiff" value="Side-by-Side Diff" />
871 if( P("diff")!=0 || P("sbsdiff")!=0 ){
872 u64 diffFlags = construct_diff_flags(1) | DIFF_STRIP_EOLCR;
873 Blob from, to, out;
874 DiffConfig DCfg;
875 if( P("sbsdiff")!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
876 blob_init(&to, zContent, -1);
877 blob_init(&from, skin_file_content(zBasis, zFile), -1);
878 blob_zero(&out);
879 diff_config_init(&DCfg, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
880 if( diffFlags & DIFF_SIDEBYSIDE ){
881 text_diff(&from, &to, &out, 0, &DCfg );
882 @ %s(blob_str(&out))
883 }else{
884 DCfg.diffFlags |= DIFF_LINENO;
885 text_diff(&from, &to, &out, 0, &DCfg);
886 @ <pre class="udiff">
887 @ %s(blob_str(&out))
888 @ </pre>
889 }
890 blob_reset(&from);
891
+2 -1
--- src/stash.c
+++ src/stash.c
@@ -745,20 +745,21 @@
745745
const char *zDiffCmd = 0;
746746
const char *zBinGlob = 0;
747747
int fIncludeBinary = 0;
748748
int fBaseline = 0;
749749
u64 diffFlags;
750
+ DiffConfig DCfg;
750751
751752
if( strstr(zCmd,"show")!=0 || strstr(zCmd,"cat")!=0 ){
752753
fBaseline = 1;
753754
}
754755
if( find_option("tk",0,0)!=0 ){
755756
db_close(0);
756757
diff_tk(fBaseline ? "stash show" : "stash diff", 3);
757758
return;
758759
}
759
- diffFlags = diff_options();
760
+ diffFlags = diff_options(&DCfg);
760761
if( find_option("internal","i",0)==0
761762
&& (diffFlags & DIFF_HTML)==0
762763
){
763764
zDiffCmd = diff_command_external(zCmd[0]=='g');
764765
}
765766
--- src/stash.c
+++ src/stash.c
@@ -745,20 +745,21 @@
745 const char *zDiffCmd = 0;
746 const char *zBinGlob = 0;
747 int fIncludeBinary = 0;
748 int fBaseline = 0;
749 u64 diffFlags;
 
750
751 if( strstr(zCmd,"show")!=0 || strstr(zCmd,"cat")!=0 ){
752 fBaseline = 1;
753 }
754 if( find_option("tk",0,0)!=0 ){
755 db_close(0);
756 diff_tk(fBaseline ? "stash show" : "stash diff", 3);
757 return;
758 }
759 diffFlags = diff_options();
760 if( find_option("internal","i",0)==0
761 && (diffFlags & DIFF_HTML)==0
762 ){
763 zDiffCmd = diff_command_external(zCmd[0]=='g');
764 }
765
--- src/stash.c
+++ src/stash.c
@@ -745,20 +745,21 @@
745 const char *zDiffCmd = 0;
746 const char *zBinGlob = 0;
747 int fIncludeBinary = 0;
748 int fBaseline = 0;
749 u64 diffFlags;
750 DiffConfig DCfg;
751
752 if( strstr(zCmd,"show")!=0 || strstr(zCmd,"cat")!=0 ){
753 fBaseline = 1;
754 }
755 if( find_option("tk",0,0)!=0 ){
756 db_close(0);
757 diff_tk(fBaseline ? "stash show" : "stash diff", 3);
758 return;
759 }
760 diffFlags = diff_options(&DCfg);
761 if( find_option("internal","i",0)==0
762 && (diffFlags & DIFF_HTML)==0
763 ){
764 zDiffCmd = diff_command_external(zCmd[0]=='g');
765 }
766
+3 -1
--- src/wiki.c
+++ src/wiki.c
@@ -1816,10 +1816,11 @@
18161816
const char *zPid;
18171817
Manifest *pW1, *pW2 = 0;
18181818
int rid1, rid2, nextRid;
18191819
Blob w1, w2, d;
18201820
u64 diffFlags;
1821
+ DiffConfig DCfg;
18211822
18221823
login_check_credentials();
18231824
if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
18241825
zId = P("id");
18251826
if( zId==0 ){
@@ -1859,11 +1860,12 @@
18591860
}
18601861
style_set_current_feature("wiki");
18611862
style_header("Changes To %s", pW1->zWikiTitle);
18621863
blob_zero(&d);
18631864
diffFlags = construct_diff_flags(1);
1864
- text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
1865
+ diff_config_init(&DCfg, diffFlags | DIFF_HTML | DIFF_LINENO);
1866
+ text_diff(&w2, &w1, &d, 0, &DCfg);
18651867
@ <pre class="udiff">
18661868
@ %s(blob_str(&d))
18671869
@ <pre>
18681870
manifest_destroy(pW1);
18691871
manifest_destroy(pW2);
18701872
--- src/wiki.c
+++ src/wiki.c
@@ -1816,10 +1816,11 @@
1816 const char *zPid;
1817 Manifest *pW1, *pW2 = 0;
1818 int rid1, rid2, nextRid;
1819 Blob w1, w2, d;
1820 u64 diffFlags;
 
1821
1822 login_check_credentials();
1823 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
1824 zId = P("id");
1825 if( zId==0 ){
@@ -1859,11 +1860,12 @@
1859 }
1860 style_set_current_feature("wiki");
1861 style_header("Changes To %s", pW1->zWikiTitle);
1862 blob_zero(&d);
1863 diffFlags = construct_diff_flags(1);
1864 text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
 
1865 @ <pre class="udiff">
1866 @ %s(blob_str(&d))
1867 @ <pre>
1868 manifest_destroy(pW1);
1869 manifest_destroy(pW2);
1870
--- src/wiki.c
+++ src/wiki.c
@@ -1816,10 +1816,11 @@
1816 const char *zPid;
1817 Manifest *pW1, *pW2 = 0;
1818 int rid1, rid2, nextRid;
1819 Blob w1, w2, d;
1820 u64 diffFlags;
1821 DiffConfig DCfg;
1822
1823 login_check_credentials();
1824 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
1825 zId = P("id");
1826 if( zId==0 ){
@@ -1859,11 +1860,12 @@
1860 }
1861 style_set_current_feature("wiki");
1862 style_header("Changes To %s", pW1->zWikiTitle);
1863 blob_zero(&d);
1864 diffFlags = construct_diff_flags(1);
1865 diff_config_init(&DCfg, diffFlags | DIFF_HTML | DIFF_LINENO);
1866 text_diff(&w2, &w1, &d, 0, &DCfg);
1867 @ <pre class="udiff">
1868 @ %s(blob_str(&d))
1869 @ <pre>
1870 manifest_destroy(pW1);
1871 manifest_destroy(pW2);
1872

Keyboard Shortcuts

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