1/*
| 1/*
|
2 * FreeBSD install - a package for the installation and maintainance
| 2 * FreeBSD install - a package for the installation and maintenance
|
3 * of non-core utilities. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * Maxim Sobolev 15 * 31 July 2001 16 * 17 */ 18 19#include <sys/cdefs.h>
| 3 * of non-core utilities. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * Maxim Sobolev 15 * 31 July 2001 16 * 17 */ 18 19#include <sys/cdefs.h>
|
20__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/lib/version.c 98766 2002-06-24 16:03:24Z markm $");
| 20__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/lib/version.c 101677 2002-08-11 13:05:30Z schweikh $");
|
21 22#include "lib.h" 23#include <err.h> 24 25/* 26 * Routines to assist with PLIST_FMT_VER numbers in the packing 27 * lists. 28 * 29 * Following is the PLIST_FMT_VER history: 30 * 1.0 - Initial revision; 31 * 1.1 - When recording/checking checksum of symlink use hash of readlink()
| 21 22#include "lib.h" 23#include <err.h> 24 25/* 26 * Routines to assist with PLIST_FMT_VER numbers in the packing 27 * lists. 28 * 29 * Following is the PLIST_FMT_VER history: 30 * 1.0 - Initial revision; 31 * 1.1 - When recording/checking checksum of symlink use hash of readlink()
|
32 * value insted of the hash of an object this links points to.
| 32 * value instead of the hash of an object this links points to.
|
33 * 34 */ 35int 36verscmp(Package *pkg, int major, int minor) 37{ 38 int rval = 0; 39 40 if ((pkg->fmtver_maj < major) || (pkg->fmtver_maj == major && 41 pkg->fmtver_mnr < minor)) 42 rval = -1; 43 else if ((pkg->fmtver_maj > major) || (pkg->fmtver_maj == major && 44 pkg->fmtver_mnr > minor)) 45 rval = 1; 46 47 return rval; 48} 49 50/* 51 * version_of(pkgname, epoch, revision) returns a pointer to the version 52 * portion of a package name and the two special components. 53 * 54 * Jeremy D. Lea. 55 */ 56const char * 57version_of(const char *pkgname, int *epoch, int *revision) 58{ 59 char *ch; 60 61 if (pkgname == NULL) 62 errx(2, "%s: Passed NULL pkgname.", __func__); 63 if (epoch != NULL) { 64 if ((ch = strrchr(pkgname, ',')) == NULL) 65 *epoch = 0; 66 else 67 *epoch = atoi(&ch[1]); 68 } 69 if (revision != NULL) { 70 if ((ch = strrchr(pkgname, '_')) == NULL) 71 *revision = 0; 72 else 73 *revision = atoi(&ch[1]); 74 } 75 /* Cheat if we are just passed a version, not a valid package name */ 76 if ((ch = strrchr(pkgname, '-')) == NULL) 77 return pkgname; 78 else 79 return &ch[1]; 80} 81 82/* 83 * version_cmp(pkg1, pkg2) returns -1, 0 or 1 depending on if the version 84 * components of pkg1 is less than, equal to or greater than pkg2. No
| 33 * 34 */ 35int 36verscmp(Package *pkg, int major, int minor) 37{ 38 int rval = 0; 39 40 if ((pkg->fmtver_maj < major) || (pkg->fmtver_maj == major && 41 pkg->fmtver_mnr < minor)) 42 rval = -1; 43 else if ((pkg->fmtver_maj > major) || (pkg->fmtver_maj == major && 44 pkg->fmtver_mnr > minor)) 45 rval = 1; 46 47 return rval; 48} 49 50/* 51 * version_of(pkgname, epoch, revision) returns a pointer to the version 52 * portion of a package name and the two special components. 53 * 54 * Jeremy D. Lea. 55 */ 56const char * 57version_of(const char *pkgname, int *epoch, int *revision) 58{ 59 char *ch; 60 61 if (pkgname == NULL) 62 errx(2, "%s: Passed NULL pkgname.", __func__); 63 if (epoch != NULL) { 64 if ((ch = strrchr(pkgname, ',')) == NULL) 65 *epoch = 0; 66 else 67 *epoch = atoi(&ch[1]); 68 } 69 if (revision != NULL) { 70 if ((ch = strrchr(pkgname, '_')) == NULL) 71 *revision = 0; 72 else 73 *revision = atoi(&ch[1]); 74 } 75 /* Cheat if we are just passed a version, not a valid package name */ 76 if ((ch = strrchr(pkgname, '-')) == NULL) 77 return pkgname; 78 else 79 return &ch[1]; 80} 81 82/* 83 * version_cmp(pkg1, pkg2) returns -1, 0 or 1 depending on if the version 84 * components of pkg1 is less than, equal to or greater than pkg2. No
|
85 * comparision of the basenames is done.
| 85 * comparison of the basenames is done.
|
86 *
| 86 *
|
87 * The port verison is defined by:
| 87 * The port version is defined by:
|
88 * ${PORTVERSION}[_${PORTREVISION}][,${PORTEPOCH}]
| 88 * ${PORTVERSION}[_${PORTREVISION}][,${PORTEPOCH}]
|
89 * ${PORTEPOCH} supercedes ${PORTVERSION} supercedes ${PORTREVISION}.
| 89 * ${PORTEPOCH} supersedes ${PORTVERSION} supersedes ${PORTREVISION}.
|
90 * See the commit log for revision 1.349 of ports/Mk/bsd.port.mk 91 * for more information. 92 * 93 * The epoch and revision are defined to be a single number, while the rest 94 * of the version should conform to the porting guidelines. It can contain
| 90 * See the commit log for revision 1.349 of ports/Mk/bsd.port.mk 91 * for more information. 92 * 93 * The epoch and revision are defined to be a single number, while the rest 94 * of the version should conform to the porting guidelines. It can contain
|
95 * multiple components, seperated by a period, including letters.
| 95 * multiple components, separated by a period, including letters.
|
96 * 97 * The tests below allow for significantly more latitude in the version 98 * numbers than is allowed in the guidelines. No point in wasting user's 99 * time enforcing them here. That's what flamewars are for. 100 * 101 * Jeremy D. Lea. 102 */ 103int 104version_cmp(const char *pkg1, const char *pkg2) 105{ 106 const char *c1, *c2, *v1, *v2; 107 char *t1, *t2; 108 int e1, e2, r1, r2, n1, n2; 109 110 v1 = version_of(pkg1, &e1, &r1); 111 v2 = version_of(pkg2, &e2, &r2); 112 /* Minor optimisation. */ 113 if (strcmp(v1, v2) == 0) 114 return 0; 115 /* First compare epoch. */ 116 if (e1 != e2) 117 return (e1 < e2 ? -1 : 1); 118 else { 119 /* 120 * We walk down the versions, trying to convert to numbers. 121 * We terminate when we reach an underscore, a comma or the 122 * string terminator, thanks to a nasty trick with strchr(). 123 * strtol() conveniently gobbles up the chars it converts. 124 */ 125 c1 = strchr("_,", v1[0]); 126 c2 = strchr("_,", v2[0]); 127 while (c1 == NULL && c2 == NULL) { 128 n1 = strtol(v1, &t1, 10); 129 n2 = strtol(v2, &t2, 10); 130 if (n1 != n2) 131 return (n1 < n2 ? -1 : 1); 132 /* 133 * The numbers are equal, check for letters. Assume they're 134 * letters purely because strtol() didn't chomp them. 135 */ 136 c1 = strchr("_,.", t1[0]); 137 c2 = strchr("_,.", t2[0]); 138 if (c1 == NULL && c2 == NULL) { 139 /* Both have letters. Compare them. */ 140 if (t1[0] != t2[0]) 141 return (t1[0] < t2[0] ? -1 : 1); 142 /* Boring. The letters are equal. Carry on. */ 143 v1 = &t1[1], v2 = &t2[1]; 144 } else if (c1 == NULL) { 145 /* 146 * Letters are strange. After a number, a letter counts 147 * as greater, but after a period it's less. 148 */ 149 return (isdigit(v1[0]) ? 1 : -1); 150 } else if (c2 == NULL) { 151 return (isdigit(v2[0]) ? -1 : 1); 152 } else { 153 /* Neither were letters. Advance over the period. */ 154 v1 = (t1[0] == '.' ? &t1[1] : t1); 155 v2 = (t2[0] == '.' ? &t2[1] : t2); 156 } 157 c1 = strchr("_,", v1[0]); 158 c2 = strchr("_,", v2[0]); 159 } 160 /* If we got here, check if one version has something left. */ 161 if (c1 == NULL) 162 return (isdigit(v1[0]) ? 1 : -1); 163 if (c2 == NULL) 164 return (isdigit(v2[0]) ? -1 : 1); 165 /* We've run out of version. Try the revision... */ 166 if (r1 != r2) 167 return (r1 < r2 ? -1 : 1); 168 else 169 return 0; 170 } 171}
| 96 * 97 * The tests below allow for significantly more latitude in the version 98 * numbers than is allowed in the guidelines. No point in wasting user's 99 * time enforcing them here. That's what flamewars are for. 100 * 101 * Jeremy D. Lea. 102 */ 103int 104version_cmp(const char *pkg1, const char *pkg2) 105{ 106 const char *c1, *c2, *v1, *v2; 107 char *t1, *t2; 108 int e1, e2, r1, r2, n1, n2; 109 110 v1 = version_of(pkg1, &e1, &r1); 111 v2 = version_of(pkg2, &e2, &r2); 112 /* Minor optimisation. */ 113 if (strcmp(v1, v2) == 0) 114 return 0; 115 /* First compare epoch. */ 116 if (e1 != e2) 117 return (e1 < e2 ? -1 : 1); 118 else { 119 /* 120 * We walk down the versions, trying to convert to numbers. 121 * We terminate when we reach an underscore, a comma or the 122 * string terminator, thanks to a nasty trick with strchr(). 123 * strtol() conveniently gobbles up the chars it converts. 124 */ 125 c1 = strchr("_,", v1[0]); 126 c2 = strchr("_,", v2[0]); 127 while (c1 == NULL && c2 == NULL) { 128 n1 = strtol(v1, &t1, 10); 129 n2 = strtol(v2, &t2, 10); 130 if (n1 != n2) 131 return (n1 < n2 ? -1 : 1); 132 /* 133 * The numbers are equal, check for letters. Assume they're 134 * letters purely because strtol() didn't chomp them. 135 */ 136 c1 = strchr("_,.", t1[0]); 137 c2 = strchr("_,.", t2[0]); 138 if (c1 == NULL && c2 == NULL) { 139 /* Both have letters. Compare them. */ 140 if (t1[0] != t2[0]) 141 return (t1[0] < t2[0] ? -1 : 1); 142 /* Boring. The letters are equal. Carry on. */ 143 v1 = &t1[1], v2 = &t2[1]; 144 } else if (c1 == NULL) { 145 /* 146 * Letters are strange. After a number, a letter counts 147 * as greater, but after a period it's less. 148 */ 149 return (isdigit(v1[0]) ? 1 : -1); 150 } else if (c2 == NULL) { 151 return (isdigit(v2[0]) ? -1 : 1); 152 } else { 153 /* Neither were letters. Advance over the period. */ 154 v1 = (t1[0] == '.' ? &t1[1] : t1); 155 v2 = (t2[0] == '.' ? &t2[1] : t2); 156 } 157 c1 = strchr("_,", v1[0]); 158 c2 = strchr("_,", v2[0]); 159 } 160 /* If we got here, check if one version has something left. */ 161 if (c1 == NULL) 162 return (isdigit(v1[0]) ? 1 : -1); 163 if (c2 == NULL) 164 return (isdigit(v2[0]) ? -1 : 1); 165 /* We've run out of version. Try the revision... */ 166 if (r1 != r2) 167 return (r1 < r2 ? -1 : 1); 168 else 169 return 0; 170 } 171}
|