diff options
author | Arch Librarian <arch@canonical.com> | 2004-09-20 16:51:41 +0000 |
---|---|---|
committer | Arch Librarian <arch@canonical.com> | 2004-09-20 16:51:41 +0000 |
commit | 8c515d6281328e490673b8dc94a7d69987d5a027 (patch) | |
tree | 2764584aacf2d2ea35a923980b84184a85a977be /test | |
parent | bc4af0b920be60156e5567ada3339b432d3f6e3a (diff) |
Version checker
Author: jgg
Date: 1998-11-26 23:29:19 GMT
Version checker
Diffstat (limited to 'test')
-rw-r--r-- | test/makefile | 6 | ||||
-rw-r--r-- | test/versions.lst | 34 | ||||
-rw-r--r-- | test/versiontest.cc | 217 |
3 files changed, 257 insertions, 0 deletions
diff --git a/test/makefile b/test/makefile index bf1b1834c..c12e05f1f 100644 --- a/test/makefile +++ b/test/makefile @@ -16,3 +16,9 @@ PROGRAM=scratch-test SLIBS = -lapt-pkg SOURCE = scratch.cc include $(PROGRAM_H) + +# Version compare tester +PROGRAM=versiontest +SLIBS = -lapt-pkg +SOURCE = versiontest.cc +include $(PROGRAM_H) diff --git a/test/versions.lst b/test/versions.lst new file mode 100644 index 000000000..d5d343ba2 --- /dev/null +++ b/test/versions.lst @@ -0,0 +1,34 @@ +# List of +# ver1 ver2 ret +# Of versions worth testing +# 1 means that ver1 > ver2 +# -1 means that ver1 < ver2 +# 0 means that ver1 = ver2 +7.6p2-4 7.6-0 1 +1.0.3-3 1.0-1 1 + +# Important attributes +- . -1 +p - -1 +a - -1 +z - -1 +a . -1 +z . -1 + +# Epochs +1:0.4 10.3 1 +1:1.25-4 1:1.25-8 -1 + +# Junk +1:1.2.13-3 1:1.2.13-3.1 -1 +2.0.7pre1-4 2.0.7r-1 -1 + +# Test some properties of text strings +0-pre 0-pre 0 +0-pre 0-pree -1 + +1.1.6r2-2 1.1.6r-1 1 +2.6b2-1 2.6b-2 1 + +98.1p5-1 98.1-pre2-b6-2 -1 +0.4a6-2 0.4-1 1 diff --git a/test/versiontest.cc b/test/versiontest.cc new file mode 100644 index 000000000..d3bfe18fe --- /dev/null +++ b/test/versiontest.cc @@ -0,0 +1,217 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: versiontest.cc,v 1.1 1998/11/26 23:29:20 jgg Exp $ +/* ###################################################################### + + 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 + + ##################################################################### */ + /*}}}*/ +#include <system.h> +#include <apt-pkg/error.h> +#include <apt-pkg/version.h> +#include <iostream.h> +#include <fstream.h> + +static int verrevcmp(const char *val, const char *ref) +{ + int vc, rc; + long vl, rl; + const char *vp, *rp; + + if (!val) + val = ""; + if (!ref) + ref = ""; + for (;;) + { + vp = val; + while (*vp && !isdigit(*vp)) + vp++; + rp = ref; + while (*rp && !isdigit(*rp)) + rp++; + for (;;) + { + vc= val == vp ? 0 : *val++; + rc= ref == rp ? 0 : *ref++; + if (!rc && !vc) + break; + if (vc && !isalpha(vc)) + vc += 256; /* assumes ASCII character set */ + if (rc && !isalpha(rc)) + rc += 256; + if (vc != rc) + return vc - rc; + } + val = vp; + ref = rp; + vl = 0; + if (isdigit(*vp)) + vl = strtol(val,(char**)&val,10); + rl = 0; + if (isdigit(*rp)) + rl = strtol(ref,(char**)&ref,10); + if (vl != rl) + return vl - rl; + if (!*val && !*ref) + return 0; + if (!*val) + return -1; + if (!*ref) + return +1; + } +} + +#if 0 +static int verrevcmp(const char *val, const char *ref) +{ + int vc, rc; + long vl, rl; + const char *vp, *rp; + + if (!val) val= ""; + if (!ref) ref= ""; + for (;;) + { + vp= val; while (*vp && !isdigit(*vp) && *vp != '~') vp++; + rp= ref; while (*rp && !isdigit(*rp) && *rp != '~') rp++; + for (;;) + { + vc= val == vp ? 0 : *val++; + rc= ref == rp ? 0 : *ref++; + if (!rc && !vc) break; + if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */ + if (rc && !isalpha(rc)) rc += 256; + if (vc != rc) return vc - rc; + } + + val= vp; + ref= rp; + if (*vp == '~') val++; + if (*rp == '~') ref++; + vl=0; if (isdigit(*val)) vl= strtol(val,(char**)&val,10); + rl=0; if (isdigit(*ref)) rl= strtol(ref,(char**)&ref,10); + if (vl == 0 && rl == 0) + { + if (*vp == '~' && *rp != '~') return -1; + if (*vp != '~' && *rp == '~') return +1; + } + if (*vp == '~') + vl *= -1; + if (*rp == '~') + rl *= -1; + if (vl != rl) return vl - rl; + if (!*val && !*ref) return 0; + if (!*val) + { + if (*ref == '~') + return +1; + else + return -1; + } + + if (!*ref) + { + if (*val == '~') + return -1; + else + return +1; + } + } +} +#endif + +bool RunTest(const char *File) +{ + ifstream F(File,ios::in | ios::nocreate); + 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 Expected = atoi(I); + int Res = pkgVersionCompare(A.c_str(),B.c_str()); + int Res2 = verrevcmp(A.c_str(),B.c_str()); + cout << "'" << A << "' ? '" << B << "' = " << Res << " (= " << Expected << ") " << Res2 << endl; + if (Res != Expected) + _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected); + + // Check the reverse as well + Expected = -1*Expected; + Res = pkgVersionCompare(B.c_str(),A.c_str()); + Res2 = verrevcmp(B.c_str(),A.c_str()); + cout << "'" << B << "' ? '" << A << "' = " << Res << " (= " << Expected << ") " << Res2 << endl; + if (Res != Expected) + _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected); + } +} + +int main(int argc, char *argv[]) +{ + if (argc <= 1) + { + cerr << "You must specify a test file" << endl; + return 0; + } + + RunTest(argv[1]); + + // Print any errors or warnings found + if (_error->empty() == false) + { + string Err; + while (_error->empty() == false) + { + + bool Type = _error->PopMessage(Err); + if (Type == true) + cout << "E: " << Err << endl; + else + cout << "W: " << Err << endl; + } + + return 0; + } +} |