diff options
author | Tobias Stoeckmann <tobias@cvs.openbsd.org> | 2007-10-09 12:59:54 +0000 |
---|---|---|
committer | Tobias Stoeckmann <tobias@cvs.openbsd.org> | 2007-10-09 12:59:54 +0000 |
commit | 868da502acb914afd9fd6404607bb4374154c97a (patch) | |
tree | 7a927eea01461164dfaa078db3a4e3bcbbb82b49 /usr.bin/cvs/rcs.c | |
parent | 121846ddfbd76e9f8e2cf4234cda9c8cb2f92457 (diff) |
Added proper support for branch revisions in annotate.
OK niallo@, twice :)
Diffstat (limited to 'usr.bin/cvs/rcs.c')
-rw-r--r-- | usr.bin/cvs/rcs.c | 117 |
1 files changed, 115 insertions, 2 deletions
diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c index d3d7048bba2..c93eea9c11f 100644 --- a/usr.bin/cvs/rcs.c +++ b/usr.bin/cvs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.224 2007/10/09 12:18:53 tobias Exp $ */ +/* $OpenBSD: rcs.c,v 1.225 2007/10/09 12:59:53 tobias Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -1091,6 +1091,7 @@ rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines, lp->l_line = NULL; lp->l_needsfree = 0; } + lp->l_delta = rdp; TAILQ_INSERT_AFTER(&(dlines->l_lines), dlp, lp, l_list); dlp = lp; @@ -2800,7 +2801,7 @@ next: goto again; } done: - /* put remaining lines of 1.1 into annotate buffer */ + /* put remaining lines into annotate buffer */ if (annotate == ANNOTATE_NOW) { for (line = TAILQ_FIRST(&(dlines->l_lines)); line != NULL; line = nline) { @@ -2825,6 +2826,118 @@ done: return (dlines); } +void +rcs_annotate_getlines(RCSFILE *rfp, RCSNUM *frev, struct cvs_line ***alines) +{ + size_t plen; + int i, nextroot; + RCSNUM *bnum; + struct rcs_branch *brp; + struct rcs_delta *rdp, *trdp; + u_char *patch; + struct cvs_line *line; + struct cvs_lines *dlines, *plines; + + if (!RCSNUM_ISBRANCHREV(frev)) + fatal("rcs_annotate_getlines: branch revision expected"); + + /* revision on branch, get the branch root */ + nextroot = 2; + bnum = rcsnum_alloc(); + rcsnum_cpy(frev, bnum, nextroot); + + /* + * Going from HEAD to 1.1 enables the use of an array, which is + * much faster. Unfortunately this is not possible with branch + * revisions, so copy over our alines (array) into dlines (tailq). + */ + dlines = xcalloc(1, sizeof(*dlines)); + TAILQ_INIT(&(dlines->l_lines)); + line = xcalloc(1, sizeof(*line)); + TAILQ_INSERT_TAIL(&(dlines->l_lines), line, l_list); + + for (i = 0; (*alines)[i] != NULL; i++) { + line = (*alines)[i]; + line->l_lineno = i + 1; + TAILQ_INSERT_TAIL(&(dlines->l_lines), line, l_list); + } + + rdp = rcs_findrev(rfp, bnum); + if (rdp == NULL) + fatal("failed to grab branch root revision"); + + do { + nextroot += 2; + rcsnum_cpy(frev, bnum, nextroot); + + TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) { + for (i = 0; i < nextroot - 1; i++) + if (brp->rb_num->rn_id[i] != bnum->rn_id[i]) + break; + if (i == nextroot - 1) + break; + } + + if (brp == NULL) + fatal("expected branch not found on branch list"); + + if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) + fatal("failed to get delta for target rev"); + + for (;;) { + if (rdp->rd_next->rn_len != 0) { + trdp = rcs_findrev(rfp, rdp->rd_next); + if (trdp == NULL) + fatal("failed to grab next revision"); + } + + if (rdp->rd_tlen == 0) { + rcs_parse_deltatexts(rfp, rdp->rd_num); + if (rdp->rd_tlen == 0) { + if (!rcsnum_differ(rdp->rd_num, bnum)) + break; + rdp = trdp; + continue; + } + } + + plen = rdp->rd_tlen; + patch = rdp->rd_text; + plines = cvs_splitlines(patch, plen); + rcs_patch_lines(dlines, plines, NULL, rdp); + cvs_freelines(plines); + + if (!rcsnum_differ(rdp->rd_num, bnum)) + break; + + rdp = trdp; + } + } while (rcsnum_differ(rdp->rd_num, frev)); + + if (bnum != frev) + rcsnum_free(bnum); + + /* + * All lines have been parsed, now they must be copied over + * into alines (array) again. + */ + xfree(*alines); + + i = 0; + TAILQ_FOREACH(line, &(dlines->l_lines), l_list) { + if (line->l_line != NULL) + i++; + } + *alines = xmalloc((i + 1) * sizeof(struct cvs_line *)); + (*alines)[i] = NULL; + + i = 0; + TAILQ_FOREACH(line, &(dlines->l_lines), l_list) { + if (line->l_line != NULL) + (*alines)[i++] = line; + } +} + /* * rcs_rev_getbuf() * |