diff options
Diffstat (limited to 'contrib/cvs/src/log.c')
-rw-r--r-- | contrib/cvs/src/log.c | 197 |
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; } |