diff options
Diffstat (limited to 'contrib/csup/misc.c')
-rw-r--r-- | contrib/csup/misc.c | 156 |
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); +} |