Fossil SCM

Corrections to line counting in the formatDiff procedure that drives the DiffBuilder object. Remove the test-rawdiff command and substitute and undocumented --raw option on the various diff commands.

drh 2021-08-30 02:36 diff-color-enhancements
Commit 5e70c3ff96d97d392886d2dad0529e0085a612efc97cfa508a3640396de33716
2 files changed +54 -59 +4 -1
+54 -59
--- src/diff.c
+++ src/diff.c
@@ -42,13 +42,14 @@
4242
#define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
4343
#define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
4444
#define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
4545
#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
4646
#define DIFF_SLOW_SBS (((u64)0x20)<<32) /* Better but slower side-by-side */
47
-#define DIFF_WEBPAGE (((u64)0x40)<<32) /* Complete webpage */
48
-#define DIFF_BROWSER (((u64)0x80)<<32) /* The --browser option */
49
-#define DIFF_DEBUG1 (((u64)0x100000)<<32) /* Debugging diff output */
47
+#define DIFF_WEBPAGE (((u64)0x00040)<<32) /* Complete webpage */
48
+#define DIFF_BROWSER (((u64)0x00080)<<32) /* The --browser option */
49
+#define DIFF_DEBUG (((u64)0x00100)<<32) /* Debugging diff output */
50
+#define DIFF_RAW (((u64)0x00200)<<32) /* Raw triples - for debugging */
5051
5152
/*
5253
** These error messages are shared in multiple locations. They are defined
5354
** here for consistency.
5455
*/
@@ -1532,51 +1533,52 @@
15321533
/* Subclass add additional fields */
15331534
};
15341535
15351536
/************************* DiffBuilderDebug ********************************/
15361537
static void dfdebugSkip(DiffBuilder *p, unsigned int n){
1537
- fossil_print("SKIP %d (%d..%d left and %d..%d right)\n",
1538
+ blob_appendf(p->pOut, "SKIP %d (%d..%d left and %d..%d right)\n",
15381539
n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n);
15391540
p->lnLeft += n;
15401541
p->lnRight += n;
15411542
}
15421543
static void dfdebugCommon(DiffBuilder *p, const DLine *pLine){
15431544
p->lnLeft++;
15441545
p->lnRight++;
1545
- fossil_print("COMMON %8u %8u %.*s\n",
1546
+ blob_appendf(p->pOut, "COMMON %8u %8u %.*s\n",
15461547
p->lnLeft, p->lnRight, (int)pLine->n, pLine->z);
15471548
}
15481549
static void dfdebugInsert(DiffBuilder *p, const DLine *pLine){
15491550
p->lnRight++;
1550
- fossil_print("RIGHT %8d %.*s\n",
1551
+ blob_appendf(p->pOut, "RIGHT %8d %.*s\n",
15511552
p->lnRight, (int)pLine->n, pLine->z);
15521553
}
15531554
static void dfdebugDelete(DiffBuilder *p, const DLine *pLine){
15541555
p->lnLeft++;
1555
- fossil_print("LEFT %8u %.*s\n",
1556
+ blob_appendf(p->pOut, "LEFT %8u %.*s\n",
15561557
p->lnLeft, (int)pLine->n, pLine->z);
15571558
}
15581559
static void dfdebugEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
15591560
p->lnLeft++;
15601561
p->lnRight++;
1561
- fossil_print("EDIT %8u %.*s\n %8u %.*s\n",
1562
+ blob_appendf(p->pOut, "EDIT %8u %.*s\n %8u %.*s\n",
15621563
p->lnLeft, (int)pX->n, pX->z, p->lnRight, (int)pY->n, pY->z);
15631564
}
15641565
static void dfdebugEnd(DiffBuilder *p){
1565
- fossil_print("END with %u lines left and %u lines right\n",
1566
+ blob_appendf(p->pOut, "END with %u lines left and %u lines right\n",
15661567
p->lnLeft, p->lnRight);
15671568
fossil_free(p);
15681569
}
1569
-static DiffBuilder *dfdebugNew(void){
1570
+static DiffBuilder *dfdebugNew(Blob *pOut){
15701571
DiffBuilder *p = fossil_malloc(sizeof(*p));
15711572
p->xSkip = dfdebugSkip;
15721573
p->xCommon = dfdebugCommon;
15731574
p->xInsert = dfdebugInsert;
15741575
p->xDelete = dfdebugDelete;
15751576
p->xEdit = dfdebugEdit;
15761577
p->xEnd = dfdebugEnd;
15771578
p->lnLeft = p->lnRight = 0;
1579
+ p->pOut = pOut;
15781580
return p;
15791581
}
15801582
/****************************************************************************/
15811583
15821584
/*
@@ -1597,11 +1599,11 @@
15971599
unsigned int nr; /* Number of COPY/DELETE/INSERT triples to process */
15981600
unsigned int mxr; /* Maximum value for r */
15991601
unsigned int na, nb; /* Number of lines shown from A and B */
16001602
unsigned int i, j; /* Loop counters */
16011603
unsigned int m, ma, mb;/* Number of lines to output */
1602
- unsigned int skip; /* Number of lines to skip */
1604
+ signed int skip = 0; /* Number of lines to skip */
16031605
unsigned int nContext; /* Lines of context above and below each change */
16041606
16051607
nContext = diff_context_lines(diffFlags);
16061608
A = p->aFrom;
16071609
B = p->aTo;
@@ -1636,12 +1638,12 @@
16361638
b = xb;
16371639
continue;
16381640
}
16391641
}
16401642
1641
- /* For the current block comprising nr triples, figure out
1642
- ** how many lines of A and B are to be displayed
1643
+ /* Figure out how many lines of A and B are to be displayed
1644
+ ** for this change block.
16431645
*/
16441646
if( R[r]>nContext ){
16451647
na = nb = nContext;
16461648
skip = R[r] - nContext;
16471649
}else{
@@ -1662,18 +1664,18 @@
16621664
for(i=1; i<nr; i++){
16631665
na += R[r+i*3];
16641666
nb += R[r+i*3];
16651667
}
16661668
1667
- if( skip>0 ){
1668
- pBuilder->xSkip(pBuilder, skip);
1669
- }
1670
-
16711669
/* Show the initial common area */
16721670
a += skip;
16731671
b += skip;
16741672
m = R[r] - skip;
1673
+ if( r ) skip -= nContext;
1674
+ if( skip>0 ){
1675
+ pBuilder->xSkip(pBuilder, skip);
1676
+ }
16751677
for(j=0; j<m; j++){
16761678
pBuilder->xCommon(pBuilder, &A[a+j]);
16771679
}
16781680
a += m;
16791681
b += m;
@@ -1720,14 +1722,17 @@
17201722
17211723
/* Show the final common area */
17221724
assert( nr==i );
17231725
m = R[r+nr*3];
17241726
if( m>nContext ) m = nContext;
1725
- for(j=0; j<m; j++){
1727
+ for(j=0; j<m && j<nContext; j++){
17261728
pBuilder->xCommon(pBuilder, &A[a+j]);
17271729
}
17281730
}
1731
+ if( R[r]>nContext ){
1732
+ pBuilder->xSkip(pBuilder, R[r] - nContext);
1733
+ }
17291734
pBuilder->xEnd(pBuilder);
17301735
}
17311736
17321737
17331738
/*
@@ -2170,18 +2175,26 @@
21702175
blob_append(pOut, msg, -1);
21712176
}
21722177
}
21732178
21742179
/*
2175
-** Generate a report of the differences between files pA and pB.
2176
-** If pOut is not NULL then a unified diff is appended there. It
2177
-** is assumed that pOut has already been initialized. If pOut is
2178
-** NULL, then a pointer to an array of integers is returned.
2179
-** The integers come in triples. For each triple,
2180
-** the elements are the number of lines copied, the number of
2181
-** lines deleted, and the number of lines inserted. The vector
2182
-** is terminated by a triple of all zeros.
2180
+** Generate a report of the differences between files pA_Blob and pB_Blob.
2181
+**
2182
+** If pOut!=NULL then append text to pOut that will be the difference,
2183
+** formatted according to flags in diffFlags. The pOut Blob must have
2184
+** already been initialized.
2185
+**
2186
+** If pOut==NULL then no formatting occurs. Instead, this routine
2187
+** returns a pointer to an array of integers. The integers come in
2188
+** triples. The elements of each triple are:
2189
+**
2190
+** 1. The number of lines to copy
2191
+** 2. The number of lines to delete
2192
+** 3. The number of lines to insert
2193
+**
2194
+** The return vector is terminated bin a triple of all zeros. The caller
2195
+** should free the returned vector using fossil_free().
21832196
**
21842197
** This diff utility does not work on binary files. If a binary
21852198
** file is encountered, 0 is returned and pOut is written with
21862199
** text "cannot compute difference between binary files".
21872200
*/
@@ -2261,14 +2274,21 @@
22612274
g.diffCnt[2] += nDel;
22622275
if( nIns+nDel ){
22632276
g.diffCnt[0]++;
22642277
blob_appendf(pOut, "%10d %10d", nIns, nDel);
22652278
}
2279
+ }else if( diffFlags & DIFF_RAW ){
2280
+ const int *R = c.aEdit;
2281
+ unsigned int r;
2282
+ for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2283
+ blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
2284
+ R[r], R[r+1], R[r+2]);
2285
+ }
22662286
}else if( diffFlags & DIFF_SIDEBYSIDE ){
22672287
sbsDiff(&c, pOut, pRe, diffFlags);
2268
- }else if( diffFlags & DIFF_DEBUG1 ){
2269
- DiffBuilder *pBuilder = dfdebugNew();
2288
+ }else if( diffFlags & DIFF_DEBUG ){
2289
+ DiffBuilder *pBuilder = dfdebugNew(pOut);
22702290
formatDiff(&c, pRe, diffFlags, pBuilder);
22712291
}else{
22722292
contextDiff(&c, pOut, pRe, diffFlags);
22732293
}
22742294
fossil_free(c.aFrom);
@@ -2344,40 +2364,16 @@
23442364
}
23452365
if( find_option("by",0,0)!=0 ){
23462366
diffFlags |= DIFF_HTML|DIFF_WEBPAGE|DIFF_LINENO|DIFF_BROWSER
23472367
|DIFF_SIDEBYSIDE;
23482368
}
2349
- return diffFlags;
2350
-}
2351
-
2352
-/*
2353
-** COMMAND: test-rawdiff
2354
-**
2355
-** Usage: %fossil test-rawdiff FILE1 FILE2
2356
-**
2357
-** Show a minimal sequence of Copy/Delete/Insert operations needed to convert
2358
-** FILE1 into FILE2. This command is intended for use in testing and debugging
2359
-** the built-in difference engine of Fossil.
2360
-*/
2361
-void test_rawdiff_cmd(void){
2362
- Blob a, b;
2363
- int r;
2364
- int i;
2365
- int *R;
2366
- u64 diffFlags = diff_options();
2367
- if( g.argc<4 ) usage("FILE1 FILE2 ...");
2368
- blob_read_from_file(&a, g.argv[2], ExtFILE);
2369
- for(i=3; i<g.argc; i++){
2370
- if( i>3 ) fossil_print("-------------------------------\n");
2371
- blob_read_from_file(&b, g.argv[i], ExtFILE);
2372
- R = text_diff(&a, &b, 0, 0, diffFlags);
2373
- for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2374
- fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
2375
- }
2376
- /* free(R); */
2377
- blob_reset(&b);
2378
- }
2369
+
2370
+ /* Undocumented and unsupported flags used for development
2371
+ ** debugging and analysis: */
2372
+ if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
2373
+ if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
2374
+ return diffFlags;
23792375
}
23802376
23812377
/*
23822378
** COMMAND: test-diff
23832379
**
@@ -2401,11 +2397,10 @@
24012397
if( zRe ){
24022398
const char *zErr = re_compile(&pRe, zRe, 0);
24032399
if( zErr ) fossil_fatal("regex error: %s", zErr);
24042400
}
24052401
diffFlag = diff_options();
2406
- if( find_option("debug",0,0)!=0 ) diffFlag |= DIFF_DEBUG1;
24072402
verify_all_options();
24082403
if( g.argc!=4 ) usage("FILE1 FILE2");
24092404
blob_zero(&out);
24102405
diff_begin(diffFlag);
24112406
diff_print_filenames(g.argv[2], g.argv[3], diffFlag, &out);
24122407
--- src/diff.c
+++ src/diff.c
@@ -42,13 +42,14 @@
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45 #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
46 #define DIFF_SLOW_SBS (((u64)0x20)<<32) /* Better but slower side-by-side */
47 #define DIFF_WEBPAGE (((u64)0x40)<<32) /* Complete webpage */
48 #define DIFF_BROWSER (((u64)0x80)<<32) /* The --browser option */
49 #define DIFF_DEBUG1 (((u64)0x100000)<<32) /* Debugging diff output */
 
50
51 /*
52 ** These error messages are shared in multiple locations. They are defined
53 ** here for consistency.
54 */
@@ -1532,51 +1533,52 @@
1532 /* Subclass add additional fields */
1533 };
1534
1535 /************************* DiffBuilderDebug ********************************/
1536 static void dfdebugSkip(DiffBuilder *p, unsigned int n){
1537 fossil_print("SKIP %d (%d..%d left and %d..%d right)\n",
1538 n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n);
1539 p->lnLeft += n;
1540 p->lnRight += n;
1541 }
1542 static void dfdebugCommon(DiffBuilder *p, const DLine *pLine){
1543 p->lnLeft++;
1544 p->lnRight++;
1545 fossil_print("COMMON %8u %8u %.*s\n",
1546 p->lnLeft, p->lnRight, (int)pLine->n, pLine->z);
1547 }
1548 static void dfdebugInsert(DiffBuilder *p, const DLine *pLine){
1549 p->lnRight++;
1550 fossil_print("RIGHT %8d %.*s\n",
1551 p->lnRight, (int)pLine->n, pLine->z);
1552 }
1553 static void dfdebugDelete(DiffBuilder *p, const DLine *pLine){
1554 p->lnLeft++;
1555 fossil_print("LEFT %8u %.*s\n",
1556 p->lnLeft, (int)pLine->n, pLine->z);
1557 }
1558 static void dfdebugEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1559 p->lnLeft++;
1560 p->lnRight++;
1561 fossil_print("EDIT %8u %.*s\n %8u %.*s\n",
1562 p->lnLeft, (int)pX->n, pX->z, p->lnRight, (int)pY->n, pY->z);
1563 }
1564 static void dfdebugEnd(DiffBuilder *p){
1565 fossil_print("END with %u lines left and %u lines right\n",
1566 p->lnLeft, p->lnRight);
1567 fossil_free(p);
1568 }
1569 static DiffBuilder *dfdebugNew(void){
1570 DiffBuilder *p = fossil_malloc(sizeof(*p));
1571 p->xSkip = dfdebugSkip;
1572 p->xCommon = dfdebugCommon;
1573 p->xInsert = dfdebugInsert;
1574 p->xDelete = dfdebugDelete;
1575 p->xEdit = dfdebugEdit;
1576 p->xEnd = dfdebugEnd;
1577 p->lnLeft = p->lnRight = 0;
 
1578 return p;
1579 }
1580 /****************************************************************************/
1581
1582 /*
@@ -1597,11 +1599,11 @@
1597 unsigned int nr; /* Number of COPY/DELETE/INSERT triples to process */
1598 unsigned int mxr; /* Maximum value for r */
1599 unsigned int na, nb; /* Number of lines shown from A and B */
1600 unsigned int i, j; /* Loop counters */
1601 unsigned int m, ma, mb;/* Number of lines to output */
1602 unsigned int skip; /* Number of lines to skip */
1603 unsigned int nContext; /* Lines of context above and below each change */
1604
1605 nContext = diff_context_lines(diffFlags);
1606 A = p->aFrom;
1607 B = p->aTo;
@@ -1636,12 +1638,12 @@
1636 b = xb;
1637 continue;
1638 }
1639 }
1640
1641 /* For the current block comprising nr triples, figure out
1642 ** how many lines of A and B are to be displayed
1643 */
1644 if( R[r]>nContext ){
1645 na = nb = nContext;
1646 skip = R[r] - nContext;
1647 }else{
@@ -1662,18 +1664,18 @@
1662 for(i=1; i<nr; i++){
1663 na += R[r+i*3];
1664 nb += R[r+i*3];
1665 }
1666
1667 if( skip>0 ){
1668 pBuilder->xSkip(pBuilder, skip);
1669 }
1670
1671 /* Show the initial common area */
1672 a += skip;
1673 b += skip;
1674 m = R[r] - skip;
 
 
 
 
1675 for(j=0; j<m; j++){
1676 pBuilder->xCommon(pBuilder, &A[a+j]);
1677 }
1678 a += m;
1679 b += m;
@@ -1720,14 +1722,17 @@
1720
1721 /* Show the final common area */
1722 assert( nr==i );
1723 m = R[r+nr*3];
1724 if( m>nContext ) m = nContext;
1725 for(j=0; j<m; j++){
1726 pBuilder->xCommon(pBuilder, &A[a+j]);
1727 }
1728 }
 
 
 
1729 pBuilder->xEnd(pBuilder);
1730 }
1731
1732
1733 /*
@@ -2170,18 +2175,26 @@
2170 blob_append(pOut, msg, -1);
2171 }
2172 }
2173
2174 /*
2175 ** Generate a report of the differences between files pA and pB.
2176 ** If pOut is not NULL then a unified diff is appended there. It
2177 ** is assumed that pOut has already been initialized. If pOut is
2178 ** NULL, then a pointer to an array of integers is returned.
2179 ** The integers come in triples. For each triple,
2180 ** the elements are the number of lines copied, the number of
2181 ** lines deleted, and the number of lines inserted. The vector
2182 ** is terminated by a triple of all zeros.
 
 
 
 
 
 
 
 
2183 **
2184 ** This diff utility does not work on binary files. If a binary
2185 ** file is encountered, 0 is returned and pOut is written with
2186 ** text "cannot compute difference between binary files".
2187 */
@@ -2261,14 +2274,21 @@
2261 g.diffCnt[2] += nDel;
2262 if( nIns+nDel ){
2263 g.diffCnt[0]++;
2264 blob_appendf(pOut, "%10d %10d", nIns, nDel);
2265 }
 
 
 
 
 
 
 
2266 }else if( diffFlags & DIFF_SIDEBYSIDE ){
2267 sbsDiff(&c, pOut, pRe, diffFlags);
2268 }else if( diffFlags & DIFF_DEBUG1 ){
2269 DiffBuilder *pBuilder = dfdebugNew();
2270 formatDiff(&c, pRe, diffFlags, pBuilder);
2271 }else{
2272 contextDiff(&c, pOut, pRe, diffFlags);
2273 }
2274 fossil_free(c.aFrom);
@@ -2344,40 +2364,16 @@
2344 }
2345 if( find_option("by",0,0)!=0 ){
2346 diffFlags |= DIFF_HTML|DIFF_WEBPAGE|DIFF_LINENO|DIFF_BROWSER
2347 |DIFF_SIDEBYSIDE;
2348 }
2349 return diffFlags;
2350 }
2351
2352 /*
2353 ** COMMAND: test-rawdiff
2354 **
2355 ** Usage: %fossil test-rawdiff FILE1 FILE2
2356 **
2357 ** Show a minimal sequence of Copy/Delete/Insert operations needed to convert
2358 ** FILE1 into FILE2. This command is intended for use in testing and debugging
2359 ** the built-in difference engine of Fossil.
2360 */
2361 void test_rawdiff_cmd(void){
2362 Blob a, b;
2363 int r;
2364 int i;
2365 int *R;
2366 u64 diffFlags = diff_options();
2367 if( g.argc<4 ) usage("FILE1 FILE2 ...");
2368 blob_read_from_file(&a, g.argv[2], ExtFILE);
2369 for(i=3; i<g.argc; i++){
2370 if( i>3 ) fossil_print("-------------------------------\n");
2371 blob_read_from_file(&b, g.argv[i], ExtFILE);
2372 R = text_diff(&a, &b, 0, 0, diffFlags);
2373 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2374 fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
2375 }
2376 /* free(R); */
2377 blob_reset(&b);
2378 }
2379 }
2380
2381 /*
2382 ** COMMAND: test-diff
2383 **
@@ -2401,11 +2397,10 @@
2401 if( zRe ){
2402 const char *zErr = re_compile(&pRe, zRe, 0);
2403 if( zErr ) fossil_fatal("regex error: %s", zErr);
2404 }
2405 diffFlag = diff_options();
2406 if( find_option("debug",0,0)!=0 ) diffFlag |= DIFF_DEBUG1;
2407 verify_all_options();
2408 if( g.argc!=4 ) usage("FILE1 FILE2");
2409 blob_zero(&out);
2410 diff_begin(diffFlag);
2411 diff_print_filenames(g.argv[2], g.argv[3], diffFlag, &out);
2412
--- src/diff.c
+++ src/diff.c
@@ -42,13 +42,14 @@
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45 #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
46 #define DIFF_SLOW_SBS (((u64)0x20)<<32) /* Better but slower side-by-side */
47 #define DIFF_WEBPAGE (((u64)0x00040)<<32) /* Complete webpage */
48 #define DIFF_BROWSER (((u64)0x00080)<<32) /* The --browser option */
49 #define DIFF_DEBUG (((u64)0x00100)<<32) /* Debugging diff output */
50 #define DIFF_RAW (((u64)0x00200)<<32) /* Raw triples - for debugging */
51
52 /*
53 ** These error messages are shared in multiple locations. They are defined
54 ** here for consistency.
55 */
@@ -1532,51 +1533,52 @@
1533 /* Subclass add additional fields */
1534 };
1535
1536 /************************* DiffBuilderDebug ********************************/
1537 static void dfdebugSkip(DiffBuilder *p, unsigned int n){
1538 blob_appendf(p->pOut, "SKIP %d (%d..%d left and %d..%d right)\n",
1539 n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n);
1540 p->lnLeft += n;
1541 p->lnRight += n;
1542 }
1543 static void dfdebugCommon(DiffBuilder *p, const DLine *pLine){
1544 p->lnLeft++;
1545 p->lnRight++;
1546 blob_appendf(p->pOut, "COMMON %8u %8u %.*s\n",
1547 p->lnLeft, p->lnRight, (int)pLine->n, pLine->z);
1548 }
1549 static void dfdebugInsert(DiffBuilder *p, const DLine *pLine){
1550 p->lnRight++;
1551 blob_appendf(p->pOut, "RIGHT %8d %.*s\n",
1552 p->lnRight, (int)pLine->n, pLine->z);
1553 }
1554 static void dfdebugDelete(DiffBuilder *p, const DLine *pLine){
1555 p->lnLeft++;
1556 blob_appendf(p->pOut, "LEFT %8u %.*s\n",
1557 p->lnLeft, (int)pLine->n, pLine->z);
1558 }
1559 static void dfdebugEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1560 p->lnLeft++;
1561 p->lnRight++;
1562 blob_appendf(p->pOut, "EDIT %8u %.*s\n %8u %.*s\n",
1563 p->lnLeft, (int)pX->n, pX->z, p->lnRight, (int)pY->n, pY->z);
1564 }
1565 static void dfdebugEnd(DiffBuilder *p){
1566 blob_appendf(p->pOut, "END with %u lines left and %u lines right\n",
1567 p->lnLeft, p->lnRight);
1568 fossil_free(p);
1569 }
1570 static DiffBuilder *dfdebugNew(Blob *pOut){
1571 DiffBuilder *p = fossil_malloc(sizeof(*p));
1572 p->xSkip = dfdebugSkip;
1573 p->xCommon = dfdebugCommon;
1574 p->xInsert = dfdebugInsert;
1575 p->xDelete = dfdebugDelete;
1576 p->xEdit = dfdebugEdit;
1577 p->xEnd = dfdebugEnd;
1578 p->lnLeft = p->lnRight = 0;
1579 p->pOut = pOut;
1580 return p;
1581 }
1582 /****************************************************************************/
1583
1584 /*
@@ -1597,11 +1599,11 @@
1599 unsigned int nr; /* Number of COPY/DELETE/INSERT triples to process */
1600 unsigned int mxr; /* Maximum value for r */
1601 unsigned int na, nb; /* Number of lines shown from A and B */
1602 unsigned int i, j; /* Loop counters */
1603 unsigned int m, ma, mb;/* Number of lines to output */
1604 signed int skip = 0; /* Number of lines to skip */
1605 unsigned int nContext; /* Lines of context above and below each change */
1606
1607 nContext = diff_context_lines(diffFlags);
1608 A = p->aFrom;
1609 B = p->aTo;
@@ -1636,12 +1638,12 @@
1638 b = xb;
1639 continue;
1640 }
1641 }
1642
1643 /* Figure out how many lines of A and B are to be displayed
1644 ** for this change block.
1645 */
1646 if( R[r]>nContext ){
1647 na = nb = nContext;
1648 skip = R[r] - nContext;
1649 }else{
@@ -1662,18 +1664,18 @@
1664 for(i=1; i<nr; i++){
1665 na += R[r+i*3];
1666 nb += R[r+i*3];
1667 }
1668
 
 
 
 
1669 /* Show the initial common area */
1670 a += skip;
1671 b += skip;
1672 m = R[r] - skip;
1673 if( r ) skip -= nContext;
1674 if( skip>0 ){
1675 pBuilder->xSkip(pBuilder, skip);
1676 }
1677 for(j=0; j<m; j++){
1678 pBuilder->xCommon(pBuilder, &A[a+j]);
1679 }
1680 a += m;
1681 b += m;
@@ -1720,14 +1722,17 @@
1722
1723 /* Show the final common area */
1724 assert( nr==i );
1725 m = R[r+nr*3];
1726 if( m>nContext ) m = nContext;
1727 for(j=0; j<m && j<nContext; j++){
1728 pBuilder->xCommon(pBuilder, &A[a+j]);
1729 }
1730 }
1731 if( R[r]>nContext ){
1732 pBuilder->xSkip(pBuilder, R[r] - nContext);
1733 }
1734 pBuilder->xEnd(pBuilder);
1735 }
1736
1737
1738 /*
@@ -2170,18 +2175,26 @@
2175 blob_append(pOut, msg, -1);
2176 }
2177 }
2178
2179 /*
2180 ** Generate a report of the differences between files pA_Blob and pB_Blob.
2181 **
2182 ** If pOut!=NULL then append text to pOut that will be the difference,
2183 ** formatted according to flags in diffFlags. The pOut Blob must have
2184 ** already been initialized.
2185 **
2186 ** If pOut==NULL then no formatting occurs. Instead, this routine
2187 ** returns a pointer to an array of integers. The integers come in
2188 ** triples. The elements of each triple are:
2189 **
2190 ** 1. The number of lines to copy
2191 ** 2. The number of lines to delete
2192 ** 3. The number of lines to insert
2193 **
2194 ** The return vector is terminated bin a triple of all zeros. The caller
2195 ** should free the returned vector using fossil_free().
2196 **
2197 ** This diff utility does not work on binary files. If a binary
2198 ** file is encountered, 0 is returned and pOut is written with
2199 ** text "cannot compute difference between binary files".
2200 */
@@ -2261,14 +2274,21 @@
2274 g.diffCnt[2] += nDel;
2275 if( nIns+nDel ){
2276 g.diffCnt[0]++;
2277 blob_appendf(pOut, "%10d %10d", nIns, nDel);
2278 }
2279 }else if( diffFlags & DIFF_RAW ){
2280 const int *R = c.aEdit;
2281 unsigned int r;
2282 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2283 blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
2284 R[r], R[r+1], R[r+2]);
2285 }
2286 }else if( diffFlags & DIFF_SIDEBYSIDE ){
2287 sbsDiff(&c, pOut, pRe, diffFlags);
2288 }else if( diffFlags & DIFF_DEBUG ){
2289 DiffBuilder *pBuilder = dfdebugNew(pOut);
2290 formatDiff(&c, pRe, diffFlags, pBuilder);
2291 }else{
2292 contextDiff(&c, pOut, pRe, diffFlags);
2293 }
2294 fossil_free(c.aFrom);
@@ -2344,40 +2364,16 @@
2364 }
2365 if( find_option("by",0,0)!=0 ){
2366 diffFlags |= DIFF_HTML|DIFF_WEBPAGE|DIFF_LINENO|DIFF_BROWSER
2367 |DIFF_SIDEBYSIDE;
2368 }
2369
2370 /* Undocumented and unsupported flags used for development
2371 ** debugging and analysis: */
2372 if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
2373 if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
2374 return diffFlags;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2375 }
2376
2377 /*
2378 ** COMMAND: test-diff
2379 **
@@ -2401,11 +2397,10 @@
2397 if( zRe ){
2398 const char *zErr = re_compile(&pRe, zRe, 0);
2399 if( zErr ) fossil_fatal("regex error: %s", zErr);
2400 }
2401 diffFlag = diff_options();
 
2402 verify_all_options();
2403 if( g.argc!=4 ) usage("FILE1 FILE2");
2404 blob_zero(&out);
2405 diff_begin(diffFlag);
2406 diff_print_filenames(g.argv[2], g.argv[3], diffFlag, &out);
2407
+4 -1
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -135,12 +135,15 @@
135135
const char *zRight,
136136
u64 diffFlags,
137137
Blob *diffBlob
138138
){
139139
char *z = 0;
140
- if( diffFlags & (DIFF_BRIEF|DIFF_DEBUG1) ){
140
+ if( diffFlags & (DIFF_BRIEF|DIFF_RAW) ){
141141
/* no-op */
142
+ }else if( diffFlags & DIFF_DEBUG ){
143
+ fossil_print("FILE-LEFT %s\nFILE-RIGHT %s\n",
144
+ zLeft, zRight);
142145
}else if( diffFlags & DIFF_WEBPAGE ){
143146
if( fossil_strcmp(zLeft,zRight)==0 ){
144147
z = mprintf("<h1>%h</h1>\n", zLeft);
145148
}else{
146149
z = mprintf("<h1>%h &lrarr; %h</h1>\n", zLeft, zRight);
147150
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -135,12 +135,15 @@
135 const char *zRight,
136 u64 diffFlags,
137 Blob *diffBlob
138 ){
139 char *z = 0;
140 if( diffFlags & (DIFF_BRIEF|DIFF_DEBUG1) ){
141 /* no-op */
 
 
 
142 }else if( diffFlags & DIFF_WEBPAGE ){
143 if( fossil_strcmp(zLeft,zRight)==0 ){
144 z = mprintf("<h1>%h</h1>\n", zLeft);
145 }else{
146 z = mprintf("<h1>%h &lrarr; %h</h1>\n", zLeft, zRight);
147
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -135,12 +135,15 @@
135 const char *zRight,
136 u64 diffFlags,
137 Blob *diffBlob
138 ){
139 char *z = 0;
140 if( diffFlags & (DIFF_BRIEF|DIFF_RAW) ){
141 /* no-op */
142 }else if( diffFlags & DIFF_DEBUG ){
143 fossil_print("FILE-LEFT %s\nFILE-RIGHT %s\n",
144 zLeft, zRight);
145 }else if( diffFlags & DIFF_WEBPAGE ){
146 if( fossil_strcmp(zLeft,zRight)==0 ){
147 z = mprintf("<h1>%h</h1>\n", zLeft);
148 }else{
149 z = mprintf("<h1>%h &lrarr; %h</h1>\n", zLeft, zRight);
150

Keyboard Shortcuts

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