14 char str[1024]; /* string rep of the version */
17 int release; /* a trailing -\d+ value */
18 const char *s; /* start component */
19 int cn; /* current component number */
20 int len; /* current component length */
22 const char *next; /* start of potential next component */
23 int sep; /* number of characters in separator */
25 int nv; /* numeric value */
26 int type; /* 0 null, 1 text, 2 numeric */
29 static void init_ver(struct ver *v, const char *s) {
31 strncpy(v->str, s, 1023);
45 static int cmp_strlen(const char *a, size_t alen, const char *b, size_t blen) {
53 } else if (!a && !b) {
59 } else if (blen && !alen) {
61 } else if (!alen && !blen) {
65 shortest = alen < blen ? alen : blen;
67 base = strncmp(a, b, shortest);
73 return alen < blen ? -1 : 1;
76 return base < 0 ? -1 : 1;
79 static int ver_cmp(struct ver *a, struct ver *b) {
80 if (a->type == 0 && b->type == 0) {
83 if (a->type != b->type) {
84 return a->type < b->type ? -1 : 1;
87 if (a->type == TEXT) {
89 if (a->s && ! b->s) return 1;
90 if (b->s && ! a->s) return -1;
91 if (!b->s && ! a->s) {
94 cmp = strcmp(a->s, b->s);
98 return cmp < 0 ? -1 : 1;
100 if (a->type == NUMERIC) {
102 return a->nv < b->nv ? -1 : 1;
107 static int next_comp(struct ver *v) {
108 const char *s, *next;
114 /* skip over anything that isn't alphanumeric */
116 while (*next && !isalnum(*next)) {
120 /* zero return if at end of string */
132 while (isdigit(*s)) {
133 v->nv = v->nv * 10 + *s-'0';
138 } else if (isalpha(*s)) {
140 while (*s && (isalpha(*s) || *s == '-') ) {
145 /* last character in a alphabetic can't be a - */
160 * alphabetic less than numeric
161 * return -1 if vsa < vsb, 0 if equal, 1 if vsa > vsb
163 int zpm_vercmp(const char *vsa, const char *vsb) {
165 struct zpm_version_info ainfo, binfo;
168 char astr[256], bstr[256];
180 zpm_parse_version(vsa, &ainfo);
181 zpm_parse_version(vsb, &binfo);
182 cmp = cmp_strlen(ainfo.name, ainfo.namelen, binfo.name, binfo.namelen);
188 if (ainfo.verlen > 255) {
191 if (binfo.verlen > 255) {
195 strncpy(astr, ainfo.version, ainfo.verlen);
196 strncpy(bstr, binfo.version, binfo.verlen);
197 astr[ainfo.verlen] = 0;
198 bstr[binfo.verlen] = 0;
206 if (an == 0 && a.type == 2 && b.sep == 0 && b.type == 1) {
208 } else if (bn == 0 && b.type == 2 && a.sep == 0 && a.type == 1) {
211 cmp = an < bn ? -1 : 1; break;
213 if (an == 0 && bn == 0) {
216 cmp = ver_cmp(&a, &b);
226 /* compare release */
227 if (ainfo.release != binfo.release) {
228 cmp = ainfo.release < binfo.release ? -1 : 1;