]> git.saurik.com Git - apt.git/blame - test/interactive-helper/rpmver.cc
Merge remote-tracking branch 'donkult/debian/sid' into debian/sid
[apt.git] / test / interactive-helper / rpmver.cc
CommitLineData
c0a00c82
AL
1#include <apt-pkg/debversion.h>
2#include <rpm/rpmio.h>
3#include <rpm/misc.h>
4#include <stdlib.h>
9ce3cfc9 5#include <stdio.h>
11e97c45
AL
6#include <ctype.h>
7
8#define xisdigit(x) isdigit(x)
9#define xisalpha(x) isalpha(x)
10#define xisalnum(x) (isdigit(x) || isalpha(x))
11
5a8748f1
AL
12using namespace std;
13
11e97c45
AL
14int rpmvercmp(const char * a, const char * b)
15{
11e97c45
AL
16 char * str1, * str2;
17 char * one, * two;
11e97c45
AL
18 int isnum;
19
20 /* easy comparison to see if versions are identical */
21 if (!strcmp(a, b)) return 0;
22
23 str1 = (char *)alloca(strlen(a) + 1);
24 str2 = (char *)alloca(strlen(b) + 1);
25
26 strcpy(str1, a);
27 strcpy(str2, b);
28
29 one = str1;
30 two = str2;
31
32 /* loop through each version segment of str1 and str2 and compare them */
33 while (*one && *two) {
34 while (*one && !xisalnum(*one)) one++;
35 while (*two && !xisalnum(*two)) two++;
36
37 str1 = one;
38 str2 = two;
39
40 /* grab first completely alpha or completely numeric segment */
41 /* leave one and two pointing to the start of the alpha or numeric */
42 /* segment and walk str1 and str2 to end of segment */
43 if (xisdigit(*str1)) {
44 while (*str1 && xisdigit(*str1)) str1++;
45 while (*str2 && xisdigit(*str2)) str2++;
46 isnum = 1;
47 } else {
48 while (*str1 && xisalpha(*str1)) str1++;
49 while (*str2 && xisalpha(*str2)) str2++;
50 isnum = 0;
51 }
52
53 /* save character at the end of the alpha or numeric segment */
54 /* so that they can be restored after the comparison */
9ce3cfc9 55 char oldch1 = *str1;
11e97c45 56 *str1 = '\0';
9ce3cfc9 57 char oldch2 = *str2;
11e97c45
AL
58 *str2 = '\0';
59
60 /* take care of the case where the two version segments are */
61 /* different types: one numeric, the other alpha (i.e. empty) */
62 if (one == str1) return -1; /* arbitrary */
63 if (two == str2) return 1;
64
65 if (isnum) {
66 /* this used to be done by converting the digit segments */
67 /* to ints using atoi() - it's changed because long */
68 /* digit segments can overflow an int - this should fix that. */
69
70 /* throw away any leading zeros - it's a number, right? */
71 while (*one == '0') one++;
72 while (*two == '0') two++;
73
74 /* whichever number has more digits wins */
75 if (strlen(one) > strlen(two)) return 1;
76 if (strlen(two) > strlen(one)) return -1;
77 }
78
79 /* strcmp will return which one is greater - even if the two */
80 /* segments are alpha or if they are numeric. don't return */
81 /* if they are equal because there might be more segments to */
82 /* compare */
9ce3cfc9 83 int rc = strcmp(one, two);
11e97c45
AL
84 if (rc) return rc;
85
86 /* restore character that was replaced by null above */
87 *str1 = oldch1;
88 one = str1;
89 *str2 = oldch2;
90 two = str2;
91 }
92
93 /* this catches the case where all numeric and alpha segments have */
94 /* compared identically but the segment sepparating characters were */
95 /* different */
96 if ((!*one) && (!*two)) return 0;
97
98 /* whichever version still has characters left over wins */
99 if (!*one) return -1; else return 1;
100}
c0a00c82
AL
101
102int main(int argc,const char *argv[])
103{
11e97c45
AL
104 printf("%i\n",strcmp(argv[1],argv[2]));
105
c0a00c82
AL
106 printf("'%s' <> '%s': ",argv[1],argv[2]);
107 printf("rpm: %i deb: %i\n",rpmvercmp(argv[1],argv[2]),
108 debVS.CmpFragment(argv[1],argv[1]+strlen(argv[1]),
109 argv[2],argv[2]+strlen(argv[2])));
110
111 printf("'%s' <> '%s': ",argv[2],argv[1]);
112 printf("rpm: %i deb: %i\n",rpmvercmp(argv[2],argv[1]),
113 debVS.CmpFragment(argv[2],argv[2]+strlen(argv[2]),
114 argv[1],argv[1]+strlen(argv[1])));
115 return 0;
116}