Fixed up test dir WRT aliencode
[ntk/apt.git] / test / versiontest.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: versiontest.cc,v 1.1 1998/11/26 23:29:20 jgg Exp $
4 /* ######################################################################
5
6 Version Test - Simple program to run through a file and comare versions.
7
8 Each version is compared and the result is checked against an expected
9 result in the file. The format of the file is
10 a b Res
11 Where Res is -1, 1, 0. dpkg -D=1 --compare-versions a "<" b can be
12 used to determine what Res should be. # at the start of the line
13 is a comment and blank lines are skipped
14
15 ##################################################################### */
16 /*}}}*/
17 #include <system.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/version.h>
20 #include <iostream.h>
21 #include <fstream.h>
22
23 static int verrevcmp(const char *val, const char *ref)
24 {
25 int vc, rc;
26 long vl, rl;
27 const char *vp, *rp;
28
29 if (!val)
30 val = "";
31 if (!ref)
32 ref = "";
33 for (;;)
34 {
35 vp = val;
36 while (*vp && !isdigit(*vp))
37 vp++;
38 rp = ref;
39 while (*rp && !isdigit(*rp))
40 rp++;
41 for (;;)
42 {
43 vc= val == vp ? 0 : *val++;
44 rc= ref == rp ? 0 : *ref++;
45 if (!rc && !vc)
46 break;
47 if (vc && !isalpha(vc))
48 vc += 256; /* assumes ASCII character set */
49 if (rc && !isalpha(rc))
50 rc += 256;
51 if (vc != rc)
52 return vc - rc;
53 }
54 val = vp;
55 ref = rp;
56 vl = 0;
57 if (isdigit(*vp))
58 vl = strtol(val,(char**)&val,10);
59 rl = 0;
60 if (isdigit(*rp))
61 rl = strtol(ref,(char**)&ref,10);
62 if (vl != rl)
63 return vl - rl;
64 if (!*val && !*ref)
65 return 0;
66 if (!*val)
67 return -1;
68 if (!*ref)
69 return +1;
70 }
71 }
72
73 #if 0
74 static int verrevcmp(const char *val, const char *ref)
75 {
76 int vc, rc;
77 long vl, rl;
78 const char *vp, *rp;
79
80 if (!val) val= "";
81 if (!ref) ref= "";
82 for (;;)
83 {
84 vp= val; while (*vp && !isdigit(*vp) && *vp != '~') vp++;
85 rp= ref; while (*rp && !isdigit(*rp) && *rp != '~') rp++;
86 for (;;)
87 {
88 vc= val == vp ? 0 : *val++;
89 rc= ref == rp ? 0 : *ref++;
90 if (!rc && !vc) break;
91 if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
92 if (rc && !isalpha(rc)) rc += 256;
93 if (vc != rc) return vc - rc;
94 }
95
96 val= vp;
97 ref= rp;
98 if (*vp == '~') val++;
99 if (*rp == '~') ref++;
100 vl=0; if (isdigit(*val)) vl= strtol(val,(char**)&val,10);
101 rl=0; if (isdigit(*ref)) rl= strtol(ref,(char**)&ref,10);
102 if (vl == 0 && rl == 0)
103 {
104 if (*vp == '~' && *rp != '~') return -1;
105 if (*vp != '~' && *rp == '~') return +1;
106 }
107 if (*vp == '~')
108 vl *= -1;
109 if (*rp == '~')
110 rl *= -1;
111 if (vl != rl) return vl - rl;
112 if (!*val && !*ref) return 0;
113 if (!*val)
114 {
115 if (*ref == '~')
116 return +1;
117 else
118 return -1;
119 }
120
121 if (!*ref)
122 {
123 if (*val == '~')
124 return -1;
125 else
126 return +1;
127 }
128 }
129 }
130 #endif
131
132 bool RunTest(const char *File)
133 {
134 ifstream F(File,ios::in | ios::nocreate);
135 if (!F != 0)
136 return false;
137
138 char Buffer[300];
139 int CurLine = 0;
140
141 while (1)
142 {
143 F.getline(Buffer,sizeof(Buffer));
144 CurLine++;
145 if (F.eof() != 0)
146 return true;
147 if (!F != 0)
148 return _error->Error("Line %u in %s is too long",CurLine,File);
149
150 // Comment
151 if (Buffer[0] == '#' || Buffer[0] == 0)
152 continue;
153
154 // First version
155 char *I;
156 char *Start = Buffer;
157 for (I = Buffer; *I != 0 && *I != ' '; I++);
158 string A(Start, I - Start);
159
160 if (*I == 0)
161 return _error->Error("Invalid line %u",CurLine);
162
163 // Second version
164 I++;
165 Start = I;
166 for (I = Start; *I != 0 && *I != ' '; I++);
167 string B(Start,I - Start);
168
169 if (*I == 0 || I[1] == 0)
170 return _error->Error("Invalid line %u",CurLine);
171
172 // Result
173 I++;
174 int Expected = atoi(I);
175 int Res = pkgVersionCompare(A.c_str(),B.c_str());
176 int Res2 = verrevcmp(A.c_str(),B.c_str());
177 cout << "'" << A << "' ? '" << B << "' = " << Res << " (= " << Expected << ") " << Res2 << endl;
178 if (Res != Expected)
179 _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected);
180
181 // Check the reverse as well
182 Expected = -1*Expected;
183 Res = pkgVersionCompare(B.c_str(),A.c_str());
184 Res2 = verrevcmp(B.c_str(),A.c_str());
185 cout << "'" << B << "' ? '" << A << "' = " << Res << " (= " << Expected << ") " << Res2 << endl;
186 if (Res != Expected)
187 _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected);
188 }
189 }
190
191 int main(int argc, char *argv[])
192 {
193 if (argc <= 1)
194 {
195 cerr << "You must specify a test file" << endl;
196 return 0;
197 }
198
199 RunTest(argv[1]);
200
201 // Print any errors or warnings found
202 if (_error->empty() == false)
203 {
204 string Err;
205 while (_error->empty() == false)
206 {
207
208 bool Type = _error->PopMessage(Err);
209 if (Type == true)
210 cout << "E: " << Err << endl;
211 else
212 cout << "W: " << Err << endl;
213 }
214
215 return 0;
216 }
217 }