diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2006-06-01 20:00:53 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2006-06-01 20:00:53 +0000 |
commit | 91b2539f3bccc40a19757de24447e2354b98f1dd (patch) | |
tree | 39012707a6d654af0794262dc74b337a2dd43f2a /usr.bin | |
parent | 43c990ab0f3db918c8ea3707f821a4667127e554 (diff) |
major rewrite of some rcs parsing stuff:
- rework rcs_getrev() to correctly support branches
- rework rcs_translate_tag() to correctly translate given symbols or
branches into their matching revisions
- rework rcs_rev_add() to correctly update its 'next' pointers
and insert the new revision in the correct place on the list.
- rework rcs_head_get() to return the latest revision on the default
branch if it has been set or the normal HEAD revision otherwise.
- no longer access the rf_head member of the RCSFILE struct manually,
use the rcs_head_get() function which correctly returns the HEAD
revision, there might be a default branch that has to be used.
- for now, when commiting a new revision reset the default branch.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/cvs/add.c | 9 | ||||
-rw-r--r-- | usr.bin/cvs/commit.c | 9 | ||||
-rw-r--r-- | usr.bin/cvs/file.c | 5 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.c | 281 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/status.c | 5 |
6 files changed, 155 insertions, 158 deletions
diff --git a/usr.bin/cvs/add.c b/usr.bin/cvs/add.c index cef95503659..4cea0ab5246 100644 --- a/usr.bin/cvs/add.c +++ b/usr.bin/cvs/add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: add.c,v 1.51 2006/05/30 21:32:52 joris Exp $ */ +/* $OpenBSD: add.c,v 1.52 2006/06/01 20:00:52 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -175,10 +175,12 @@ add_file(struct cvs_file *cf) BUF *b; int added, l, stop; char *entry, revbuf[16], tbuf[32]; + RCSNUM *head; CVSENTRIES *entlist; if (cf->file_rcs != NULL) - rcsnum_tostr(cf->file_rcs->rf_head, revbuf, sizeof(revbuf)); + rcsnum_tostr(rcs_head_get(cf->file_rcs), + revbuf, sizeof(revbuf)); added = stop = 0; switch (cf->file_status) { @@ -216,7 +218,8 @@ add_file(struct cvs_file *cf) xfree(entry); - b = rcs_getrev(cf->file_rcs, cf->file_rcs->rf_head); + head = rcs_head_get(cf->file_rcs); + b = rcs_getrev(cf->file_rcs, head); if (b == NULL) fatal("cvs_add_local: failed to get HEAD"); diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c index ecbf62ab1f6..4a4bb408428 100644 --- a/usr.bin/cvs/commit.c +++ b/usr.bin/cvs/commit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commit.c,v 1.67 2006/05/31 23:27:38 joris Exp $ */ +/* $OpenBSD: commit.c,v 1.68 2006/06/01 20:00:52 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -165,7 +165,7 @@ cvs_commit_local(struct cvs_file *cf) if (cf->file_status == FILE_MODIFIED || cf->file_status == FILE_REMOVED || (cf->file_status == FILE_ADDED && cf->file_rcs != NULL && cf->file_rcs->rf_dead == 1)) - rcsnum_tostr(cf->file_rcs->rf_head, rbuf, sizeof(rbuf)); + rcsnum_tostr(rcs_head_get(cf->file_rcs), rbuf, sizeof(rbuf)); else strlcpy(rbuf, "Non-existent", sizeof(rbuf)); @@ -260,6 +260,11 @@ cvs_commit_local(struct cvs_file *cf) fatal("cvs_commit_local: failed to set state"); } + if (cf->file_rcs->rf_branch != NULL) { + rcsnum_free(cf->file_rcs->rf_branch); + cf->file_rcs->rf_branch = NULL; + } + rcs_write(cf->file_rcs); if (cf->file_status == FILE_REMOVED) { diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c index 0c2e90a9450..1ff07bbe332 100644 --- a/usr.bin/cvs/file.c +++ b/usr.bin/cvs/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.155 2006/05/31 01:26:22 joris Exp $ */ +/* $OpenBSD: file.c,v 1.156 2006/06/01 20:00:52 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> @@ -607,6 +607,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag, int loud) case CVS_OP_COMMIT: rflags = RCS_WRITE; break; + case CVS_OP_IMPORT: case CVS_OP_LOG: rflags |= RCS_PARSE_FULLY; break; @@ -642,7 +643,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag, int loud) if (tag != NULL && cf->file_rcs != NULL) cf->file_rcsrev = rcs_translate_tag(tag, cf->file_rcs); else if (cf->file_rcs != NULL) - cf->file_rcsrev = cf->file_rcs->rf_head; + cf->file_rcsrev = rcs_head_get(cf->file_rcs); else cf->file_rcsrev = NULL; diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c index dc0be399bee..b54157d744d 100644 --- a/usr.bin/cvs/rcs.c +++ b/usr.bin/cvs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.179 2006/05/31 22:25:59 joris Exp $ */ +/* $OpenBSD: rcs.c,v 1.180 2006/06/01 20:00:52 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -591,9 +591,16 @@ out: * * Retrieve the revision number of the head revision for the RCS file <file>. */ -const RCSNUM * +RCSNUM * rcs_head_get(RCSFILE *file) { + char br[16]; + + if (file->rf_branch != NULL) { + rcsnum_tostr(file->rf_branch, br, sizeof(br)); + return (rcs_translate_tag(br, file)); + } + return (file->rf_head); } @@ -1061,7 +1068,8 @@ rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) lineno = (int)strtol((lp->l_line + 1), &ep, 10); if (lineno > dlines->l_nblines || lineno < 0 || *ep != ' ') - fatal("invalid line specification in RCS patch"); + fatal("invalid line specification in RCS patch: %s", + ep); ep++; nbln = (int)strtol(ep, &ep, 10); if (nbln < 0 || *ep != '\0') @@ -1140,139 +1148,109 @@ rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) BUF* rcs_getrev(RCSFILE *rfp, RCSNUM *frev) { - u_int i, numlen; - int isbranch, lookonbranch, found; - 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); - - if (frev == RCS_HEAD_REV) - rev = rfp->rf_head; - else - rev = frev; + size_t i; + int done, nextroot, found; + BUF *rcsbuf; + RCSNUM *tnum, *bnum; + struct rcs_branch *brp; + struct rcs_delta *hrdp, *trdp, *rdp; + char *data; - /* 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); - } - } + if ((hrdp = rcs_findrev(rfp, rfp->rf_head)) == NULL) + fatal("rcs_getrev: no HEAD revision"); - /* No matter what, we're going to need up the the description parsed */ - rcs_parse_desc(rfp, NULL); + tnum = frev; + rcs_parse_deltatexts(rfp, hrdp->rd_num); - rdp = rcs_findrev(rfp, rfp->rf_head); - if (rdp == NULL) { - cvs_log(LP_ERR, "failed to get RCS HEAD revision"); - return (NULL); + /* revision on branch, get the branch root */ + nextroot = 2; + if (RCSNUM_ISBRANCHREV(tnum)) { + bnum = rcsnum_alloc(); + rcsnum_cpy(tnum, bnum, nextroot); + } else { + bnum = tnum; } - if (rdp->rd_tlen == 0) - rcs_parse_deltatexts(rfp, rfp->rf_head); + rcsbuf = cvs_buf_alloc(hrdp->rd_tlen, BUF_AUTOEXT); + cvs_buf_append(rcsbuf, hrdp->rd_text, hrdp->rd_tlen); - len = rdp->rd_tlen; - if (len == 0) { - rbuf = cvs_buf_alloc(1, 0); - cvs_buf_empty(rbuf); - return (rbuf); - } + done = 0; - rbuf = cvs_buf_alloc(len, BUF_AUTOEXT); - cvs_buf_append(rbuf, rdp->rd_text, len); + rdp = hrdp; + if (!rcsnum_differ(rdp->rd_num, bnum)) + goto next; - isbranch = 0; - brev = NULL; + if ((rdp = rcs_findrev(rfp, hrdp->rd_next)) == NULL) + return (rcsbuf); - /* - * 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) - return (NULL); +again: + for (;;) { + if (rdp->rd_next->rn_len != 0) { + trdp = rcs_findrev(rfp, rdp->rd_next); + if (trdp == NULL) + fatal("failed to grab next revision"); + } - rev = rdp->rd_num; - } else { - if (RCSNUM_ISBRANCHREV(rev)) { - brev = rcsnum_revtobr(rev); - isbranch = 1; + 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; + } } - } - lookonbranch = 0; - crev = NULL; + cvs_buf_putc(rcsbuf, '\0'); + data = cvs_buf_release(rcsbuf); - /* Apply patches backwards to get the right version. - */ - do { - found = 0; - - if (rcsnum_cmp(rfp->rf_head, rev, 0) == 0) + rcsbuf = cvs_patchfile(data, rdp->rd_text, rcs_patch_lines); + if (rcsbuf == NULL) + fatal("rcs_getrev: failed to apply rcsdiff"); + xfree(data); + + if (!rcsnum_differ(rdp->rd_num, bnum)) break; - if (isbranch == 1 && rdp->rd_num->rn_len < rev->rn_len && - !TAILQ_EMPTY(&(rdp->rd_branches))) - lookonbranch = 1; + rdp = trdp; + } - 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; - } +next: + if (!rcsnum_differ(rdp->rd_num, frev)) + done = 1; - if (i == numlen) { - crev = rb->rb_num; - found = 1; + if (RCSNUM_ISBRANCHREV(frev) && done != 1) { + nextroot += 2; + rcsnum_cpy(frev, bnum, nextroot); + + TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) { + found = 1; + for (i = 0; i < nextroot - 1; i++) { + if (brp->rb_num->rn_id[i] != bnum->rn_id[i]) { + found = 0; break; } } - if (found == 0) - crev = rdp->rd_next; - } else { - crev = rdp->rd_next; - } - rdp = rcs_findrev(rfp, crev); - if (rdp == NULL) { - cvs_buf_free(rbuf); - return (NULL); + /* XXX */ + if (found == 0) + fatal("no matching branch on list"); + break; } - 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); + if (brp == NULL) + fatal("expected branch not found on branch list"); - bp = cvs_buf_release(rbuf); - rbuf = cvs_patchfile((char *)bp, (char *)rdp->rd_text, - rcs_patch_lines); - xfree(bp); + if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) + fatal("rcs_getrev: failed to get delta for target rev"); - if (rbuf == NULL) - break; - } while (rcsnum_cmp(crev, rev, 0) != 0); + goto again; + } - if (cvs_buf_getc(rbuf, cvs_buf_len(rbuf)-1) != '\n' && - rbuf != NULL) - cvs_buf_putc(rbuf, '\n'); + if (bnum != tnum) + rcsnum_free(bnum); - return (rbuf); + return (rcsbuf); } /* @@ -1294,6 +1272,7 @@ rcs_rev_add(RCSFILE *rf, RCSNUM *rev, const char *msg, time_t date, { time_t now; struct passwd *pw; + struct rcs_branch *brp; struct rcs_delta *ordp, *rdp; if (rev == RCS_HEAD_REV) { @@ -1324,13 +1303,6 @@ rcs_rev_add(RCSFILE *rf, RCSNUM *rev, const char *msg, time_t date, rdp->rd_next = rcsnum_alloc(); - if (!(rf->rf_flags & RCS_CREATE)) { - /* next should point to the previous HEAD */ - ordp = TAILQ_FIRST(&(rf->rf_delta)); - rcsnum_cpy(ordp->rd_num, rdp->rd_next, 0); - } - - if (username == NULL) username = pw->pw_name; @@ -1344,9 +1316,27 @@ rcs_rev_add(RCSFILE *rf, RCSNUM *rev, const char *msg, time_t date, time(&now); gmtime_r(&now, &(rdp->rd_date)); - TAILQ_INSERT_HEAD(&(rf->rf_delta), rdp, rd_list); + if (RCSNUM_ISBRANCHREV(rev)) + TAILQ_INSERT_TAIL(&(rf->rf_delta), rdp, rd_list); + else + TAILQ_INSERT_HEAD(&(rf->rf_delta), rdp, rd_list); rf->rf_ndelta++; + if (!(rf->rf_flags & RCS_CREATE)) { + if (RCSNUM_ISBRANCHREV(rev)) { + brp = xmalloc(sizeof(*brp)); + brp->rb_num = rcsnum_alloc(); + rcsnum_cpy(rdp->rd_num, brp->rb_num, 0); + TAILQ_INSERT_TAIL(&(rdp->rd_branches), brp, rb_list); + + ordp = TAILQ_PREV(rdp, cvs_tqh, rd_list); + rcsnum_cpy(rdp->rd_num, ordp->rd_next, 0); + } else { + ordp = TAILQ_NEXT(rdp, rd_list); + rcsnum_cpy(ordp->rd_num, rdp->rd_next, 0); + } + } + /* not synced anymore */ rf->rf_flags &= ~RCS_SYNCED; @@ -1619,6 +1609,7 @@ rcs_parse_deltas(RCSFILE *rfp, RCSNUM *rev) if (rcsnum_cmp(enddelta->rd_num, rev, 0) == 0) break; } + if (ret == 0) { rfp->rf_flags |= PARSED_DELTAS; break; @@ -1746,6 +1737,9 @@ rcs_parse_admin(RCSFILE *rfp) int tok, ntok, hmask; struct rcs_key *rk; + rfp->rf_head = NULL; + rfp->rf_branch = NULL; + /* hmask is a mask of the headers already encountered */ hmask = 0; for (;;) { @@ -2951,60 +2945,53 @@ RCSNUM * rcs_translate_tag(const char *revstr, RCSFILE *rfp) { size_t i; + int nextroot; RCSNUM *rev, *brev; struct rcs_branch *brp; struct rcs_delta *rdp, *brdp; - char foo[16]; + char revision[16]; rev = rcs_sym_getrev(rfp, revstr); if (rev == NULL) { if ((rev = rcsnum_parse(revstr)) == NULL) - fatal("%s is an invalid revision/symbol", revstr); + fatal("tag %s does not exist (0)", revstr); } if (RCSNUM_ISBRANCH(rev)) { brev = rcsnum_alloc(); - rcsnum_cpy(rev, brev, 2); + rcsnum_cpy(rev, brev, rev->rn_len - 1); + } else { + brev = rev; + } - if ((rdp = rcs_findrev(rfp, brev)) == NULL) - fatal("rcs_translate_tag: cannot find branch root " - "for '%s'", revstr); + if ((rdp = rcs_findrev(rfp, brev)) == NULL) + fatal("tag %s does not exist (1)", revstr); + if (RCSNUM_ISBRANCH(rev)) { TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) { - if (brp->rb_num->rn_len < 4) - fatal("rcs_translate_tag: bad branch " - "revision on list"); - for (i = 0; i < rev->rn_len; i++) { - if (rev->rn_id[i] != brp->rb_num->rn_id[i]) - continue; + if (brp->rb_num->rn_id[i] != rev->rn_id[i]) + break; } - rcsnum_tostr(brp->rb_num, foo, sizeof(foo)); + if (i != rev->rn_len) + continue; + break; } - if (brp == NULL) { - if (cvs_cmdop == CVS_OP_IMPORT) - return (NULL); - rcsnum_cpy(rdp->rd_num, rev, 0); - return (rev); - } + if (brp == NULL) + return (NULL); - if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) { - rcsnum_tostr(brp->rb_num, foo, sizeof(foo)); - fatal("rcs_translate_tag: cannot find branch rev %s", - foo); - } + if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) + fatal("tag %s does not exist (3)", revstr); - brdp = rdp; - while (brdp->rd_next->rn_len != 0) { - brdp = rcs_findrev(rfp, brdp->rd_next); - if (brdp == NULL) - fatal("rcs_translate_tag: next is NULL"); + while (rdp->rd_next->rn_len != 0) { + if ((rdp = rcs_findrev(rfp, rdp->rd_next)) == NULL) + fatal("tag %s does not exist (4)", revstr); } - rcsnum_cpy(brdp->rd_num, rev, 0); + rcsnum_cpy(rdp->rd_num, rev, 0); } return (rev); diff --git a/usr.bin/cvs/rcs.h b/usr.bin/cvs/rcs.h index a69a4877072..c267536a4c1 100644 --- a/usr.bin/cvs/rcs.h +++ b/usr.bin/cvs/rcs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.h,v 1.67 2006/05/31 18:26:14 joris Exp $ */ +/* $OpenBSD: rcs.h,v 1.68 2006/06/01 20:00:52 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -219,7 +219,7 @@ extern int rcs_errno; RCSFILE *rcs_open(const char *, int, int, ...); void rcs_close(RCSFILE *); -const RCSNUM *rcs_head_get(RCSFILE *); +RCSNUM *rcs_head_get(RCSFILE *); int rcs_head_set(RCSFILE *, RCSNUM *); const RCSNUM *rcs_branch_get(RCSFILE *); int rcs_branch_set(RCSFILE *, const RCSNUM *); diff --git a/usr.bin/cvs/status.c b/usr.bin/cvs/status.c index 737f9b082ea..74031556617 100644 --- a/usr.bin/cvs/status.c +++ b/usr.bin/cvs/status.c @@ -1,4 +1,4 @@ -/* $OpenBSD: status.c,v 1.61 2006/05/30 21:32:52 joris Exp $ */ +/* $OpenBSD: status.c,v 1.62 2006/06/01 20:00:52 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -155,7 +155,8 @@ cvs_status_local(struct cvs_file *cf) if (len >= sizeof(buf)) fatal("cvs_status_local: truncation"); } else { - rcsnum_tostr(cf->file_rcs->rf_head, revbuf, sizeof(revbuf)); + rcsnum_tostr(rcs_head_get(cf->file_rcs), + revbuf, sizeof(revbuf)); l = snprintf(buf, sizeof(buf), "%s\t%s", revbuf, cf->file_rpath); if (l == -1 || l >= (int)sizeof(buf)) |