aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.7/python-lib/cuddlefish/version_comparator.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.7/python-lib/cuddlefish/version_comparator.py')
-rw-r--r--tools/addon-sdk-1.7/python-lib/cuddlefish/version_comparator.py206
1 files changed, 206 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.7/python-lib/cuddlefish/version_comparator.py b/tools/addon-sdk-1.7/python-lib/cuddlefish/version_comparator.py
new file mode 100644
index 0000000..3999e71
--- /dev/null
+++ b/tools/addon-sdk-1.7/python-lib/cuddlefish/version_comparator.py
@@ -0,0 +1,206 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+'''
+ This is a really crummy, slow Python implementation of the Mozilla
+ platform's nsIVersionComparator interface:
+
+ https://developer.mozilla.org/En/NsIVersionComparator
+
+ For more information, also see:
+
+ http://mxr.mozilla.org/mozilla/source/xpcom/glue/nsVersionComparator.cpp
+'''
+
+import re
+import sys
+
+class VersionPart(object):
+ '''
+ Examples:
+
+ >>> VersionPart('1')
+ (1, None, 0, None)
+
+ >>> VersionPart('1pre')
+ (1, 'pre', 0, None)
+
+ >>> VersionPart('1pre10')
+ (1, 'pre', 10, None)
+
+ >>> VersionPart('1pre10a')
+ (1, 'pre', 10, 'a')
+
+ >>> VersionPart('1+')
+ (2, 'pre', 0, None)
+
+ >>> VersionPart('*').numA == sys.maxint
+ True
+
+ >>> VersionPart('1') < VersionPart('2')
+ True
+
+ >>> VersionPart('2') > VersionPart('1')
+ True
+
+ >>> VersionPart('1') == VersionPart('1')
+ True
+
+ >>> VersionPart('1pre') > VersionPart('1')
+ False
+
+ >>> VersionPart('1') < VersionPart('1pre')
+ False
+
+ >>> VersionPart('1pre1') < VersionPart('1pre2')
+ True
+
+ >>> VersionPart('1pre10b') > VersionPart('1pre10a')
+ True
+
+ >>> VersionPart('1pre10b') == VersionPart('1pre10b')
+ True
+
+ >>> VersionPart('1pre10a') < VersionPart('1pre10b')
+ True
+
+ >>> VersionPart('1') > VersionPart('')
+ True
+ '''
+
+ _int_part = re.compile('[+-]?(\d*)(.*)')
+ _num_chars = '0123456789+-'
+
+ def __init__(self, part):
+ self.numA = 0
+ self.strB = None
+ self.numC = 0
+ self.extraD = None
+
+ if not part:
+ return
+
+ if part == '*':
+ self.numA = sys.maxint
+ else:
+ match = self._int_part.match(part)
+ self.numA = int(match.group(1))
+ self.strB = match.group(2) or None
+ if self.strB == '+':
+ self.strB = 'pre'
+ self.numA += 1
+ elif self.strB:
+ i = 0
+ num_found = -1
+ for char in self.strB:
+ if char in self._num_chars:
+ num_found = i
+ break
+ i += 1
+ if num_found != -1:
+ match = self._int_part.match(self.strB[num_found:])
+ self.numC = int(match.group(1))
+ self.extraD = match.group(2) or None
+ self.strB = self.strB[:num_found]
+
+ def _strcmp(self, str1, str2):
+ # Any string is *before* no string.
+ if str1 is None:
+ if str2 is None:
+ return 0
+ else:
+ return 1
+
+ if str2 is None:
+ return -1
+
+ return cmp(str1, str2)
+
+ def __cmp__(self, other):
+ r = cmp(self.numA, other.numA)
+ if r:
+ return r
+
+ r = self._strcmp(self.strB, other.strB)
+ if r:
+ return r
+
+ r = cmp(self.numC, other.numC)
+ if r:
+ return r
+
+ return self._strcmp(self.extraD, other.extraD)
+
+ def __repr__(self):
+ return repr((self.numA, self.strB, self.numC, self.extraD))
+
+def compare(a, b):
+ '''
+ Examples:
+
+ >>> compare('1', '2')
+ -1
+
+ >>> compare('1', '1')
+ 0
+
+ >>> compare('2', '1')
+ 1
+
+ >>> compare('1.0pre1', '1.0pre2')
+ -1
+
+ >>> compare('1.0pre2', '1.0')
+ -1
+
+ >>> compare('1.0', '1.0.0')
+ 0
+
+ >>> compare('1.0.0', '1.0.0.0')
+ 0
+
+ >>> compare('1.0.0.0', '1.1pre')
+ -1
+
+ >>> compare('1.1pre', '1.1pre0')
+ 0
+
+ >>> compare('1.1pre0', '1.0+')
+ 0
+
+ >>> compare('1.0+', '1.1pre1a')
+ -1
+
+ >>> compare('1.1pre1a', '1.1pre1')
+ -1
+
+ >>> compare('1.1pre1', '1.1pre10a')
+ -1
+
+ >>> compare('1.1pre10a', '1.1pre10')
+ -1
+
+ >>> compare('1.1pre10a', '1.*')
+ -1
+ '''
+
+ a_parts = a.split('.')
+ b_parts = b.split('.')
+
+ if len(a_parts) < len(b_parts):
+ a_parts.extend([''] * (len(b_parts) - len(a_parts)))
+ else:
+ b_parts.extend([''] * (len(a_parts) - len(b_parts)))
+
+ for a_part, b_part in zip(a_parts, b_parts):
+ r = cmp(VersionPart(a_part), VersionPart(b_part))
+ if r:
+ return r
+
+ return 0
+
+if __name__ == '__main__':
+ import doctest
+
+ doctest.testmod(verbose=True)