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