Added translation using Weblate (Italian)
[cygwin-setup.git] / csu_util / version_compare.cc
blob687a8d31aec38c7d6d3eebc1462e0c74b1ed61a0
1 /*
2 * Copyright (c) 2004 Max Bowsher
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
12 * Written by Max Bowsher
15 #include "version_compare.h"
17 static inline bool isdigit(char c) { return (c >= '0' && c <= '9'); }
19 /* Sort two version numbers, comparing equivalently seperated strings of
20 * digits numerically.
22 * Returns a positive number if (a > b)
23 * Returns a negative number if (a < b)
24 * Returns zero if (a == b)
26 * Inspired but not equivalent to rpmvercmp().
28 int version_compare (std::string a, std::string b)
30 if (a == b) return 0;
32 size_t apos1, apos2 = 0, bpos1, bpos2 = 0;
33 size_t alen = a.length(), blen = b.length();
34 bool isnum;
35 int cval;
37 while (apos2 < alen && bpos2 < blen)
39 apos1 = apos2;
40 bpos1 = bpos2;
42 if (isdigit(a[apos2]))
44 while (apos2 < alen && isdigit(a[apos2])) apos2++;
45 while (bpos2 < blen && isdigit(b[bpos2])) bpos2++;
46 isnum = true;
48 else
50 while (apos2 < alen && !isdigit(a[apos2])) apos2++;
51 while (bpos2 < blen && !isdigit(b[bpos2])) bpos2++;
52 isnum = false;
55 /* if (apos1 == apos2) { a logical impossibility has happened; } */
57 /* isdigit(a[0]) != isdigit(b[0])
58 * arbitrarily sort the non-digit first */
59 if (bpos1 == bpos2) return (isnum ? 1 : -1);
61 if (isnum)
63 /* skip numeric leading zeros */
64 while (apos1 < alen && a[apos1] == '0') apos1++;
65 while (bpos1 < blen && b[bpos1] == '0') bpos1++;
67 /* if one number has more digits, it is greater */
68 if (apos2-apos1 > bpos2-bpos1) return 1;
69 if (apos2-apos1 < bpos2-bpos1) return -1;
72 /* do an ordinary lexicographic string comparison */
73 cval = a.compare(apos1, apos2-apos1, b, bpos1, bpos2-bpos1);
74 if (cval) return (cval < 1 ? -1 : 1);
77 /* ran out of characters in one string, without finding a difference */
79 /* maybe they were the same version, but with different leading zeros */
80 if (apos2 == alen && bpos2 == blen) return 0;
82 /* the version with a suffix remaining is greater */
83 return (apos2 < alen ? 1 : -1);
86 #ifdef TESTING_VERSION_COMPARE
88 #include <iostream>
89 #include <iomanip>
91 struct version_pair
93 const char *a;
94 const char *b;
97 static version_pair test_data[] =
99 { "1.0.0", "2.0.0" },
100 { ".0.0", "2.0.0" },
101 { "alpha", "beta" },
102 { "1.0", "1.0.0" },
103 { "2.456", "2.1000" },
104 { "2.1000", "3.111" },
105 { "2.001", "2.1" },
106 { "2.34", "2.34" },
107 { NULL, NULL }
110 int main(int argc, char* argv[])
112 version_pair *i = test_data;
114 while (i->a)
116 cout << setw(10) << i->a << ", " << setw(10) << i->b << " : "
117 << version_compare(i->a, i->b) << ", " << version_compare(i->b, i->a)
118 << endl;
119 i++;
122 return 0;
125 #endif