=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/rcs.c,v retrieving revision 1.217 retrieving revision 1.218 diff -c -r1.217 -r1.218 *** src/usr.bin/cvs/rcs.c 2007/09/07 23:05:04 1.217 --- src/usr.bin/cvs/rcs.c 2007/09/13 13:10:57 1.218 *************** *** 1,4 **** ! /* $OpenBSD: rcs.c,v 1.217 2007/09/07 23:05:04 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. --- 1,4 ---- ! /* $OpenBSD: rcs.c,v 1.218 2007/09/13 13:10:57 tobias Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. *************** *** 73,78 **** --- 73,82 ---- #define RCS_NOSCOL 0x01 /* no terminating semi-colon */ #define RCS_VOPT 0x02 /* value is optional */ + #define ANNOTATE_NEVER 0 + #define ANNOTATE_NOW 1 + #define ANNOTATE_LATER 2 + /* opaque parse data */ struct rcs_pdata { u_int rp_lines; *************** *** 219,225 **** int rcs_errno = RCS_ERR_NOERR; ! int rcs_patch_lines(struct cvs_lines *, struct cvs_lines *); static void rcs_parse_init(RCSFILE *); static int rcs_parse_admin(RCSFILE *); static int rcs_parse_delta(RCSFILE *); --- 223,230 ---- int rcs_errno = RCS_ERR_NOERR; ! int rcs_patch_lines(struct cvs_lines *, struct cvs_lines *, ! struct cvs_line **, struct rcs_delta *); static void rcs_parse_init(RCSFILE *); static int rcs_parse_admin(RCSFILE *); static int rcs_parse_delta(RCSFILE *); *************** *** 1022,1028 **** } int ! rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) { u_char op; char *ep; --- 1027,1034 ---- } int ! rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines, ! struct cvs_line **alines, struct rcs_delta *rdp) { u_char op; char *ep; *************** *** 1075,1081 **** for (i = 0; (i < nbln) && (dlp != NULL); i++) { ndlp = TAILQ_NEXT(dlp, l_list); TAILQ_REMOVE(&(dlines->l_lines), dlp, l_list); ! xfree(dlp); dlp = ndlp; /* last line is gone - reset dlp */ if (dlp == NULL) { --- 1081,1092 ---- for (i = 0; (i < nbln) && (dlp != NULL); i++) { ndlp = TAILQ_NEXT(dlp, l_list); TAILQ_REMOVE(&(dlines->l_lines), dlp, l_list); ! if (alines != NULL && dlp->l_line != NULL) { ! dlp->l_delta = rdp; ! alines[dlp->l_lineno_orig - 1] = ! dlp; ! } else ! xfree(dlp); dlp = ndlp; /* last line is gone - reset dlp */ if (dlp == NULL) { *************** *** 1091,1096 **** --- 1102,1113 ---- if (lp == NULL) fatal("truncated RCS patch"); 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, lp, l_list); dlp = lp; *************** *** 2623,2636 **** * return it as a pointer to a struct cvs_lines. */ struct cvs_lines * ! rcs_rev_getlines(RCSFILE *rfp, RCSNUM *frev) { size_t plen; ! int i, done, nextroot; RCSNUM *tnum, *bnum; struct rcs_branch *brp; ! struct rcs_delta *hrdp, *trdp, *rdp; u_char *patch; struct cvs_lines *dlines, *plines; if ((hrdp = rcs_findrev(rfp, rfp->rf_head)) == NULL) --- 2640,2654 ---- * return it as a pointer to a struct cvs_lines. */ struct cvs_lines * ! rcs_rev_getlines(RCSFILE *rfp, RCSNUM *frev, struct cvs_line ***alines) { size_t plen; ! int annotate, done, i, nextroot; RCSNUM *tnum, *bnum; struct rcs_branch *brp; ! struct rcs_delta *hrdp, *prdp, *rdp, *trdp; u_char *patch; + struct cvs_line *line, *nline; struct cvs_lines *dlines, *plines; if ((hrdp = rcs_findrev(rfp, rfp->rf_head)) == NULL) *************** *** 2648,2661 **** bnum = tnum; } dlines = cvs_splitlines(hrdp->rd_text, hrdp->rd_tlen); done = 0; rdp = hrdp; ! if (!rcsnum_differ(rdp->rd_num, bnum)) ! goto next; if ((rdp = rcs_findrev(rfp, hrdp->rd_next)) == NULL) goto done; --- 2666,2708 ---- 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); done = 0; rdp = hrdp; ! if (!rcsnum_differ(rdp->rd_num, bnum)) { ! 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) goto done; *************** *** 2680,2691 **** plen = rdp->rd_tlen; patch = rdp->rd_text; plines = cvs_splitlines(patch, plen); ! rcs_patch_lines(dlines, plines); cvs_freelines(plines); ! if (!rcsnum_differ(rdp->rd_num, bnum)) ! break; rdp = trdp; } --- 2727,2763 ---- plen = rdp->rd_tlen; patch = rdp->rd_text; plines = cvs_splitlines(patch, plen); ! if (annotate == ANNOTATE_NOW) ! rcs_patch_lines(dlines, plines, *alines, prdp); ! else ! rcs_patch_lines(dlines, plines, NULL, NULL); cvs_freelines(plines); ! if (!rcsnum_differ(rdp->rd_num, bnum)) { ! 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; } *************** *** 2705,2712 **** break; } ! if (brp == NULL) fatal("expected branch not found on branch list"); if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) fatal("rcs_rev_getlines: failed to get delta for target rev"); --- 2777,2794 ---- break; } ! 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"); + } if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL) fatal("rcs_rev_getlines: failed to get delta for target rev"); *************** *** 2714,2719 **** --- 2796,2820 ---- goto again; } 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) rcsnum_free(bnum); *************** *** 2738,2744 **** BUF *bp; expand = 0; ! lines = rcs_rev_getlines(rfp, rev); bp = cvs_buf_alloc(1024, BUF_AUTOEXT); if (!(mode & RCS_KWEXP_NONE)) { --- 2839,2845 ---- BUF *bp; expand = 0; ! lines = rcs_rev_getlines(rfp, rev, NULL); bp = cvs_buf_alloc(1024, BUF_AUTOEXT); if (!(mode & RCS_KWEXP_NONE)) { *************** *** 2785,2791 **** extern int print_stdout; expand = 0; ! lines = rcs_rev_getlines(rfp, rev); if (!(mode & RCS_KWEXP_NONE)) { if (rfp->rf_expand != NULL) --- 2886,2892 ---- extern int print_stdout; expand = 0; ! lines = rcs_rev_getlines(rfp, rev, NULL); if (!(mode & RCS_KWEXP_NONE)) { if (rfp->rf_expand != NULL)