Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Begin adding value that used to be function arguments into the DiffConfig object. This check-in deals with the pRe parameter. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | diff-config |
| Files: | files | file ages | folders |
| SHA3-256: |
bdb4bfaa3a69bdf3129c8f7f2353e20d |
| User & Date: | drh 2021-09-06 20:51:15.508 |
Context
|
2021-09-06
| ||
| 22:24 | For the --json diff output, generate an array of objects, one object per file and the diff array all contained within the object. ... (Closed-Leaf check-in: 4ab3525927 user: drh tags: diff-config) | |
| 20:51 | Begin adding value that used to be function arguments into the DiffConfig object. This check-in deals with the pRe parameter. ... (check-in: bdb4bfaa3a user: drh tags: diff-config) | |
| 19:24 | Futher integration of DiffConfig up and down the diff stack. ... (check-in: 7c1498aeff user: drh tags: diff-config) | |
Changes
Changes to src/ajax.c.
| ︙ | ︙ | |||
153 154 155 156 157 158 159 |
** set of flags suitable for passing to text_diff().
*/
void ajax_render_diff(Blob * pOrig, Blob *pContent, u64 diffFlags){
Blob out = empty_blob;
DiffConfig DCfg;
diff_config_init(&DCfg, diffFlags);
| | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
** set of flags suitable for passing to text_diff().
*/
void ajax_render_diff(Blob * pOrig, Blob *pContent, u64 diffFlags){
Blob out = empty_blob;
DiffConfig DCfg;
diff_config_init(&DCfg, diffFlags);
text_diff(pOrig, pContent, &out, &DCfg);
if(blob_size(&out)==0){
/* nothing to do */
}else if(DIFF_SIDEBYSIDE & diffFlags){
CX("%b",&out);
}else{
CX("<pre class='udiff'>%b</pre>",&out);
}
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
88 89 90 91 92 93 94 |
** TCL, JSON, HTML vs. plain-text).
**
** * Number of lines of context surrounding each difference block
**
** * Width of output columns for text side-by-side diffop
*/
struct DiffConfig {
| | > > > > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
** TCL, JSON, HTML vs. plain-text).
**
** * Number of lines of context surrounding each difference block
**
** * Width of output columns for text side-by-side diffop
*/
struct DiffConfig {
u64 diffFlags; /* Diff flags */
u32 nFile; /* Number of files diffed so far */
const char *zDiffCmd; /* External diff command to use instead of builtin */
const char *zBinGlob; /* GLOB pattern for binary files */
ReCompiled *pRe; /* Show only changes matching this pattern */
};
#endif /* INTERFACE */
/*
** Initialize memory for a DiffConfig based on just a diffFlags integer.
*/
|
| ︙ | ︙ | |||
1967 1968 1969 1970 1971 1972 1973 | } /* ** Format a diff using a DiffBuilder object */ static void formatDiff( DContext *p, /* The computed diff */ | < | 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 |
}
/*
** Format a diff using a DiffBuilder object
*/
static void formatDiff(
DContext *p, /* The computed diff */
DiffConfig *pCfg, /* Configuration options */
DiffBuilder *pBuilder /* The formatter object */
){
const DLine *A; /* Left side of the diff */
const DLine *B; /* Right side of the diff */
unsigned int a = 0; /* Index of next line in A[] */
unsigned int b = 0; /* Index of next line in B[] */
|
| ︙ | ︙ | |||
2001 2002 2003 2004 2005 2006 2007 |
for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
/* If there is a regex, skip this block (generate no diff output)
** if the regex matches or does not match both insert and delete.
** Only display the block if one side matches but the other side does
** not.
*/
| | | | | 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 |
for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
/* If there is a regex, skip this block (generate no diff output)
** if the regex matches or does not match both insert and delete.
** Only display the block if one side matches but the other side does
** not.
*/
if( pCfg->pRe ){
int hideBlock = 1;
int xa = a, xb = b;
for(i=0; hideBlock && i<nr; i++){
int c1, c2;
xa += R[r+i*3];
xb += R[r+i*3];
c1 = re_dline_match(pCfg->pRe, &A[xa], R[r+i*3+1]);
c2 = re_dline_match(pCfg->pRe, &B[xb], R[r+i*3+2]);
hideBlock = c1==c2;
xa += R[r+i*3+1];
xb += R[r+i*3+2];
}
if( hideBlock ){
a = xa;
b = xb;
|
| ︙ | ︙ | |||
2618 2619 2620 2621 2622 2623 2624 | ** file is encountered, 0 is returned and pOut is written with ** text "cannot compute difference between binary files". */ int *text_diff( Blob *pA_Blob, /* FROM file */ Blob *pB_Blob, /* TO file */ Blob *pOut, /* Write diff here if not NULL */ | < > | 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 |
** file is encountered, 0 is returned and pOut is written with
** text "cannot compute difference between binary files".
*/
int *text_diff(
Blob *pA_Blob, /* FROM file */
Blob *pB_Blob, /* TO file */
Blob *pOut, /* Write diff here if not NULL */
DiffConfig *pCfg /* Configuration options */
){
int ignoreWs; /* Ignore whitespace */
DContext c;
pCfg->nFile++;
if( pCfg->diffFlags & DIFF_INVERT ){
Blob *pTemp = pA_Blob;
pA_Blob = pB_Blob;
pB_Blob = pTemp;
}
ignoreWs = (pCfg->diffFlags & DIFF_IGNORE_ALLWS)!=0;
blob_to_utf8_no_bom(pA_Blob, 0);
|
| ︙ | ︙ | |||
2701 2702 2703 2704 2705 2706 2707 |
unsigned int r;
for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
R[r], R[r+1], R[r+2]);
}
}else if( pCfg->diffFlags & DIFF_JSON ){
DiffBuilder *pBuilder = dfjsonNew(pOut);
| | | | | | | 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 |
unsigned int r;
for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
R[r], R[r+1], R[r+2]);
}
}else if( pCfg->diffFlags & DIFF_JSON ){
DiffBuilder *pBuilder = dfjsonNew(pOut);
formatDiff(&c, pCfg, pBuilder);
blob_append_char(pOut, '\n');
}else if( pCfg->diffFlags & DIFF_TCL ){
DiffBuilder *pBuilder = dftclNew(pOut);
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
DiffBuilder *pBuilder;
if( pCfg->diffFlags & DIFF_HTML ){
pBuilder = dfsplitNew(pOut);
}else{
pBuilder = dfsbsNew(pOut, pCfg);
}
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_DEBUG ){
DiffBuilder *pBuilder = dfdebugNew(pOut);
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_HTML ){
DiffBuilder *pBuilder = dfunifiedNew(pOut);
formatDiff(&c, pCfg, pBuilder);
}else{
contextDiff(&c, pOut, pCfg);
}
fossil_free(c.aFrom);
fossil_free(c.aTo);
fossil_free(c.aEdit);
return 0;
|
| ︙ | ︙ | |||
2838 2839 2840 2841 2842 2843 2844 |
**
** This command used to be called "test-diff". The older "test-diff" spelling
** still works, for compatibility.
*/
void xdiff_cmd(void){
Blob a, b, out;
const char *zRe; /* Regex filter for diff output */
| < > | < | | | 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 |
**
** This command used to be called "test-diff". The older "test-diff" spelling
** still works, for compatibility.
*/
void xdiff_cmd(void){
Blob a, b, out;
const char *zRe; /* Regex filter for diff output */
DiffConfig DCfg;
if( find_option("tk",0,0)!=0 ){
diff_tk("xdiff", 2);
return;
}
find_option("i",0,0);
find_option("v",0,0);
diff_options(&DCfg, 0);
zRe = find_option("regexp","e",1);
if( zRe ){
const char *zErr = re_compile(&DCfg.pRe, zRe, 0);
if( zErr ) fossil_fatal("regex error: %s", zErr);
}
verify_all_options();
if( g.argc!=4 ) usage("FILE1 FILE2");
blob_zero(&out);
diff_begin(&DCfg);
diff_print_filenames(g.argv[2], g.argv[3], &DCfg, &out);
blob_read_from_file(&a, g.argv[2], ExtFILE);
blob_read_from_file(&b, g.argv[3], ExtFILE);
text_diff(&a, &b, &out, &DCfg);
blob_write_to_file(&out, "-");
diff_end(&DCfg, 0);
re_free(DCfg.pRe);
}
/**************************************************************************
** The basic difference engine is above. What follows is the annotation
** engine. Both are in the same file since they share many components.
*/
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
428 429 430 431 432 433 434 |
if( pCfg->diffFlags & DIFF_BRIEF ){
if( blob_compare(pFile1, &file2) ){
fossil_print("CHANGED %s\n", zName);
}
}else{
blob_zero(&out);
if( fSwapDiff ){
| | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
if( pCfg->diffFlags & DIFF_BRIEF ){
if( blob_compare(pFile1, &file2) ){
fossil_print("CHANGED %s\n", zName);
}
}else{
blob_zero(&out);
if( fSwapDiff ){
text_diff(&file2, pFile1, &out, pCfg);
}else{
text_diff(pFile1, &file2, &out, pCfg);
}
if( blob_size(&out) ){
if( pCfg->diffFlags & DIFF_NUMSTAT ){
if( !diffBlob ){
fossil_print("%s %s\n", blob_str(&out), zName);
}else{
blob_appendf(diffBlob, "%s %s\n", blob_str(&out), zName);
|
| ︙ | ︙ | |||
539 540 541 542 543 544 545 |
DiffConfig *pCfg /* Diff flags */
){
if( pCfg->diffFlags & DIFF_BRIEF ) return;
if( zDiffCmd==0 ){
Blob out; /* Diff output text */
blob_zero(&out);
| | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 |
DiffConfig *pCfg /* Diff flags */
){
if( pCfg->diffFlags & DIFF_BRIEF ) return;
if( zDiffCmd==0 ){
Blob out; /* Diff output text */
blob_zero(&out);
text_diff(pFile1, pFile2, &out, pCfg);
if( pCfg->diffFlags & DIFF_NUMSTAT ){
fossil_print("%s %s\n", blob_str(&out), zName);
}else{
diff_print_filenames(zName, zName, pCfg, 0);
fossil_print("%s\n", blob_str(&out));
}
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
328 329 330 331 332 333 334 | /* ** Append the difference between artifacts to the output */ static void append_diff( const char *zFrom, /* Diff from this artifact */ const char *zTo, /* ... to this artifact */ | | < < | | | < | | < | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
/*
** Append the difference between artifacts to the output
*/
static void append_diff(
const char *zFrom, /* Diff from this artifact */
const char *zTo, /* ... to this artifact */
DiffConfig *pCfg /* The diff configuration */
){
int fromid;
int toid;
Blob from, to;
if( zFrom ){
fromid = uuid_to_rid(zFrom, 0);
content_get(fromid, &from);
}else{
blob_zero(&from);
}
if( zTo ){
toid = uuid_to_rid(zTo, 0);
content_get(toid, &to);
}else{
blob_zero(&to);
}
if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
}else{
pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
}
text_diff(&from, &to, cgi_output_blob(), pCfg);
blob_reset(&from);
blob_reset(&to);
}
/*
** Write a line of web-page output that shows changes that have occurred
** to a file between two check-ins.
*/
static void append_file_change_line(
const char *zCkin, /* The checkin on which the change occurs */
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */
int mperm /* executable or symlink permission for zNew */
){
@ <p>
if( !g.perm.Hyperlink ){
if( zNew==0 ){
@ Deleted %h(zName).
}else if( zOld==0 ){
|
| ︙ | ︙ | |||
391 392 393 394 395 396 397 |
@ %h(zName) became a symlink.
}else{
@ %h(zName) became a regular file.
}
}else{
@ Changes to %h(zName).
}
| | | | 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
@ %h(zName) became a symlink.
}else{
@ %h(zName) became a regular file.
}
}else{
@ Changes to %h(zName).
}
if( pCfg ){
append_diff(zOld, zNew, pCfg);
}
}else{
if( zOld && zNew ){
if( fossil_strcmp(zOld, zNew)!=0 ){
@ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
@ %h(zName)</a>
@ from %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>
|
| ︙ | ︙ | |||
426 427 428 429 430 431 432 |
}else if( zOld ){
@ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zOld,zCkin))\
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
}else{
@ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
}
| | | | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
}else if( zOld ){
@ Deleted %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zOld,zCkin))\
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
}else{
@ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
}
if( pCfg ){
append_diff(zOld, zNew, pCfg);
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
@
@ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a>
}
}
@ </p>
}
/*
** Generate javascript to enhance HTML diffs.
*/
void append_diff_javascript(int sideBySide){
if( !sideBySide ) return;
builtin_request_js("diff.js");
}
/*
** Construct an appropriate diffFlag for text_diff() based on query
** parameters and the to boolean arguments.
*/
DiffConfig *construct_diff_flags(int diffType, DiffConfig *pCfg){
u64 diffFlags = 0; /* Zero means do not show any diff */
if( diffType>0 ){
int x;
if( diffType==2 ){
diffFlags = DIFF_SIDEBYSIDE;
/* "dw" query parameter determines width of each column */
|
| ︙ | ︙ | |||
472 473 474 475 476 477 478 |
x = atoi(PD("dc","7"));
if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
diffFlags += x;
/* The "noopt" parameter disables diff optimization */
if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT;
diffFlags |= DIFF_STRIP_EOLCR;
| > > | > | > | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
x = atoi(PD("dc","7"));
if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
diffFlags += x;
/* The "noopt" parameter disables diff optimization */
if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT;
diffFlags |= DIFF_STRIP_EOLCR;
diff_config_init(pCfg, diffFlags);
return pCfg;
}else{
diff_config_init(pCfg, 0);
return 0;
}
}
/*
** WEBPAGE: ci_tags
** URL: /ci_tags?name=ARTIFACTID
**
** Show all tags and properties for a given check-in.
|
| ︙ | ︙ | |||
614 615 616 617 618 619 620 |
** or a tag or branch name that identifies the check-in.
*/
void ci_page(void){
Stmt q1, q2, q3;
int rid;
int isLeaf;
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
| < | | > | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
** or a tag or branch name that identifies the check-in.
*/
void ci_page(void){
Stmt q1, q2, q3;
int rid;
int isLeaf;
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
const char *zName; /* Name of the check-in to be displayed */
const char *zUuid; /* Hash of zName, found via blob.uuid */
const char *zParent; /* Hash of the parent check-in (if any) */
const char *zRe; /* regex parameter */
ReCompiled *pRe = 0; /* regex */
const char *zW; /* URL param for ignoring whitespace */
const char *zPage = "vinfo"; /* Page that shows diffs */
const char *zPageHide = "ci"; /* Page that hides diffs */
const char *zBrName; /* Branch name */
DiffConfig DCfg,*pCfg; /* Type of diff */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_set_current_feature("vinfo");
zName = P("name");
rid = name_to_rid_www("name");
if( rid==0 ){
|
| ︙ | ︙ | |||
878 879 880 881 882 883 884 |
wiki_render_associated("checkin", zUuid, 0);
}
render_backlink_graph(zUuid, "<div class=\"section\">References</div>\n");
@ <div class="section">Context</div>
render_checkin_context(rid, 0, 0, 0);
@ <div class="section">Changes</div>
@ <div class="sectionmenu">
| | > | | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 |
wiki_render_associated("checkin", zUuid, 0);
}
render_backlink_graph(zUuid, "<div class=\"section\">References</div>\n");
@ <div class="section">Context</div>
render_checkin_context(rid, 0, 0, 0);
@ <div class="section">Changes</div>
@ <div class="sectionmenu">
pCfg = construct_diff_flags(diffType, &DCfg);
DCfg.pRe = pRe;
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
if( diffType!=0 ){
@ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\
@ Hide Diffs</a>
}
if( diffType!=1 ){
@ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
@ Unified Diffs</a>
|
| ︙ | ︙ | |||
933 934 935 936 937 938 939 |
while( db_step(&q3)==SQLITE_ROW ){
const char *zName = db_column_text(&q3,0);
int mperm = db_column_int(&q3, 1);
const char *zOld = db_column_text(&q3,2);
const char *zNew = db_column_text(&q3,3);
const char *zOldName = db_column_text(&q3, 4);
append_file_change_line(zUuid, zName, zOld, zNew, zOldName,
| | | | 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 |
while( db_step(&q3)==SQLITE_ROW ){
const char *zName = db_column_text(&q3,0);
int mperm = db_column_int(&q3, 1);
const char *zOld = db_column_text(&q3,2);
const char *zNew = db_column_text(&q3,3);
const char *zOldName = db_column_text(&q3, 4);
append_file_change_line(zUuid, zName, zOld, zNew, zOldName,
pCfg,mperm);
}
db_finalize(&q3);
append_diff_javascript(diffType);
builtin_fossil_js_bundle_or("info-diff",NULL);
style_finish_page();
}
/*
** WEBPAGE: winfo
** URL: /winfo?name=HASH
|
| ︙ | ︙ | |||
1167 1168 1169 1170 1171 1172 1173 |
** inv "Invert". Exchange the roles of from= and to=
**
** Show all differences between two check-ins.
*/
void vdiff_page(void){
int ridFrom, ridTo;
int diffType = 0; /* 0: none, 1: unified, 2: side-by-side */
| < > | 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 |
** inv "Invert". Exchange the roles of from= and to=
**
** Show all differences between two check-ins.
*/
void vdiff_page(void){
int ridFrom, ridTo;
int diffType = 0; /* 0: none, 1: unified, 2: side-by-side */
Manifest *pFrom, *pTo;
ManifestFile *pFileFrom, *pFileTo;
const char *zBranch;
const char *zFrom;
const char *zTo;
const char *zRe;
const char *zGlob;
char *zMergeOrigin = 0;
ReCompiled *pRe = 0;
DiffConfig DCfg, *pCfg = 0;
int graphFlags = 0;
Blob qp;
int bInvert = PB("inv");
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
login_anonymous_available();
|
| ︙ | ︙ | |||
1229 1230 1231 1232 1233 1234 1235 |
blob_appendf(&qp, "&glob=%T", zGlob);
}
}
if( PB("nc") ){
graphFlags |= TIMELINE_NOCOLOR;
blob_appendf(&qp, "&nc");
}
| | | | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 |
blob_appendf(&qp, "&glob=%T", zGlob);
}
}
if( PB("nc") ){
graphFlags |= TIMELINE_NOCOLOR;
blob_appendf(&qp, "&nc");
}
pCfg = construct_diff_flags(diffType, &DCfg);
if( DCfg.diffFlags & DIFF_IGNORE_ALLWS ){
blob_appendf(&qp, "&w");
}
style_set_current_feature("vdiff");
if( zBranch==0 ){
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
}
if( diffType!=0 ){
|
| ︙ | ︙ | |||
1253 1254 1255 1256 1257 1258 1259 |
if( zBranch==0 ){
style_submenu_element("Invert","%R/vdiff?diff=%d&inv&%b", diffType, &qp);
}
if( zGlob ){
style_submenu_element("Clear glob", "%R/vdiff?diff=%d&%b", diffType, &qp);
}else{
style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo,
| | | 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 |
if( zBranch==0 ){
style_submenu_element("Invert","%R/vdiff?diff=%d&inv&%b", diffType, &qp);
}
if( zGlob ){
style_submenu_element("Clear glob", "%R/vdiff?diff=%d&%b", diffType, &qp);
}else{
style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo,
(DCfg.diffFlags & DIFF_IGNORE_ALLWS)?"&w":"");
}
if( diffType!=0 ){
style_submenu_checkbox("w", "Ignore Whitespace", 0, 0);
}
if( zBranch ){
style_header("Changes On Branch %h", zBranch);
}else{
|
| ︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 |
}
blob_reset(&qp);
manifest_file_rewind(pFrom);
pFileFrom = manifest_file_next(pFrom, 0);
manifest_file_rewind(pTo);
pFileTo = manifest_file_next(pTo, 0);
while( pFileFrom || pFileTo ){
int cmp;
if( pFileFrom==0 ){
cmp = +1;
}else if( pFileTo==0 ){
cmp = -1;
}else{
cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
}
if( cmp<0 ){
if( !zGlob || sqlite3_strglob(zGlob, pFileFrom->zName)==0 ){
append_file_change_line(zFrom, pFileFrom->zName,
| > | | | | 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 |
}
blob_reset(&qp);
manifest_file_rewind(pFrom);
pFileFrom = manifest_file_next(pFrom, 0);
manifest_file_rewind(pTo);
pFileTo = manifest_file_next(pTo, 0);
DCfg.pRe = pRe;
while( pFileFrom || pFileTo ){
int cmp;
if( pFileFrom==0 ){
cmp = +1;
}else if( pFileTo==0 ){
cmp = -1;
}else{
cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
}
if( cmp<0 ){
if( !zGlob || sqlite3_strglob(zGlob, pFileFrom->zName)==0 ){
append_file_change_line(zFrom, pFileFrom->zName,
pFileFrom->zUuid, 0, 0, pCfg, 0);
}
pFileFrom = manifest_file_next(pFrom, 0);
}else if( cmp>0 ){
if( !zGlob || sqlite3_strglob(zGlob, pFileTo->zName)==0 ){
append_file_change_line(zTo, pFileTo->zName,
0, pFileTo->zUuid, 0, pCfg,
manifest_file_mperm(pFileTo));
}
pFileTo = manifest_file_next(pTo, 0);
}else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
pFileFrom = manifest_file_next(pFrom, 0);
pFileTo = manifest_file_next(pTo, 0);
}else{
if(!zGlob || (sqlite3_strglob(zGlob, pFileFrom->zName)==0
|| sqlite3_strglob(zGlob, pFileTo->zName)==0) ){
append_file_change_line(zFrom, pFileFrom->zName,
pFileFrom->zUuid,
pFileTo->zUuid, 0, pCfg,
manifest_file_mperm(pFileTo));
}
pFileFrom = manifest_file_next(pFrom, 0);
pFileTo = manifest_file_next(pTo, 0);
}
}
manifest_destroy(pFrom);
|
| ︙ | ︙ | |||
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 |
char *zV1;
char *zV2;
const char *zRe;
ReCompiled *pRe = 0;
u64 diffFlags;
u32 objdescFlags = 0;
int verbose = PB("verbose");
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
diffType = preferred_diff_type();
if( P("from") && P("to") ){
v1 = artifact_from_ci_and_filename("from");
v2 = artifact_from_ci_and_filename("to");
| > | 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 |
char *zV1;
char *zV2;
const char *zRe;
ReCompiled *pRe = 0;
u64 diffFlags;
u32 objdescFlags = 0;
int verbose = PB("verbose");
DiffConfig DCfg;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
diffType = preferred_diff_type();
if( P("from") && P("to") ){
v1 = artifact_from_ci_and_filename("from");
v2 = artifact_from_ci_and_filename("to");
|
| ︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 |
DiffConfig DCfg;
pOut = cgi_output_blob();
cgi_set_content_type("text/plain");
diffFlags = 4;
content_get(v1, &c1);
content_get(v2, &c2);
diff_config_init(&DCfg, diffFlags);
| > | | > | 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 |
DiffConfig DCfg;
pOut = cgi_output_blob();
cgi_set_content_type("text/plain");
diffFlags = 4;
content_get(v1, &c1);
content_get(v2, &c2);
diff_config_init(&DCfg, diffFlags);
DCfg.pRe = pRe;
text_diff(&c1, &c2, pOut, &DCfg);
blob_reset(&c1);
blob_reset(&c2);
return;
}
zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
construct_diff_flags(diffType, &DCfg);
DCfg.diffFlags |= DIFF_HTML;
style_set_current_feature("fdiff");
style_header("Diff");
style_submenu_checkbox("w", "Ignore Whitespace", 0, 0);
if( diffType==2 ){
style_submenu_element("Unified Diff", "%R/fdiff?v1=%T&v2=%T&diff=1",
P("v1"), P("v2"));
|
| ︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 1820 1821 |
object_description(v1, objdescFlags,0, 0);
@ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2>
object_description(v2, objdescFlags,0, 0);
}
if( pRe ){
@ <b>Only differences that match regular expression "%h(zRe)"
@ are shown.</b>
}
@ <hr />
| > | | 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 |
object_description(v1, objdescFlags,0, 0);
@ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2>
object_description(v2, objdescFlags,0, 0);
}
if( pRe ){
@ <b>Only differences that match regular expression "%h(zRe)"
@ are shown.</b>
DCfg.pRe = pRe;
}
@ <hr />
append_diff(zV1, zV2, &DCfg);
append_diff_javascript(diffType);
style_finish_page();
}
/*
** WEBPAGE: raw
** URL: /raw/ARTIFACTID
|
| ︙ | ︙ |
Changes to src/json_diff.c.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
*/
cson_value * json_generate_diff(const char *zFrom, const char *zTo,
int nContext, char fSbs,
char fHtml){
int fromid;
int toid;
int outLen;
Blob from = empty_blob, to = empty_blob, out = empty_blob;
cson_value * rc = NULL;
int flags = (DIFF_CONTEXT_MASK & nContext)
| (fSbs ? DIFF_SIDEBYSIDE : 0)
| (fHtml ? DIFF_HTML : 0);
fromid = name_to_typed_rid(zFrom, "*");
if(fromid<=0){
json_set_err(FSL_JSON_E_UNRESOLVED_UUID,
"Could not resolve 'from' ID.");
return NULL;
}
toid = name_to_typed_rid(zTo, "*");
if(toid<=0){
json_set_err(FSL_JSON_E_UNRESOLVED_UUID,
"Could not resolve 'to' ID.");
return NULL;
}
content_get(fromid, &from);
content_get(toid, &to);
blob_zero(&out);
| > > | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
*/
cson_value * json_generate_diff(const char *zFrom, const char *zTo,
int nContext, char fSbs,
char fHtml){
int fromid;
int toid;
int outLen;
DiffConfig DCfg;
Blob from = empty_blob, to = empty_blob, out = empty_blob;
cson_value * rc = NULL;
int flags = (DIFF_CONTEXT_MASK & nContext)
| (fSbs ? DIFF_SIDEBYSIDE : 0)
| (fHtml ? DIFF_HTML : 0);
fromid = name_to_typed_rid(zFrom, "*");
if(fromid<=0){
json_set_err(FSL_JSON_E_UNRESOLVED_UUID,
"Could not resolve 'from' ID.");
return NULL;
}
toid = name_to_typed_rid(zTo, "*");
if(toid<=0){
json_set_err(FSL_JSON_E_UNRESOLVED_UUID,
"Could not resolve 'to' ID.");
return NULL;
}
content_get(fromid, &from);
content_get(toid, &to);
blob_zero(&out);
diff_config_init(&DCfg, flags);
text_diff(&from, &to, &out, &DCfg);
blob_reset(&from);
blob_reset(&to);
outLen = blob_size(&out);
if(outLen>=0){
rc = cson_value_new_string(blob_buffer(&out),
(unsigned int)blob_size(&out));
}
|
| ︙ | ︙ |
Changes to src/json_wiki.c.
| ︙ | ︙ | |||
517 518 519 520 521 522 523 | char const * zV2 = NULL; cson_object * pay = NULL; int argPos = g.json.dispatchDepth; int r1 = 0, r2 = 0; Manifest * pW1 = NULL, *pW2 = NULL; Blob w1 = empty_blob, w2 = empty_blob, d = empty_blob; char const * zErrTag = NULL; | | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
char const * zV2 = NULL;
cson_object * pay = NULL;
int argPos = g.json.dispatchDepth;
int r1 = 0, r2 = 0;
Manifest * pW1 = NULL, *pW2 = NULL;
Blob w1 = empty_blob, w2 = empty_blob, d = empty_blob;
char const * zErrTag = NULL;
DiffConfig DCfg;
char * zUuid = NULL;
if( !g.perm.Hyperlink ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'h' permissions.");
return NULL;
}
|
| ︙ | ︙ | |||
565 566 567 568 569 570 571 |
goto manifest;
}
blob_init(&w1, pW1->zWiki, -1);
blob_zero(&w2);
blob_init(&w2, pW2->zWiki, -1);
blob_zero(&d);
| | | | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 |
goto manifest;
}
blob_init(&w1, pW1->zWiki, -1);
blob_zero(&w2);
blob_init(&w2, pW2->zWiki, -1);
blob_zero(&d);
diff_config_init(&DCfg, DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR);
text_diff(&w1, &w2, &d, &DCfg);
blob_reset(&w1);
blob_reset(&w2);
pay = cson_new_object();
zUuid = json_wiki_get_uuid_for_rid( pW1->rid );
cson_object_set(pay, "v1", json_new_string(zUuid) );
|
| ︙ | ︙ |
Changes to src/merge3.c.
| ︙ | ︙ | |||
194 195 196 197 198 199 200 201 202 203 204 205 206 207 | int *aC1; /* Changes from pPivot to pV1 */ int *aC2; /* Changes from pPivot to pV2 */ int i1, i2; /* Index into aC1[] and aC2[] */ int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */ int limit1, limit2; /* Sizes of aC1[] and aC2[] */ int nConflict = 0; /* Number of merge conflicts seen so far */ int useCrLf = 0; blob_zero(pOut); /* Merge results stored in pOut */ /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM), ** keep it in the output. This should be secure enough not to cause ** unintended changes to the merged file and consistent with what ** users are using in their source files. | > | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | int *aC1; /* Changes from pPivot to pV1 */ int *aC2; /* Changes from pPivot to pV2 */ int i1, i2; /* Index into aC1[] and aC2[] */ int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */ int limit1, limit2; /* Sizes of aC1[] and aC2[] */ int nConflict = 0; /* Number of merge conflicts seen so far */ int useCrLf = 0; DiffConfig DCfg; blob_zero(pOut); /* Merge results stored in pOut */ /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM), ** keep it in the output. This should be secure enough not to cause ** unintended changes to the merged file and consistent with what ** users are using in their source files. |
| ︙ | ︙ | |||
222 223 224 225 226 227 228 | ** and pPivot => pV2 (into aC2). Each of the aC1 and aC2 arrays is ** an array of integer triples. Within each triple, the first integer ** is the number of lines of text to copy directly from the pivot, ** the second integer is the number of lines of text to omit from the ** pivot, and the third integer is the number of lines of text that are ** inserted. The edit array ends with a triple of 0,0,0. */ | > | | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
** and pPivot => pV2 (into aC2). Each of the aC1 and aC2 arrays is
** an array of integer triples. Within each triple, the first integer
** is the number of lines of text to copy directly from the pivot,
** the second integer is the number of lines of text to omit from the
** pivot, and the third integer is the number of lines of text that are
** inserted. The edit array ends with a triple of 0,0,0.
*/
diff_config_init(&DCfg, 0);
aC1 = text_diff(pPivot, pV1, 0, &DCfg);
aC2 = text_diff(pPivot, pV2, 0, &DCfg);
if( aC1==0 || aC2==0 ){
free(aC1);
free(aC2);
return -1;
}
blob_rewind(pV1); /* Rewind inputs: Needed to reconstruct output */
|
| ︙ | ︙ |
Changes to src/skins.c.
| ︙ | ︙ | |||
865 866 867 868 869 870 871 |
}
@ <hr />
@ Baseline: \
skin_emit_skin_selector("basis", zBasis, zDraft);
@ <input type="submit" name="diff" value="Unified Diff" />
@ <input type="submit" name="sbsdiff" value="Side-by-Side Diff" />
if( P("diff")!=0 || P("sbsdiff")!=0 ){
| < > > | | | | | | 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
}
@ <hr />
@ Baseline: \
skin_emit_skin_selector("basis", zBasis, zDraft);
@ <input type="submit" name="diff" value="Unified Diff" />
@ <input type="submit" name="sbsdiff" value="Side-by-Side Diff" />
if( P("diff")!=0 || P("sbsdiff")!=0 ){
Blob from, to, out;
DiffConfig DCfg;
construct_diff_flags(1, &DCfg);
DCfg.diffFlags |= DIFF_STRIP_EOLCR;
if( P("sbsdiff")!=0 ) DCfg.diffFlags |= DIFF_SIDEBYSIDE;
blob_init(&to, zContent, -1);
blob_init(&from, skin_file_content(zBasis, zFile), -1);
blob_zero(&out);
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
text_diff(&from, &to, &out, &DCfg);
@ %s(blob_str(&out))
}else{
DCfg.diffFlags |= DIFF_LINENO;
text_diff(&from, &to, &out, &DCfg);
@ <pre class="udiff">
@ %s(blob_str(&out))
@ </pre>
}
blob_reset(&from);
blob_reset(&to);
blob_reset(&out);
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 |
*/
void wdiff_page(void){
const char *zId;
const char *zPid;
Manifest *pW1, *pW2 = 0;
int rid1, rid2, nextRid;
Blob w1, w2, d;
| < | 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 |
*/
void wdiff_page(void){
const char *zId;
const char *zPid;
Manifest *pW1, *pW2 = 0;
int rid1, rid2, nextRid;
Blob w1, w2, d;
DiffConfig DCfg;
login_check_credentials();
if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
zId = P("id");
if( zId==0 ){
rid1 = atoi(PD("rid","0"));
|
| ︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 |
nextRid = wiki_next(wiki_tagid(pW1->zWikiTitle),pW1->rDate);
if( nextRid ){
style_submenu_element("Next", "%R/wdiff?rid=%d", nextRid);
}
style_set_current_feature("wiki");
style_header("Changes To %s", pW1->zWikiTitle);
blob_zero(&d);
| | | | | 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 |
nextRid = wiki_next(wiki_tagid(pW1->zWikiTitle),pW1->rDate);
if( nextRid ){
style_submenu_element("Next", "%R/wdiff?rid=%d", nextRid);
}
style_set_current_feature("wiki");
style_header("Changes To %s", pW1->zWikiTitle);
blob_zero(&d);
construct_diff_flags(1, &DCfg);
DCfg.diffFlags |= DIFF_HTML | DIFF_LINENO;
text_diff(&w2, &w1, &d, &DCfg);
@ <pre class="udiff">
@ %s(blob_str(&d))
@ <pre>
manifest_destroy(pW1);
manifest_destroy(pW2);
style_finish_page();
}
|
| ︙ | ︙ |