summaryrefslogtreecommitdiffstats
path: root/contrib/csup/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/csup/misc.c')
-rw-r--r--contrib/csup/misc.c156
1 files changed, 141 insertions, 15 deletions
diff --git a/contrib/csup/misc.c b/contrib/csup/misc.c
index 97a02ab..6a53b3c 100644
--- a/contrib/csup/misc.c
+++ b/contrib/csup/misc.c
@@ -202,10 +202,10 @@ commonpathlength(const char *a, size_t alen, const char *b, size_t blen)
return (minlen);
}
-char *
-pathlast(char *path)
+const char *
+pathlast(const char *path)
{
- char *s;
+ const char *s;
s = strrchr(path, '/');
if (s == NULL)
@@ -249,34 +249,87 @@ rcsdatetotime(const char *revdate)
}
/*
- * Returns a buffer allocated with malloc() containing the absolute
- * pathname to the checkout file made from the prefix and the path
- * of the corresponding RCS file relatively to the prefix. If the
- * filename is not an RCS filename, NULL will be returned.
+ * Checks if a file is an RCS file.
*/
-char *
-checkoutpath(const char *prefix, const char *file)
+int
+isrcs(const char *file, size_t *len)
{
const char *cp;
- char *path;
- size_t len;
if (file[0] == '/')
- return (NULL);
+ return (0);
cp = file;
while ((cp = strstr(cp, "..")) != NULL) {
if (cp == file || cp[2] == '\0' ||
(cp[-1] == '/' && cp[2] == '/'))
- return (NULL);
+ return (0);
cp += 2;
}
- len = strlen(file);
- if (len < 2 || file[len - 1] != 'v' || file[len - 2] != ',')
+ *len = strlen(file);
+ if (*len < 2 || file[*len - 1] != 'v' || file[*len - 2] != ',') {
+ return (0);
+ }
+
+ return (1);
+}
+
+/*
+ * Returns a buffer allocated with malloc() containing the absolute
+ * pathname to the checkout file made from the prefix and the path
+ * of the corresponding RCS file relatively to the prefix. If the
+ * filename is not an RCS filename, NULL will be returned.
+ */
+char *
+checkoutpath(const char *prefix, const char *file)
+{
+ char *path;
+ size_t len;
+
+ if (!isrcs(file, &len))
return (NULL);
xasprintf(&path, "%s/%.*s", prefix, (int)len - 2, file);
return (path);
}
+/*
+ * Returns a cvs path allocated with malloc() containing absolute pathname to a
+ * file in cvs mode which can reside in the attic. XXX: filename has really no
+ * restrictions.
+ */
+char *
+cvspath(const char *prefix, const char *file, int attic)
+{
+ const char *last;
+ char *path;
+
+ last = pathlast(file);
+ if (attic)
+ xasprintf(&path, "%s/%.*sAttic/%s", prefix, (int)(last - file),
+ file, last);
+ else
+ xasprintf(&path, "%s/%s", prefix, file);
+
+ return (path);
+}
+
+/*
+ * Regular or attic path if regular fails.
+ * XXX: This should perhaps also check if the Attic file exists too, and return
+ * NULL if not.
+ */
+char *
+atticpath(const char *prefix, const char *file)
+{
+ char *path;
+
+ path = cvspath(prefix, file, 0);
+ if (access(path, F_OK) != 0) {
+ free(path);
+ path = cvspath(prefix, file, 1);
+ }
+ return (path);
+}
+
int
mkdirhier(char *path, mode_t mask)
{
@@ -520,3 +573,76 @@ bt_free(struct backoff_timer *bt)
free(bt);
}
+
+/* Compare two revisions. */
+int
+rcsnum_cmp(char *revision1, char *revision2)
+{
+ char *rev1, *rev2, *rev1orig, *rev2orig;
+ char *tmp1, *tmp2;
+ long num1, num2;
+ int retval;
+
+ rev1orig = xstrdup(revision1);
+ rev2orig = xstrdup(revision2);
+ retval = 0;
+
+ rev1 = rev1orig;
+ rev2 = rev2orig;
+ tmp1 = strsep(&rev1, ".");
+ tmp2 = strsep(&rev2, ".");
+ while (tmp1 != NULL && tmp2 != NULL) {
+ num1 = strtol(tmp1, NULL, 10);
+ num2 = strtol(tmp2, NULL, 10);
+ if (num1 > num2) {
+ retval = 1;
+ goto done;
+ } else if (num1 < num2) {
+ retval = -1;
+ goto done;
+ }
+ tmp1 = strsep(&rev1, ".");
+ tmp2 = strsep(&rev2, ".");
+ }
+
+ /* If one of them is longer (not null), the shortest is the highest
+ * ranked. */
+ if (tmp2 != NULL && tmp1 == NULL)
+ retval = -1;
+ else if (tmp2 == NULL && tmp1 != NULL)
+ retval = 1;
+
+done:
+ free(rev1orig);
+ free(rev2orig);
+ return (retval);
+}
+
+/* Returns 0 if a rcsrev is not a trunk revision number. */
+int
+rcsrev_istrunk(char *revnum)
+{
+ char *tmp;
+
+ tmp = strchr(revnum, '.');
+ tmp++;
+ if (strchr(tmp, '.') != NULL)
+ return (0);
+ return (1);
+}
+
+/* Return prefix of rcsfile. */
+char *
+rcsrev_prefix(char *revnum)
+{
+ char *modrev, *pos;
+
+ modrev = xstrdup(revnum);
+ pos = strrchr(modrev, '.');
+ if (pos == NULL) {
+ free(modrev);
+ return (NULL);
+ }
+ *pos = '\0';
+ return (modrev);
+}
OpenPOWER on IntegriCloud