| | @@ -330,17 +330,15 @@ |
| 330 | 330 | ** Append the difference between artifacts to the output |
| 331 | 331 | */ |
| 332 | 332 | static void append_diff( |
| 333 | 333 | const char *zFrom, /* Diff from this artifact */ |
| 334 | 334 | const char *zTo, /* ... to this artifact */ |
| 335 | | - u64 diffFlags, /* Diff formatting flags */ |
| 336 | | - ReCompiled *pRe /* Only show change matching this regex */ |
| 335 | + DiffConfig *pCfg /* The diff configuration */ |
| 337 | 336 | ){ |
| 338 | 337 | int fromid; |
| 339 | 338 | int toid; |
| 340 | 339 | Blob from, to; |
| 341 | | - DiffConfig DCfg; |
| 342 | 340 | if( zFrom ){ |
| 343 | 341 | fromid = uuid_to_rid(zFrom, 0); |
| 344 | 342 | content_get(fromid, &from); |
| 345 | 343 | }else{ |
| 346 | 344 | blob_zero(&from); |
| | @@ -349,17 +347,16 @@ |
| 349 | 347 | toid = uuid_to_rid(zTo, 0); |
| 350 | 348 | content_get(toid, &to); |
| 351 | 349 | }else{ |
| 352 | 350 | blob_zero(&to); |
| 353 | 351 | } |
| 354 | | - if( diffFlags & DIFF_SIDEBYSIDE ){ |
| 355 | | - diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; |
| 352 | + if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){ |
| 353 | + pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; |
| 356 | 354 | }else{ |
| 357 | | - diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; |
| 355 | + pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; |
| 358 | 356 | } |
| 359 | | - diff_config_init(&DCfg, diffFlags); |
| 360 | | - text_diff(&from, &to, cgi_output_blob(), pRe, &DCfg); |
| 357 | + text_diff(&from, &to, cgi_output_blob(), pCfg); |
| 361 | 358 | blob_reset(&from); |
| 362 | 359 | blob_reset(&to); |
| 363 | 360 | } |
| 364 | 361 | |
| 365 | 362 | /* |
| | @@ -370,12 +367,11 @@ |
| 370 | 367 | const char *zCkin, /* The checkin on which the change occurs */ |
| 371 | 368 | const char *zName, /* Name of the file that has changed */ |
| 372 | 369 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 373 | 370 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 374 | 371 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 375 | | - u64 diffFlags, /* Flags for text_diff(). Zero to omit diffs */ |
| 376 | | - ReCompiled *pRe, /* Only show diffs that match this regex, if not NULL */ |
| 372 | + DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */ |
| 377 | 373 | int mperm /* executable or symlink permission for zNew */ |
| 378 | 374 | ){ |
| 379 | 375 | @ <p> |
| 380 | 376 | if( !g.perm.Hyperlink ){ |
| 381 | 377 | if( zNew==0 ){ |
| | @@ -393,12 +389,12 @@ |
| 393 | 389 | @ %h(zName) became a regular file. |
| 394 | 390 | } |
| 395 | 391 | }else{ |
| 396 | 392 | @ Changes to %h(zName). |
| 397 | 393 | } |
| 398 | | - if( diffFlags ){ |
| 399 | | - append_diff(zOld, zNew, diffFlags, pRe); |
| 394 | + if( pCfg ){ |
| 395 | + append_diff(zOld, zNew, pCfg); |
| 400 | 396 | } |
| 401 | 397 | }else{ |
| 402 | 398 | if( zOld && zNew ){ |
| 403 | 399 | if( fossil_strcmp(zOld, zNew)!=0 ){ |
| 404 | 400 | @ Modified %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\ |
| | @@ -428,12 +424,12 @@ |
| 428 | 424 | @ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>. |
| 429 | 425 | }else{ |
| 430 | 426 | @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\ |
| 431 | 427 | @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>. |
| 432 | 428 | } |
| 433 | | - if( diffFlags ){ |
| 434 | | - append_diff(zOld, zNew, diffFlags, pRe); |
| 429 | + if( pCfg ){ |
| 430 | + append_diff(zOld, zNew, pCfg); |
| 435 | 431 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 436 | 432 | @ |
| 437 | 433 | @ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a> |
| 438 | 434 | } |
| 439 | 435 | } |
| | @@ -450,11 +446,11 @@ |
| 450 | 446 | |
| 451 | 447 | /* |
| 452 | 448 | ** Construct an appropriate diffFlag for text_diff() based on query |
| 453 | 449 | ** parameters and the to boolean arguments. |
| 454 | 450 | */ |
| 455 | | -u64 construct_diff_flags(int diffType){ |
| 451 | +DiffConfig *construct_diff_flags(int diffType, DiffConfig *pCfg){ |
| 456 | 452 | u64 diffFlags = 0; /* Zero means do not show any diff */ |
| 457 | 453 | if( diffType>0 ){ |
| 458 | 454 | int x; |
| 459 | 455 | if( diffType==2 ){ |
| 460 | 456 | diffFlags = DIFF_SIDEBYSIDE; |
| | @@ -474,12 +470,16 @@ |
| 474 | 470 | diffFlags += x; |
| 475 | 471 | |
| 476 | 472 | /* The "noopt" parameter disables diff optimization */ |
| 477 | 473 | if( PD("noopt",0)!=0 ) diffFlags |= DIFF_NOOPT; |
| 478 | 474 | diffFlags |= DIFF_STRIP_EOLCR; |
| 475 | + diff_config_init(pCfg, diffFlags); |
| 476 | + return pCfg; |
| 477 | + }else{ |
| 478 | + diff_config_init(pCfg, 0); |
| 479 | + return 0; |
| 479 | 480 | } |
| 480 | | - return diffFlags; |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | /* |
| 484 | 484 | ** WEBPAGE: ci_tags |
| 485 | 485 | ** URL: /ci_tags?name=ARTIFACTID |
| | @@ -616,20 +616,20 @@ |
| 616 | 616 | void ci_page(void){ |
| 617 | 617 | Stmt q1, q2, q3; |
| 618 | 618 | int rid; |
| 619 | 619 | int isLeaf; |
| 620 | 620 | int diffType; /* 0: no diff, 1: unified, 2: side-by-side */ |
| 621 | | - u64 diffFlags; /* Flag parameter for text_diff() */ |
| 622 | 621 | const char *zName; /* Name of the check-in to be displayed */ |
| 623 | 622 | const char *zUuid; /* Hash of zName, found via blob.uuid */ |
| 624 | 623 | const char *zParent; /* Hash of the parent check-in (if any) */ |
| 625 | 624 | const char *zRe; /* regex parameter */ |
| 626 | 625 | ReCompiled *pRe = 0; /* regex */ |
| 627 | | - const char *zW; /* URL param for ignoring whitespace */ |
| 626 | + const char *zW; /* URL param for ignoring whitespace */ |
| 628 | 627 | const char *zPage = "vinfo"; /* Page that shows diffs */ |
| 629 | 628 | const char *zPageHide = "ci"; /* Page that hides diffs */ |
| 630 | | - const char *zBrName; /* Branch name */ |
| 629 | + const char *zBrName; /* Branch name */ |
| 630 | + DiffConfig DCfg,*pCfg; /* Type of diff */ |
| 631 | 631 | |
| 632 | 632 | login_check_credentials(); |
| 633 | 633 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 634 | 634 | style_set_current_feature("vinfo"); |
| 635 | 635 | zName = P("name"); |
| | @@ -880,12 +880,13 @@ |
| 880 | 880 | render_backlink_graph(zUuid, "<div class=\"section\">References</div>\n"); |
| 881 | 881 | @ <div class="section">Context</div> |
| 882 | 882 | render_checkin_context(rid, 0, 0, 0); |
| 883 | 883 | @ <div class="section">Changes</div> |
| 884 | 884 | @ <div class="sectionmenu"> |
| 885 | | - diffFlags = construct_diff_flags(diffType); |
| 886 | | - zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 885 | + pCfg = construct_diff_flags(diffType, &DCfg); |
| 886 | + DCfg.pRe = pRe; |
| 887 | + zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 887 | 888 | if( diffType!=0 ){ |
| 888 | 889 | @ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\ |
| 889 | 890 | @ Hide Diffs</a> |
| 890 | 891 | } |
| 891 | 892 | if( diffType!=1 ){ |
| | @@ -935,14 +936,14 @@ |
| 935 | 936 | int mperm = db_column_int(&q3, 1); |
| 936 | 937 | const char *zOld = db_column_text(&q3,2); |
| 937 | 938 | const char *zNew = db_column_text(&q3,3); |
| 938 | 939 | const char *zOldName = db_column_text(&q3, 4); |
| 939 | 940 | append_file_change_line(zUuid, zName, zOld, zNew, zOldName, |
| 940 | | - diffFlags,pRe,mperm); |
| 941 | + pCfg,mperm); |
| 941 | 942 | } |
| 942 | 943 | db_finalize(&q3); |
| 943 | | - append_diff_javascript(diffType==2); |
| 944 | + append_diff_javascript(diffType); |
| 944 | 945 | builtin_fossil_js_bundle_or("info-diff",NULL); |
| 945 | 946 | style_finish_page(); |
| 946 | 947 | } |
| 947 | 948 | |
| 948 | 949 | /* |
| | @@ -1169,20 +1170,20 @@ |
| 1169 | 1170 | ** Show all differences between two check-ins. |
| 1170 | 1171 | */ |
| 1171 | 1172 | void vdiff_page(void){ |
| 1172 | 1173 | int ridFrom, ridTo; |
| 1173 | 1174 | int diffType = 0; /* 0: none, 1: unified, 2: side-by-side */ |
| 1174 | | - u64 diffFlags = 0; |
| 1175 | 1175 | Manifest *pFrom, *pTo; |
| 1176 | 1176 | ManifestFile *pFileFrom, *pFileTo; |
| 1177 | 1177 | const char *zBranch; |
| 1178 | 1178 | const char *zFrom; |
| 1179 | 1179 | const char *zTo; |
| 1180 | 1180 | const char *zRe; |
| 1181 | 1181 | const char *zGlob; |
| 1182 | 1182 | char *zMergeOrigin = 0; |
| 1183 | 1183 | ReCompiled *pRe = 0; |
| 1184 | + DiffConfig DCfg, *pCfg = 0; |
| 1184 | 1185 | int graphFlags = 0; |
| 1185 | 1186 | Blob qp; |
| 1186 | 1187 | int bInvert = PB("inv"); |
| 1187 | 1188 | |
| 1188 | 1189 | login_check_credentials(); |
| | @@ -1231,12 +1232,12 @@ |
| 1231 | 1232 | } |
| 1232 | 1233 | if( PB("nc") ){ |
| 1233 | 1234 | graphFlags |= TIMELINE_NOCOLOR; |
| 1234 | 1235 | blob_appendf(&qp, "&nc"); |
| 1235 | 1236 | } |
| 1236 | | - diffFlags = construct_diff_flags(diffType); |
| 1237 | | - if( diffFlags & DIFF_IGNORE_ALLWS ){ |
| 1237 | + pCfg = construct_diff_flags(diffType, &DCfg); |
| 1238 | + if( DCfg.diffFlags & DIFF_IGNORE_ALLWS ){ |
| 1238 | 1239 | blob_appendf(&qp, "&w"); |
| 1239 | 1240 | } |
| 1240 | 1241 | style_set_current_feature("vdiff"); |
| 1241 | 1242 | if( zBranch==0 ){ |
| 1242 | 1243 | style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo); |
| | @@ -1255,11 +1256,11 @@ |
| 1255 | 1256 | } |
| 1256 | 1257 | if( zGlob ){ |
| 1257 | 1258 | style_submenu_element("Clear glob", "%R/vdiff?diff=%d&%b", diffType, &qp); |
| 1258 | 1259 | }else{ |
| 1259 | 1260 | style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, |
| 1260 | | - (diffFlags & DIFF_IGNORE_ALLWS)?"&w":""); |
| 1261 | + (DCfg.diffFlags & DIFF_IGNORE_ALLWS)?"&w":""); |
| 1261 | 1262 | } |
| 1262 | 1263 | if( diffType!=0 ){ |
| 1263 | 1264 | style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); |
| 1264 | 1265 | } |
| 1265 | 1266 | if( zBranch ){ |
| | @@ -1303,10 +1304,11 @@ |
| 1303 | 1304 | |
| 1304 | 1305 | manifest_file_rewind(pFrom); |
| 1305 | 1306 | pFileFrom = manifest_file_next(pFrom, 0); |
| 1306 | 1307 | manifest_file_rewind(pTo); |
| 1307 | 1308 | pFileTo = manifest_file_next(pTo, 0); |
| 1309 | + DCfg.pRe = pRe; |
| 1308 | 1310 | while( pFileFrom || pFileTo ){ |
| 1309 | 1311 | int cmp; |
| 1310 | 1312 | if( pFileFrom==0 ){ |
| 1311 | 1313 | cmp = +1; |
| 1312 | 1314 | }else if( pFileTo==0 ){ |
| | @@ -1315,17 +1317,17 @@ |
| 1315 | 1317 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 1316 | 1318 | } |
| 1317 | 1319 | if( cmp<0 ){ |
| 1318 | 1320 | if( !zGlob || sqlite3_strglob(zGlob, pFileFrom->zName)==0 ){ |
| 1319 | 1321 | append_file_change_line(zFrom, pFileFrom->zName, |
| 1320 | | - pFileFrom->zUuid, 0, 0, diffFlags, pRe, 0); |
| 1322 | + pFileFrom->zUuid, 0, 0, pCfg, 0); |
| 1321 | 1323 | } |
| 1322 | 1324 | pFileFrom = manifest_file_next(pFrom, 0); |
| 1323 | 1325 | }else if( cmp>0 ){ |
| 1324 | 1326 | if( !zGlob || sqlite3_strglob(zGlob, pFileTo->zName)==0 ){ |
| 1325 | 1327 | append_file_change_line(zTo, pFileTo->zName, |
| 1326 | | - 0, pFileTo->zUuid, 0, diffFlags, pRe, |
| 1328 | + 0, pFileTo->zUuid, 0, pCfg, |
| 1327 | 1329 | manifest_file_mperm(pFileTo)); |
| 1328 | 1330 | } |
| 1329 | 1331 | pFileTo = manifest_file_next(pTo, 0); |
| 1330 | 1332 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 1331 | 1333 | pFileFrom = manifest_file_next(pFrom, 0); |
| | @@ -1333,11 +1335,11 @@ |
| 1333 | 1335 | }else{ |
| 1334 | 1336 | if(!zGlob || (sqlite3_strglob(zGlob, pFileFrom->zName)==0 |
| 1335 | 1337 | || sqlite3_strglob(zGlob, pFileTo->zName)==0) ){ |
| 1336 | 1338 | append_file_change_line(zFrom, pFileFrom->zName, |
| 1337 | 1339 | pFileFrom->zUuid, |
| 1338 | | - pFileTo->zUuid, 0, diffFlags, pRe, |
| 1340 | + pFileTo->zUuid, 0, pCfg, |
| 1339 | 1341 | manifest_file_mperm(pFileTo)); |
| 1340 | 1342 | } |
| 1341 | 1343 | pFileFrom = manifest_file_next(pFrom, 0); |
| 1342 | 1344 | pFileTo = manifest_file_next(pTo, 0); |
| 1343 | 1345 | } |
| | @@ -1724,10 +1726,11 @@ |
| 1724 | 1726 | const char *zRe; |
| 1725 | 1727 | ReCompiled *pRe = 0; |
| 1726 | 1728 | u64 diffFlags; |
| 1727 | 1729 | u32 objdescFlags = 0; |
| 1728 | 1730 | int verbose = PB("verbose"); |
| 1731 | + DiffConfig DCfg; |
| 1729 | 1732 | |
| 1730 | 1733 | login_check_credentials(); |
| 1731 | 1734 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1732 | 1735 | diffType = preferred_diff_type(); |
| 1733 | 1736 | if( P("from") && P("to") ){ |
| | @@ -1777,19 +1780,21 @@ |
| 1777 | 1780 | cgi_set_content_type("text/plain"); |
| 1778 | 1781 | diffFlags = 4; |
| 1779 | 1782 | content_get(v1, &c1); |
| 1780 | 1783 | content_get(v2, &c2); |
| 1781 | 1784 | diff_config_init(&DCfg, diffFlags); |
| 1782 | | - text_diff(&c1, &c2, pOut, pRe, &DCfg); |
| 1785 | + DCfg.pRe = pRe; |
| 1786 | + text_diff(&c1, &c2, pOut, &DCfg); |
| 1783 | 1787 | blob_reset(&c1); |
| 1784 | 1788 | blob_reset(&c2); |
| 1785 | 1789 | return; |
| 1786 | 1790 | } |
| 1787 | 1791 | |
| 1788 | 1792 | zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); |
| 1789 | 1793 | zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); |
| 1790 | | - diffFlags = construct_diff_flags(diffType) | DIFF_HTML; |
| 1794 | + construct_diff_flags(diffType, &DCfg); |
| 1795 | + DCfg.diffFlags |= DIFF_HTML; |
| 1791 | 1796 | |
| 1792 | 1797 | style_set_current_feature("fdiff"); |
| 1793 | 1798 | style_header("Diff"); |
| 1794 | 1799 | style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); |
| 1795 | 1800 | if( diffType==2 ){ |
| | @@ -1815,13 +1820,14 @@ |
| 1815 | 1820 | object_description(v2, objdescFlags,0, 0); |
| 1816 | 1821 | } |
| 1817 | 1822 | if( pRe ){ |
| 1818 | 1823 | @ <b>Only differences that match regular expression "%h(zRe)" |
| 1819 | 1824 | @ are shown.</b> |
| 1825 | + DCfg.pRe = pRe; |
| 1820 | 1826 | } |
| 1821 | 1827 | @ <hr /> |
| 1822 | | - append_diff(zV1, zV2, diffFlags, pRe); |
| 1828 | + append_diff(zV1, zV2, &DCfg); |
| 1823 | 1829 | append_diff_javascript(diffType); |
| 1824 | 1830 | style_finish_page(); |
| 1825 | 1831 | } |
| 1826 | 1832 | |
| 1827 | 1833 | /* |
| 1828 | 1834 | |