1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
/* ######################################################################
Version Test - Simple program to run through a file and comare versions.
Each version is compared and the result is checked against an expected
result in the file. The format of the file is
a b Res
Where Res is -1, 1, 0. dpkg -D=1 --compare-versions a "<" b can be
used to determine what Res should be. # at the start of the line
is a comment and blank lines are skipped
The runner will also call dpkg --compare-versions to check if APT and
dpkg have (still) the same idea.
##################################################################### */
/*}}}*/
#include <apt-pkg/macros.h>
#include <apt-pkg/error.h>
#include <apt-pkg/version.h>
#include <apt-pkg/debversion.h>
#include <apt-pkg/fileutl.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
static bool callDPkg(const char *val, const char *ref, const char &op) {
pid_t Process = ExecFork();
if (Process == 0)
{
const char * args[6];
args[0] = "/usr/bin/dpkg";
args[1] = "--compare-versions";
args[2] = val;
args[3] = (op == 1) ? ">>" : ( (op == 0) ? "=" : "<<");
args[4] = ref;
args[5] = 0;
execv(args[0], (char**) args);
exit(1);
}
int Ret;
waitpid(Process, &Ret, 0);
return WIFEXITED(Ret) == true && WEXITSTATUS(Ret) == 0;
}
static void assertVersion(int const &CurLine, string const &A, string const &B, int const &Expected) {
int Res = debVS.CmpVersion(A.c_str(), B.c_str());
bool const dpkg = callDPkg(A.c_str(),B.c_str(), Expected);
Res = (Res < 0) ? -1 : ( (Res > 0) ? 1 : Res);
if (Res != Expected)
_error->Error("Comparison failed on line %u. '%s' '%s' '%s' %i != %i",CurLine,A.c_str(),((Expected == 1) ? "<<" : ( (Expected == 0) ? "=" : ">>")) ,B.c_str(),Res,Expected);
if (dpkg == false)
_error->Error("DPkg differ with line: %u. '%s' '%s' '%s' == false",CurLine,A.c_str(),((Expected == 1) ? "<<" : ( (Expected == 0) ? "=" : ">>")),B.c_str());
}
static bool RunTest(const char *File)
{
if (FileExists(File) == false)
return _error->Error("Versiontestfile %s doesn't exist!", File);
ifstream F(File,ios::in);
if (!F != 0)
return false;
char Buffer[300];
int CurLine = 0;
while (1)
{
F.getline(Buffer,sizeof(Buffer));
CurLine++;
if (F.eof() != 0)
return true;
if (!F != 0)
return _error->Error("Line %u in %s is too long",CurLine,File);
// Comment
if (Buffer[0] == '#' || Buffer[0] == 0)
continue;
// First version
char *I;
char *Start = Buffer;
for (I = Buffer; *I != 0 && *I != ' '; I++);
string A(Start, I - Start);
if (*I == 0)
return _error->Error("Invalid line %u",CurLine);
// Second version
I++;
Start = I;
for (I = Start; *I != 0 && *I != ' '; I++);
string B(Start,I - Start);
if (*I == 0 || I[1] == 0)
return _error->Error("Invalid line %u",CurLine);
// Result
I++;
int const Expected = atoi(I);
assertVersion(CurLine, A, B, Expected);
// Check the reverse as well
assertVersion(CurLine, B, A, Expected*-1);
}
}
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
else
RunTest(argv[1]);
// Print any errors or warnings found
_error->DumpErrors();
return 0;
}
|