bug-cvs
[Top][All Lists]
Advanced

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

Re: Feature request/ideas - final patch


From: Frank Hemer
Subject: Re: Feature request/ideas - final patch
Date: Fri, 8 Apr 2005 20:03:33 +0200
User-agent: KMail/1.5.1

> Yes.  It is ok to send intermediate patches.

Ok, here's the next. See src/ChangeLog for details -

Index: src/ChangeLog
===================================================================
RCS file: /cvs/ccvs/src/ChangeLog,v
retrieving revision 1.3165.2.5
diff -u -r1.3165.2.5 ChangeLog
--- src/ChangeLog       6 Apr 2005 20:11:52 -0000       1.3165.2.5
+++ src/ChangeLog       8 Apr 2005 17:56:15 -0000
@@ -1,3 +1,23 @@
+       * admin.c (admin_fileproc): Undo last commit. TAG_TRUNK test removed.
+       * commit.c (check_fileproc): Imporve comments. TAG_TRUNK test removed.
+       (commit_fileproc): TAG_TRUNK test removed.
+       (remove_file): TAG_TRUNK test removed.
+       * update.c (update_fileproc): TAG_TRUNK test removed.
+       * rcs.c: Improve comments.
+       (RCS_gethead): Remove this fn.
+       (RCS_getversion): TAG_TRUNK test removed.
+       (RCS_gettag): Remove magic conversion.
+       (RCS_nodeisbranch): Properly detect magic for numeric rev.
+       Remove magic conversion.
+       (RCS_whatbranch): Gratious reformatting. Simplify.
+       (translate_tag): Always return non-magic branches for symbolic/extended
+       tags. Add param flag to prevent conversion for non-extended tags.
+       Improve assumption verification.
+       (RCS_extract_tag): Adapt error msg to cvs conventions.
+       (RCS_getprevious): Rootdate comparison fixed.
+       (RCS_getroot): Remove magic conversion.
+       * sanity.sh: More tests added.
+
 2005-04-06  Derek Price  <address@hidden>
 
        * rcs.c (RCS_getprevious): Remove erroneous FIXME.
Index: src/admin.c
===================================================================
RCS file: /cvs/ccvs/src/admin.c,v
retrieving revision 1.107.2.3
diff -u -r1.107.2.3 admin.c
--- src/admin.c 20 Mar 2005 23:41:36 -0000      1.107.2.3
+++ src/admin.c 8 Apr 2005 17:56:15 -0000
@@ -659,9 +659,13 @@
        char *branch = &admin_data->branch[2];
        if (*branch != '\0' && !isdigit ((unsigned char) *branch))
        {
-           error (0, 0, "%s: Symbolic name %s is undefined.",
-                  rcs->path, admin_data->branch + 2);
-           status = 1;
+           branch = RCS_whatbranch (rcs, admin_data->branch + 2);
+           if (branch == NULL)
+           {
+               error (0, 0, "%s: Symbolic name %s is undefined.",
+                             rcs->path, admin_data->branch + 2);
+               status = 1;
+           }
        }
        if (status == 0)
            RCS_setbranch (rcs, branch);
Index: src/commit.c
===================================================================
RCS file: /cvs/ccvs/src/commit.c,v
retrieving revision 1.252.2.1
diff -u -r1.252.2.1 commit.c
--- src/commit.c        19 Mar 2005 15:32:14 -0000      1.252.2.1
+++ src/commit.c        8 Apr 2005 17:56:15 -0000
@@ -700,6 +700,8 @@
     Lock_Cleanup ();
     dellist (&mulist);
 
+    /* add the commitid to val-tags
+     */
     char *commitid = Xasprintf ("@%s", global_session_id);
     tag_check_valid (commitid, argc, argv, local, aflag, "", true);
     free (commitid);
@@ -890,16 +892,13 @@
                           finfo->fullname);
                    goto out;
                }
-               if (status == T_MODIFIED && vers->tag)
+               if (status == T_MODIFIED && vers->tag &&
+                   !RCS_isbranch (finfo->rcs, vers->tag))
                {
-                  if ( (*(vers->tag) != '.' || strcmp (vers->tag+1, TAG_TRUNK))
-                        && !RCS_isbranch (finfo->rcs, vers->tag) )
-                  {
-                     error (0, 0,
-                           "sticky tag `%s' for file `%s' is not a branch",
-                           vers->tag, finfo->fullname);
-                     goto out;
-                  }
+                   error (0, 0,
+                          "sticky tag `%s' for file `%s' is not a branch",
+                          vers->tag, finfo->fullname);
+                   goto out;
                }
            }
            if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
@@ -1362,7 +1361,6 @@
     {
        char *rev = RCS_getversion (finfo->rcs, write_dirtag, NULL, 1, NULL);
        if (rev != NULL
-           && !(*write_dirtag == '.' && !strcmp (write_dirtag+1, TAG_TRUNK))
            && !RCS_nodeisbranch (finfo->rcs, write_dirtag))
            write_dirnonbranch = 1;
        if (rev != NULL)
@@ -1420,16 +1418,6 @@
     }
     else if (ci->status == T_ADDED)
     {
-
-        /* prevent adding files to a branch named TAG_TRUNK as this
-        * is a synonym for the trunk itself
-        */
-        if (ci->tag && *ci->tag == '.' && !strcmp (ci->tag + 1, TAG_TRUNK))
-       {
-           free (ci->tag);
-           ci->tag = NULL;
-       }
-
        if (checkaddfile (finfo->file, finfo->repository, ci->tag, ci->options,
                          &finfo->rcs) != 0)
        {
@@ -1448,7 +1436,7 @@
            /* If numeric, it is on the trunk; check_fileproc enforced
               this.  */
            && !isdigit ((unsigned char) ci->tag[0]))
-          {
+       {
            if (finfo->rcs == NULL)
                error (1, 0, "internal error: no parsed RCS file");
            if (ci->rev)
@@ -1774,8 +1762,7 @@
        error (1, 0, "internal error: no parsed RCS file");
 
     branch = 0;
-    if (tag && !(branch = RCS_nodeisbranch (finfo->rcs, tag))
-       && !(*tag == '.' && !strcmp (tag+1, TAG_TRUNK)))
+    if (tag && !(branch = RCS_nodeisbranch (finfo->rcs, tag)))
     {
        /* a symbolic tag is specified; just remove the tag from the file */
        if ((retcode = RCS_deltag (finfo->rcs, tag)) != 0)
Index: src/rcs.c
===================================================================
RCS file: /cvs/ccvs/src/rcs.c,v
retrieving revision 1.341.2.4
diff -u -r1.341.2.4 rcs.c
--- src/rcs.c   6 Apr 2005 20:11:52 -0000       1.341.2.4
+++ src/rcs.c   8 Apr 2005 17:56:20 -0000
@@ -105,8 +105,7 @@
 static char *RCS_getnext (RCSNode *, const char *);
 static char *RCS_getorigin (RCSNode *, const char *);
 static char *RCS_getcommitid (RCSNode *, const char *, bool);
-static char *RCS_gethead (RCSNode *, const char *);
-static char *translate_tag (RCSNode *rcs, const char *tag);
+static char *translate_tag (RCSNode *rcs, const char *, bool);
 static char *translate_symtag (RCSNode *, const char *);
 static char *RCS_addbranch (RCSNode *, const char *);
 static char *truncate_revnum (const char *);
@@ -2150,6 +2149,24 @@
 
 
 
+/* Return true if TAG is does not start with a number and consist entirely of
+ * numbers and dots.
+ *
+ * (N.N.N.N.prev is now a valid tag).
+ */
+static inline bool
+is_symbolic (const char *tag)
+{
+    assert (tag && *tag);
+    if (!isdigit (*tag)) return true;
+    for (tag++; *tag; tag++)
+       if (!(isdigit (*tag) || *tag == '.')) return true;
+    if (*--tag == '.') return true;
+    return false;
+}
+
+
+
 /*
  * Version Number
  * 
@@ -2172,30 +2189,29 @@
     {
        char *branch, *rev;
 
-       if (*tag == '.' && !strcmp (tag+1, TAG_TRUNK))
+       if (! RCS_nodeisbranch (rcs, tag))
        {
-           return RCS_getdatetrunk (rcs, date, force_tag_match);
+           /* We can't get a particular date if the tag is not a
+              branch.  */
+           return NULL;
        }
-       else
-       {
-           if (! RCS_nodeisbranch (rcs, tag))
-           {
-               /* We can't get a particular date if the tag is not a
-                  branch.  */
-               return NULL;
-           }
 
-           /* Work out the branch.  */
-           if (! isdigit ((unsigned char) tag[0]))
-               branch = RCS_whatbranch (rcs, tag);
-           else
-               branch = xstrdup (tag);
-
-           /* Fetch the revision of branch as of date.  */
+       /* Work out the branch.  */
+       if (is_symbolic (tag))
+           branch = RCS_whatbranch (rcs, tag);
+       else
+           branch = xstrdup (tag);
+
+       int dots = numdots (branch);
+
+       /* Fetch the revision of branch as of date.  */
+       if (!dots)
+           rev = RCS_getdatetrunk (rcs, date, force_tag_match);
+       else 
            rev = RCS_getdatebranch (rcs, date, branch);
-           free (branch);
-           return rev;
-       }
+
+       free (branch);
+       return rev;
     }
     else if (tag)
        return RCS_gettag (rcs, tag, force_tag_match, simple_tag);
@@ -2293,10 +2309,12 @@
     if (tag && STREQ (tag, TAG_HEAD))
         return RCS_head (rcs);
 
-    /* If valid tag let translate_tag say yea or nay. */
+    /* If valid tag let RCS_extract_tag say yea or nay. */
     char *tmp = RCS_extract_tag (tag, true);
     if (tmp) free (tmp);
-    rev = translate_tag (rcs, tag);
+
+    /* We need to preserve magic branch numbers here */
+    rev = translate_tag (rcs, tag, true);
 
     /* Trust the caller to print warnings. */
     return rev;
@@ -2304,24 +2322,6 @@
 
 
 
-/* Return true if TAG is does not start with a number and consist entirely of
- * numbers and dots.
- *
- * (N.N.N.N.prev is now a valid tag).
- */
-static inline bool
-is_symbolic (const char *tag)
-{
-    assert (tag && *tag);
-    if (!isdigit (*tag)) return true;
-    for (tag++; *tag; tag++)
-       if (!(isdigit (*tag) || *tag == '.')) return true;
-    if (*--tag == '.') return true;
-    return false;
-}
-
-
-
 /*
  * Find the revision for a specific tag.
  * If force_tag_match is set, return NULL if an exact match is not
@@ -2361,46 +2361,29 @@
     {
        char *version;
 
-       /* If we got a symbolic tag, resolve it to a numeric */
-       version = translate_tag (rcs, symtag);
-       if (version != NULL)
+       /* Resolve to a numeric revision number */
+       version = translate_tag (rcs, symtag, false);
+       if (version)
        {
            int dots;
-           char *magic, *branch, *cp;
-
            tag = version;
 
            /*
-            * If this is a magic revision, we turn it into either its
+            * If this is a branch tag, we turn it into either its
             * physical branch equivalent (if one exists) or into
             * its base revision, which we assume exists.
             */
            dots = numdots (tag);
-           if (dots > 2 && (dots & 1) != 0)
+           if (dots && !(dots & 1))
            {
-               branch = strrchr (tag, '.');
-               cp = branch++ - 1;
-               while (*cp != '.')
-                   cp--;
-
-               /* see if we have .magic-branch. (".0.") */
-               magic = xmalloc (strlen (tag) + 1);
-               (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
-               if (strncmp (magic, cp, strlen (magic)) == 0)
-               {
-                   /* it's magic.  See if the branch exists */
-                   *cp = '\0';         /* turn it into a revision */
-                   (void) sprintf (magic, "%s.%s", tag, branch);
-                   branch = RCS_getbranch (rcs, magic, 1);
-                   free (magic);
-                   if (branch != NULL)
-                   {
-                       free (tag);
-                       return branch;
-                   }
-                   return tag;
+               version = RCS_getbranch (rcs, tag, 1);
+               if (version != NULL)
+               {
+                   free (tag);
+                   return version;
                }
-               free (magic);
+               *strrchr (tag, '.') = '\0';
+               return tag;
            }
        }
        else
@@ -2559,12 +2542,14 @@
  * or symbolic tag resolves to a "branch" within the rcs file.
  *
  * FIXME: this is the same as RCS_nodeisbranch except for the special 
- *        case for handling a null rcsnode.
+ *        case for handling a null rcsnode and numeric magic branches.
  */
 int
 RCS_isbranch (RCSNode *rcs, const char *rev)
 {
-    /* numeric revisions are easy -- even number of dots is a branch */
+    /* numeric revisions are easy -- even number of dots is a branch
+     * Note that magic branch numbers are not checked
+     */
     if (isdigit ((unsigned char) *rev))
        return (numdots (rev) & 1) == 0;
 
@@ -2595,41 +2580,39 @@
 
     assert (rcs);
 
-    /* numeric revisions are easy -- even number of dots is a branch */
+    /* numeric revisions are easy -- even number of dots is a branch
+     * Note that we need to care about magic branch numbers
+     */
     if (!is_symbolic (tag))
-        return !(numdots (tag) & 1);
+    {
+        dots = numdots (tag);
+        if (dots > 1)
+       {
+           char *magic;
+           char *p = strrchr (tag, '.') - 1;
+           while (*p != '.') --p;
+           magic = Xasprintf (".%d.", RCS_MAGIC_BRANCH);
+           if (!strncmp (p, magic, strlen (magic)))
+           {
+               free (magic);
+               return (dots & 1);
+           }
+           free (magic);
+       }
+        return !(dots & 1);
+    }
+
+    /* resolve to its numeric equivalent and remove magic */
+    version = translate_tag (rcs, tag, false);
 
-    version = translate_tag (rcs, tag);
     if (!version) return false;
 
     dots = numdots (version);
+    free (version);
+
     if (!(dots & 1))
-    {
-       free (version);
        return true;
-    }
 
-    /* got a symbolic tag match, but it's not a branch; see if it's magic */
-    if (dots > 2)
-    {
-       char *magic;
-       char *branch = strrchr (version, '.');
-       char *cp = branch - 1;
-       while (*cp != '.')
-           cp--;
-
-       /* see if we have .magic-branch. (".0.") */
-       magic = xmalloc (strlen (version) + 1);
-       (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
-       if (strncmp (magic, cp, strlen (magic)) == 0)
-       {
-           free (magic);
-           free (version);
-           return true;
-       }
-       free (magic);
-    }
-    free (version);
     return false;
 }
 
@@ -2653,38 +2636,41 @@
     if (is_symbolic (tag))
     {
        /* now, look for a match in the symbols list */
-       version = translate_tag (rcs, tag);
+       version = translate_tag (rcs, tag, false);
        if (!version) return NULL;
+       dots = numdots (version);
     }
     else
+    {
        version = xstrdup (tag);
+       dots = numdots (version);
+
+       if (dots > 2 && (dots & 1))
+       {
+           /* See if it's magic; Convert into physical equivalent if so */
+           char *magic;
+           char *branch = strrchr (version, '.');
+           char *p = branch++ - 1;
+           while (*p != '.') --p;
+
+           /* see if we have .magic-branch. (".0.") */
+           magic = Xasprintf (".%d.", RCS_MAGIC_BRANCH);
+           if (!strncmp (p, magic, strlen (magic)))
+           {
+               /* It's magic! Construct the real branch */
+               free (magic);
+               *p = '\0';    /* turn it into a revision */
+               magic = Xasprintf ("%s.%s", version, branch);
+               free (version);
+               return magic;
+           }
+           free (magic);
+       }
+    }
 
-    dots = numdots (version);
     if (!(dots & 1))
        return version;
 
-    /* got a symbolic tag match, but it's not a branch; see if it's magic */
-    if (dots > 2)
-    {
-       char *magic;
-       char *branch = strrchr (version, '.');
-       char *cp = branch++ - 1;
-       while (*cp != '.')
-           cp--;
-
-       /* see if we have .magic-branch. (".0.") */
-       magic = xmalloc (strlen (version) + 1);
-       (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
-       if (strncmp (magic, cp, strlen (magic)) == 0)
-       {
-           /* yep.  it's magic.  now, construct the real branch */
-           *cp = '\0';                 /* turn it into a revision */
-           (void) sprintf (magic, "%s.%s", version, branch);
-           free (version);
-           return magic;
-       }
-       free (magic);
-    }
     free (version);
     return NULL;
 }
@@ -2841,7 +2827,7 @@
 
     if (is_symbolic (tag))
     {
-       num = translate_tag (rcs, tag);
+       num = translate_tag (rcs, tag, false);
        if (!num) return NULL;
     }
     else
@@ -3325,6 +3311,10 @@
  * RETURN
  *     Branch: return the HEAD-1 revision or NULL
  *     Revision: return the previous revision or NULL
+ *
+ * ASSUMPTIONS
+ *   The tag is valid, it has been validated by RCS_check_tag
+ *   The Tag does not contain RCS_MAGIC_BRANCH
  */
 static char *
 RCS_getprevious (RCSNode *rcs, const char *rev)
@@ -3351,22 +3341,26 @@
     if (dots > 1) /* revision on a branch */
     {
         /* find the root revision */
-        *strrchr (trev, '.') = '\0';
+        char *p1 = strrchr (trev, '.');
+       *p1 = '\0';
        int len = strlen (trev);
-        *strrchr (trev, '.') = '\0';
+        char *p2 = strrchr (trev, '.');
+       *p2 = '\0';
 
         RCSVers *vers = NULL;
         Node *node = findnode (rcs->versions, trev);
         if (node && (vers = node->data) && vers->branches)
        {
-          char *rootdate = vers->date;
+           *p1 = '.';
+           *p2 = '.';
+           char *rootdate = vers->date;
            Node *head = vers->branches->list;
            Node *br;
            for (br = head->next; br != head; br = br->next)
            {
                if (node = findnode (rcs->versions, br->key))
                {
-                   if (strncmp (((RCSVers *)node->data)->version, rev, len))
+                   if (strncmp (((RCSVers *)node->data)->version, trev, len))
                        continue;
                       
                    ++len;
@@ -3374,12 +3368,15 @@
                    while (node != NULL)
                    {
                        vers = node->data;
-                       if (STREQ (vers->version + len, rev + len))
+                       if (STREQ (vers->version + len, trev + len))
                        {
                            if (p)
                                retval = xstrdup (p);
                            else if (RCS_datecmp (vers->date, rootdate))
-                               retval = xstrdup (trev);
+                           {
+                               *p2 = '\0';
+                               retval = xstrdup (trev);
+                           }
                            break;
                        }
 
@@ -3392,6 +3389,7 @@
                        else
                            node = NULL;
                    }
+                   break;
                }
            }
        }
@@ -3422,7 +3420,7 @@
         if (prev && STREQ (trev, "1.1"))
         {
             /* This is 1.1;  if the date of 1.1 is the same as that for
-            * the VENDOR.1 version, then return the VENDOR version with
+            * the VENDOR.1 version, then return the latest VENDOR version with
             * a timestamp before the 1.2 timestamp (point of merge). The
             * date of 1.1. and VENDOR.1 differs if the first version of
             * a file is created by a regular cvs add and commit, and there
@@ -3491,6 +3489,10 @@
  * RETURN
  *     Branch: NULL (There cannot be a revision)
  *     Revision: returns the next revision or NULL
+ *
+ * ASSUMPTIONS
+ *   The tag is valid, it has been validated by RCS_check_tag
+ *   The Tag does not contain RCS_MAGIC_BRANCH
  */
 static char *
 RCS_getnext (RCSNode *rcs, const char *rev)
@@ -3555,6 +3557,10 @@
 /*
  * Find the origin revision, which is the first revision
  * on either the trunk or a branch if added there.
+ *
+ * ASSUMPTIONS
+ *   The tag is valid, it has been validated by RCS_check_tag
+ *   The Tag does not contain RCS_MAGIC_BRANCH
  */
 static char *
 RCS_getorigin (RCSNode *rcs, const char *rev)
@@ -3696,6 +3702,10 @@
 /*
  * Find the branchpoint, no matter if rev points
  * to a branch or a revision
+ *
+ * ASSUMPTIONS
+ *   The tag is valid, it has been validated by RCS_check_tag
+ *   The Tag does not contain RCS_MAGIC_BRANCH
  */
 static char *
 RCS_getroot (RCSNode *rcs, const char *rev)
@@ -3707,22 +3717,7 @@
     if (dots > 1)
     {
         int len;
-        char *tmp = xstrdup (rev);
-
-       /* remove ev. magic branch num */
-       if (dots > 2 && (dots & 1))
-       {
-           int i;
-           const char *p = rev;
-           for (i = 1; i < dots; ++i)
-               p = strchr (p+1, '.');
-           if (!strncmp (p, ".0.", 3))
-           {
-               strcpy (tmp + (p - rev), p + 2);
-               --dots;
-           }
-       }
-       retval = xstrdup (tmp);
+       retval = xstrdup (rev);
 
         if (dots & 1)
        {
@@ -3756,7 +3751,7 @@
                for (br = head->next; br != head; br = br->next)
                {
                   //check if br->key is on branch rev
-                  if (!strncmp (tmp, br->key, len))
+                  if (!strncmp (rev, br->key, len))
                   {
                       if (node = findnode (rcs->versions, br->key))
                       {
@@ -3764,20 +3759,17 @@
                           if (vers->dead && !RCS_datecmp (rootdate, 
vers->date))
                           {
                               free (retval);
-                              free (tmp);
                               if (STREQ (vers->version, rev))
                                   return NULL;
                               else
                                   return xstrdup (vers->version);
                           }
                       }
-                      free (tmp);
                       return retval;
                   }
                }
            }
        }
-       free (tmp);
        free (retval);
     }
     return NULL;
@@ -3827,64 +3819,26 @@
 
 
 
-/*
- * Find the head of branch of current revision
- */
-static char *
-RCS_gethead (RCSNode *rcs, const char *rev)
-{
-    char *retval = NULL;
-    int dots = numdots (rev);
-    if (!dots)
-        return NULL;
-
-    char *tmp = xstrdup (rev);
-
-    /* remove ev. magic branch num */
-    if (dots > 2 && (dots & 1))
-    {
-        int i;
-        const char *p = rev;
-        for (i = 1; i < dots; ++i)
-            p = strchr (p+1, '.');
-        assert (p);
-        if (!strncmp (p, ".0.", 3))
-        {
-            strcpy (tmp + (p - rev), p + 2);
-           --dots;
-        }
-    }
-
-    if (dots > 1)
-    {
-        if (dots & 1)
-           *(strrchr (tmp, '.')) = '\0';
-       retval = RCS_branch_head (rcs, tmp);
-    }
-    else
-        retval = xstrdup (rcs->head);
-    free (tmp);
-
-    return retval;
-}
-
-
-
 /* Translate special/symbolic tags into their revision thus:
  *
  *   - If TAG starts numeric, rely on its formating up to the first
  *     non-numberic-tag character ([^0-9.]) to resolve a base revision.
  *   - Else, resolve everything before the first `.' as a symbolic tag to
- *     determine the base tag.
+ *     determine the base tag. Convert magic branch numbers into their
+ *     physical equivalent.
  *   - Resolve any remaining tag extensions (.trunk, .head, ...).
  *
  * RETURNS
  *   NULL on error.
  *   A newly malloc'd string containing the resolved revision, otherwise.
+ *
+ * ASSUMPTIONS
+ *   The Tag is valid, it has been validated by RCS_check_tag
  */
 static char *
-translate_tag (RCSNode *rcs, const char *tag)
+translate_tag (RCSNode *rcs, const char *tag, bool keepmagic)
 {
+/*     printf("translate_tag: %s\n",tag); */
     char c;
     char *retval = NULL;
     char *tmp, *tmpval;
@@ -3915,7 +3869,6 @@
        tmp = p;
        if (*p--) *p = '\0';
        retval = xstrdup (tmpval);
-       /* FIXME?  Validate numeric revision?  */
     }
     else
         tmp = tmpval;
@@ -3925,30 +3878,51 @@
     if (token)
     {
         bool force;
+       if (!keepmagic && retval && RCS_nodeisbranch (rcs, retval))
+       {
+           assert (*token); /* see => assumptions */
+           /* We have an initial numeric revision, check
+            * for magic rev numbers and convert to their
+            * physical equivalent if so.
+            */
+           char *p = RCS_whatbranch (rcs, retval);
+           free (retval);
+           retval = p;
+       }
        do
        {
+           assert (*token); /* see => assumptions */
            force = false;
            if (!retval)
            {
+               /* there is no base revision and no initial numeric revision */
                if (token == tmp)
                {
-                   if (*token)
+                   /* tag does not start with a dot */
+                   retval = translate_symtag (rcs, token);
+                   if (retval)
                    {
-                       retval = translate_symtag (rcs, token);
-                       if (!retval)
-                           /* Return NULL.  Callers will generate the "TAG
-                            * not found" message.
+                       if (keepmagic && (token = strtok (NULL,".")))
+                       {
+                           /* The next token needs to be evaluated here because
+                            * we need to know whether magic revision numbers
+                            * need to be converted to their physical 
equivalent.
+                            * Set force flag to not lose this token
                             */
-                           break;
-                   }
-                   else
-                       /* tags starting with `.' modify BASE.  */
-                       continue;
-                   if (RCS_nodeisbranch (rcs, retval))
-                   {
-                       char *p = RCS_whatbranch (rcs, retval);
-                       free (retval);
-                       retval = p;
+                           force = true;
+                           keepmagic = false;
+                       }
+                           
+                       if (!keepmagic && retval && RCS_nodeisbranch (rcs, 
retval))
+                       {
+                           /* convert magic rev numbers into their
+                            * physical equivalent
+                            */
+                           char *p = RCS_whatbranch (rcs, retval);
+                           free (retval);
+                           retval = p;
+                           if (!retval) force = false;
+                       }
                    }
                }
                else if (STREQ (token, TAG_TRUNK))
@@ -3956,35 +3930,51 @@
                    /* .trunk is a branch tag, but rcs->head is a revision.  */
                    char *p;
                    retval = RCS_head (rcs);
-                   if (!retval) return NULL;
 
-                   /* A non-null return from RCS_head is guaranteed to not
-                    * specify a branch and to have at least one dot.
-                    */
-                   p = strrchr (retval, '.');
-                   *p = '\0';
+                   if (retval)
+                   {
+                       /* A non-null return from RCS_head is guaranteed to not
+                        * specify a branch and to have at least one dot.
+                        */
+                       p = strrchr (retval, '.');
+                       *p = '\0';
+                   }
                }
                else if (STREQ (token, TAG_COMMITID))
                {
                    char *commitid = strtok (NULL,".");
                    if (token = strtok (NULL,"."))
-                      force = true;
+                       /* The next token needs to be evaluated here because
+                        * RCS_getcommitid needs to know whether a previous
+                        * revision is requested (performance enhancement).
+                        * Set force flag to ensure the next token gets resolved
+                        * if it is not a '.prev' token.
+                        */
+                       force = true;
                    if (commitid)
                    {
-                      bool previous = (token && STREQ (token, TAG_PREVIOUS));
-                      retval = RCS_getcommitid (rcs, commitid, previous);
-                      if (previous || !retval)
-                          force = false;
+                       bool previous = (token && STREQ (token, TAG_PREVIOUS));
+                       retval = RCS_getcommitid (rcs, commitid, previous);
+                       if (previous || !retval)
+                           force = false;
                    }
                }
                else if (!STREQ (token, TAG_DOTBASE))
+                   /* Does it make sense to output an error msg here?
+                    * Actualy this is more or less a help for debugging
+                    * since this only happens if the assumptions fail
+                    */
                    error (1, 0, "Tag `%s': invalid head: `%s'", token, tag);
+
+               /* If no retval and no force flag => return NULL.
+                * Callers will generate the "TAG not found" message.
+                */
            }
            else
            {
                char *p = retval;
                if (STREQ (token, TAG_DOTHEAD))
-                   retval = RCS_gethead (rcs, p);
+                   retval = RCS_branch_head (rcs, p);
                else if (STREQ (token, TAG_PREVIOUS))
                    retval = RCS_getprevious (rcs, p);
                else if (STREQ (token, TAG_ORIGIN))
@@ -3994,6 +3984,10 @@
                else if (STREQ (token, TAG_NEXT))
                    retval = RCS_getnext (rcs, p);
                else
+                   /* Does it make sense to output an error msg here?
+                    * Actualy this is more or less a help for debugging
+                    * since this only happens if the assumptions fail
+                    */
                    error (1, 0,
                           "Tag `%s': invalid extension: `%s'", token, tag);
                free (p);
@@ -4002,7 +3996,7 @@
        while (force || (retval && (token = strtok (NULL, "."))) );
     }
     free (tmpval);
-
+/*     printf("translate_tag: '%s' => '%s'\n",tag,retval); */
     return retval;
 }
 
@@ -4187,7 +4181,7 @@
 
     if (strstr (p,".."))
         error (1, 0, "\
-Numeric tag %s invalid.  Numeric tags should be of the form X[.X]...", tag);
+Numeric tag `%s' invalid.  Numeric tags should be of the form X[.X]...", tag);
 
     bool dot = false;
     while (p)
@@ -4198,7 +4192,7 @@
            break;
        else if (dot && first)
            error (1, 0, "\
-Numeric tag '%s' invalid. Numeric tags should be of the form X[.X]...", tag);
+Numeric tag `%s' invalid. Numeric tags should be of the form X[.X]...", tag);
        else
        {
            dot = false;
@@ -4209,7 +4203,7 @@
 
     if ( (*p && !first && !dot) || tag[strlen (tag)-1] == '.')
         error (1, 0, "\
-Tag '%s' is invalid. Combined tags should be of the form X[.X]...", tag);
+Tag `%s' invalid. Combined tags should be of the form X[.X]...", tag);
 
     bool deptag = false;
     bool multi = true;
@@ -4245,7 +4239,7 @@
                    }
                    else
                        error (1, 0,"\
-Tag '%s' invalid. Reserved expression without leading dot: '%s'", tag, token);
+Tag `%s' invalid. Reserved expression without leading dot: `%s'", tag, token);
                }
                else if (STREQ (token, TAG_TRUNK))
                {
@@ -4267,7 +4261,7 @@
                }
                else if (!files)
                    error (1, 0,"\
-Tag '%s' invalid. Tag must not be relative: '.%s'", tag, token);
+Tag `%s' invalid. Tag must not be relative: `.%s'", tag, token);
                else if (STREQ (token, TAG_ORIGIN)
                         || STREQ (token, TAG_DOTHEAD))
                {
@@ -4282,14 +4276,14 @@
                }
                else
                    error (1, 0,"\
-Tag '%s' invalid. Cannot resolve head: '.%s'", tag, token);
+Tag `%s' invalid. Cannot resolve head: `.%s'", tag, token);
            }
            else if (deptag)
                error (1, 0,"\
-Tag '%s' invalid. Deprecated prefix before extension: '%s'", tag, token);
+Tag `%s' invalid. Deprecated prefix before extension: `%s'", tag, token);
            else if (!multi)
                error (1, 0,"\
-Tag '%s' invalid. Extension not allowed: '%s'", tag, token);
+Tag `%s' invalid. Extension not allowed: `%s'", tag, token);
            else if (STREQ (token, TAG_ORIGIN)
                     || STREQ (token, TAG_DOTHEAD))
            {
@@ -4297,14 +4291,14 @@
                    prev = token;
                else
                    error (1, 0,"\
-Tag '%s' invalid. Duplicate extension: '%s'", tag, token);
+Tag `%s' invalid. Duplicate extension: `%s'", tag, token);
 
            }
            else if ((!STREQ (token, TAG_PREVIOUS))
                      && (!STREQ (token, TAG_NEXT))
                      && (!STREQ (token, TAG_ROOT)))
                error (1, 0,"\
-Tag '%s' invalid. Cannot resolve extension: '%s'", tag, token);
+Tag `%s' invalid. Cannot resolve extension: `%s'", tag, token);
            else
                prev = NULL;
        }
Index: src/sanity.sh
===================================================================
RCS file: /cvs/ccvs/src/sanity.sh,v
retrieving revision 1.1053.2.2
diff -u -r1.1053.2.2 sanity.sh
--- src/sanity.sh       19 Mar 2005 17:36:47 -0000      1.1053.2.2
+++ src/sanity.sh       8 Apr 2005 17:56:32 -0000
@@ -12298,6 +12298,8 @@
          #   .prev
          #   .root
          #   .origin
+         save_TZ=$TZ
+         TZ=UTC0; export TZ
          module=tag-ext
          mkdir $module; cd $module
          mkdir top; cd top
@@ -12616,7 +12618,19 @@
          dotest_fail tag-ext-26 "$testcvs -Q -n diff -r \.prev" \
 "${SPROG} \[diff aborted\]: Tag .\.prev. invalid\. Tag must not be relative: 
.\.prev."
 
-         dotest_fail tag-ext-27 "$testcvs diff -r \.prev file2 file3" \
+         echo tcontent >file4
+         dotest tag-ext-27 "$testcvs -Q add file4"
+
+         dotest tag-ext-28 "$testcvs -Q ci -maddtrunk"
+
+         rm file4
+         dotest tag-ext-29 "$testcvs remove file4" \
+"cvs remove: scheduling \`file4' for removal
+cvs remove: use \`cvs commit' to remove this file permanently"
+
+         dotest tag-ext-30 "$testcvs -Q ci -mremtrunk"
+
+         dotest_fail tag-ext-31 "$testcvs diff -r \.prev file2 file3" \
 "Index: file2
 ===================================================================
 RCS file: $CVSROOT_DIRNAME/$module/file2,v
@@ -12638,13 +12652,13 @@
 ---
 > tcontent"
 
-         dotest_fail tag-ext-29 "$testcvs diff -r \.root file2 file3" \
+         dotest_fail tag-ext-32 "$testcvs diff -r \.root file2 file3" \
 "cvs diff: tag \.root is not in file file2
 cvs diff: tag \.root is not in file file3"
 
-         dotest tag-ext-30 "$testcvs diff -r \.origin.head file2 file3"
+         dotest tag-ext-33 "$testcvs diff -r \.origin.head file2 file3"
 
-         dotest_fail tag-ext-31 "$testcvs diff -r BRANCH1-1\.root file2 file3" 
\
+         dotest_fail tag-ext-34 "$testcvs diff -r BRANCH1-1\.root file2 file3" 
\
 "Index: file2
 ===================================================================
 RCS file: $CVSROOT_DIRNAME/$module/file2,v
@@ -12666,15 +12680,183 @@
 ---
 > tcontent"
 
-         dotest_fail tag-ext-32 "$testcvs diff -r BRANCH1-1\.root\.prev\.head 
file2 file3" \
+         dotest_fail tag-ext-35 "$testcvs diff -r BRANCH1-1\.root\.prev\.head 
file2 file3" \
 "cvs diff: tag BRANCH1-1\.root\.prev\.head is not in file file3"
 
+         dotest tag-ext-36 "$testcvs -q update -r BRANCH1 file3" \
+"U file3"
+
+         dotest tag-ext-37 "$testcvs tag -b BRANCH1-2 file3" \
+"T file3"
+
+         echo b1content3 >file3
+         dotest tag-ext-38 "$testcvs -Q ci -maddbranch1 file3"
+
+         dotest tag-ext-39 "$testcvs -q update -r BRANCH1-2 file3" \
+"U file3"
+
+         echo b1-2content1 >file3
+         dotest tag-ext-40 "$testcvs -Q ci -maddbranch1-2.1 file3"
+
+         echo b1-2content2 >file3
+         dotest tag-ext-41 "$testcvs -Q ci -maddbranch1-2.2 file3"
+
+         dotest tag-ext-42 "$testcvs tag -b BRANCH1-2-1 file3" \
+"T file3"
+
+         echo b1-2content3 >file3
+         dotest tag-ext-43 "$testcvs -Q ci -maddbranch1-2.3 file3"
+
+         dotest tag-ext-44 "$testcvs -q update -r BRANCH1-2-1 file3" \
+"U file3"
+
+         echo b1-2-1content1 >file3
+         dotest tag-ext-45 "$testcvs -Q ci -maddbranch1-2-1.1 file3"
+
+         echo b1-2-1content2 >file3
+         dotest tag-ext-46 "$testcvs -Q ci -maddbranch1-2-1.2 file3"
+
+
+         echo b1-2-1content3 >file3
+         dotest tag-ext-47 "$testcvs -Q ci -maddbranch1-2-1.3 file3"
+
+         echo b1-2-1content4 >file3
+         dotest tag-ext-48 "$testcvs -Q ci -maddbranch1-2-1.4 file3"
+
+         echo b1-2-1content5 >file3
+         dotest tag-ext-49 "$testcvs -Q ci -maddbranch1-2-1.5 file3"
+
+         echo b1-2-1content6 >file3
+         dotest tag-ext-50 "$testcvs -Q ci -maddbranch1-2-1.6 file3"
+
+         echo b1-2-1content7 >file3
+         dotest tag-ext-51 "$testcvs -Q ci -maddbranch1-2-1.7 file3"
+
+         echo b1-2-1content8 >file3
+         dotest tag-ext-52 "$testcvs -Q ci -maddbranch1-2-1.8 file3"
+
+         echo b1-2-1content9 >file3
+         dotest tag-ext-53 "$testcvs -Q ci -maddbranch1-2-1.9 file3"
+
+         dotest tag-ext-54 "$testcvs tag -b BRANCH1-2-1-1 file3" \
+"T file3"
+
+         echo b1-2-1content10 >file3
+         dotest tag-ext-55 "$testcvs -Q ci -maddbranch1-2-1.10 file3"
+
+         rm file3
+         dotest tag-ext-56 "$testcvs remove file3" \
+"cvs remove: scheduling \`file3' for removal
+cvs remove: use \`cvs commit' to remove this file permanently"
+
+         dotest tag-ext-57 "$testcvs -Q ci -mremBRANCH1-2-1.11 file3"
+
+         dotest tag-ext-58 "$testcvs -q update -r BRANCH1-2-1-1 file3" \
+"U file3"
+
+         echo b1-2-1-1content1 >file3
+         dotest tag-ext-59 "$testcvs -Q ci -maddbranch1-2-1-1.1 file3"
+
+         echo b1-2-1-1content2 >file3
+         dotest tag-ext-60 "$testcvs -Q ci -maddbranch1-2-1-1.2 file3"
+
+         dotest tag-ext-61 "$testcvs tag -b BRANCH1-2-1-1-1-1 file3" \
+"T file3"
+
+         echo b1-2-1-1content3 >file3
+         dotest tag-ext-62 "$testcvs -Q ci -maddbranch1-2-1-1.3 file3"
+
+         dotest tag-ext-63 "$testcvs admin -o 1.1.2.2.2.2.2.4::1.1.2.2.2.2.2.8 
file3" \
+"RCS file: $CVSROOT_DIRNAME/$module/file3,v
+deleting revision 1\.1\.2\.2\.2\.2\.2\.5
+deleting revision 1\.1\.2\.2\.2\.2\.2\.6
+deleting revision 1\.1\.2\.2\.2\.2\.2\.7
+done"
+
+         dotest tag-ext-64 "$testcvs admin -o 1.1.2.2.2.2.2.2::1.1.2.2.2.2.2.4 
file3" \
+"RCS file: $CVSROOT_DIRNAME/$module/file3,v
+deleting revision 1\.1\.2\.2\.2\.2\.2\.3
+done"
+
+         dotest_fail tag-ext-65 "$testcvs diff -r \.root\.root\.root\.head 
file3" \
+"Index: file3
+===================================================================
+RCS file: $CVSROOT_DIRNAME/$module/file3,v
+retrieving revision 1\.1\.2\.3
+retrieving revision 1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+diff -r1\.1\.2\.3 -r1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+1c1
+< b1content3
+---
+> b1-2-1-1content3"
+
+         dotest_fail tag-ext-66 "$testcvs diff -r \.origin -r \.origin\.head 
file3" \
+"Index: file3
+===================================================================
+RCS file: $CVSROOT_DIRNAME/$module/file3,v
+retrieving revision 1\.1\.2\.1
+retrieving revision 1\.1\.2\.3
+diff -r1\.1\.2\.1 -r1\.1\.2\.3
+1c1
+< b1content
+---
+> b1content3"
+
+         dotest tag-ext-67 "$testcvs diff -r \.origin\.prev -r \.root\.head 
file3"
+
+         dotest_fail tag-ext-68 "$testcvs diff -r \.origin\.prev -r \.root 
file3" \
+"cvs diff: tag \.origin\.prev is not in file file3"
+
+         dotest_fail tag-ext-69 "$testcvs diff -r \.origin -r \.root\.head 
file3" \
+"cvs diff: Tag \.root\.head refers to a dead (removed) revision in file 
\`file3'\.
+cvs diff: No comparison available\.  Pass \`-N' to \`cvs diff'?"
+
+         dotest_fail tag-ext-70 "$testcvs diff -r 
\.prev\.prev\.prev\.prev\.prev\.prev\.prev\.prev\.prev\.prev\.prev file3" \
+"Index: file3
+===================================================================
+RCS file: $CVSROOT_DIRNAME/$module/file3,v
+retrieving revision 1\.1\.2\.1
+retrieving revision 1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+diff -r1\.1\.2\.1 -r1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+1c1
+< b1content
+---
+> b1-2-1-1content3"
+
+         date_T1=`getrlogdate -r1\.2 tag-ext/file3`
+         date_T2=`getrlogdate -r1\.1\.2\.2\.2\.2\.2\.8 tag-ext/file3`
+         
+         dotest_fail tag-ext-71 "$testcvs diff -r \.trunk:'$date_T1' file3" \
+"Index: file3
+===================================================================
+RCS file: $CVSROOT_DIRNAME/$module/file3,v
+retrieving revision 1\.2
+retrieving revision 1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+diff -r1\.2 -r1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+1c1
+< content
+---
+> b1-2-1-1content3"
+
+         dotest_fail tag-ext-72 "$testcvs diff -r BRANCH1-2-1:'$date_T2' 
file3" \
+"Index: file3
+===================================================================
+RCS file: $CVSROOT_DIRNAME/$module/file3,v
+retrieving revision 1\.1\.2\.2\.2\.2\.2\.8
+retrieving revision 1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+diff -r1\.1\.2\.2\.2\.2\.2\.8 -r1\.1\.2\.2\.2\.2\.2\.9\.2\.3
+1c1
+< b1-2-1content8
+---
+> b1-2-1-1content3"
+
          # clean up
          dokeep
          restore_adm
          cd ../..
          rm -r $module
          modify_repo rm -rf $CVSROOT_DIRNAME/tag-ext
+         TZ = $save_TZ
          ;;
 
 
@@ -26587,7 +26769,7 @@
          #
          dotest_fail admin-28-4 "${testcvs} admin -ntagnine:1.a.2 file2"  \
 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${SPROG} \[admin aborted\]: Tag .1\.a\.2. invalid. Cannot resolve extension: 
'a'"
+${SPROG} \[admin aborted\]: Tag .1\.a\.2. invalid. Cannot resolve extension: 
\`a'"
 
          # Confirm that a missing tag is not a fatal error.
          dotest admin-28-5.1 "${testcvs} -Q tag BO+GUS file1" ''
Index: src/update.c
===================================================================
RCS file: /cvs/ccvs/src/update.c,v
retrieving revision 1.252.2.1
diff -u -r1.252.2.1 update.c
--- src/update.c        19 Mar 2005 15:32:15 -0000      1.252.2.1
+++ src/update.c        8 Apr 2005 17:56:34 -0000
@@ -612,7 +612,6 @@
     {
        char *rev = RCS_getversion (finfo->rcs, tag, NULL, 1, NULL);
        if (rev != NULL
-           && !(*tag == '.' && !strcmp (tag+1, TAG_TRUNK))
            && nonbranch != (nb = !RCS_nodeisbranch (finfo->rcs, tag)))
        {
            if (nonbranch >= 0 && !warned && !quiet)


Enjoy,
Frank

-- 
- The LinCVS Team -
http://www.lincvs.com





reply via email to

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