summaryrefslogtreecommitdiff
path: root/usr.bin/cvs/rcs.c
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2006-03-30 23:06:26 +0000
committerJoris Vink <joris@cvs.openbsd.org>2006-03-30 23:06:26 +0000
commit493f701ec4fdf601584a36d24c99719f463cbae9 (patch)
tree082f9069625bb08be41f709cae48c0fdfc38481c /usr.bin/cvs/rcs.c
parent22e826a15c97365b4ddd9ed8486e9b16a82a75ba (diff)
first part of supporting branches in openrcs. right now we can only
check them out. commit is not working yet, but will be soon. tested by myself and ray@ okay ray@
Diffstat (limited to 'usr.bin/cvs/rcs.c')
-rw-r--r--usr.bin/cvs/rcs.c179
1 files changed, 122 insertions, 57 deletions
diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c
index 62fc1b6b2c7..e7ece10e923 100644
--- a/usr.bin/cvs/rcs.c
+++ b/usr.bin/cvs/rcs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.c,v 1.155 2006/03/29 09:16:53 ray Exp $ */
+/* $OpenBSD: rcs.c,v 1.156 2006/03/30 23:06:25 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -1169,12 +1169,14 @@ rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines)
BUF*
rcs_getrev(RCSFILE *rfp, RCSNUM *frev)
{
- int res;
+ u_int i, numlen;
+ int isbranch, lookonbranch;
size_t len;
void *bp;
- RCSNUM *crev, *rev;
+ RCSNUM *crev, *rev, *brev;
BUF *rbuf;
struct rcs_delta *rdp = NULL;
+ struct rcs_branch *rb;
if (rfp->rf_head == NULL)
return (NULL);
@@ -1184,10 +1186,12 @@ rcs_getrev(RCSFILE *rfp, RCSNUM *frev)
else
rev = frev;
- res = rcsnum_cmp(rfp->rf_head, rev, 0);
- if (res == 1) {
- rcs_errno = RCS_ERR_NOENT;
- return (NULL);
+ /* XXX rcsnum_cmp() */
+ for (i = 0; i < rfp->rf_head->rn_len; i++) {
+ if (rfp->rf_head->rn_id[i] < rev->rn_id[i]) {
+ rcs_errno = RCS_ERR_NOENT;
+ return (NULL);
+ }
}
/* No matter what, we're going to need up the the description parsed */
@@ -1198,8 +1202,10 @@ rcs_getrev(RCSFILE *rfp, RCSNUM *frev)
cvs_log(LP_ERR, "failed to get RCS HEAD revision");
return (NULL);
}
+
if (rdp->rd_tlen == 0)
rcs_parse_deltatexts(rfp, rfp->rf_head);
+
len = rdp->rd_tlen;
if (len == 0) {
rbuf = cvs_buf_alloc(1, 0);
@@ -1210,33 +1216,86 @@ rcs_getrev(RCSFILE *rfp, RCSNUM *frev)
rbuf = cvs_buf_alloc(len, BUF_AUTOEXT);
cvs_buf_append(rbuf, rdp->rd_text, len);
- if (res != 0) {
- /* Apply patches backwards to get the right version.
- * This will need some rework to support sub branches.
- */
- do {
- crev = rdp->rd_next;
- rdp = rcs_findrev(rfp, crev);
- if (rdp == NULL) {
- cvs_buf_free(rbuf);
- return (NULL);
- }
- cvs_buf_putc(rbuf, '\0');
- /* check if we have parsed this rev's deltatext */
- if (rdp->rd_tlen == 0)
- rcs_parse_deltatexts(rfp, rdp->rd_num);
-
- bp = cvs_buf_release(rbuf);
- rbuf = cvs_patchfile((char *)bp, (char *)rdp->rd_text,
- rcs_patch_lines);
- xfree(bp);
- if (rbuf == NULL)
- break;
- } while (rcsnum_cmp(crev, rev, 0) != 0);
+ isbranch = 0;
+ brev = NULL;
+
+ /*
+ * If a branch was passed, get the latest revision on it.
+ */
+ if (RCSNUM_ISBRANCH(rev)) {
+ brev = rev;
+ rdp = rcs_findrev(rfp, rev);
+ if (rdp == NULL)
+ fatal("failed to translate branch to latest revision");
+
+ rev = rdp->rd_num;
+ } else {
+ if (RCSNUM_ISBRANCHREV(rev)) {
+ brev = rcsnum_revtobr(rev);
+ isbranch = 1;
+ }
}
+
+ lookonbranch = 0;
+ crev = NULL;
+
+ /* Apply patches backwards to get the right version.
+ */
+ do {
+ if (rcsnum_cmp(rfp->rf_head, rev, 0) == 0)
+ break;
+
+ if ((isbranch == 1) && (rdp->rd_num->rn_len < rev->rn_len) &&
+ (!TAILQ_EMPTY(&(rdp->rd_branches))))
+ lookonbranch = 1;
+
+ if (isbranch && lookonbranch == 1) {
+ lookonbranch = 0;
+ TAILQ_FOREACH(rb, &(rdp->rd_branches), rb_list) {
+ /* XXX rcsnum_cmp() is totally broken for
+ * this purpose.
+ */
+ numlen = MIN(brev->rn_len, rb->rb_num->rn_len);
+ for (i = 0; i < numlen; i++) {
+ if (rb->rb_num->rn_id[i] !=
+ brev->rn_id[i])
+ break;
+ }
+
+ if (i == numlen) {
+ crev = rb->rb_num;
+ break;
+ }
+ }
+ } else {
+ crev = rdp->rd_next;
+ }
+
+ rdp = rcs_findrev(rfp, crev);
+ if (rdp == NULL) {
+ cvs_buf_free(rbuf);
+ return (NULL);
+ }
+
+ cvs_buf_putc(rbuf, '\0');
+
+ /* check if we have parsed this rev's deltatext */
+ if (rdp->rd_tlen == 0)
+ rcs_parse_deltatexts(rfp, rdp->rd_num);
+
+ bp = cvs_buf_release(rbuf);
+ rbuf = cvs_patchfile((char *)bp, (char *)rdp->rd_text,
+ rcs_patch_lines);
+ xfree(bp);
+
+ if (rbuf == NULL)
+ break;
+ } while (rcsnum_cmp(crev, rev, 0) != 0);
+
if (cvs_buf_getc(rbuf, cvs_buf_len(rbuf)-1) != '\n'
&& rbuf != NULL)
cvs_buf_putc(rbuf, '\n');
+
return (rbuf);
}
@@ -1284,7 +1343,6 @@ rcs_rev_add(RCSFILE *rf, RCSNUM *rev, const char *msg, time_t date,
memset(rdp, 0, sizeof(*rdp));
TAILQ_INIT(&(rdp->rd_branches));
- TAILQ_INIT(&(rdp->rd_snodes));
rdp->rd_num = rcsnum_alloc();
rcsnum_cpy(rev, rdp->rd_num, 0);
@@ -1355,43 +1413,56 @@ rcs_rev_remove(RCSFILE *rf, RCSNUM *rev)
*
* Find a specific revision's delta entry in the tree of the RCS file <rfp>.
* The revision number is given in <rev>.
+ *
+ * If the given revision is a branch number, we translate it into the latest
+ * revision on the branch.
+ *
* Returns a pointer to the delta on success, or NULL on failure.
*/
struct rcs_delta *
rcs_findrev(RCSFILE *rfp, RCSNUM *rev)
{
u_int cmplen;
- struct rcs_delta *rdp, *enddelta;
- struct rcs_dlist *hp;
- int found;
+ struct rcs_delta *rdp;
+ RCSNUM *brev, *frev;
/*
* We need to do more parsing if the last revision in the linked list
* is greater than the requested revision.
*/
- enddelta = TAILQ_LAST(&(rfp->rf_delta), rcs_dlist);
- if ((enddelta == NULL)
- || (rcsnum_cmp(enddelta->rd_num, rev, 0) == -1)) {
+ rdp = TAILQ_LAST(&(rfp->rf_delta), rcs_dlist);
+ if ((rdp == NULL)
+ || (rcsnum_cmp(rdp->rd_num, rev, 0) == -1)) {
rcs_parse_deltas(rfp, rev);
}
- cmplen = 2;
- hp = &(rfp->rf_delta);
+ /*
+ * Translate a branch into the latest revision on the branch itself.
+ */
+ if (RCSNUM_ISBRANCH(rev)) {
+ brev = rcsnum_brtorev(rev);
+ frev = brev;
+ for (;;) {
+ rdp = rcs_findrev(rfp, frev);
+ if (rdp == NULL)
+ fatal("failed to translate branch to last revision");
- do {
- found = 0;
- TAILQ_FOREACH(rdp, hp, rd_list) {
- if (rcsnum_cmp(rdp->rd_num, rev, cmplen) == 0) {
- if (cmplen == rev->rn_len)
- return (rdp);
-
- hp = &(rdp->rd_snodes);
- cmplen += 2;
- found = 1;
+ if (rdp->rd_next->rn_len == 0)
break;
- }
+
+ frev = rdp->rd_next;
}
- } while (found && cmplen < rev->rn_len);
+
+ rcsnum_free(brev);
+ return (rdp);
+ }
+
+ cmplen = rev->rn_len;
+
+ TAILQ_FOREACH(rdp, &(rfp->rf_delta), rd_list) {
+ if (rcsnum_cmp(rdp->rd_num, rev, cmplen) == 0)
+ return (rdp);
+ }
return (NULL);
}
@@ -1791,7 +1862,6 @@ rcs_parse_delta(RCSFILE *rfp)
rdp->rd_next = rcsnum_alloc();
TAILQ_INIT(&(rdp->rd_branches));
- TAILQ_INIT(&(rdp->rd_snodes));
tok = rcs_gettok(rfp);
if (tok == RCS_TOK_DESC) {
@@ -2265,11 +2335,6 @@ rcs_freedelta(struct rcs_delta *rdp)
xfree(rb);
}
- while ((crdp = TAILQ_FIRST(&(rdp->rd_snodes))) != NULL) {
- TAILQ_REMOVE(&(rdp->rd_snodes), crdp, rd_list);
- rcs_freedelta(crdp);
- }
-
xfree(rdp);
}