version 1.179, 2006/05/31 22:25:59 |
version 1.180, 2006/06/01 20:00:52 |
|
|
* |
* |
* Retrieve the revision number of the head revision for the RCS file <file>. |
* Retrieve the revision number of the head revision for the RCS file <file>. |
*/ |
*/ |
const RCSNUM * |
RCSNUM * |
rcs_head_get(RCSFILE *file) |
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); |
return (file->rf_head); |
} |
} |
|
|
|
|
lineno = (int)strtol((lp->l_line + 1), &ep, 10); |
lineno = (int)strtol((lp->l_line + 1), &ep, 10); |
if (lineno > dlines->l_nblines || lineno < 0 || |
if (lineno > dlines->l_nblines || lineno < 0 || |
*ep != ' ') |
*ep != ' ') |
fatal("invalid line specification in RCS patch"); |
fatal("invalid line specification in RCS patch: %s", |
|
ep); |
ep++; |
ep++; |
nbln = (int)strtol(ep, &ep, 10); |
nbln = (int)strtol(ep, &ep, 10); |
if (nbln < 0 || *ep != '\0') |
if (nbln < 0 || *ep != '\0') |
|
|
BUF* |
BUF* |
rcs_getrev(RCSFILE *rfp, RCSNUM *frev) |
rcs_getrev(RCSFILE *rfp, RCSNUM *frev) |
{ |
{ |
u_int i, numlen; |
size_t i; |
int isbranch, lookonbranch, found; |
int done, nextroot, found; |
size_t len; |
BUF *rcsbuf; |
void *bp; |
RCSNUM *tnum, *bnum; |
RCSNUM *crev, *rev, *brev; |
struct rcs_branch *brp; |
BUF *rbuf; |
struct rcs_delta *hrdp, *trdp, *rdp; |
struct rcs_delta *rdp = NULL; |
char *data; |
struct rcs_branch *rb; |
|
|
|
if (rfp->rf_head == NULL) |
if ((hrdp = rcs_findrev(rfp, rfp->rf_head)) == NULL) |
return (NULL); |
fatal("rcs_getrev: no HEAD revision"); |
|
|
if (frev == RCS_HEAD_REV) |
tnum = frev; |
rev = rfp->rf_head; |
rcs_parse_deltatexts(rfp, hrdp->rd_num); |
else |
|
rev = frev; |
|
|
|
/* XXX rcsnum_cmp() */ |
/* revision on branch, get the branch root */ |
for (i = 0; i < rfp->rf_head->rn_len; i++) { |
nextroot = 2; |
if (rfp->rf_head->rn_id[i] < rev->rn_id[i]) { |
if (RCSNUM_ISBRANCHREV(tnum)) { |
rcs_errno = RCS_ERR_NOENT; |
bnum = rcsnum_alloc(); |
return (NULL); |
rcsnum_cpy(tnum, bnum, nextroot); |
} |
} else { |
|
bnum = tnum; |
} |
} |
|
|
/* No matter what, we're going to need up the the description parsed */ |
rcsbuf = cvs_buf_alloc(hrdp->rd_tlen, BUF_AUTOEXT); |
rcs_parse_desc(rfp, NULL); |
cvs_buf_append(rcsbuf, hrdp->rd_text, hrdp->rd_tlen); |
|
|
rdp = rcs_findrev(rfp, rfp->rf_head); |
done = 0; |
if (rdp == NULL) { |
|
cvs_log(LP_ERR, "failed to get RCS HEAD revision"); |
|
return (NULL); |
|
} |
|
|
|
if (rdp->rd_tlen == 0) |
rdp = hrdp; |
rcs_parse_deltatexts(rfp, rfp->rf_head); |
if (!rcsnum_differ(rdp->rd_num, bnum)) |
|
goto next; |
|
|
len = rdp->rd_tlen; |
if ((rdp = rcs_findrev(rfp, hrdp->rd_next)) == NULL) |
if (len == 0) { |
return (rcsbuf); |
rbuf = cvs_buf_alloc(1, 0); |
|
cvs_buf_empty(rbuf); |
|
return (rbuf); |
|
} |
|
|
|
rbuf = cvs_buf_alloc(len, BUF_AUTOEXT); |
again: |
cvs_buf_append(rbuf, rdp->rd_text, len); |
for (;;) { |
|
if (rdp->rd_next->rn_len != 0) { |
|
trdp = rcs_findrev(rfp, rdp->rd_next); |
|
if (trdp == NULL) |
|
fatal("failed to grab next revision"); |
|
} |
|
|
isbranch = 0; |
if (rdp->rd_tlen == 0) { |
brev = NULL; |
rcs_parse_deltatexts(rfp, rdp->rd_num); |
|
if (rdp->rd_tlen == 0) { |
/* |
if (!rcsnum_differ(rdp->rd_num, bnum)) |
* If a branch was passed, get the latest revision on it. |
break; |
*/ |
rdp = trdp; |
if (RCSNUM_ISBRANCH(rev)) { |
continue; |
brev = rev; |
} |
rdp = rcs_findrev(rfp, rev); |
|
if (rdp == NULL) |
|
return (NULL); |
|
|
|
rev = rdp->rd_num; |
|
} else { |
|
if (RCSNUM_ISBRANCHREV(rev)) { |
|
brev = rcsnum_revtobr(rev); |
|
isbranch = 1; |
|
} |
} |
} |
|
|
|
lookonbranch = 0; |
cvs_buf_putc(rcsbuf, '\0'); |
crev = NULL; |
data = cvs_buf_release(rcsbuf); |
|
|
/* Apply patches backwards to get the right version. |
rcsbuf = cvs_patchfile(data, rdp->rd_text, rcs_patch_lines); |
*/ |
if (rcsbuf == NULL) |
do { |
fatal("rcs_getrev: failed to apply rcsdiff"); |
found = 0; |
xfree(data); |
|
|
if (rcsnum_cmp(rfp->rf_head, rev, 0) == 0) |
if (!rcsnum_differ(rdp->rd_num, bnum)) |
break; |
break; |
|
|
if (isbranch == 1 && rdp->rd_num->rn_len < rev->rn_len && |
rdp = trdp; |
!TAILQ_EMPTY(&(rdp->rd_branches))) |
} |
lookonbranch = 1; |
|
|
|
if (isbranch && lookonbranch == 1) { |
next: |
lookonbranch = 0; |
if (!rcsnum_differ(rdp->rd_num, frev)) |
TAILQ_FOREACH(rb, &(rdp->rd_branches), rb_list) { |
done = 1; |
/* 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) { |
if (RCSNUM_ISBRANCHREV(frev) && done != 1) { |
crev = rb->rb_num; |
nextroot += 2; |
found = 1; |
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; |
break; |
} |
} |
} |
} |
|
|
|
/* XXX */ |
if (found == 0) |
if (found == 0) |
crev = rdp->rd_next; |
fatal("no matching branch on list"); |
} else { |
break; |
crev = rdp->rd_next; |
|
} |
} |
|
|
rdp = rcs_findrev(rfp, crev); |
if (brp == NULL) |
if (rdp == NULL) { |
fatal("expected branch not found on branch list"); |
cvs_buf_free(rbuf); |
|
return (NULL); |
|
} |
|
|
|
cvs_buf_putc(rbuf, '\0'); |
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) |
|
fatal("rcs_getrev: failed to get delta for target rev"); |
|
|
/* check if we have parsed this rev's deltatext */ |
goto again; |
if (rdp->rd_tlen == 0) |
} |
rcs_parse_deltatexts(rfp, rdp->rd_num); |
|
|
|
bp = cvs_buf_release(rbuf); |
if (bnum != tnum) |
rbuf = cvs_patchfile((char *)bp, (char *)rdp->rd_text, |
rcsnum_free(bnum); |
rcs_patch_lines); |
|
xfree(bp); |
|
|
|
if (rbuf == NULL) |
return (rcsbuf); |
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); |
|
} |
} |
|
|
/* |
/* |
|
|
{ |
{ |
time_t now; |
time_t now; |
struct passwd *pw; |
struct passwd *pw; |
|
struct rcs_branch *brp; |
struct rcs_delta *ordp, *rdp; |
struct rcs_delta *ordp, *rdp; |
|
|
if (rev == RCS_HEAD_REV) { |
if (rev == RCS_HEAD_REV) { |
|
|
|
|
rdp->rd_next = rcsnum_alloc(); |
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) |
if (username == NULL) |
username = pw->pw_name; |
username = pw->pw_name; |
|
|
|
|
time(&now); |
time(&now); |
gmtime_r(&now, &(rdp->rd_date)); |
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++; |
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 */ |
/* not synced anymore */ |
rf->rf_flags &= ~RCS_SYNCED; |
rf->rf_flags &= ~RCS_SYNCED; |
|
|
|
|
if (rcsnum_cmp(enddelta->rd_num, rev, 0) == 0) |
if (rcsnum_cmp(enddelta->rd_num, rev, 0) == 0) |
break; |
break; |
} |
} |
|
|
if (ret == 0) { |
if (ret == 0) { |
rfp->rf_flags |= PARSED_DELTAS; |
rfp->rf_flags |= PARSED_DELTAS; |
break; |
break; |
|
|
int tok, ntok, hmask; |
int tok, ntok, hmask; |
struct rcs_key *rk; |
struct rcs_key *rk; |
|
|
|
rfp->rf_head = NULL; |
|
rfp->rf_branch = NULL; |
|
|
/* hmask is a mask of the headers already encountered */ |
/* hmask is a mask of the headers already encountered */ |
hmask = 0; |
hmask = 0; |
for (;;) { |
for (;;) { |
|
|
rcs_translate_tag(const char *revstr, RCSFILE *rfp) |
rcs_translate_tag(const char *revstr, RCSFILE *rfp) |
{ |
{ |
size_t i; |
size_t i; |
|
int nextroot; |
RCSNUM *rev, *brev; |
RCSNUM *rev, *brev; |
struct rcs_branch *brp; |
struct rcs_branch *brp; |
struct rcs_delta *rdp, *brdp; |
struct rcs_delta *rdp, *brdp; |
char foo[16]; |
char revision[16]; |
|
|
rev = rcs_sym_getrev(rfp, revstr); |
rev = rcs_sym_getrev(rfp, revstr); |
if (rev == NULL) { |
if (rev == NULL) { |
if ((rev = rcsnum_parse(revstr)) == 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)) { |
if (RCSNUM_ISBRANCH(rev)) { |
brev = rcsnum_alloc(); |
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) |
if ((rdp = rcs_findrev(rfp, brev)) == NULL) |
fatal("rcs_translate_tag: cannot find branch root " |
fatal("tag %s does not exist (1)", revstr); |
"for '%s'", revstr); |
|
|
|
|
if (RCSNUM_ISBRANCH(rev)) { |
TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) { |
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++) { |
for (i = 0; i < rev->rn_len; i++) { |
if (rev->rn_id[i] != brp->rb_num->rn_id[i]) |
if (brp->rb_num->rn_id[i] != rev->rn_id[i]) |
continue; |
break; |
} |
} |
|
|
rcsnum_tostr(brp->rb_num, foo, sizeof(foo)); |
if (i != rev->rn_len) |
|
continue; |
|
|
break; |
break; |
} |
} |
|
|
if (brp == NULL) { |
if (brp == NULL) |
if (cvs_cmdop == CVS_OP_IMPORT) |
return (NULL); |
return (NULL); |
|
rcsnum_cpy(rdp->rd_num, rev, 0); |
|
return (rev); |
|
} |
|
|
|
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) { |
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) |
rcsnum_tostr(brp->rb_num, foo, sizeof(foo)); |
fatal("tag %s does not exist (3)", revstr); |
fatal("rcs_translate_tag: cannot find branch rev %s", |
|
foo); |
|
} |
|
|
|
brdp = rdp; |
while (rdp->rd_next->rn_len != 0) { |
while (brdp->rd_next->rn_len != 0) { |
if ((rdp = rcs_findrev(rfp, rdp->rd_next)) == NULL) |
brdp = rcs_findrev(rfp, brdp->rd_next); |
fatal("tag %s does not exist (4)", revstr); |
if (brdp == NULL) |
|
fatal("rcs_translate_tag: next is NULL"); |
|
} |
} |
|
|
rcsnum_cpy(brdp->rd_num, rev, 0); |
rcsnum_cpy(rdp->rd_num, rev, 0); |
} |
} |
|
|
return (rev); |
return (rev); |