cvs-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-cvs] Changes to ccvs/src/annotate.c [signed-commits]


From: Derek Robert Price
Subject: [Cvs-cvs] Changes to ccvs/src/annotate.c [signed-commits]
Date: Tue, 11 Oct 2005 22:46:41 -0400

Index: ccvs/src/annotate.c
diff -u /dev/null ccvs/src/annotate.c:1.20.4.1
--- /dev/null   Wed Oct 12 02:46:41 2005
+++ ccvs/src/annotate.c Wed Oct 12 02:46:36 2005
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ *                                  and others.
+ *
+ * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (c) 1989-1992, Brian Berliner
+ * 
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS source distribution.
+ * 
+ * Show last revision where each line modified
+ * 
+ * Prints the specified files with each line annotated with the revision
+ * number where it was last modified.  With no argument, annotates all
+ * all the files in the directory (recursive by default).
+ */
+
+#include "cvs.h"
+
+/* Options from the command line.  */
+
+static int force_tag_match = 1;
+static int force_binary = 0;
+static char *tag = NULL;
+static int tag_validated;
+static char *date = NULL;
+
+static int is_rannotate;
+
+static int annotate_fileproc (void *callerdat, struct file_info *);
+static int rannotate_proc (int argc, char **argv, char *xwhere,
+                                char *mwhere, char *mfile, int shorten,
+                                int local, char *mname, char *msg);
+
+static const char *const annotate_usage[] =
+{
+    "Usage: %s %s [-lRfF] [-r rev] [-D date] [files...]\n",
+    "\t-l\tLocal directory only, no recursion.\n",
+    "\t-R\tProcess directories recursively.\n",
+    "\t-f\tUse head revision if tag/date not found.\n",
+    "\t-F\tAnnotate binary files.\n",
+    "\t-r rev\tAnnotate file as of specified revision/tag.\n",
+    "\t-D date\tAnnotate file as of specified date.\n",
+    "(Specify the --help global option for a list of other help options)\n",
+    NULL
+};
+
+/* Command to show the revision, date, and author where each line of a
+   file was modified.  */
+
+int
+annotate (int argc, char **argv)
+{
+    int local = 0;
+    int err = 0;
+    int c;
+
+    is_rannotate = (strcmp(cvs_cmd_name, "rannotate") == 0);
+
+    if (argc == -1)
+       usage (annotate_usage);
+
+    optind = 0;
+    while ((c = getopt (argc, argv, "+lr:D:fFR")) != -1)
+    {
+       switch (c)
+       {
+           case 'l':
+               local = 1;
+               break;
+           case 'R':
+               local = 0;
+               break;
+           case 'r':
+               parse_tagdate (&tag, &date, optarg);
+               break;
+           case 'D':
+               if (date) free (date);
+               date = Make_Date (optarg);
+               break;
+           case 'f':
+               force_tag_match = 0;
+               break;
+           case 'F':
+               force_binary = 1;
+               break;
+           case '?':
+           default:
+               usage (annotate_usage);
+               break;
+       }
+    }
+    argc -= optind;
+    argv += optind;
+
+#ifdef CLIENT_SUPPORT
+    if (current_parsed_root->isremote)
+    {
+       start_server ();
+
+       if (is_rannotate && !supported_request ("rannotate"))
+           error (1, 0, "server does not support rannotate");
+
+       ign_setup ();
+
+       if (local)
+           send_arg ("-l");
+       if (!force_tag_match)
+           send_arg ("-f");
+       if (force_binary)
+           send_arg ("-F");
+       option_with_arg ("-r", tag);
+       if (date)
+           client_senddate (date);
+       send_arg ("--");
+       if (is_rannotate)
+       {
+           int i;
+           for (i = 0; i < argc; i++)
+               send_arg (argv[i]);
+           send_to_server ("rannotate\012", 0);
+       }
+       else
+       {
+           send_files (argc, argv, local, 0, SEND_NO_CONTENTS, SIGN_NEVER,
+                       NULL, NULL);
+           send_file_names (argc, argv, SEND_EXPAND_WILD);
+           send_to_server ("annotate\012", 0);
+       }
+       return get_responses_and_close ();
+    }
+#endif /* CLIENT_SUPPORT */
+
+    if (is_rannotate)
+    {
+       DBM *db;
+       int i;
+       db = open_module ();
+       for (i = 0; i < argc; i++)
+       {
+           err += do_module (db, argv[i], MISC, "Annotating", rannotate_proc,
+                             NULL, 0, local, 0, 0, NULL);
+       }
+       close_module (db);
+    }
+    else
+    {
+       err = rannotate_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0,
+                             local, NULL, NULL);
+    }
+
+    return err;
+}
+    
+
+static int
+rannotate_proc (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_rannotate)
+    {
+       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 = Xasprintf ("%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);
+           free (where);
+           return 1;
+       }
+       /* End section which is identical to patch_proc.  */
+
+       if (force_tag_match && tag != NULL)
+           which = W_REPOS | W_ATTIC;
+       else
+           which = W_REPOS;
+    }
+    else
+    {
+        where = NULL;
+        which = W_LOCAL;
+        repository = "";
+    }
+
+    if (tag != NULL && !tag_validated)
+    {
+       tag_check_valid (tag, argc - 1, argv + 1, local, 0, repository, false);
+       tag_validated = 1;
+    }
+
+    err = start_recursion (annotate_fileproc, NULL, NULL, NULL, NULL,
+                          argc - 1, argv + 1, local, which, 0, CVS_LOCK_READ,
+                          where, 1, repository);
+    if (which & W_REPOS)
+       free (repository);
+    if (where != NULL)
+       free (where);
+    return err;
+}
+
+
+static int
+annotate_fileproc (void *callerdat, struct file_info *finfo)
+{
+    char *expand, *version;
+
+    if (finfo->rcs == NULL)
+        return 1;
+
+    if (finfo->rcs->flags & PARTIAL)
+        RCS_reparsercsfile (finfo->rcs, NULL, NULL);
+
+    expand = RCS_getexpand (finfo->rcs);
+    version = RCS_getversion (finfo->rcs, tag, date, force_tag_match, NULL);
+
+    if (version == NULL)
+        return 0;
+
+    /* Distinguish output for various files if we are processing
+       several files.  */
+    cvs_outerr ("\nAnnotations for ", 0);
+    cvs_outerr (finfo->fullname, 0);
+    cvs_outerr ("\n***************\n", 0);
+
+    if (!force_binary && expand && expand[0] == 'b')
+    {
+        cvs_outerr ("Skipping binary file -- -F not specified.\n", 0);
+    }
+    else
+    {
+       RCS_deltas (finfo->rcs, NULL, NULL,
+                   version, RCS_ANNOTATE, NULL, NULL, NULL, NULL);
+    }
+    free (version);
+    return 0;
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]