Fossil SCM

Set up the main file list loop for merge_info_html().

stephan 2024-12-07 19:52 merge-info-html
Commit 8145725503168303667ac75b1f0e25428c1f3005ba9d4211490efb209aa50253
2 files changed +108 -16 +22 -1
+108 -16
--- src/merge.c
+++ src/merge.c
@@ -297,14 +297,16 @@
297297
*/
298298
static void merge_info_html(int bBrowser, /* 0=HTML only, no browser */
299299
int bDark, /* use dark mode */
300300
int bAll, /* All changes, not just merged content */
301301
int nContext /* Diff context lines */){
302
- Blob out = empty_blob;
303
- MergeBuilderHtml mbh;
304
- MergeBuilder * mb = &mbh.base;
305
- Stmt q;
302
+ MergeBuilderHtml mbh; /* Merge builder */
303
+ MergeBuilder * mb = &mbh.base; /* Merge builder base class ref */
304
+ Blob pivot = empty_blob,
305
+ v1 = empty_blob, v2 = empty_blob,
306
+ out = empty_blob; /* Merge builder content */
307
+ Stmt q; /* MERGESTAT query */
306308
307309
/* Figure out which files to process. We do this level of indirection
308310
** so that the loop which follows is identical for both the all-files and
309311
** the CLI-list-of-files cases work identically.
310312
*/
@@ -341,35 +343,125 @@
341343
gotRid);
342344
blob_reset(&fname);
343345
}
344346
}
345347
346
- mergebuilder_init_html(&mbh);
347
- mb->nContext = nContext;
348348
blob_append(&out, diff_webpage_header(bDark), -1);
349349
merge_info_html_css(&out);
350
- mb->pOut = &out;
350
+ mergebuilder_init_html(&mbh);
351
+ mb->nContext = nContext;
351352
352353
db_prepare(&q,
353
- /* 0 1 2 3 4 5 6 7 8 9 */
354
- "SELECT op, fnp, ridp, fn, ridv, sz, fnm, ridm, fnr, coalesce(fnr,fn) name"
355
- " FROM mergestat WHERE rowid IN mi_html ORDER BY name"
354
+ /* 0 1 2 3 4 5 6 7 */
355
+ "SELECT fnp, ridp, fn, ridv, sz, fnm, ridm, fnr"
356
+ " FROM mergestat WHERE rowid IN mi_html"
357
+ " ORDER BY coalesce(fnr,fn,fnp)"
356358
);
357359
blob_append(&out, "<ul>\n", 5);
358360
while( SQLITE_ROW==db_step(&q) ){
359
- blob_appendf(&out, "<li>%s %h</li>\n",
360
- db_column_text(&q,0), db_column_text(&q,9));
361
- }
361
+ const char * zFN; /* A filename */
362
+ char * zToFree[5] = {0,0,0,0,0}; /* String memory to free */
363
+ unsigned zToFreeNdx = 0; /* Current index into zToFree */
364
+ int rid = 0; /* A blob rid */
365
+ int sz; /* File size */
366
+ unsigned int i; /* Loop counter */
367
+
368
+ /* Most of this loop is copy/paste/slight adjust from
369
+ ** merge_info_tcl(). We can possibly consolidate this setup into a
370
+ ** separate funciton. */
371
+
372
+ /* Set up the baseline/pivot... */
373
+ zFN = db_column_text(&q, 0);
374
+ if( zFN==0 ){
375
+ /* No pivot because the file was added */
376
+ mb->zPivot = "(no baseline)";
377
+ blob_reset(&pivot);
378
+ }else{
379
+ mb->zPivot = zToFree[zToFreeNdx++] =
380
+ mprintf("%s (baseline)", file_tail(zFN));
381
+ rid = db_column_int(&q, 1);
382
+ content_get(rid, &pivot);
383
+ }
384
+ mb->pPivot = &pivot;
385
+
386
+ /* Set up the merge-in as V2 */
387
+ zFN = db_column_text(&q, 5);
388
+ if( zFN==0 ){
389
+ /* File deleted in the merged-in branch */
390
+ mb->zV2 = "(deleted file)";
391
+ blob_zero(&v2);
392
+ }else{
393
+ mb->zV2 = zToFree[zToFreeNdx++] =
394
+ mprintf("%s (merge-in)", file_tail(zFN));
395
+ rid = db_column_int(&q, 6);
396
+ content_get(rid, &v2);
397
+ }
398
+ mb->pV2 = &v1;
399
+
400
+ /* Set up the merge-in as V1 */
401
+ zFN = db_column_text(&q, 2);
402
+ if( zFN==0 ){
403
+ /* File added by merge */
404
+ mb->zV1 = "(no original)";
405
+ blob_zero(&v1);
406
+ }else{
407
+ mb->zV1 = zToFree[zToFreeNdx++] =
408
+ mprintf("%s (local)", file_tail(zFN));
409
+ rid = db_column_int(&q, 3);
410
+ sz = db_column_int(&q, 4);
411
+ if( rid==0 && sz>0 ){
412
+ /* The origin file had been edited so we'll have to pull its
413
+ ** original content out of the undo buffer */
414
+ Stmt q2;
415
+ db_prepare(&q2,
416
+ "SELECT content FROM undo"
417
+ " WHERE pathname=%Q AND octet_length(content)=%d",
418
+ zFN, sz
419
+ );
420
+ blob_zero(&v1);
421
+ if( db_step(&q2)==SQLITE_ROW ){
422
+ db_column_blob(&q, 0, &v1);
423
+ }else{
424
+ mb->zV1 = "(local content missing)";
425
+ }
426
+ db_finalize(&q2);
427
+ }else{
428
+ /* The origin file was unchanged when the merge first occurred */
429
+ content_get(rid, &v1);
430
+ }
431
+ }
432
+ mb->pV1 = &v2;
433
+
434
+ /* Set up the output */
435
+ zFN = db_column_text(&q, 7);
436
+ if( zFN==0 ){
437
+ mb->zOut = "(Merge Result)";
438
+ }else{
439
+ mb->zOut = zToFree[zToFreeNdx++] =
440
+ mprintf("%s (after merge)", file_tail(zFN));
441
+ }
442
+ mb->pOut = &out;
443
+
444
+ assert( zToFreeNdx <= sizeof(zToFree)/sizeof(zToFree[0]) );
445
+
446
+ merge_three_blobs(mb);
447
+ for(i = 0; i < zToFreeNdx; ++i ){
448
+ fossil_free(zToFree[i]);
449
+ zToFree[i] = 0;
450
+ }
451
+ }/* for-each-file loop */
452
+ db_finalize(&q);
453
+ mb->xDestroy(mb);
362454
blob_append(&out, "</ul>\n", 6);
363455
364
- db_finalize(&q);
365
-
366456
blob_append(&out, diff_webpage_footer(), -1);
457
+ blob_reset(&v1);
458
+ blob_reset(&v2);
459
+ blob_reset(&pivot);
367460
blob_append_char(&out, '\n');
368461
blob_write_to_file(&out, "-");
369462
blob_reset(&out);
370
- mb->xDestroy(mb);
371463
db_multi_exec("DROP TABLE mi_html");
372464
}
373465
374466
/*
375467
** COMMAND: merge-info
376468
--- src/merge.c
+++ src/merge.c
@@ -297,14 +297,16 @@
297 */
298 static void merge_info_html(int bBrowser, /* 0=HTML only, no browser */
299 int bDark, /* use dark mode */
300 int bAll, /* All changes, not just merged content */
301 int nContext /* Diff context lines */){
302 Blob out = empty_blob;
303 MergeBuilderHtml mbh;
304 MergeBuilder * mb = &mbh.base;
305 Stmt q;
 
 
306
307 /* Figure out which files to process. We do this level of indirection
308 ** so that the loop which follows is identical for both the all-files and
309 ** the CLI-list-of-files cases work identically.
310 */
@@ -341,35 +343,125 @@
341 gotRid);
342 blob_reset(&fname);
343 }
344 }
345
346 mergebuilder_init_html(&mbh);
347 mb->nContext = nContext;
348 blob_append(&out, diff_webpage_header(bDark), -1);
349 merge_info_html_css(&out);
350 mb->pOut = &out;
 
351
352 db_prepare(&q,
353 /* 0 1 2 3 4 5 6 7 8 9 */
354 "SELECT op, fnp, ridp, fn, ridv, sz, fnm, ridm, fnr, coalesce(fnr,fn) name"
355 " FROM mergestat WHERE rowid IN mi_html ORDER BY name"
 
356 );
357 blob_append(&out, "<ul>\n", 5);
358 while( SQLITE_ROW==db_step(&q) ){
359 blob_appendf(&out, "<li>%s %h</li>\n",
360 db_column_text(&q,0), db_column_text(&q,9));
361 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362 blob_append(&out, "</ul>\n", 6);
363
364 db_finalize(&q);
365
366 blob_append(&out, diff_webpage_footer(), -1);
 
 
 
367 blob_append_char(&out, '\n');
368 blob_write_to_file(&out, "-");
369 blob_reset(&out);
370 mb->xDestroy(mb);
371 db_multi_exec("DROP TABLE mi_html");
372 }
373
374 /*
375 ** COMMAND: merge-info
376
--- src/merge.c
+++ src/merge.c
@@ -297,14 +297,16 @@
297 */
298 static void merge_info_html(int bBrowser, /* 0=HTML only, no browser */
299 int bDark, /* use dark mode */
300 int bAll, /* All changes, not just merged content */
301 int nContext /* Diff context lines */){
302 MergeBuilderHtml mbh; /* Merge builder */
303 MergeBuilder * mb = &mbh.base; /* Merge builder base class ref */
304 Blob pivot = empty_blob,
305 v1 = empty_blob, v2 = empty_blob,
306 out = empty_blob; /* Merge builder content */
307 Stmt q; /* MERGESTAT query */
308
309 /* Figure out which files to process. We do this level of indirection
310 ** so that the loop which follows is identical for both the all-files and
311 ** the CLI-list-of-files cases work identically.
312 */
@@ -341,35 +343,125 @@
343 gotRid);
344 blob_reset(&fname);
345 }
346 }
347
 
 
348 blob_append(&out, diff_webpage_header(bDark), -1);
349 merge_info_html_css(&out);
350 mergebuilder_init_html(&mbh);
351 mb->nContext = nContext;
352
353 db_prepare(&q,
354 /* 0 1 2 3 4 5 6 7 */
355 "SELECT fnp, ridp, fn, ridv, sz, fnm, ridm, fnr"
356 " FROM mergestat WHERE rowid IN mi_html"
357 " ORDER BY coalesce(fnr,fn,fnp)"
358 );
359 blob_append(&out, "<ul>\n", 5);
360 while( SQLITE_ROW==db_step(&q) ){
361 const char * zFN; /* A filename */
362 char * zToFree[5] = {0,0,0,0,0}; /* String memory to free */
363 unsigned zToFreeNdx = 0; /* Current index into zToFree */
364 int rid = 0; /* A blob rid */
365 int sz; /* File size */
366 unsigned int i; /* Loop counter */
367
368 /* Most of this loop is copy/paste/slight adjust from
369 ** merge_info_tcl(). We can possibly consolidate this setup into a
370 ** separate funciton. */
371
372 /* Set up the baseline/pivot... */
373 zFN = db_column_text(&q, 0);
374 if( zFN==0 ){
375 /* No pivot because the file was added */
376 mb->zPivot = "(no baseline)";
377 blob_reset(&pivot);
378 }else{
379 mb->zPivot = zToFree[zToFreeNdx++] =
380 mprintf("%s (baseline)", file_tail(zFN));
381 rid = db_column_int(&q, 1);
382 content_get(rid, &pivot);
383 }
384 mb->pPivot = &pivot;
385
386 /* Set up the merge-in as V2 */
387 zFN = db_column_text(&q, 5);
388 if( zFN==0 ){
389 /* File deleted in the merged-in branch */
390 mb->zV2 = "(deleted file)";
391 blob_zero(&v2);
392 }else{
393 mb->zV2 = zToFree[zToFreeNdx++] =
394 mprintf("%s (merge-in)", file_tail(zFN));
395 rid = db_column_int(&q, 6);
396 content_get(rid, &v2);
397 }
398 mb->pV2 = &v1;
399
400 /* Set up the merge-in as V1 */
401 zFN = db_column_text(&q, 2);
402 if( zFN==0 ){
403 /* File added by merge */
404 mb->zV1 = "(no original)";
405 blob_zero(&v1);
406 }else{
407 mb->zV1 = zToFree[zToFreeNdx++] =
408 mprintf("%s (local)", file_tail(zFN));
409 rid = db_column_int(&q, 3);
410 sz = db_column_int(&q, 4);
411 if( rid==0 && sz>0 ){
412 /* The origin file had been edited so we'll have to pull its
413 ** original content out of the undo buffer */
414 Stmt q2;
415 db_prepare(&q2,
416 "SELECT content FROM undo"
417 " WHERE pathname=%Q AND octet_length(content)=%d",
418 zFN, sz
419 );
420 blob_zero(&v1);
421 if( db_step(&q2)==SQLITE_ROW ){
422 db_column_blob(&q, 0, &v1);
423 }else{
424 mb->zV1 = "(local content missing)";
425 }
426 db_finalize(&q2);
427 }else{
428 /* The origin file was unchanged when the merge first occurred */
429 content_get(rid, &v1);
430 }
431 }
432 mb->pV1 = &v2;
433
434 /* Set up the output */
435 zFN = db_column_text(&q, 7);
436 if( zFN==0 ){
437 mb->zOut = "(Merge Result)";
438 }else{
439 mb->zOut = zToFree[zToFreeNdx++] =
440 mprintf("%s (after merge)", file_tail(zFN));
441 }
442 mb->pOut = &out;
443
444 assert( zToFreeNdx <= sizeof(zToFree)/sizeof(zToFree[0]) );
445
446 merge_three_blobs(mb);
447 for(i = 0; i < zToFreeNdx; ++i ){
448 fossil_free(zToFree[i]);
449 zToFree[i] = 0;
450 }
451 }/* for-each-file loop */
452 db_finalize(&q);
453 mb->xDestroy(mb);
454 blob_append(&out, "</ul>\n", 6);
455
 
 
456 blob_append(&out, diff_webpage_footer(), -1);
457 blob_reset(&v1);
458 blob_reset(&v2);
459 blob_reset(&pivot);
460 blob_append_char(&out, '\n');
461 blob_write_to_file(&out, "-");
462 blob_reset(&out);
 
463 db_multi_exec("DROP TABLE mi_html");
464 }
465
466 /*
467 ** COMMAND: merge-info
468
+22 -1
--- src/merge3.c
+++ src/merge3.c
@@ -180,10 +180,26 @@
180180
*/
181181
Blob aCol[11];
182182
};
183183
#endif /* INTERFACE */
184184
185
+/*
186
+** Column IDs for MergeBuilderHtml::aCol.
187
+*/
188
+enum MBHtml {
189
+ MBH_COL_BASELINE_LN = 0,
190
+ MBH_COL_BASELINE = 1,
191
+ MBH_COL_BASELINE_SEP = 2,
192
+ MBH_COL_LOCAL_LN = 3,
193
+ MBH_COL_LOCAL = 4,
194
+ MBH_COL_LOCAL_SEP = 5,
195
+ MBH_COL_MERGEDIN_LN = 6,
196
+ MBH_COL_MERGEDIN = 7,
197
+ MBH_COL_MERGEDIN_SEP = 8,
198
+ MBH_COL_RESULT_LN = 9,
199
+ MBH_COL_RESULT = 10
200
+};
185201
186202
/************************* Generic MergeBuilder ******************************/
187203
/* These are generic methods for MergeBuilder. They just output debugging
188204
** information. But some of them are useful as base methods for other useful
189205
** implementations of MergeBuilder.
@@ -702,14 +718,16 @@
702718
/* MergeBuilderHtml::xStart() */
703719
static void htmlStart(MergeBuilder *p){
704720
MergeBuilderHtml *pH = (MergeBuilderHtml*)p;
705721
unsigned int i;
706722
707
- /* TODO: open HTML table */
708723
for(i = 0; i < sizeof(pH->aCol)/sizeof(Blob); ++i){
709724
blob_zero(&pH->aCol[i]);
710725
}
726
+ /* TODO: open HTML table in p->pOut */
727
+ blob_appendf(p->pOut, "<li>%h &rarr; (%h, %h) &rarr; %h",
728
+ p->zPivot, p->zV1, p->zV2, p->zOut);
711729
}
712730
713731
/* MergeBuilderHtml::xEnd() */
714732
static void htmlEnd(MergeBuilder *p){
715733
MergeBuilderHtml *pH = (MergeBuilderHtml*)p;
@@ -717,10 +735,13 @@
717735
718736
/* TODO: flush pH->aCol to p->pOut and close HTML table */
719737
for(i = 0; i < sizeof(pH->aCol)/sizeof(Blob); ++i){
720738
blob_reset(&pH->aCol[i]);
721739
}
740
+ blob_append(p->pOut, "</li>\n", -1);
741
+ p->pV1 = p->pV2 = p->pPivot = p->pOut = 0;
742
+ p->zPivot = p->zV1 = p->zV2 = p->zOut = 0;
722743
}
723744
724745
/* MergeBuilderHtml::xSame() */
725746
static void htmlSame(MergeBuilder *p, unsigned int N){
726747
}
727748
--- src/merge3.c
+++ src/merge3.c
@@ -180,10 +180,26 @@
180 */
181 Blob aCol[11];
182 };
183 #endif /* INTERFACE */
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
186 /************************* Generic MergeBuilder ******************************/
187 /* These are generic methods for MergeBuilder. They just output debugging
188 ** information. But some of them are useful as base methods for other useful
189 ** implementations of MergeBuilder.
@@ -702,14 +718,16 @@
702 /* MergeBuilderHtml::xStart() */
703 static void htmlStart(MergeBuilder *p){
704 MergeBuilderHtml *pH = (MergeBuilderHtml*)p;
705 unsigned int i;
706
707 /* TODO: open HTML table */
708 for(i = 0; i < sizeof(pH->aCol)/sizeof(Blob); ++i){
709 blob_zero(&pH->aCol[i]);
710 }
 
 
 
711 }
712
713 /* MergeBuilderHtml::xEnd() */
714 static void htmlEnd(MergeBuilder *p){
715 MergeBuilderHtml *pH = (MergeBuilderHtml*)p;
@@ -717,10 +735,13 @@
717
718 /* TODO: flush pH->aCol to p->pOut and close HTML table */
719 for(i = 0; i < sizeof(pH->aCol)/sizeof(Blob); ++i){
720 blob_reset(&pH->aCol[i]);
721 }
 
 
 
722 }
723
724 /* MergeBuilderHtml::xSame() */
725 static void htmlSame(MergeBuilder *p, unsigned int N){
726 }
727
--- src/merge3.c
+++ src/merge3.c
@@ -180,10 +180,26 @@
180 */
181 Blob aCol[11];
182 };
183 #endif /* INTERFACE */
184
185 /*
186 ** Column IDs for MergeBuilderHtml::aCol.
187 */
188 enum MBHtml {
189 MBH_COL_BASELINE_LN = 0,
190 MBH_COL_BASELINE = 1,
191 MBH_COL_BASELINE_SEP = 2,
192 MBH_COL_LOCAL_LN = 3,
193 MBH_COL_LOCAL = 4,
194 MBH_COL_LOCAL_SEP = 5,
195 MBH_COL_MERGEDIN_LN = 6,
196 MBH_COL_MERGEDIN = 7,
197 MBH_COL_MERGEDIN_SEP = 8,
198 MBH_COL_RESULT_LN = 9,
199 MBH_COL_RESULT = 10
200 };
201
202 /************************* Generic MergeBuilder ******************************/
203 /* These are generic methods for MergeBuilder. They just output debugging
204 ** information. But some of them are useful as base methods for other useful
205 ** implementations of MergeBuilder.
@@ -702,14 +718,16 @@
718 /* MergeBuilderHtml::xStart() */
719 static void htmlStart(MergeBuilder *p){
720 MergeBuilderHtml *pH = (MergeBuilderHtml*)p;
721 unsigned int i;
722
 
723 for(i = 0; i < sizeof(pH->aCol)/sizeof(Blob); ++i){
724 blob_zero(&pH->aCol[i]);
725 }
726 /* TODO: open HTML table in p->pOut */
727 blob_appendf(p->pOut, "<li>%h &rarr; (%h, %h) &rarr; %h",
728 p->zPivot, p->zV1, p->zV2, p->zOut);
729 }
730
731 /* MergeBuilderHtml::xEnd() */
732 static void htmlEnd(MergeBuilder *p){
733 MergeBuilderHtml *pH = (MergeBuilderHtml*)p;
@@ -717,10 +735,13 @@
735
736 /* TODO: flush pH->aCol to p->pOut and close HTML table */
737 for(i = 0; i < sizeof(pH->aCol)/sizeof(Blob); ++i){
738 blob_reset(&pH->aCol[i]);
739 }
740 blob_append(p->pOut, "</li>\n", -1);
741 p->pV1 = p->pV2 = p->pPivot = p->pOut = 0;
742 p->zPivot = p->zV1 = p->zV2 = p->zOut = 0;
743 }
744
745 /* MergeBuilderHtml::xSame() */
746 static void htmlSame(MergeBuilder *p, unsigned int N){
747 }
748

Keyboard Shortcuts

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