From b7aa5de49394fb2cccba24b4beb9a06d28c8058a Mon Sep 17 00:00:00 2001 From: Ray Lai Date: Thu, 30 Mar 2006 06:11:04 +0000 Subject: Add rlog -r[REV1][:][REV2] support From Pierre-Yves Ritschard. OK niallo@ --- usr.bin/cvs/rcs.h | 3 +- usr.bin/rcs/rlog.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 104 insertions(+), 8 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/cvs/rcs.h b/usr.bin/cvs/rcs.h index 6a926aeff66..bedf3e23d66 100644 --- a/usr.bin/cvs/rcs.h +++ b/usr.bin/cvs/rcs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.h,v 1.55 2006/03/30 06:07:35 ray Exp $ */ +/* $OpenBSD: rcs.h,v 1.56 2006/03/30 06:11:03 ray Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -121,6 +121,7 @@ struct rcs_kw { /* delta flags */ #define RCS_RD_DEAD 0x01 /* dead */ +#define RCS_RD_SELECT 0x02 /* select for operation */ /* RCS error codes */ #define RCS_ERR_NOERR 0 diff --git a/usr.bin/rcs/rlog.c b/usr.bin/rcs/rlog.c index 7e983f115d2..4aadcfb94c0 100644 --- a/usr.bin/rcs/rlog.c +++ b/usr.bin/rcs/rlog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rlog.c,v 1.35 2006/03/28 09:41:35 xsa Exp $ */ +/* $OpenBSD: rlog.c,v 1.36 2006/03/30 06:11:03 ray Exp $ */ /* * Copyright (c) 2005 Joris Vink * Copyright (c) 2005, 2006 Xavier Santolaria @@ -32,15 +32,18 @@ static void rlog_file(const char *, const char *); static void rlog_rev_print(struct rcs_delta *); +static u_int rlog_rev_select(void); +#define RLOG_OPTSTRING "hLl::NqRr::s:TtVw::x::z:" #define REVSEP "----------------------------" #define REVEND \ "=============================================================================" -static int hflag, Lflag, lflag, tflag, Nflag, wflag; +static int hflag, Lflag, lflag, rflag, tflag, Nflag, wflag; static char *llist = NULL; static char *slist = NULL; static char *wlist = NULL; +static char *revisions = NULL; static RCSFILE *file; void @@ -59,8 +62,8 @@ rlog_main(int argc, char **argv) int i, ch; char fpath[MAXPATHLEN]; - hflag = Rflag = 0; - while ((ch = rcs_getopt(argc, argv, "hLl::NqRs:TtVw::x::z:")) != -1) { + hflag = Rflag = rflag = 0; + while ((ch = rcs_getopt(argc, argv, RLOG_OPTSTRING)) != -1) { switch (ch) { case 'h': hflag = 1; @@ -78,6 +81,10 @@ rlog_main(int argc, char **argv) case 'q': verbose = 0; break; + case 'r': + rflag = 1; + revisions = rcs_optarg; + break; case 'R': Rflag = 1; break; @@ -157,11 +164,17 @@ static void rlog_file(const char *fname, const char *fpath) { char numb[64]; + u_int nrev; struct rcs_sym *sym; struct rcs_access *acp; struct rcs_delta *rdp; struct rcs_lock *lkp; + if (rflag == 1) + nrev = rlog_rev_select(); + else + nrev = file->rf_ndelta; + printf("\nRCS file: %s", fpath); printf("\nWorking file: %s", fname); printf("\nhead:"); @@ -196,7 +209,7 @@ rlog_file(const char *fname, const char *fpath) printf("total revisions: %u", file->rf_ndelta); if ((file->rf_head != NULL) && (hflag == 0) && (tflag == 0)) - printf(";\tselected revisions:"); /* XXX */ + printf(";\tselected revisions: %u", nrev); printf("\n"); @@ -205,8 +218,14 @@ rlog_file(const char *fname, const char *fpath) printf("description:\n%s", file->rf_desc); if ((hflag == 0) && (tflag == 0)) { - TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list) - rlog_rev_print(rdp); + TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list) { + /* + * if selections are enabled verify that entry is + * selected. + */ + if ((rflag == 0) || (rdp->rd_flags & RCS_RD_SELECT)) + rlog_rev_print(rdp); + } } printf("%s\n", REVEND); @@ -305,3 +324,79 @@ rlog_rev_print(struct rcs_delta *rdp) rdp->rd_author, rdp->rd_state); printf("%s", rdp->rd_log); } + +static u_int +rlog_rev_select(void) +{ + int i; + u_int nrev; + char *ep; + char *lstr, *rstr; + struct rcs_delta *rdp; + struct cvs_argvector *revargv, *revrange; + RCSNUM lnum, rnum; + + nrev = 0; + (void)memset(&lnum, 0, sizeof(lnum)); + (void)memset(&rnum, 0, sizeof(rnum)); + + if (revisions == NULL) { + TAILQ_FOREACH(rdp, &file->rf_delta, rd_list) + if (rcsnum_cmp(rdp->rd_num, file->rf_head, 0) == 0) { + rdp->rd_flags |= RCS_RD_SELECT; + return (1); + } + return (0); + } + + revargv = cvs_strsplit(revisions, ","); + for (i = 0; revargv->argv[i] != NULL; i++) { + revrange = cvs_strsplit(revargv->argv[i], ":"); + if (revrange->argv[0] == NULL) + /* should not happen */ + fatal("invalid revision range: %s", revargv->argv[i]); + else if (revrange->argv[1] == NULL) { + lstr = rstr = revrange->argv[0]; + } else { + if (revrange->argv[2] != NULL) + fatal("invalid revision range: %s", + revargv->argv[i]); + lstr = revrange->argv[0]; + rstr = revrange->argv[1]; + if (strcmp(lstr, "") == 0) { + lstr = NULL; + } + if (strcmp(rstr, "") == 0) { + rstr = NULL; + } + } + + if (lstr == NULL) + lstr = RCS_HEAD_INIT; + if (rcsnum_aton(lstr, &ep, &lnum) == 0 || (*ep != '\0')) + fatal("invalid revision: %s", lstr); + + if (rstr != NULL) { + if (rcsnum_aton(rstr, &ep, &rnum) == 0 || (*ep != '\0')) + fatal("invalid revision: %s", rstr); + } else + (void)rcsnum_cpy(file->rf_head, &rnum, 0); + cvs_argv_destroy(revrange); + + TAILQ_FOREACH(rdp, &file->rf_delta, rd_list) + if ((rcsnum_cmp(rdp->rd_num, &lnum, 0) <= 0) && + (rcsnum_cmp(rdp->rd_num, &rnum, 0) >= 0) && + !(rdp->rd_flags & RCS_RD_SELECT)) { + rdp->rd_flags |= RCS_RD_SELECT; + nrev++; + } + } + cvs_argv_destroy(revargv); + + if (lnum.rn_id != NULL) + xfree(lnum.rn_id); + if (rnum.rn_id != NULL) + xfree(rnum.rn_id); + + return (nrev); +} -- cgit v1.2.3