Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Begin inserting code to implement an "annotate" command. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
9b68bc33bd40d979bd762fff98b3257d |
| User & Date: | drh 2008-02-04 16:39:09.000 |
Context
|
2008-02-04
| ||
| 17:26 | Added 'achtung' class. See the code comments. ... (check-in: b5b04dcf85 user: stephan tags: trunk) | |
| 16:39 | Begin inserting code to implement an "annotate" command. ... (check-in: 9b68bc33bd user: drh tags: trunk) | |
| 14:24 | Additional cleanup in the differencing engine. The new "dir" webpage now uses name= instead of the d= for the query parameter. ... (check-in: e81cc91aa4 user: drh tags: trunk) | |
Changes
Changes to src/diff.c.
| ︙ | ︙ | |||
547 548 549 550 551 552 553 |
if( g.argc!=4 ) usage("FILE1 FILE2");
blob_read_from_file(&a, g.argv[2]);
blob_read_from_file(&b, g.argv[3]);
blob_zero(&out);
text_diff(&a, &b, &out, 3);
blob_write_to_file(&out, "-");
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
if( g.argc!=4 ) usage("FILE1 FILE2");
blob_read_from_file(&a, g.argv[2]);
blob_read_from_file(&b, g.argv[3]);
blob_zero(&out);
text_diff(&a, &b, &out, 3);
blob_write_to_file(&out, "-");
}
/**************************************************************************
** The basic difference engine is above. What follows is the annotation
** engine. Both are in the same file since they share many components.
*/
/*
** The status of an annotation operation is recorded by an instance
** of the following structure.
*/
typedef struct Annotator Annotator;
struct Annotator {
DContext c; /* The diff-engine context */
Blob blobTo; /* Blob to free at next step */
int nOrig; /* Number of lines in original file */
int nNoSrc; /* Number of uncompleted aOrig[].zSrc entries */
struct { /* Lines of the original files... */
const char *z; /* The text of the line */
int n; /* Number of bytes (omitting trailing space and \n) */
const char *zSrc; /* Tag showing origin of this line */
} *aOrig;
int *aMap; /* Map lines for c.aTo into aOrig */
};
/*
** Initialize the annotation process by specifying the file that is
** to be annotated. The annotator takes control of the input Blob and
** will release it when it is finished with it.
*/
static int annotation_start(Annotator *p, Blob *pInput){
int i;
memset(p, 0, sizeof(*p));
p->c.aTo = break_into_lines(blob_str(pInput), &p->c.nTo);
if( p->c.aTo==0 ){
return 1;
}
p->aMap = malloc( sizeof(int)*p->c.nTo );
if( p->aMap==0 ) fossil_panic("out of memory");
for(i=0; i<p->c.nTo; i++) p->aMap[i] = i;
p->aOrig = malloc( sizeof(p->aOrig[0])*p->c.nTo );
if( p->aOrig==0 ) fossil_panic("out of memory");
for(i=0; i<p->c.nTo; i++){
p->aOrig[i].z = p->c.aTo[i].z;
p->aOrig[i].n = p->c.aTo[i].h & LENGTH_MASK;
p->aOrig[i].zSrc = 0;
}
p->nOrig = p->c.nTo;
p->nNoSrc = p->c.nTo;
return 0;
}
/*
** The input pParent is the next most recent ancestor of the file
** being annotated. Do another step of the annotation. Return true
** if additional annotation is required. zPName is the tag to insert
** on each line of the file being annotated that was contributed by
** pParent. Memory to hold zPName is leaked.
*/
static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
int i, j;
int lnTo, lnFrom;
int *aFromMap;
/* Prepare the parent file to be diffed */
p->c.aFrom = break_into_lines(blob_str(pParent), &p->c.nFrom);
if( p->c.aFrom==0 ){
return 1;
}
/* Compute the differences going from pParent to the last file
** processed */
diff_all(&p->c);
/* Where new lines are inserted on this difference, record the
** zPName as the source of the new line.
*/
for(i=lnTo=0; i<p->c.nEdit; i+=3){
lnTo += p->c.aEdit[i];
for(j=0; j<p->c.aEdit[i+2]; j++, lnTo++){
int x = p->aMap[lnTo];
if( x>=0 && p->aOrig[x].zSrc==0 ){
p->aOrig[x].zSrc = zPName;
p->nNoSrc--;
}
}
}
/* We will be converting aFrom into aTo for the next step. Compute
** a map from the aFrom into the original file being annotated.
*/
aFromMap = malloc( sizeof(int)*p->c.nFrom );
if( aFromMap==0 ){
fossil_panic("out of memory");
}
for(i=lnTo=lnFrom=0; i<p->c.nEdit; i+=3){
for(j=0; j<p->c.aEdit[i]; j++){
aFromMap[lnFrom++] = p->aMap[lnTo++];
}
for(j=0; j<p->c.aEdit[i+1]; j++){
aFromMap[lnFrom++] = -1;
}
lnTo += p->c.aEdit[i+2];
}
assert( lnFrom==p->c.nFrom );
free(p->aMap);
p->aMap = aFromMap;
/* Clear out the diff results */
free(p->c.aEdit);
p->c.aEdit = 0;
p->c.nEdit = 0;
p->c.nEditAlloc = 0;
/* Move aFrom over to aTo in preparation for the next step */
free(p->c.aTo);
if( blob_buffer(&p->blobTo) ) blob_reset(&p->blobTo);
p->blobTo = *pParent;
blob_zero(pParent);
p->c.aTo = p->c.aFrom;
p->c.nTo = p->c.nFrom;
/* Return no errors */
return 0;
}
/*
** COMMAND: test-annotate-step
*/
void test_annotate_step_cmd(void){
Blob orig, b;
Annotator x;
int i;
if( g.argc<4 ) usage("RID1 RID2 ...");
db_must_be_within_tree();
blob_zero(&b);
content_get(name_to_rid(g.argv[2]), &orig);
if( annotation_start(&x, &orig) ){
fossil_fatal("binary file");
}
for(i=3; i<g.argc; i++){
blob_zero(&b);
content_get(name_to_rid(g.argv[i]), &b);
if( annotation_step(&x, &b, g.argv[i-1]) ){
fossil_fatal("binary file");
}
}
for(i=0; i<x.nOrig; i++){
const char *zSrc = x.aOrig[i].zSrc;
if( zSrc==0 ) zSrc = g.argv[g.argc-1];
printf("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z);
}
}
|