diff options
Diffstat (limited to 'usr.bin/cvs/rcs.c')
-rw-r--r-- | usr.bin/cvs/rcs.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c index ef988ba22ae..cb40f5f365b 100644 --- a/usr.bin/cvs/rcs.c +++ b/usr.bin/cvs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.240 2008/01/28 21:33:20 tobias Exp $ */ +/* $OpenBSD: rcs.c,v 1.241 2008/01/31 20:29:16 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -1134,6 +1134,55 @@ rcs_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines, return (0); } +void +rcs_delta_stats(struct rcs_delta *rdp, int *ladded, int *lremoved) +{ + struct cvs_lines *plines; + struct cvs_line *lp; + int added, i, lineno, nbln, removed; + char op, *ep; + u_char tmp; + + added = removed = 0; + + plines = cvs_splitlines(rdp->rd_text, rdp->rd_tlen); + lp = TAILQ_FIRST(&(plines->l_lines)); + + /* skip first bogus line */ + for (lp = TAILQ_NEXT(lp, l_list); lp != NULL; + lp = TAILQ_NEXT(lp, l_list)) { + if (lp->l_len < 2) + fatal("line too short, RCS patch seems broken"); + op = *(lp->l_line); + /* NUL-terminate line buffer for strtol() safety. */ + tmp = lp->l_line[lp->l_len - 1]; + lp->l_line[lp->l_len - 1] = '\0'; + lineno = (int)strtol((lp->l_line + 1), &ep, 10); + ep++; + nbln = (int)strtol(ep, &ep, 10); + /* Restore the last byte of the buffer */ + lp->l_line[lp->l_len - 1] = tmp; + if (nbln < 0) + fatal("invalid line number specification in RCS patch"); + + if (op == 'a') { + added += nbln; + for (i = 0; i < nbln; i++) { + lp = TAILQ_NEXT(lp, l_list); + if (lp == NULL) + fatal("truncated RCS patch"); + } + } + else if (op == 'd') + removed += nbln; + else + fatal("unknown RCS patch operation '%c'", op); + } + + *ladded = added; + *lremoved = removed; +} + /* * rcs_rev_add() * |