]> pd.if.org Git - zpackage/blob - vercmp.c
add zpm-soneed
[zpackage] / vercmp.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
5
6 struct ver {
7         char str[1024]; /* string rep */
8         char *s; /* start component */
9         int cn; /* current component number */
10         char *next; /* start of potential next component */
11         char keep; /* character over-written with null byte */
12         int sep; /* number of characters in separator */
13         
14         int nv; /* numeric value */
15         int type; /* 0 null, 1 text, 2 numeric */
16         int release;
17         char *relstr;
18 };
19
20 void init_ver(struct ver *v, char *s) {
21         strncpy(v->str, s, 1023);
22         v->str[1023] = 0;
23         v->s = 0;
24         v->cn = 0;
25         v->next = v->str;
26         v->relstr = 0;
27         v->keep = 0;
28         v->sep = 0;
29
30         /* scan for trailing release */
31         int n;
32         n = strlen(v->str) - 1;
33         if (n > 0 && isdigit(v->str[n])) {
34                 while (isdigit(v->str[n])) {
35                         n--;
36                 }
37                 if (s[n] == '-') {
38                         v->relstr = v->str + n;
39                         v->release = atoi(v->str + n + 1);
40                         v->str[n] = 0;
41                 }
42         }
43
44 }
45
46 int ver_cmp(struct ver *a, struct ver *b) {
47         if (a->type == 0 && b->type == 0) {
48                 return 0;
49         }
50         if (a->type != b->type) {
51                 return a->type < b->type ? -1 : 1;
52         }
53         if (a->type == 1) {
54                 int cmp;
55                 cmp = strcmp(a->s, b->s);
56                 if (cmp == 0) {
57                         return 0;
58                 }
59                 return cmp < 0 ? -1 : 1;
60         }
61         if (a->type == 2) {
62                 if (a->nv != b->nv)
63                 return a->nv < b->nv ? -1 : 1;
64         }
65         return 0;
66 }
67
68 int next_comp(struct ver *v) {
69         char *s;
70
71         /* restore over-written character */
72         if (v->keep) {
73                 v->next[0] = v->keep;
74                 v->keep = 0;
75         }
76         s = v->next;
77
78         /* skip over anything that isn't alphanumeric */
79         v->sep = 0;
80         while (*s && !isalnum(*s)) {
81                 v->sep++;
82                 s++;
83         }
84         v->next = s;
85
86         /* zero return if at end of string */
87         if (!*s) {
88                 return 0;
89         }
90         if (isdigit(*s)) {
91                 v->type = 2;
92                 while (isdigit(*s)) s++;
93                 v->keep = *s;
94                 *s = 0;
95                 v->s = v->next;
96                 v->nv = atoi(v->s);
97         } else if (isalpha(*s)) {
98                 v->type = 1;
99                 while (isalpha(*s)) s++;
100                 v->keep = *s;
101                 *s = 0;
102                 v->s = v->next;
103         }
104         v->next = s;
105
106         return ++v->cn;
107 }
108
109 /*
110  * alphabetic less than numeric
111  */
112 int main(int ac, char *av[]) {
113         struct ver a, b;
114         int an, bn;
115         int cmp;
116
117         if (ac < 2) return 1;
118
119         init_ver(&a, av[1]);
120         init_ver(&b, av[2]);
121         do {
122                 an = next_comp(&a);
123                 bn = next_comp(&b);
124                 if (an != bn) {
125                         if (an == 0 && a.type == 2 && b.sep == 0 && b.type == 1) {
126                                 printf("1\n");
127                         } else if (bn == 0 && b.type == 2 && a.sep == 0 && a.type == 1) {
128                                 printf("-1\n");
129                         } else {
130                                 printf("%s\n", an < bn ? "-1" : "1");
131                         }
132                         exit(0);
133                 }
134                 cmp = ver_cmp(&a, &b);
135                 if (cmp != 0) {
136                         printf("%d\n", cmp);
137                         exit(0);
138                 }
139         } while (an && bn);
140
141         /* if we've gotten here, and both have releases, check those */
142         if (a.relstr && b.relstr && a.release != b.release) {
143                 printf("%s\n", a.release < b.release ? "-1" : "1");
144                 exit(0);
145         }
146         
147         printf("0\n");
148         return 0;
149 }