source: ipk/ipkg-utils-050831/ipkg-compare-versions.c@ 8564

Last change on this file since 8564 was 4890, checked in by obi, 15 years ago

[ipk] fix executable rights

  • Property svn:executable set to *
File size: 4.5 KB
Line 
1/*
2 * libdpkg - Debian packaging suite library routines
3 * vercmp.c - comparison of version numbers
4 *
5 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
6 *
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.
11 *
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.
16 *
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.
20 */
21#include <stdio.h>
22#include <stdlib.h>
23#include <ctype.h>
24#include <string.h>
25
26# define _(Text) Text
27
28struct versionrevision {
29 unsigned long epoch;
30 char *version;
31#if 0
32 const char *revision;
33 const char *familiar_revision;
34#endif
35};
36
37static int verrevcmp(const char *val, const char *ref)
38{
39 int vc, rc;
40 long vl, rl;
41 const char *vp, *rp;
42 const char *vsep, *rsep;
43
44 if (!val) val= "";
45 if (!ref) ref= "";
46 for (;;) {
47 vp= val; while (*vp && !isdigit(*vp)) vp++;
48 rp= ref; while (*rp && !isdigit(*rp)) rp++;
49 for (;;) {
50 vc= val == vp ? 0 : *val++;
51 rc= ref == rp ? 0 : *ref++;
52 if (!rc && !vc) break;
53 if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
54 if (rc && !isalpha(rc)) rc += 256;
55 if (vc != rc) return vc - rc;
56 }
57 val= vp;
58 ref= rp;
59 vl=0; if (isdigit(*vp)) vl= strtol(val,(char**)&val,10);
60 rl=0; if (isdigit(*rp)) rl= strtol(ref,(char**)&ref,10);
61 if (vl != rl) return vl - rl;
62
63 vc = *val;
64 rc = *ref;
65 vsep = strchr(".-", vc);
66 rsep = strchr(".-", rc);
67 if (vsep && !rsep) return -1;
68 if (!vsep && rsep) return +1;
69
70 if (!*val && !*ref) return 0;
71 if (!*val) return -1;
72 if (!*ref) return +1;
73 }
74}
75
76int versioncompare(const struct versionrevision *version,
77 const struct versionrevision *refversion)
78{
79 int r;
80
81 if (version->epoch > refversion->epoch) return 1;
82 if (version->epoch < refversion->epoch) return -1;
83 r= verrevcmp(version->version,refversion->version); if (r) return r;
84 return r;
85#if 0
86 r= verrevcmp(version->revision,refversion->revision); if (r) return r;
87 return verrevcmp(version->familiar_revision,refversion->familiar_revision);
88#endif
89}
90
91int versionsatisfied3(const struct versionrevision *it,
92 const struct versionrevision *ref,
93 const char *op)
94{
95 int r;
96 r= versioncompare(it,ref);
97 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0)
98 return r <= 0;
99 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0)
100 return r >= 0;
101 if (strcmp(op, "<<") == 0)
102 return r < 0;
103 if (strcmp(op, ">>") == 0)
104 return r > 0;
105 if (strcmp(op, "=") == 0)
106 return r == 0;
107 fprintf(stderr, "unknown operator: %s", op);
108
109 exit(1);
110}
111
112const char *parseversion(struct versionrevision *rversion, const char *string)
113{
114 char *hyphen, *colon, *eepochcolon;
115 unsigned long epoch;
116
117 if (!*string) return _("version string is empty");
118
119 colon= strchr(string,':');
120 if (colon) {
121 epoch= strtoul(string,&eepochcolon,10);
122 if (colon != eepochcolon) return _("epoch in version is not number");
123 if (!*++colon) return _("nothing after colon in version number");
124 string= colon;
125 rversion->epoch= epoch;
126 } else {
127 rversion->epoch= 0;
128 }
129
130#if 0
131 rversion->revision = "";
132 rversion->familiar_revision = "";
133#endif
134
135 rversion->version= malloc(strlen(string)+1);
136 strcpy(rversion->version, string);
137
138#if 0
139 fprintf(stderr,"Parsed version: %lu, %s\n",
140 rversion->epoch,
141 rversion->version);
142#endif
143
144 return 0;
145}
146
147int main(int argc, char *argv[])
148{
149 const char *err;
150 struct versionrevision ver, ref;
151
152 if (argc < 4) {
153 fprintf(stderr, "usage: %s: version op refversion\n", argv[0]);
154 return 2;
155 }
156
157 err = parseversion(&ver, argv[1]);
158 if (err) {
159 fprintf(stderr, "Invalid version `%s': %s\n", argv[1], err);
160 return 2;
161 }
162
163 err = parseversion(&ref, argv[3]);
164 if (err) {
165 fprintf(stderr, "Invalid version `%s': %s\n", argv[3], err);
166 return 2;
167 }
168
169 return ! versionsatisfied3(&ver, &ref, argv[2]);
170}
171
172
Note: See TracBrowser for help on using the repository browser.