2
* libdpkg - Debian packaging suite library routines
3
* vercmp.c - comparison of version numbers
5
* Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
7
* This is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as
9
* published by the Free Software Foundation; either version 2,
10
* or (at your option) any later version.
12
* This is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public
18
* License along with dpkg; if not, write to the Free Software
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#include <dpkg/dpkg.h>
28
#include <dpkg/dpkg-db.h>
29
#include <dpkg/parsedump.h>
31
int epochsdiffer(const struct versionrevision *a,
32
const struct versionrevision *b) {
33
return a->epoch != b->epoch;
36
/* assume ascii; warning: evaluates x multiple times! */
37
#define order(x) ((x) == '~' ? -1 \
40
: cisalpha((x)) ? (x) \
43
static int verrevcmp(const char *val, const char *ref) {
47
while (*val || *ref) {
50
while ( (*val && !cisdigit(*val)) || (*ref && !cisdigit(*ref)) ) {
51
int vc= order(*val), rc= order(*ref);
52
if (vc != rc) return vc - rc;
56
while ( *val == '0' ) val++;
57
while ( *ref == '0' ) ref++;
58
while (cisdigit(*val) && cisdigit(*ref)) {
59
if (!first_diff) first_diff= *val - *ref;
62
if (cisdigit(*val)) return 1;
63
if (cisdigit(*ref)) return -1;
64
if (first_diff) return first_diff;
69
int versioncompare(const struct versionrevision *version,
70
const struct versionrevision *refversion) {
73
if (version->epoch > refversion->epoch) return 1;
74
if (version->epoch < refversion->epoch) return -1;
75
r= verrevcmp(version->version,refversion->version); if (r) return r;
76
return verrevcmp(version->revision,refversion->revision);
79
int versionsatisfied3(const struct versionrevision *it,
80
const struct versionrevision *ref,
81
enum depverrel verrel) {
83
if (verrel == dvr_none) return 1;
84
r= versioncompare(it,ref);
86
case dvr_earlierequal: return r <= 0;
87
case dvr_laterequal: return r >= 0;
88
case dvr_earlierstrict: return r < 0;
89
case dvr_laterstrict: return r > 0;
90
case dvr_exact: return r == 0;
92
internerr("unknown depverrel '%d'", verrel);
97
int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
98
return versionsatisfied3(&it->version,&against->version,against->verrel);