| | @@ -928,15 +928,14 @@ |
| 928 | 928 | void (*xReplace)(DiffBuilder*,const DLine*,const DLine*); |
| 929 | 929 | void (*xEdit)(DiffBuilder*,const DLine*,const DLine*); |
| 930 | 930 | void (*xEnd)(DiffBuilder*); |
| 931 | 931 | unsigned int lnLeft; /* Lines seen on the left (delete) side */ |
| 932 | 932 | unsigned int lnRight; /* Lines seen on the right (insert) side */ |
| 933 | | - unsigned int nPending; /* Number of pending lines */ |
| 934 | 933 | int eState; /* State of the output */ |
| 935 | 934 | int width; /* Display width */ |
| 936 | 935 | Blob *pOut; /* Output blob */ |
| 937 | | - Blob aCol[5]; /* Holding blobs */ |
| 936 | + Blob bBuf2; /* Storage to hold retained lines */ |
| 938 | 937 | DiffConfig *pCfg; /* Configuration information */ |
| 939 | 938 | }; |
| 940 | 939 | |
| 941 | 940 | /************************* DiffBuilderDebug ********************************/ |
| 942 | 941 | /* This version of DiffBuilder is used for debugging the diff and diff |
| | @@ -1220,209 +1219,162 @@ |
| 1220 | 1219 | ** |
| 1221 | 1220 | ** The result is a <table> with four columns. The four columns hold: |
| 1222 | 1221 | ** |
| 1223 | 1222 | ** 1. The line numbers for the first file. |
| 1224 | 1223 | ** 2. The line numbers for the second file. |
| 1225 | | -** 3. The "diff mark": "+" or "-" or just a space |
| 1226 | | -** 4. Text of the line |
| 1224 | +** 3. The "diff mark": "+", "-" or blank. |
| 1225 | +** 4. Text of the line. |
| 1227 | 1226 | ** |
| 1228 | | -** Inserted lines are marked with <ins> and deleted lines are marked |
| 1229 | | -** with <del>. The whole line is marked this way, not just the part that |
| 1230 | | -** changed. The part that change has an additional nested <ins> or <del>. |
| 1231 | | -** The CSS needs to be set up such that a single <ins> or <del> gives a |
| 1232 | | -** light background and a nested <ins> or <del> gives a darker background. |
| 1233 | | -** Additional attributes (like bold font) might also be added to nested |
| 1234 | | -** <ins> and <del> since those are the characters that have actually |
| 1235 | | -** changed. |
| 1227 | +** The table cells holding the inserted and deleted lines are assigned to CSS |
| 1228 | +** classes .nul, .ins or .del to color them accordingly. The changed parts of |
| 1229 | +** each line have additional <ins> or <del> elements. The CSS needs to be set |
| 1230 | +** up such that the <ins> or <del> intensify the background color of the .ins |
| 1231 | +** and .del CSS classes. |
| 1236 | 1232 | ** |
| 1237 | 1233 | ** Accumulator strategy: |
| 1238 | 1234 | ** |
| 1239 | | -** * Delete line numbers are output directly to p->pOut |
| 1240 | | -** * Insert line numbers accumulate in p->aCol[0]. |
| 1241 | | -** * Separator marks accumulate in p->aCol[1]. |
| 1242 | | -** * Change text accumulates in p->aCol[2]. |
| 1243 | | -** * Pending insert line numbers go into p->aCol[3]. |
| 1244 | | -** * Pending insert text goes into p->aCol[4]. |
| 1235 | +** * Retained insert text goes to p->bBuf2 |
| 1236 | +** * Anything else goes directly to p->pOut |
| 1245 | 1237 | ** |
| 1246 | | -** eState is 1 if text has an open <del> |
| 1238 | +** eState is 1 if the last line was a deletion. |
| 1247 | 1239 | */ |
| 1248 | 1240 | static void dfunifiedFinishDelete(DiffBuilder *p){ |
| 1249 | 1241 | if( p->eState==0 ) return; |
| 1250 | | - blob_append(p->pOut, "</del>", 6); |
| 1251 | | - blob_append(&p->aCol[2], "</del>", 6); |
| 1252 | 1242 | p->eState = 0; |
| 1253 | 1243 | } |
| 1254 | 1244 | static void dfunifiedFinishInsert(DiffBuilder *p){ |
| 1255 | | - unsigned int i; |
| 1256 | | - if( p->nPending==0 ) return; |
| 1245 | + if( blob_size(&p->bBuf2)==0 ) return; |
| 1257 | 1246 | dfunifiedFinishDelete(p); |
| 1258 | | - |
| 1259 | | - /* Blank lines for delete line numbers for each inserted line */ |
| 1260 | | - for(i=0; i<p->nPending; i++) blob_append_char(p->pOut, '\n'); |
| 1261 | | - |
| 1262 | | - /* Insert line numbers */ |
| 1263 | | - blob_append(&p->aCol[0], "<ins>", 5); |
| 1264 | | - blob_append_xfer(&p->aCol[0], &p->aCol[3]); |
| 1265 | | - blob_append(&p->aCol[0], "</ins>", 6); |
| 1266 | | - |
| 1267 | | - /* "+" marks for the separator on inserted lines */ |
| 1268 | | - for(i=0; i<p->nPending; i++) blob_append(&p->aCol[1], "+\n", 2); |
| 1269 | | - |
| 1270 | | - /* Text of the inserted lines */ |
| 1271 | | - blob_append(&p->aCol[2], "<ins>", 5); |
| 1272 | | - blob_append_xfer(&p->aCol[2], &p->aCol[4]); |
| 1273 | | - blob_append(&p->aCol[2], "</ins>", 6); |
| 1274 | | - |
| 1275 | | - p->nPending = 0; |
| 1247 | + blob_append_xfer(p->pOut,&p->bBuf2); |
| 1276 | 1248 | } |
| 1277 | 1249 | static void dfunifiedFinishRow(DiffBuilder *p){ |
| 1278 | 1250 | dfunifiedFinishDelete(p); |
| 1279 | 1251 | dfunifiedFinishInsert(p); |
| 1280 | | - if( blob_size(&p->aCol[0])==0 ) return; |
| 1281 | | - blob_append(p->pOut, "</pre></td><td class=\"diffln difflnr\"><pre>\n", -1); |
| 1282 | | - blob_append_xfer(p->pOut, &p->aCol[0]); |
| 1283 | | - blob_append(p->pOut, "</pre></td><td class=\"diffsep\"><pre>\n", -1); |
| 1284 | | - blob_append_xfer(p->pOut, &p->aCol[1]); |
| 1285 | | - blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtu\"><pre>\n",-1); |
| 1286 | | - blob_append_xfer(p->pOut, &p->aCol[2]); |
| 1287 | | - blob_append(p->pOut, "</pre></td></tr>\n", -1); |
| 1288 | 1252 | } |
| 1289 | 1253 | static void dfunifiedStartRow(DiffBuilder *p){ |
| 1290 | | - if( blob_size(&p->aCol[0])>0 ) return; |
| 1291 | | - blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">" |
| 1292 | | - "<td class=\"diffln difflnl\"><pre>\n", ++nChunk); |
| 1293 | 1254 | } |
| 1294 | 1255 | static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){ |
| 1295 | 1256 | dfunifiedFinishRow(p); |
| 1296 | 1257 | if( p->pCfg && p->pCfg->zLeftHash ){ |
| 1297 | 1258 | blob_appendf(p->pOut, |
| 1298 | 1259 | "<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\"" |
| 1299 | 1260 | " id=\"skip%xh%xi%x\">\n", |
| 1300 | | - p->lnLeft+1, p->lnLeft+n, |
| 1301 | | - nChunk, p->lnLeft, n); |
| 1261 | + p->lnLeft+1, p->lnLeft+n, nChunk, p->lnLeft, n); |
| 1302 | 1262 | }else{ |
| 1303 | 1263 | blob_append(p->pOut, "<tr>", 4); |
| 1304 | 1264 | } |
| 1305 | | - blob_append(p->pOut, "<td class=\"diffln difflne\">" |
| 1306 | | - "︙</td><td></td><td></td></tr>\n", -1); |
| 1265 | + blob_append(p->pOut, "<td class=\"diffln difflne\" colspan=\"4\">" |
| 1266 | + "︙</td></tr>\n", -1); |
| 1307 | 1267 | p->lnLeft += n; |
| 1308 | 1268 | p->lnRight += n; |
| 1309 | 1269 | } |
| 1310 | 1270 | static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){ |
| 1311 | 1271 | dfunifiedStartRow(p); |
| 1312 | 1272 | dfunifiedFinishDelete(p); |
| 1313 | 1273 | dfunifiedFinishInsert(p); |
| 1314 | 1274 | p->lnLeft++; |
| 1315 | 1275 | p->lnRight++; |
| 1316 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1317 | | - blob_appendf(&p->aCol[0],"%d\n",p->lnRight); |
| 1318 | | - blob_append_char(&p->aCol[1], '\n'); |
| 1319 | | - htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n); |
| 1320 | | - blob_append_char(&p->aCol[2], '\n'); |
| 1276 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1277 | + blob_appendf(p->pOut, "<td class=\"diffln difflnl\">%d</td>", p->lnLeft); |
| 1278 | + blob_appendf(p->pOut, "<td class=\"diffln difflnr\">%d</td>", p->lnRight); |
| 1279 | + blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25); |
| 1280 | + blob_append (p->pOut, "<td class=\"difftxt difftxtu\">", 29); |
| 1281 | + htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n); |
| 1282 | + blob_append (p->pOut, "</td>", 5); |
| 1283 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1321 | 1284 | } |
| 1322 | 1285 | static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){ |
| 1323 | 1286 | dfunifiedStartRow(p); |
| 1324 | 1287 | p->lnRight++; |
| 1325 | | - blob_appendf(&p->aCol[3],"%d\n", p->lnRight); |
| 1326 | | - blob_append(&p->aCol[4], "<ins>", 5); |
| 1327 | | - htmlize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n); |
| 1328 | | - blob_append(&p->aCol[4], "</ins>\n", 7); |
| 1329 | | - p->nPending++; |
| 1288 | + blob_append (&p->bBuf2, "<tr class=\"diffline\">", 21); |
| 1289 | + blob_append (&p->bBuf2, "<td class=\"diffln difflnl ins\"></td>", 36); |
| 1290 | + blob_appendf(&p->bBuf2, "<td class=\"diffln difflnr ins\">%d</td>", |
| 1291 | + p->lnRight); |
| 1292 | + blob_append (&p->bBuf2, "<td class=\"diffsep ins\">+</td>", 30); |
| 1293 | + blob_append (&p->bBuf2, "<td class=\"difftxt difftxtu ins\"><ins>", 38); |
| 1294 | + htmlize_to_blob(&p->bBuf2, pLine->z, (int)pLine->n); |
| 1295 | + blob_append (&p->bBuf2, "</ins></td>", 11); |
| 1296 | + blob_append (&p->bBuf2, "</tr>\n", 6); |
| 1330 | 1297 | } |
| 1331 | 1298 | static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){ |
| 1332 | 1299 | dfunifiedStartRow(p); |
| 1333 | 1300 | dfunifiedFinishInsert(p); |
| 1334 | 1301 | if( p->eState==0 ){ |
| 1335 | 1302 | dfunifiedFinishInsert(p); |
| 1336 | | - blob_append(p->pOut, "<del>", 5); |
| 1337 | | - blob_append(&p->aCol[2], "<del>", 5); |
| 1338 | | - p->eState = 1; |
| 1339 | | - } |
| 1340 | | - p->lnLeft++; |
| 1341 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1342 | | - blob_append_char(&p->aCol[0],'\n'); |
| 1343 | | - blob_append(&p->aCol[1],"-\n",2); |
| 1344 | | - blob_append(&p->aCol[2], "<del>", 5); |
| 1345 | | - htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n); |
| 1346 | | - blob_append(&p->aCol[2], "</del>\n", 7); |
| 1347 | | -} |
| 1348 | | -static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){ |
| 1349 | | - dfunifiedStartRow(p); |
| 1350 | | - if( p->eState==0 ){ |
| 1351 | | - dfunifiedFinishInsert(p); |
| 1352 | | - blob_append(p->pOut, "<del>", 5); |
| 1353 | | - blob_append(&p->aCol[2], "<del>", 5); |
| 1354 | | - p->eState = 1; |
| 1355 | | - } |
| 1356 | | - p->lnLeft++; |
| 1357 | | - p->lnRight++; |
| 1358 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1359 | | - blob_append_char(&p->aCol[0], '\n'); |
| 1360 | | - blob_append(&p->aCol[1], "-\n", 2); |
| 1361 | | - |
| 1362 | | - htmlize_to_blob(&p->aCol[2], pX->z, pX->n); |
| 1363 | | - blob_append_char(&p->aCol[2], '\n'); |
| 1364 | | - |
| 1365 | | - blob_appendf(&p->aCol[3],"%d\n", p->lnRight); |
| 1366 | | - |
| 1367 | | - htmlize_to_blob(&p->aCol[4], pY->z, pY->n); |
| 1368 | | - blob_append_char(&p->aCol[4], '\n'); |
| 1369 | | - p->nPending++; |
| 1303 | + p->eState = 1; |
| 1304 | + } |
| 1305 | + p->lnLeft++; |
| 1306 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1307 | + blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft); |
| 1308 | + blob_append (p->pOut, "<td class=\"diffln difflnr del\"></td>", 36); |
| 1309 | + blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30); |
| 1310 | + blob_append (p->pOut, "<td class=\"difftxt difftxtu del\"><del>", 38); |
| 1311 | + htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n); |
| 1312 | + blob_append (p->pOut, "</del></td>", 11); |
| 1313 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1314 | +} |
| 1315 | +static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){ |
| 1316 | + assert( 0 && "The seemingly unused function dfunifiedReplace() was called!"); |
| 1370 | 1317 | } |
| 1371 | 1318 | static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){ |
| 1372 | 1319 | int i; |
| 1373 | 1320 | int x; |
| 1374 | 1321 | LineChange chng; |
| 1375 | 1322 | oneLineChange(pX, pY, &chng); |
| 1376 | 1323 | dfunifiedStartRow(p); |
| 1377 | 1324 | if( p->eState==0 ){ |
| 1378 | 1325 | dfunifiedFinishInsert(p); |
| 1379 | | - blob_append(p->pOut, "<del>", 5); |
| 1380 | | - blob_append(&p->aCol[2], "<del>", 5); |
| 1381 | 1326 | p->eState = 1; |
| 1382 | 1327 | } |
| 1383 | 1328 | p->lnLeft++; |
| 1384 | 1329 | p->lnRight++; |
| 1385 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1386 | | - blob_append_char(&p->aCol[0], '\n'); |
| 1387 | | - blob_append(&p->aCol[1], "-\n", 2); |
| 1388 | | - |
| 1389 | | - for(i=x=0; i<chng.n; i++){ |
| 1330 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1331 | + blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft); |
| 1332 | + blob_append (p->pOut, "<td class=\"diffln difflnr del\"></td>", 36); |
| 1333 | + blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30); |
| 1334 | + blob_append (p->pOut, "<td class=\"difftxt difftxtu del\">", 33); |
| 1335 | + for( i=x=0; i<chng.n; i++ ){ |
| 1390 | 1336 | int ofst = chng.a[i].iStart1; |
| 1391 | 1337 | int len = chng.a[i].iLen1; |
| 1392 | 1338 | if( len ){ |
| 1393 | | - htmlize_to_blob(&p->aCol[2], pX->z+x, ofst - x); |
| 1339 | + htmlize_to_blob(p->pOut, pX->z+x, ofst - x); |
| 1394 | 1340 | x = ofst; |
| 1395 | | - blob_append(&p->aCol[2], "<del>", 5); |
| 1396 | | - htmlize_to_blob(&p->aCol[2], pX->z+x, len); |
| 1341 | + blob_append(p->pOut, "<del>", 5); |
| 1342 | + htmlize_to_blob(p->pOut, pX->z+x, len); |
| 1397 | 1343 | x += len; |
| 1398 | | - blob_append(&p->aCol[2], "</del>", 6); |
| 1344 | + blob_append(p->pOut, "</del>", 6); |
| 1399 | 1345 | } |
| 1400 | 1346 | } |
| 1401 | | - htmlize_to_blob(&p->aCol[2], pX->z+x, pX->n - x); |
| 1402 | | - blob_append_char(&p->aCol[2], '\n'); |
| 1403 | | - |
| 1404 | | - blob_appendf(&p->aCol[3],"%d\n", p->lnRight); |
| 1405 | | - for(i=x=0; i<chng.n; i++){ |
| 1347 | + htmlize_to_blob(p->pOut, pX->z+x, pX->n - x); |
| 1348 | + blob_append (p->pOut, "</td>", 5); |
| 1349 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1350 | + blob_append (&p->bBuf2, "<tr class=\"diffline\">", 21); |
| 1351 | + blob_append (&p->bBuf2, "<td class=\"diffln difflnl ins\"></td>", 36); |
| 1352 | + blob_appendf(&p->bBuf2, "<td class=\"diffln difflnr ins\">%d</td>", |
| 1353 | + p->lnRight); |
| 1354 | + blob_append (&p->bBuf2, "<td class=\"diffsep ins\">+</td>", 30); |
| 1355 | + blob_append (&p->bBuf2, "<td class=\"difftxt difftxtu ins\">", 33); |
| 1356 | + for( i=x=0; i<chng.n; i++ ){ |
| 1406 | 1357 | int ofst = chng.a[i].iStart2; |
| 1407 | 1358 | int len = chng.a[i].iLen2; |
| 1408 | 1359 | if( len ){ |
| 1409 | | - htmlize_to_blob(&p->aCol[4], pY->z+x, ofst - x); |
| 1360 | + htmlize_to_blob(&p->bBuf2, pY->z+x, ofst - x); |
| 1410 | 1361 | x = ofst; |
| 1411 | | - blob_append(&p->aCol[4], "<ins>", 5); |
| 1412 | | - htmlize_to_blob(&p->aCol[4], pY->z+x, len); |
| 1362 | + blob_append(&p->bBuf2, "<ins>", 5); |
| 1363 | + htmlize_to_blob(&p->bBuf2, pY->z+x, len); |
| 1413 | 1364 | x += len; |
| 1414 | | - blob_append(&p->aCol[4], "</ins>", 6); |
| 1365 | + blob_append(&p->bBuf2, "</ins>", 6); |
| 1415 | 1366 | } |
| 1416 | 1367 | } |
| 1417 | | - htmlize_to_blob(&p->aCol[4], pY->z+x, pY->n - x); |
| 1418 | | - blob_append_char(&p->aCol[4], '\n'); |
| 1419 | | - p->nPending++; |
| 1368 | + htmlize_to_blob(&p->bBuf2, pY->z+x, pY->n - x); |
| 1369 | + blob_append (&p->bBuf2, "</td>", 5); |
| 1370 | + blob_append (&p->bBuf2, "</tr>\n", 6); |
| 1420 | 1371 | } |
| 1421 | 1372 | static void dfunifiedEnd(DiffBuilder *p){ |
| 1422 | 1373 | dfunifiedFinishRow(p); |
| 1423 | | - blob_append(p->pOut, "</table>\n",-1); |
| 1374 | + blob_append(p->pOut, "</table>\n", 9); |
| 1375 | + blob_reset(&p->bBuf2); |
| 1424 | 1376 | fossil_free(p); |
| 1425 | 1377 | } |
| 1426 | 1378 | static DiffBuilder *dfunifiedNew(Blob *pOut, DiffConfig *pCfg){ |
| 1427 | 1379 | DiffBuilder *p = fossil_malloc(sizeof(*p)); |
| 1428 | 1380 | p->xSkip = dfunifiedSkip; |
| | @@ -1432,220 +1384,158 @@ |
| 1432 | 1384 | p->xReplace = dfunifiedReplace; |
| 1433 | 1385 | p->xEdit = dfunifiedEdit; |
| 1434 | 1386 | p->xEnd = dfunifiedEnd; |
| 1435 | 1387 | p->lnLeft = p->lnRight = 0; |
| 1436 | 1388 | p->eState = 0; |
| 1437 | | - p->nPending = 0; |
| 1438 | 1389 | p->pOut = pOut; |
| 1439 | 1390 | if( pCfg->zLeftHash ){ |
| 1440 | 1391 | blob_appendf(pOut, "<table class=\"diff udiff\" data-lefthash=\"%s\">\n", |
| 1441 | | - pCfg->zLeftHash); |
| 1392 | + pCfg->zLeftHash); |
| 1442 | 1393 | }else{ |
| 1443 | | - blob_append(pOut, "<table class=\"diff udiff\">\n", -1); |
| 1394 | + blob_append(pOut, "<table class=\"diff udiff\">\n", 27); |
| 1444 | 1395 | } |
| 1445 | | - blob_init(&p->aCol[0], 0, 0); |
| 1446 | | - blob_init(&p->aCol[1], 0, 0); |
| 1447 | | - blob_init(&p->aCol[2], 0, 0); |
| 1448 | | - blob_init(&p->aCol[3], 0, 0); |
| 1449 | | - blob_init(&p->aCol[4], 0, 0); |
| 1396 | + blob_init(&p->bBuf2, 0, 0); |
| 1450 | 1397 | p->pCfg = pCfg; |
| 1451 | 1398 | return p; |
| 1452 | 1399 | } |
| 1453 | 1400 | |
| 1454 | 1401 | /************************* DiffBuilderSplit ******************************/ |
| 1455 | 1402 | /* This formatter creates a side-by-side diff in HTML. The output is a |
| 1456 | | -** <table> with 5 columns: |
| 1457 | | -** |
| 1458 | | -** 1. Line numbers for the first file. |
| 1459 | | -** 2. Text for the first file. |
| 1460 | | -** 3. The difference mark. "<", ">", "|" or blank |
| 1461 | | -** 4. Line numbers for the second file. |
| 1462 | | -** 5. Text for the second file. |
| 1463 | | -** |
| 1464 | | -** The <ins> and <del> strategy is the same as for unified diff above. |
| 1465 | | -** In fact, the same CSS can be used for both. |
| 1403 | +** <table> with 6 columns: |
| 1404 | +** |
| 1405 | +** 1. Line numbers for the first file. |
| 1406 | +** 2. First difference mark: "+", "-" or blank. |
| 1407 | +** 3. Text for the first file. |
| 1408 | +** 4. Line numbers for the second file. |
| 1409 | +** 5. Second difference mark: "+", "-" or blank. |
| 1410 | +** 6. Text for the second file. |
| 1411 | +** |
| 1412 | +** The styling approach with .nul, .ins and .del CSS classes and <ins> and |
| 1413 | +** <del> elements is the same as for the unified diffs above. In fact, the |
| 1414 | +** same CSS can be used for both. |
| 1466 | 1415 | ** |
| 1467 | 1416 | ** Accumulator strategy: |
| 1468 | 1417 | ** |
| 1469 | | -** * Left line numbers are output directly to p->pOut |
| 1470 | | -** * Left text accumulates in p->aCol[0]. |
| 1471 | | -** * Edit marks accumulates in p->aCol[1]. |
| 1472 | | -** * Right line numbers accumulate in p->aCol[2]. |
| 1473 | | -** * Right text accumulates in p->aCol[3]. |
| 1418 | +** * All output goes directly to p->pOut |
| 1474 | 1419 | ** |
| 1475 | | -** eState: |
| 1476 | | -** 0 In common block |
| 1477 | | -** 1 Have <del> on the left |
| 1478 | | -** 2 Have <ins> on the right |
| 1479 | | -** 3 Have <del> on left and <ins> on the right |
| 1420 | +** eState is not unused. |
| 1480 | 1421 | */ |
| 1481 | | -static void dfsplitChangeState(DiffBuilder *p, int newState){ |
| 1482 | | - if( p->eState == newState ) return; |
| 1483 | | - if( (p->eState&1)==0 && (newState & 1)!=0 ){ |
| 1484 | | - blob_append(p->pOut, "<del>", 5); |
| 1485 | | - blob_append(&p->aCol[0], "<del>", 5); |
| 1486 | | - p->eState |= 1; |
| 1487 | | - }else if( (p->eState&1)!=0 && (newState & 1)==0 ){ |
| 1488 | | - blob_append(p->pOut, "</del>", 6); |
| 1489 | | - blob_append(&p->aCol[0], "</del>", 6); |
| 1490 | | - p->eState &= ~1; |
| 1491 | | - } |
| 1492 | | - if( (p->eState&2)==0 && (newState & 2)!=0 ){ |
| 1493 | | - blob_append(&p->aCol[2], "<ins>", 5); |
| 1494 | | - blob_append(&p->aCol[3], "<ins>", 5); |
| 1495 | | - p->eState |= 2; |
| 1496 | | - }else if( (p->eState&2)!=0 && (newState & 2)==0 ){ |
| 1497 | | - blob_append(&p->aCol[2], "</ins>", 6); |
| 1498 | | - blob_append(&p->aCol[3], "</ins>", 6); |
| 1499 | | - p->eState &= ~2; |
| 1500 | | - } |
| 1501 | | -} |
| 1502 | | -static void dfsplitFinishRow(DiffBuilder *p){ |
| 1503 | | - if( blob_size(&p->aCol[0])==0 ) return; |
| 1504 | | - dfsplitChangeState(p, 0); |
| 1505 | | - blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtl\"><pre>\n",-1); |
| 1506 | | - blob_append_xfer(p->pOut, &p->aCol[0]); |
| 1507 | | - blob_append(p->pOut, "</pre></td><td class=\"diffsep\"><pre>\n", -1); |
| 1508 | | - blob_append_xfer(p->pOut, &p->aCol[1]); |
| 1509 | | - blob_append(p->pOut, "</pre></td><td class=\"diffln difflnr\"><pre>\n",-1); |
| 1510 | | - blob_append_xfer(p->pOut, &p->aCol[2]); |
| 1511 | | - blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtr\"><pre>\n",-1); |
| 1512 | | - blob_append_xfer(p->pOut, &p->aCol[3]); |
| 1513 | | - blob_append(p->pOut, "</pre></td></tr>\n", -1); |
| 1514 | | -} |
| 1515 | | -static void dfsplitStartRow(DiffBuilder *p){ |
| 1516 | | - if( blob_size(&p->aCol[0])>0 ) return; |
| 1517 | | - blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">" |
| 1518 | | - "<td class=\"diffln difflnl\"><pre>\n", ++nChunk); |
| 1519 | | - p->eState = 0; |
| 1520 | | -} |
| 1521 | 1422 | static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){ |
| 1522 | | - dfsplitFinishRow(p); |
| 1523 | 1423 | if( p->pCfg && p->pCfg->zLeftHash ){ |
| 1524 | 1424 | blob_appendf(p->pOut, |
| 1525 | 1425 | "<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\"" |
| 1526 | 1426 | " id=\"skip%xh%xi%x\">\n", |
| 1527 | | - p->lnLeft+1, p->lnLeft+n, |
| 1528 | | - nChunk,p->lnLeft,n); |
| 1427 | + p->lnLeft+1, p->lnLeft+n, nChunk, p->lnLeft, n); |
| 1529 | 1428 | }else{ |
| 1530 | 1429 | blob_append(p->pOut, "<tr>", 4); |
| 1531 | 1430 | } |
| 1532 | 1431 | blob_append(p->pOut, |
| 1533 | | - "<td class=\"diffln difflnl difflne\">︙</td>" |
| 1534 | | - "<td></td><td></td>" |
| 1535 | | - "<td class=\"diffln difflnr difflne\">︙</td>" |
| 1536 | | - "<td/td></tr>\n", -1); |
| 1432 | + "<td class=\"diffln difflnl difflne\" colspan=\"3\">︙</td>" |
| 1433 | + "<td class=\"diffln difflnr difflne\" colspan=\"3\">︙</td>" |
| 1434 | + "</tr>\n", -1); |
| 1537 | 1435 | p->lnLeft += n; |
| 1538 | 1436 | p->lnRight += n; |
| 1539 | 1437 | } |
| 1540 | 1438 | static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){ |
| 1541 | | - dfsplitStartRow(p); |
| 1542 | | - dfsplitChangeState(p, 0); |
| 1543 | 1439 | p->lnLeft++; |
| 1544 | 1440 | p->lnRight++; |
| 1545 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1546 | | - htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n); |
| 1547 | | - blob_append_char(&p->aCol[0], '\n'); |
| 1548 | | - blob_append_char(&p->aCol[1], '\n'); |
| 1549 | | - blob_appendf(&p->aCol[2],"%d\n",p->lnRight); |
| 1550 | | - htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n); |
| 1551 | | - blob_append_char(&p->aCol[3], '\n'); |
| 1441 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1442 | + blob_appendf(p->pOut, "<td class=\"diffln difflnl\">%d</td>", p->lnLeft); |
| 1443 | + blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25); |
| 1444 | + blob_append (p->pOut, "<td class=\"difftxt difftxtl\">", 29); |
| 1445 | + htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n); |
| 1446 | + blob_append (p->pOut, "</td>", 5); |
| 1447 | + blob_appendf(p->pOut, "<td class=\"diffln difflnr\">%d</td>", p->lnRight); |
| 1448 | + blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25); |
| 1449 | + blob_append (p->pOut, "<td class=\"difftxt difftxtr\">", 29); |
| 1450 | + htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n); |
| 1451 | + blob_append (p->pOut, "</td>", 5); |
| 1452 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1552 | 1453 | } |
| 1553 | 1454 | static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){ |
| 1554 | | - dfsplitStartRow(p); |
| 1555 | | - dfsplitChangeState(p, 2); |
| 1556 | 1455 | p->lnRight++; |
| 1557 | | - blob_append_char(p->pOut, '\n'); |
| 1558 | | - blob_append_char(&p->aCol[0], '\n'); |
| 1559 | | - blob_append(&p->aCol[1], ">\n", -1); |
| 1560 | | - blob_appendf(&p->aCol[2],"%d\n", p->lnRight); |
| 1561 | | - blob_append(&p->aCol[3], "<ins>", 5); |
| 1562 | | - htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n); |
| 1563 | | - blob_append(&p->aCol[3], "</ins>\n", 7); |
| 1456 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1457 | + blob_append (p->pOut, "<td class=\"diffln difflnl nul\"></td>", 36); |
| 1458 | + blob_append (p->pOut, "<td class=\"diffsep nul\"></td>", 29); |
| 1459 | + blob_append (p->pOut, "<td class=\"difftxt difftxtl nul\"></td>", 38); |
| 1460 | + blob_appendf(p->pOut, "<td class=\"diffln difflnr ins\">%d</td>", p->lnRight); |
| 1461 | + blob_append (p->pOut, "<td class=\"diffsep ins\">+</td>", 30); |
| 1462 | + blob_append (p->pOut, "<td class=\"difftxt difftxtr ins\"><ins>", 38); |
| 1463 | + htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n); |
| 1464 | + blob_append (p->pOut, "</ins></td>", 11); |
| 1465 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1564 | 1466 | } |
| 1565 | 1467 | static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){ |
| 1566 | | - dfsplitStartRow(p); |
| 1567 | | - dfsplitChangeState(p, 1); |
| 1568 | 1468 | p->lnLeft++; |
| 1569 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1570 | | - blob_append(&p->aCol[0], "<del>", 5); |
| 1571 | | - htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n); |
| 1572 | | - blob_append(&p->aCol[0], "</del>\n", 7); |
| 1573 | | - blob_append(&p->aCol[1], "<\n", -1); |
| 1574 | | - blob_append_char(&p->aCol[2],'\n'); |
| 1575 | | - blob_append_char(&p->aCol[3],'\n'); |
| 1469 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1470 | + blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft); |
| 1471 | + blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30); |
| 1472 | + blob_append (p->pOut, "<td class=\"difftxt difftxtl del\"><del>", 38); |
| 1473 | + htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n); |
| 1474 | + blob_append (p->pOut, "</del></td>", 11); |
| 1475 | + blob_append (p->pOut, "<td class=\"diffln difflnr nul\"></td>", 36); |
| 1476 | + blob_append (p->pOut, "<td class=\"diffsep nul\"></td>", 29); |
| 1477 | + blob_append (p->pOut, "<td class=\"difftxt difftxtr nul\"></td>", 38); |
| 1478 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1576 | 1479 | } |
| 1577 | 1480 | static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){ |
| 1578 | | - dfsplitStartRow(p); |
| 1579 | | - dfsplitChangeState(p, 3); |
| 1580 | | - p->lnLeft++; |
| 1581 | | - p->lnRight++; |
| 1582 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1583 | | - htmlize_to_blob(&p->aCol[0], pX->z, pX->n); |
| 1584 | | - blob_append_char(&p->aCol[0], '\n'); |
| 1585 | | - |
| 1586 | | - blob_append(&p->aCol[1], "|\n", 2); |
| 1587 | | - |
| 1588 | | - blob_appendf(&p->aCol[2],"%d\n", p->lnRight); |
| 1589 | | - |
| 1590 | | - htmlize_to_blob(&p->aCol[3], pY->z, pY->n); |
| 1591 | | - blob_append_char(&p->aCol[3], '\n'); |
| 1481 | + assert( 0 && "The seemingly unused function dfsplitReplace() was called!"); |
| 1592 | 1482 | } |
| 1593 | 1483 | static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){ |
| 1594 | 1484 | int i; |
| 1595 | 1485 | int x; |
| 1596 | 1486 | LineChange chng; |
| 1597 | 1487 | oneLineChange(pX, pY, &chng); |
| 1598 | | - dfsplitStartRow(p); |
| 1599 | | - dfsplitChangeState(p, 3); |
| 1600 | 1488 | p->lnLeft++; |
| 1601 | 1489 | p->lnRight++; |
| 1602 | | - blob_appendf(p->pOut,"%d\n", p->lnLeft); |
| 1603 | | - for(i=x=0; i<chng.n; i++){ |
| 1490 | + blob_append (p->pOut, "<tr class=\"diffline\">", 21); |
| 1491 | + blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft); |
| 1492 | + blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30); |
| 1493 | + blob_append (p->pOut, "<td class=\"difftxt difftxtl del\">", 33); |
| 1494 | + for( i=x=0; i<chng.n; i++ ){ |
| 1604 | 1495 | int ofst = chng.a[i].iStart1; |
| 1605 | 1496 | int len = chng.a[i].iLen1; |
| 1606 | 1497 | if( len ){ |
| 1607 | | - htmlize_to_blob(&p->aCol[0], pX->z+x, ofst - x); |
| 1498 | + htmlize_to_blob(p->pOut, pX->z+x, ofst - x); |
| 1608 | 1499 | x = ofst; |
| 1609 | 1500 | if( chng.a[i].iLen2 ){ |
| 1610 | | - blob_append(&p->aCol[0], "<del class='edit'>", -1); |
| 1501 | + blob_append(p->pOut, "<del class=\"edit\">", 18); |
| 1611 | 1502 | }else{ |
| 1612 | | - blob_append(&p->aCol[0], "<del>", 5); |
| 1503 | + blob_append(p->pOut, "<del>", 5); |
| 1613 | 1504 | } |
| 1614 | | - htmlize_to_blob(&p->aCol[0], pX->z+x, len); |
| 1505 | + htmlize_to_blob(p->pOut, pX->z+x, len); |
| 1615 | 1506 | x += len; |
| 1616 | | - blob_append(&p->aCol[0], "</del>", 6); |
| 1507 | + blob_append(p->pOut, "</del>", 6); |
| 1617 | 1508 | } |
| 1618 | 1509 | } |
| 1619 | | - htmlize_to_blob(&p->aCol[0], pX->z+x, pX->n - x); |
| 1620 | | - blob_append_char(&p->aCol[0], '\n'); |
| 1621 | | - |
| 1622 | | - blob_append(&p->aCol[1], "|\n", 2); |
| 1623 | | - |
| 1624 | | - blob_appendf(&p->aCol[2],"%d\n", p->lnRight); |
| 1625 | | - for(i=x=0; i<chng.n; i++){ |
| 1510 | + htmlize_to_blob(p->pOut, pX->z+x, pX->n - x); |
| 1511 | + blob_append (p->pOut, "</td>", 5); |
| 1512 | + blob_appendf(p->pOut, "<td class=\"diffln difflnr ins\">%d</td>", p->lnRight); |
| 1513 | + blob_append (p->pOut, "<td class=\"diffsep ins\">+</td>", 30); |
| 1514 | + blob_append (p->pOut, "<td class=\"difftxt difftxtr ins\">", 33); |
| 1515 | + for( i=x=0; i<chng.n; i++ ){ |
| 1626 | 1516 | int ofst = chng.a[i].iStart2; |
| 1627 | 1517 | int len = chng.a[i].iLen2; |
| 1628 | 1518 | if( len ){ |
| 1629 | | - htmlize_to_blob(&p->aCol[3], pY->z+x, ofst - x); |
| 1519 | + htmlize_to_blob(p->pOut, pY->z+x, ofst - x); |
| 1630 | 1520 | x = ofst; |
| 1631 | 1521 | if( chng.a[i].iLen1 ){ |
| 1632 | | - blob_append(&p->aCol[3], "<ins class='edit'>", -1); |
| 1522 | + blob_append(p->pOut, "<ins class=\"edit\">", 18); |
| 1633 | 1523 | }else{ |
| 1634 | | - blob_append(&p->aCol[3], "<ins>", 5); |
| 1524 | + blob_append(p->pOut, "<ins>", 5); |
| 1635 | 1525 | } |
| 1636 | | - htmlize_to_blob(&p->aCol[3], pY->z+x, len); |
| 1526 | + htmlize_to_blob(p->pOut, pY->z+x, len); |
| 1637 | 1527 | x += len; |
| 1638 | | - blob_append(&p->aCol[3], "</ins>", 6); |
| 1528 | + blob_append(p->pOut, "</ins>", 6); |
| 1639 | 1529 | } |
| 1640 | 1530 | } |
| 1641 | | - htmlize_to_blob(&p->aCol[3], pY->z+x, pY->n - x); |
| 1642 | | - blob_append_char(&p->aCol[3], '\n'); |
| 1531 | + htmlize_to_blob(p->pOut, pY->z+x, pY->n - x); |
| 1532 | + blob_append (p->pOut, "</td>", 5); |
| 1533 | + blob_append (p->pOut, "</tr>\n", 6); |
| 1643 | 1534 | } |
| 1644 | 1535 | static void dfsplitEnd(DiffBuilder *p){ |
| 1645 | | - dfsplitFinishRow(p); |
| 1646 | | - blob_append(p->pOut, "</table>\n",-1); |
| 1536 | + blob_append(p->pOut, "</table>\n", 9); |
| 1647 | 1537 | fossil_free(p); |
| 1648 | 1538 | } |
| 1649 | 1539 | static DiffBuilder *dfsplitNew(Blob *pOut, DiffConfig *pCfg){ |
| 1650 | 1540 | DiffBuilder *p = fossil_malloc(sizeof(*p)); |
| 1651 | 1541 | p->xSkip = dfsplitSkip; |
| | @@ -1661,17 +1551,12 @@ |
| 1661 | 1551 | if( pCfg->zLeftHash ){ |
| 1662 | 1552 | blob_appendf(pOut, |
| 1663 | 1553 | "<table class=\"diff splitdiff\" data-lefthash=\"%s\">\n", |
| 1664 | 1554 | pCfg->zLeftHash); |
| 1665 | 1555 | }else{ |
| 1666 | | - blob_append(pOut, "<table class=\"diff splitdiff\">\n", -1); |
| 1556 | + blob_append(pOut, "<table class=\"diff splitdiff\">\n", 31); |
| 1667 | 1557 | } |
| 1668 | | - blob_init(&p->aCol[0], 0, 0); |
| 1669 | | - blob_init(&p->aCol[1], 0, 0); |
| 1670 | | - blob_init(&p->aCol[2], 0, 0); |
| 1671 | | - blob_init(&p->aCol[3], 0, 0); |
| 1672 | | - blob_init(&p->aCol[4], 0, 0); |
| 1673 | 1558 | p->pCfg = pCfg; |
| 1674 | 1559 | return p; |
| 1675 | 1560 | } |
| 1676 | 1561 | |
| 1677 | 1562 | /************************* DiffBuilderSbs ******************************/ |
| 1678 | 1563 | |