=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/rcs.c,v retrieving revision 1.155 retrieving revision 1.156 diff -c -r1.155 -r1.156 *** src/usr.bin/cvs/rcs.c 2006/03/29 09:16:53 1.155 --- src/usr.bin/cvs/rcs.c 2006/03/30 23:06:25 1.156 *************** *** 1,4 **** ! /* $OpenBSD: rcs.c,v 1.155 2006/03/29 09:16:53 ray Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. --- 1,4 ---- ! /* $OpenBSD: rcs.c,v 1.156 2006/03/30 23:06:25 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. *************** *** 1169,1180 **** BUF* rcs_getrev(RCSFILE *rfp, RCSNUM *frev) { ! int res; size_t len; void *bp; ! RCSNUM *crev, *rev; BUF *rbuf; struct rcs_delta *rdp = NULL; if (rfp->rf_head == NULL) return (NULL); --- 1169,1182 ---- BUF* rcs_getrev(RCSFILE *rfp, RCSNUM *frev) { ! u_int i, numlen; ! int isbranch, lookonbranch; size_t len; void *bp; ! RCSNUM *crev, *rev, *brev; BUF *rbuf; struct rcs_delta *rdp = NULL; + struct rcs_branch *rb; if (rfp->rf_head == NULL) return (NULL); *************** *** 1184,1193 **** else rev = frev; ! res = rcsnum_cmp(rfp->rf_head, rev, 0); ! if (res == 1) { ! rcs_errno = RCS_ERR_NOENT; ! return (NULL); } /* No matter what, we're going to need up the the description parsed */ --- 1186,1197 ---- else rev = frev; ! /* 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,1205 **** --- 1202,1211 ---- 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,1242 **** 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); } if (cvs_buf_getc(rbuf, cvs_buf_len(rbuf)-1) != '\n' && rbuf != NULL) cvs_buf_putc(rbuf, '\n'); return (rbuf); } --- 1216,1301 ---- rbuf = cvs_buf_alloc(len, BUF_AUTOEXT); cvs_buf_append(rbuf, rdp->rd_text, len); ! 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,1290 **** 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); --- 1343,1348 ---- *************** *** 1355,1398 **** * * Find a specific revision's delta entry in the tree of the RCS file . * The revision number is given in . * 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; /* * 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)) { rcs_parse_deltas(rfp, rev); } ! cmplen = 2; ! hp = &(rfp->rf_delta); ! 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; break; ! } } - } while (found && cmplen < rev->rn_len); return (NULL); } --- 1413,1469 ---- * * Find a specific revision's delta entry in the tree of the RCS file . * The revision number is given in . + * + * 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; ! RCSNUM *brev, *frev; /* * We need to do more parsing if the last revision in the linked list * is greater than the requested revision. */ ! rdp = TAILQ_LAST(&(rfp->rf_delta), rcs_dlist); ! if ((rdp == NULL) ! || (rcsnum_cmp(rdp->rd_num, rev, 0) == -1)) { rcs_parse_deltas(rfp, rev); } ! /* ! * 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"); ! if (rdp->rd_next->rn_len == 0) break; ! ! frev = rdp->rd_next; } + 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,1797 **** rdp->rd_next = rcsnum_alloc(); TAILQ_INIT(&(rdp->rd_branches)); - TAILQ_INIT(&(rdp->rd_snodes)); tok = rcs_gettok(rfp); if (tok == RCS_TOK_DESC) { --- 1862,1867 ---- *************** *** 2263,2273 **** TAILQ_REMOVE(&(rdp->rd_branches), rb, rb_list); rcsnum_free(rb->rb_num); xfree(rb); - } - - while ((crdp = TAILQ_FIRST(&(rdp->rd_snodes))) != NULL) { - TAILQ_REMOVE(&(rdp->rd_snodes), crdp, rd_list); - rcs_freedelta(crdp); } xfree(rdp); --- 2333,2338 ----