summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/log.c')
-rw-r--r--contrib/cvs/src/log.c197
1 files changed, 175 insertions, 22 deletions
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index 2e230e3..1930ae5 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -30,6 +30,8 @@ struct option_revlist
/* Nonzero if there was a trailing `.', which means to print only
the head revision of a branch. */
int branchhead;
+ /* Nonzero if first and last are inclusive. */
+ int inclusive;
};
/* This structure holds information derived from option_revlist given
@@ -46,6 +48,8 @@ struct revlist
/* The number of fields in these revisions (one more than
numdots). */
int fields;
+ /* Whether first & last are to be included or excluded. */
+ int inclusive;
};
/* This structure holds information parsed from the -d option. */
@@ -105,6 +109,9 @@ struct log_data_and_rcs
RCSNode *rcs;
};
+static int rlog_proc PROTO((int argc, char **argv, char *xwhere,
+ char *mwhere, char *mfile, int shorten,
+ int local_specified, char *mname, char *msg));
static Dtype log_dirproc PROTO ((void *callerdat, char *dir,
char *repository, char *update_dir,
List *entries));
@@ -131,6 +138,9 @@ static void log_version PROTO ((struct log_data *, struct revlist *,
static int log_branch PROTO ((Node *, void *));
static int version_compare PROTO ((const char *, const char *, int));
+static struct log_data log_data;
+static int is_rlog;
+
static const char *const log_usage[] =
{
"Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n",
@@ -142,6 +152,15 @@ static const char *const log_usage[] =
"\t-N\tDo not list tags.\n",
"\t-b\tOnly list revisions on the default branch.\n",
"\t-r[revisions]\tSpecify revision(s)s to list.\n",
+ "\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n",
+ "\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n",
+ "\t rev: rev and following revisions on the same branch.\n",
+ "\t rev:: After rev on the same branch.\n",
+ "\t :rev rev and previous revisions on the same branch.\n",
+ "\t ::rev Before rev on the same branch.\n",
+ "\t rev Just rev.\n",
+ "\t branch All revisions on the branch.\n",
+ "\t branch. The last revision on the branch.\n",
"\t-d dates\tSpecify dates (D1<D2 for range, D for latest before).\n",
"\t-s states\tOnly list revisions with specified states.\n",
"\t-w[logins]\tOnly list revisions checked in by specified logins.\n",
@@ -198,9 +217,10 @@ cvslog (argc, argv)
int c;
int err = 0;
int local = 0;
- struct log_data log_data;
struct option_revlist **prl;
+ is_rlog = (strcmp (command_name, "rlog") == 0);
+
if (argc == -1)
usage (log_usage);
@@ -252,11 +272,13 @@ cvslog (argc, argv)
break;
}
}
+ argc -= optind;
+ argv += optind;
wrap_setup ();
#ifdef CLIENT_SUPPORT
- if (client_active)
+ if (current_parsed_root->isremote)
{
struct datelist *p;
struct option_revlist *rp;
@@ -264,7 +286,10 @@ cvslog (argc, argv)
/* We're the local client. Fire up the remote server. */
start_server ();
-
+
+ if (is_rlog && !supported_request ("rlog"))
+ error (1, 0, "server does not support rlog");
+
ign_setup ();
if (log_data.default_branch)
@@ -332,6 +357,8 @@ cvslog (argc, argv)
if (rp->first != NULL)
send_to_server (rp->first, 0);
send_to_server (":", 1);
+ if (!rp->inclusive)
+ send_to_server (":", 1);
if (rp->last != NULL)
send_to_server (rp->last, 0);
}
@@ -347,10 +374,19 @@ cvslog (argc, argv)
send_arg_list ("-w", log_data.authorlist);
dellist (&log_data.authorlist);
- send_files (argc - optind, argv + optind, local, 0, SEND_NO_CONTENTS);
- send_file_names (argc - optind, argv + optind, SEND_EXPAND_WILD);
-
- send_to_server ("log\012", 0);
+ if (is_rlog)
+ {
+ int i;
+ for (i = 0; i < argc; i++)
+ send_arg (argv[i]);
+ send_to_server ("rlog\012", 0);
+ }
+ else
+ {
+ send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
+ send_to_server ("log\012", 0);
+ }
err = get_responses_and_close ();
return err;
}
@@ -361,11 +397,24 @@ cvslog (argc, argv)
if (findnode (log_data.authorlist, "@@MYSELF") != NULL)
log_parse_list (&log_data.authorlist, getcaller ());
- err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc,
- (DIRLEAVEPROC) NULL, (void *) &log_data,
- argc - optind, argv + optind, local,
- W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
- (char *) NULL, 1);
+ if (is_rlog)
+ {
+ DBM *db;
+ int i;
+ db = open_module ();
+ for (i = 0; i < argc; i++)
+ {
+ err += do_module (db, argv[i], MISC, "Logging", rlog_proc,
+ (char *) NULL, 0, 0, 0, 0, (char *) NULL);
+ }
+ close_module (db);
+ }
+ else
+ {
+ err = rlog_proc (argc + 1, argv - 1, (char *) NULL,
+ (char *) NULL, (char *) NULL, 0, 0, (char *) NULL,
+ (char *) NULL);
+ }
while (log_data.revlist)
{
@@ -403,6 +452,99 @@ cvslog (argc, argv)
return (err);
}
+
+static int
+rlog_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
+ int argc;
+ char **argv;
+ char *xwhere;
+ char *mwhere;
+ char *mfile;
+ int shorten;
+ int local;
+ char *mname;
+ char *msg;
+{
+ /* Begin section which is identical to patch_proc--should this
+ be abstracted out somehow? */
+ char *myargv[2];
+ int err = 0;
+ int which;
+ char *repository;
+ char *where;
+
+ if (is_rlog)
+ {
+ repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0])
+ + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
+ (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]);
+ where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1)
+ + 1);
+ (void) strcpy (where, argv[0]);
+
+ /* if mfile isn't null, we need to set up to do only part of the module */
+ if (mfile != NULL)
+ {
+ char *cp;
+ char *path;
+
+ /* if the portion of the module is a path, put the dir part on repos */
+ if ((cp = strrchr (mfile, '/')) != NULL)
+ {
+ *cp = '\0';
+ (void) strcat (repository, "/");
+ (void) strcat (repository, mfile);
+ (void) strcat (where, "/");
+ (void) strcat (where, mfile);
+ mfile = cp + 1;
+ }
+
+ /* take care of the rest */
+ path = xmalloc (strlen (repository) + strlen (mfile) + 5);
+ (void) sprintf (path, "%s/%s", repository, mfile);
+ if (isdir (path))
+ {
+ /* directory means repository gets the dir tacked on */
+ (void) strcpy (repository, path);
+ (void) strcat (where, "/");
+ (void) strcat (where, mfile);
+ }
+ else
+ {
+ myargv[0] = argv[0];
+ myargv[1] = mfile;
+ argc = 2;
+ argv = myargv;
+ }
+ free (path);
+ }
+
+ /* cd to the starting repository */
+ if ( CVS_CHDIR (repository) < 0)
+ {
+ error (0, errno, "cannot chdir to %s", repository);
+ free (repository);
+ return (1);
+ }
+ free (repository);
+ /* End section which is identical to patch_proc. */
+
+ which = W_REPOS | W_ATTIC;
+ }
+ else
+ {
+ where = NULL;
+ which = W_LOCAL | W_REPOS | W_ATTIC;
+ }
+
+ err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc,
+ (DIRLEAVEPROC) NULL, (void *) &log_data,
+ argc - 1, argv + 1, local, which, 0, 1,
+ where, 1);
+ return err;
+}
+
+
/*
* Parse a revision list specification.
*/
@@ -442,10 +584,16 @@ log_parse_revlist (argstring)
r->branchhead = 0;
r->last = strchr (copy, ':');
if (r->last != NULL)
+ {
*r->last++ = '\0';
+ r->inclusive = (*r->last != ':');
+ if (!r->inclusive)
+ r->last++;
+ }
else
{
r->last = r->first;
+ r->inclusive = 1;
if (r->first[0] != '\0' && r->first[strlen (r->first) - 1] == '.')
{
r->branchhead = 1;
@@ -689,15 +837,15 @@ log_fileproc (callerdat, finfo)
cvs_output ("RCS file: ", 0);
cvs_output (rcsfile->path, 0);
- cvs_output ("\nWorking file: ", 0);
- if (finfo->update_dir[0] == '\0')
- cvs_output (finfo->file, 0);
- else
+ if (!is_rlog)
{
- cvs_output (finfo->update_dir, 0);
- cvs_output ("/", 0);
+ cvs_output ("\nWorking file: ", 0);
+ if (finfo->update_dir[0] != '\0')
+ {
+ cvs_output (finfo->update_dir, 0);
+ cvs_output ("/", 0);
+ }
cvs_output (finfo->file, 0);
-
}
cvs_output ("\nhead:", 0);
@@ -860,6 +1008,7 @@ log_expand_revlist (rcs, revlist, default_branch)
struct revlist *nr;
nr = (struct revlist *) xmalloc (sizeof *nr);
+ nr->inclusive = r->inclusive;
if (r->first == NULL && r->last == NULL)
{
@@ -1023,6 +1172,7 @@ log_expand_revlist (rcs, revlist, default_branch)
}
nr->last = xstrdup (nr->first);
nr->fields = numdots (nr->first) + 1;
+ nr->inclusive = 1;
nr->next = NULL;
*pr = nr;
@@ -1137,9 +1287,12 @@ log_version_requested (log_data, revlist, rcs, vnode)
vfields = numdots (v) + 1;
for (r = revlist; r != NULL; r = r->next)
{
- if (vfields == r->fields + (r->fields & 1)
- && version_compare (v, r->first, r->fields) >= 0
- && version_compare (v, r->last, r->fields) <= 0)
+ if (vfields == r->fields + (r->fields & 1) &&
+ (r->inclusive ?
+ version_compare (v, r->first, r->fields) >= 0
+ && version_compare (v, r->last, r->fields) <= 0 :
+ version_compare (v, r->first, r->fields) > 0
+ && version_compare (v, r->last, r->fields) < 0))
{
return 1;
}
OpenPOWER on IntegriCloud