version 1.217, 2007/09/07 23:05:04 |
version 1.218, 2007/09/13 13:10:57 |
|
|
#define RCS_NOSCOL 0x01 /* no terminating semi-colon */ |
#define RCS_NOSCOL 0x01 /* no terminating semi-colon */ |
#define RCS_VOPT 0x02 /* value is optional */ |
#define RCS_VOPT 0x02 /* value is optional */ |
|
|
|
#define ANNOTATE_NEVER 0 |
|
#define ANNOTATE_NOW 1 |
|
#define ANNOTATE_LATER 2 |
|
|
/* opaque parse data */ |
/* opaque parse data */ |
struct rcs_pdata { |
struct rcs_pdata { |
u_int rp_lines; |
u_int rp_lines; |
|
|
|
|
int rcs_errno = RCS_ERR_NOERR; |
int rcs_errno = RCS_ERR_NOERR; |
|
|
int rcs_patch_lines(struct cvs_lines *, struct cvs_lines *); |
int rcs_patch_lines(struct cvs_lines *, struct cvs_lines *, |
|
struct cvs_line **, struct rcs_delta *); |
static void rcs_parse_init(RCSFILE *); |
static void rcs_parse_init(RCSFILE *); |
static int rcs_parse_admin(RCSFILE *); |
static int rcs_parse_admin(RCSFILE *); |
static int rcs_parse_delta(RCSFILE *); |
static int rcs_parse_delta(RCSFILE *); |
|
|
} |
} |
|
|
int |
int |
rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) |
rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines, |
|
struct cvs_line **alines, struct rcs_delta *rdp) |
{ |
{ |
u_char op; |
u_char op; |
char *ep; |
char *ep; |
|
|
for (i = 0; (i < nbln) && (dlp != NULL); i++) { |
for (i = 0; (i < nbln) && (dlp != NULL); i++) { |
ndlp = TAILQ_NEXT(dlp, l_list); |
ndlp = TAILQ_NEXT(dlp, l_list); |
TAILQ_REMOVE(&(dlines->l_lines), dlp, l_list); |
TAILQ_REMOVE(&(dlines->l_lines), dlp, l_list); |
xfree(dlp); |
if (alines != NULL && dlp->l_line != NULL) { |
|
dlp->l_delta = rdp; |
|
alines[dlp->l_lineno_orig - 1] = |
|
dlp; |
|
} else |
|
xfree(dlp); |
dlp = ndlp; |
dlp = ndlp; |
/* last line is gone - reset dlp */ |
/* last line is gone - reset dlp */ |
if (dlp == NULL) { |
if (dlp == NULL) { |
|
|
if (lp == NULL) |
if (lp == NULL) |
fatal("truncated RCS patch"); |
fatal("truncated RCS patch"); |
TAILQ_REMOVE(&(plines->l_lines), lp, l_list); |
TAILQ_REMOVE(&(plines->l_lines), lp, l_list); |
|
if (alines != NULL) { |
|
if (lp->l_needsfree == 1) |
|
xfree(lp->l_line); |
|
lp->l_line = NULL; |
|
lp->l_needsfree = 0; |
|
} |
TAILQ_INSERT_AFTER(&(dlines->l_lines), dlp, |
TAILQ_INSERT_AFTER(&(dlines->l_lines), dlp, |
lp, l_list); |
lp, l_list); |
dlp = lp; |
dlp = lp; |
|
|
* return it as a pointer to a struct cvs_lines. |
* return it as a pointer to a struct cvs_lines. |
*/ |
*/ |
struct cvs_lines * |
struct cvs_lines * |
rcs_rev_getlines(RCSFILE *rfp, RCSNUM *frev) |
rcs_rev_getlines(RCSFILE *rfp, RCSNUM *frev, struct cvs_line ***alines) |
{ |
{ |
size_t plen; |
size_t plen; |
int i, done, nextroot; |
int annotate, done, i, nextroot; |
RCSNUM *tnum, *bnum; |
RCSNUM *tnum, *bnum; |
struct rcs_branch *brp; |
struct rcs_branch *brp; |
struct rcs_delta *hrdp, *trdp, *rdp; |
struct rcs_delta *hrdp, *prdp, *rdp, *trdp; |
u_char *patch; |
u_char *patch; |
|
struct cvs_line *line, *nline; |
struct cvs_lines *dlines, *plines; |
struct cvs_lines *dlines, *plines; |
|
|
if ((hrdp = rcs_findrev(rfp, rfp->rf_head)) == NULL) |
if ((hrdp = rcs_findrev(rfp, rfp->rf_head)) == NULL) |
|
|
bnum = tnum; |
bnum = tnum; |
} |
} |
|
|
|
if (alines != NULL) { |
|
/* start with annotate first at requested revision */ |
|
annotate = ANNOTATE_LATER; |
|
*alines = NULL; |
|
} else |
|
annotate = ANNOTATE_NEVER; |
|
|
dlines = cvs_splitlines(hrdp->rd_text, hrdp->rd_tlen); |
dlines = cvs_splitlines(hrdp->rd_text, hrdp->rd_tlen); |
|
|
done = 0; |
done = 0; |
|
|
rdp = hrdp; |
rdp = hrdp; |
if (!rcsnum_differ(rdp->rd_num, bnum)) |
if (!rcsnum_differ(rdp->rd_num, bnum)) { |
goto next; |
if (annotate == ANNOTATE_LATER) { |
|
/* found requested revision for annotate */ |
|
i = 0; |
|
TAILQ_FOREACH(line, &(dlines->l_lines), l_list) { |
|
line->l_lineno_orig = line->l_lineno; |
|
i++; |
|
} |
|
|
|
*alines = xcalloc(i + 1, sizeof(struct cvs_line *)); |
|
(*alines)[i] = NULL; |
|
annotate = ANNOTATE_NOW; |
|
|
|
/* annotate down to 1.1 from where we are */ |
|
if (bnum == tnum) |
|
bnum = rcsnum_alloc(); |
|
bnum = rcsnum_parse("1.1"); |
|
if (!rcsnum_differ(rdp->rd_num, bnum)) { |
|
goto next; |
|
} |
|
} else |
|
goto next; |
|
} |
|
|
|
prdp = hrdp; |
if ((rdp = rcs_findrev(rfp, hrdp->rd_next)) == NULL) |
if ((rdp = rcs_findrev(rfp, hrdp->rd_next)) == NULL) |
goto done; |
goto done; |
|
|
|
|
plen = rdp->rd_tlen; |
plen = rdp->rd_tlen; |
patch = rdp->rd_text; |
patch = rdp->rd_text; |
plines = cvs_splitlines(patch, plen); |
plines = cvs_splitlines(patch, plen); |
rcs_patch_lines(dlines, plines); |
if (annotate == ANNOTATE_NOW) |
|
rcs_patch_lines(dlines, plines, *alines, prdp); |
|
else |
|
rcs_patch_lines(dlines, plines, NULL, NULL); |
cvs_freelines(plines); |
cvs_freelines(plines); |
|
|
if (!rcsnum_differ(rdp->rd_num, bnum)) |
if (!rcsnum_differ(rdp->rd_num, bnum)) { |
break; |
if (annotate != ANNOTATE_LATER) |
|
break; |
|
|
|
/* found requested revision for annotate */ |
|
i = 0; |
|
TAILQ_FOREACH(line, &(dlines->l_lines), l_list) { |
|
line->l_lineno_orig = line->l_lineno; |
|
i++; |
|
} |
|
|
|
*alines = xcalloc(i + 1, sizeof(struct cvs_line *)); |
|
(*alines)[i] = NULL; |
|
annotate = ANNOTATE_NOW; |
|
|
|
/* annotate down to 1.1 from where we are */ |
|
if (bnum == tnum) |
|
bnum = rcsnum_alloc(); |
|
bnum = rcsnum_parse("1.1"); |
|
|
|
if (!rcsnum_differ(rdp->rd_num, bnum)) |
|
break; |
|
} |
|
|
|
prdp = rdp; |
rdp = trdp; |
rdp = trdp; |
} |
} |
|
|
|
|
break; |
break; |
} |
} |
|
|
if (brp == NULL) |
if (brp == NULL) { |
|
if (annotate != ANNOTATE_NEVER) { |
|
if (*alines != NULL) |
|
xfree(*alines); |
|
*alines = NULL; |
|
cvs_freelines(dlines); |
|
if (bnum != tnum) |
|
rcsnum_free(bnum); |
|
return (NULL); |
|
} |
fatal("expected branch not found on branch list"); |
fatal("expected branch not found on branch list"); |
|
} |
|
|
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) |
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) |
fatal("rcs_rev_getlines: failed to get delta for target rev"); |
fatal("rcs_rev_getlines: failed to get delta for target rev"); |
|
|
goto again; |
goto again; |
} |
} |
done: |
done: |
|
/* put remaining lines of 1.1 into annotate buffer */ |
|
if (annotate == ANNOTATE_NOW) { |
|
for (line = TAILQ_FIRST(&(dlines->l_lines)); |
|
line != NULL; line = nline) { |
|
nline = TAILQ_NEXT(line, l_list); |
|
TAILQ_REMOVE(&(dlines->l_lines), line, l_list); |
|
if (line->l_line == NULL) { |
|
xfree(line); |
|
continue; |
|
} |
|
|
|
line->l_delta = rdp; |
|
(*alines)[line->l_lineno_orig - 1] = line; |
|
} |
|
|
|
cvs_freelines(dlines); |
|
dlines = NULL; |
|
} |
|
|
if (bnum != tnum) |
if (bnum != tnum) |
rcsnum_free(bnum); |
rcsnum_free(bnum); |
|
|
|
|
BUF *bp; |
BUF *bp; |
|
|
expand = 0; |
expand = 0; |
lines = rcs_rev_getlines(rfp, rev); |
lines = rcs_rev_getlines(rfp, rev, NULL); |
bp = cvs_buf_alloc(1024, BUF_AUTOEXT); |
bp = cvs_buf_alloc(1024, BUF_AUTOEXT); |
|
|
if (!(mode & RCS_KWEXP_NONE)) { |
if (!(mode & RCS_KWEXP_NONE)) { |
|
|
extern int print_stdout; |
extern int print_stdout; |
|
|
expand = 0; |
expand = 0; |
lines = rcs_rev_getlines(rfp, rev); |
lines = rcs_rev_getlines(rfp, rev, NULL); |
|
|
if (!(mode & RCS_KWEXP_NONE)) { |
if (!(mode & RCS_KWEXP_NONE)) { |
if (rfp->rf_expand != NULL) |
if (rfp->rf_expand != NULL) |