From cd0b3d77ccaa8cda411c9e1e688fbfa3e4f737a0 Mon Sep 17 00:00:00 2001 From: "bsmedberg%covad.net" Date: Sat, 23 Jul 2005 14:05:25 +0000 Subject: [PATCH] Bug 300731 - Change app/extension version scheme going forward, r=darin+shaver a=shaver git-svn-id: svn://10.0.0.236/trunk@176485 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/chrome/src/Makefile.in | 1 - mozilla/chrome/src/nsChromeRegistry.cpp | 9 +- .../update/public/nsIUpdateService.idl | 26 -- .../mozapps/update/src/nsUpdateService.js.in | 96 +------ mozilla/xpcom/base/Makefile.in | 2 + mozilla/xpcom/base/nsIVersionComparator.idl | 79 ++++++ .../xpcom/base/nsVersionComparatorImpl.cpp | 52 ++++ mozilla/xpcom/base/nsVersionComparatorImpl.h | 54 ++++ mozilla/xpcom/build/nsXPComInit.cpp | 3 + mozilla/xpcom/glue/Makefile.in | 1 + mozilla/xpcom/glue/nsVersionComparator.cpp | 247 ++++++++++++++++++ mozilla/xpcom/glue/nsVersionComparator.h | 51 ++++ mozilla/xpcom/glue/objs.mk | 1 + mozilla/xpcom/tests/Makefile.in | 6 + mozilla/xpcom/tests/TestVersionComparator.cpp | 63 +++++ .../tests/TestVersionComparatorRunner.pl | 89 +++++++ 16 files changed, 655 insertions(+), 125 deletions(-) create mode 100755 mozilla/xpcom/base/nsIVersionComparator.idl create mode 100755 mozilla/xpcom/base/nsVersionComparatorImpl.cpp create mode 100755 mozilla/xpcom/base/nsVersionComparatorImpl.h create mode 100755 mozilla/xpcom/glue/nsVersionComparator.cpp create mode 100755 mozilla/xpcom/glue/nsVersionComparator.h create mode 100755 mozilla/xpcom/tests/TestVersionComparator.cpp create mode 100755 mozilla/xpcom/tests/TestVersionComparatorRunner.pl diff --git a/mozilla/chrome/src/Makefile.in b/mozilla/chrome/src/Makefile.in index a59150e7ed9..0dff2590b8a 100644 --- a/mozilla/chrome/src/Makefile.in +++ b/mozilla/chrome/src/Makefile.in @@ -73,7 +73,6 @@ REQUIRES = xpcom \ jar \ xulapp \ unicharutil \ - update \ $(NULL) CPPSRCS = \ diff --git a/mozilla/chrome/src/nsChromeRegistry.cpp b/mozilla/chrome/src/nsChromeRegistry.cpp index 8fade171150..325fe8ea3e1 100644 --- a/mozilla/chrome/src/nsChromeRegistry.cpp +++ b/mozilla/chrome/src/nsChromeRegistry.cpp @@ -96,7 +96,7 @@ #include "nsISimpleEnumerator.h" #include "nsIStyleSheet.h" #include "nsISupportsArray.h" -#include "nsIUpdateService.h" // for nsIVersionChecker +#include "nsIVersionComparator.h" #include "nsIWindowMediator.h" #include "nsIXPConnect.h" #include "nsIXULAppInfo.h" @@ -1955,7 +1955,7 @@ CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData, static PRBool CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData, - const nsSubstring& aValue, nsIVersionChecker* aChecker, + const nsSubstring& aValue, nsIVersionComparator* aChecker, TriState& aResult) { if (! (aData.Length() > aFlag.Length() + 2)) @@ -2005,7 +2005,8 @@ CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData, } else { PRInt32 c; - nsresult rv = aChecker->Compare(aValue, testdata, &c); + nsresult rv = aChecker->Compare(NS_ConvertUTF16toUTF8(aValue), + NS_ConvertUTF16toUTF8(testdata), &c); if (NS_FAILED(rv)) { aResult = eBad; } @@ -2043,7 +2044,7 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr xpc (do_GetService("@mozilla.org/js/xpc/XPConnect;1")); - nsCOMPtr vc (do_GetService("@mozilla.org/updates/version-checker;1")); + nsCOMPtr vc (do_GetService("@mozilla.org/xpcom/version-comparator;1")); nsAutoString appID; nsAutoString appVersion; diff --git a/mozilla/toolkit/mozapps/update/public/nsIUpdateService.idl b/mozilla/toolkit/mozapps/update/public/nsIUpdateService.idl index 6147bacf5f0..ae711fcb3d1 100644 --- a/mozilla/toolkit/mozapps/update/public/nsIUpdateService.idl +++ b/mozilla/toolkit/mozapps/update/public/nsIUpdateService.idl @@ -417,29 +417,3 @@ interface nsIUpdateTimerManager : nsISupports in nsITimerCallback callback, in unsigned long interval); }; - -[scriptable, uuid(22d35700-5765-42e1-914b-a0da7c911a8c)] -interface nsIVersionChecker : nsISupports -{ - /** - * Compare two FVF versions - * @param versionA - * The first version - * @param versionB - * The second version - * @returns < 0 if A < B - * = 0 if A == B - * > 0 if B > A - * XXXben - change the return value here to return a constant - */ - long compare(in AString versionA, in AString versionB); - - /** - * Determines if a string is a valid FVF version - * @param string - * The string to validate - * @returns true if the string is a valid FVF version - */ - boolean isValidVersion(in AString version); -}; - diff --git a/mozilla/toolkit/mozapps/update/src/nsUpdateService.js.in b/mozilla/toolkit/mozapps/update/src/nsUpdateService.js.in index 058ec129ad8..64b5eb7cb11 100644 --- a/mozilla/toolkit/mozapps/update/src/nsUpdateService.js.in +++ b/mozilla/toolkit/mozapps/update/src/nsUpdateService.js.in @@ -1060,7 +1060,8 @@ UpdateService.prototype = { var majorUpdate = null, minorUpdate = null; var newestMinor = updates[0], newestMajor = updates[0]; - var vc = new VersionChecker(); + var vc = Components.classes["@mozilla.org/xpcom/version-comparator;1"] + .getService(Components.interfaces.nsIVersionComparator); for (var i = 0; i < updates.length; ++i) { if (updates[i].type == "major" && vc.compare(newestMajor.version, updates[i].version) <= 0) @@ -2231,94 +2232,6 @@ TimerManager.prototype = { } }; -/** - * Represents the version of an entity, in Firefox Version Format. - * @constructor - */ -function Version(aMajor, aMinor, aRelease, aBuild, aPlus) { - this.major = aMajor || 0; - this.minor = aMinor || 0; - this.release = aRelease || 0; - this.build = aBuild || 0; - this.plus = aPlus || 0; -} -Version.prototype = { - toString: function Version_toString() { - return this.major + "." + this.minor + "." + this.subminor + "." + this.release + (this.plus ? "+" : ""); - }, - - compare: function (aVersion) { - var fields = ["major", "minor", "release", "build", "plus"]; - - for (var i = 0; i < fields.length; ++i) { - var field = fields[i]; - if (aVersion[field] > this[field]) - return -1; - else if (aVersion[field] < this[field]) - return 1; - } - return 0; - } -} - -/** - * A service that provides a means to compare two FVF strings. - * @constructor - */ -function VersionChecker() { -} - -VersionChecker.prototype = { - ///////////////////////////////////////////////////////////////////////////// - // nsIVersionChecker - - // -ve if B is newer - // equal if A == B - // +ve if A is newer - compare: function(aVersionA, aVersionB) { - var a = this._decomposeVersion(aVersionA); - var b = this._decomposeVersion(aVersionB); - - return a.compare(b); - }, - - _decomposeVersion: function(aVersion) { - var plus = 0; - if (aVersion.charAt(aVersion.length-1) == "+") { - aVersion = aVersion.substr(0, aVersion.length-1); - plus = 1; - } - - var parts = aVersion.split("."); - - return new Version(this._getValidInt(parts[0]), - this._getValidInt(parts[1]), - this._getValidInt(parts[2]), - this._getValidInt(parts[3]), - plus); - }, - - _getValidInt: function(aPartString) { - var integer = parseInt(aPartString); - if (isNaN(integer)) - return 0; - return integer; - }, - - isValidVersion: function(aVersion) { - return /^([0-9]+\.){0,3}[0-9]+\+?$/.test(aVersion); - }, - - ///////////////////////////////////////////////////////////////////////////// - // nsISupports - QueryInterface: function(aIID) { - if (!aIID.equals(Components.interfaces.nsIVersionChecker) && - !aIID.equals(Components.interfaces.nsISupports)) - throw Components.results.NS_ERROR_NO_INTERFACE; - return this; - } -}; - #ifdef MOZ_XUL_APP /** * UpdatePrompt @@ -2505,11 +2418,6 @@ var gModule = { factory : #1#(UpdatePrompt) }, #endif - version: { CID : Components.ID("{9408E0A5-509E-45E7-80C1-0F35B99FF7A9}"), - contractID : "@mozilla.org/updates/version-checker;1", - className : "Version Checker", - factory : #1#(VersionChecker) - }, timers: { CID : Components.ID("{B322A5C0-A419-484E-96BA-D7182163899F}"), contractID : "@mozilla.org/updates/timer-manager;1", className : "Timer Manager", diff --git a/mozilla/xpcom/base/Makefile.in b/mozilla/xpcom/base/Makefile.in index 005b33c4547..8f1a6a12a6c 100644 --- a/mozilla/xpcom/base/Makefile.in +++ b/mozilla/xpcom/base/Makefile.in @@ -53,6 +53,7 @@ REQUIRES = string \ CPPSRCS = \ nsAllocator.cpp \ + nsVersionComparatorImpl.cpp \ nsConsoleMessage.cpp \ nsConsoleService.cpp \ nsDebugImpl.cpp \ @@ -118,6 +119,7 @@ XPIDLSRCS = \ nsIErrorService.idl \ nsIException.idl \ nsIExceptionService.idl \ + nsIVersionComparator.idl \ $(NULL) ifdef GC_LEAK_DETECTOR diff --git a/mozilla/xpcom/base/nsIVersionComparator.idl b/mozilla/xpcom/base/nsIVersionComparator.idl new file mode 100755 index 00000000000..cf9c53db1cf --- /dev/null +++ b/mozilla/xpcom/base/nsIVersionComparator.idl @@ -0,0 +1,79 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Application Update Service + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Ben Goodger + * Benjamin Smedberg + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +/** + * Version strings are dot-separated sequences of version-parts. + * + * A version-part consists of up to four parts, all of which are optional: + * + * + * + * Numbers are base-10, and are zero if left out. + * Strings are compared bytewise. + * + * For additional backwards compatibility, if "string-b" is "+" then + * "number-a" is incremented by 1 and "string-b" becomes "pre". + * + * 1.0pre1 + * < 1.0pre2 + * < 1.0 == 1.0.0 == 1.0.0.0 + * < 1.1pre == 1.1pre0 == 1.0+ + * < 1.1pre1a + * < 1.1pre1 + * < 1.1pre10a + * < 1.1pre10 + * + * Although not required by this interface, it is recommended that + * numbers remain within the limits of a signed char, i.e. -127 to 128. + */ +[scriptable, uuid(e6cd620a-edbb-41d2-9e42-9a2ffc8107f3)] +interface nsIVersionComparator : nsISupports +{ + /** + * Compare two version strings + * @param A The first version + * @param B The second version + * @returns < 0 if A < B + * = 0 if A == B + * > 0 if B > A + */ + long compare(in ACString A, in ACString B); +}; + diff --git a/mozilla/xpcom/base/nsVersionComparatorImpl.cpp b/mozilla/xpcom/base/nsVersionComparatorImpl.cpp new file mode 100755 index 00000000000..29849f93f36 --- /dev/null +++ b/mozilla/xpcom/base/nsVersionComparatorImpl.cpp @@ -0,0 +1,52 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XPCOM. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg . + * + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsVersionComparatorImpl.h" +#include "nsVersionComparator.h" +#include "nsString.h" + +NS_IMPL_ISUPPORTS1(nsVersionComparatorImpl, nsIVersionComparator) + +NS_IMETHODIMP +nsVersionComparatorImpl::Compare(const nsACString& A, const nsACString& B, + PRInt32 *aResult) +{ + *aResult = NS_CompareVersions(PromiseFlatCString(A).get(), + PromiseFlatCString(B).get()); + + return NS_OK; +} diff --git a/mozilla/xpcom/base/nsVersionComparatorImpl.h b/mozilla/xpcom/base/nsVersionComparatorImpl.h new file mode 100755 index 00000000000..ae63c738565 --- /dev/null +++ b/mozilla/xpcom/base/nsVersionComparatorImpl.h @@ -0,0 +1,54 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XPCOM. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg . + * + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIVersionComparator.h" + +class nsVersionComparatorImpl : public nsIVersionComparator +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIVERSIONCOMPARATOR +}; + +#define NS_VERSIONCOMPARATOR_CONTRACTID "@mozilla.org/xpcom/version-comparator;1" + +// c6e47036-ca94-4be3-963a-9abd8705f7a8 +#define NS_VERSIONCOMPARATOR_CID \ +{ 0xc6e47036, 0xca94, 0x4be3, \ + { 0x96, 0x3a, 0x9a, 0xbd, 0x87, 0x05, 0xf7, 0xa8 } } + +#define NS_VERSIONCOMPARATOR_CLASSNAME "nsVersionComparatorImpl" diff --git a/mozilla/xpcom/build/nsXPComInit.cpp b/mozilla/xpcom/build/nsXPComInit.cpp index efb3bc7263a..44638692bae 100644 --- a/mozilla/xpcom/build/nsXPComInit.cpp +++ b/mozilla/xpcom/build/nsXPComInit.cpp @@ -83,6 +83,7 @@ #include "nsThread.h" #include "nsProcess.h" #include "nsEnvironment.h" +#include "nsVersionComparatorImpl.h" #include "nsEmptyEnumerator.h" @@ -191,6 +192,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerManager) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream) NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl) NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant) @@ -313,6 +315,7 @@ static const nsModuleComponentInfo components[] = { COMPONENT(BINARYINPUTSTREAM, nsBinaryInputStreamConstructor), COMPONENT(BINARYOUTPUTSTREAM, nsBinaryOutputStreamConstructor), COMPONENT(STORAGESTREAM, nsStorageStreamConstructor), + COMPONENT(VERSIONCOMPARATOR, nsVersionComparatorImplConstructor), COMPONENT(PIPE, nsPipeConstructor), #define NS_PROPERTIES_CLASSNAME "Properties" diff --git a/mozilla/xpcom/glue/Makefile.in b/mozilla/xpcom/glue/Makefile.in index 17759a769aa..7d32f474b9a 100644 --- a/mozilla/xpcom/glue/Makefile.in +++ b/mozilla/xpcom/glue/Makefile.in @@ -76,6 +76,7 @@ SDK_HEADERS = \ nsWeakReference.h \ nsComponentManagerUtils.h \ nsServiceManagerUtils.h \ + nsVersionComparator.h \ $(NULL) SDK_LIBRARY = \ diff --git a/mozilla/xpcom/glue/nsVersionComparator.cpp b/mozilla/xpcom/glue/nsVersionComparator.cpp new file mode 100755 index 00000000000..d23e183da0c --- /dev/null +++ b/mozilla/xpcom/glue/nsVersionComparator.cpp @@ -0,0 +1,247 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XPCOM. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg . + * + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsVersionComparator.h" + +#include +#include + +struct VersionPart { + PRInt32 numA; + + const char *strB; // NOT null-terminated, can be a null pointer + PRUint32 strBlen; + + PRInt32 numC; + + char *extraD; // null-terminated +}; + +/** + * Parse a version part into a number and "extra text". + * + * @returns A pointer to the next versionpart, or null if none. + */ +static char* +ParseVP(char *part, VersionPart &result) +{ + char *dot = strchr(part, '.'); + if (dot) + *dot = '\0'; + + result.numA = strtol(part, NS_CONST_CAST(char**, &result.strB), 10); + + if (!*result.strB) { + result.strB = nsnull; + result.strBlen = 0; + result.numC = 0; + result.extraD = nsnull; + } + else { + if (result.strB[0] == '+') { + static const char kPre[] = "pre"; + + ++result.numA; + result.strB = kPre; + result.strBlen = sizeof(kPre) - 1; + } + else { + char *numstart = strpbrk(result.strB, "0123456789+-"); + if (!numstart) { + result.strBlen = strlen(result.strB); + result.numC = 0; + result.extraD = nsnull; + } + else { + result.strBlen = numstart - result.strB; + + result.numC = strtol(numstart, &result.extraD, 10); + if (!*result.extraD) + result.extraD = nsnull; + } + } + } + + if (dot) { + ++dot; + + if (!*dot) + dot = nsnull; + } + + return dot; +}; + +// compare two null-terminated strings, which may be null pointers +static PRInt32 +ns_strcmp(const char *str1, const char *str2) +{ + // any string is *before* no string + if (!str1) + return str2 != 0; + + if (!str2) + return -1; + + return strcmp(str1, str2); +} + +// compare two length-specified string, which may be null pointers +static PRInt32 +ns_strnncmp(const char *str1, PRUint32 len1, const char *str2, PRUint32 len2) +{ + // any string is *before* no string + if (!str1) + return str2 != 0; + + if (!str2) + return -1; + + for (; len1 && len2; --len1, --len2, ++str1, ++str2) { + if (*str1 < *str2) + return -1; + + if (*str1 > *str2) + return 1; + } + + if (len1 == 0) + return len2 == 0 ? 0 : -1; + + return 1; +} + +// compare two PRInt32 +static PRInt32 +ns_cmp(PRInt32 n1, PRInt32 n2) +{ + if (n1 < n2) + return -1; + + return n1 != n2; +} + +/** + * Compares two VersionParts + */ +static PRInt32 +CompareVP(VersionPart &v1, VersionPart &v2) +{ + PRInt32 r = ns_cmp(v1.numA, v2.numA); + if (r) + return r; + + r = ns_strnncmp(v1.strB, v1.strBlen, v2.strB, v2.strBlen); + if (r) + return r; + + r = ns_cmp(v1.numC, v2.numC); + if (r) + return r; + + return ns_strcmp(v1.extraD, v2.extraD); +} + +/** + * Checks to see whether the remaining vesion parts are all 0.0.0... + */ +static PRBool +OnlyZeros(char* part) +{ + VersionPart vp; + while (part = ParseVP(part, vp)) { + if (vp.numA || vp.strB || vp.numC || vp.extraD) + return PR_FALSE; + } + + return PR_TRUE; +} + +PRInt32 +NS_CompareVersions(const char *A, const char *B) +{ + char *A2 = strdup(A); + if (!A2) + return 1; + + char *B2 = strdup(B); + if (!B2) { + free(A2); + return 1; + } + + PRInt32 result; + char *a = A2, *b = B2; + + do { + VersionPart va, vb; + + a = ParseVP(a, va); + b = ParseVP(b, vb); + + result = CompareVP(va, vb); + if (result) + break; + + if (a) { + if (!b) { + // A has more parts, but B doesn't... check for 0.0.0... + if (OnlyZeros(a)) + result = 0; + else + result = 1; + + break; + } + } + else { + if (b && !OnlyZeros(b)) + // A is done, but B isn't, check for 0.0.0... + result = -1; + else // A and B are both done, they are equal! + result = 0; + + break; + } + } while (PR_TRUE); + + free(A2); + free(B2); + + return result; +} + diff --git a/mozilla/xpcom/glue/nsVersionComparator.h b/mozilla/xpcom/glue/nsVersionComparator.h new file mode 100755 index 00000000000..9d8c01868a8 --- /dev/null +++ b/mozilla/xpcom/glue/nsVersionComparator.h @@ -0,0 +1,51 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XPCOM. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg . + * + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsVersionComparator_h__ +#define nsVersionComparator_h__ + +#include "nscore.h" + +/** + * Compare two version strings. + * + * @see nsIVersionComparator + */ +PRInt32 NS_COM_GLUE +NS_CompareVersions(const char *A, const char *B); + +#endif // nsVersionComparator_h__ diff --git a/mozilla/xpcom/glue/objs.mk b/mozilla/xpcom/glue/objs.mk index 68915eca1db..ba2e6f0f87f 100644 --- a/mozilla/xpcom/glue/objs.mk +++ b/mozilla/xpcom/glue/objs.mk @@ -43,6 +43,7 @@ XPCOM_GLUE_SRC_LCSRCS = \ nsTraceRefcnt.cpp \ nsWeakReference.cpp \ nsGREGlue.cpp \ + nsVersionComparator.cpp \ $(NULL) XPCOM_GLUE_SRC_CSRCS := $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCSRCS)) diff --git a/mozilla/xpcom/tests/Makefile.in b/mozilla/xpcom/tests/Makefile.in index ca5e97a9ab5..31c9f3b1554 100644 --- a/mozilla/xpcom/tests/Makefile.in +++ b/mozilla/xpcom/tests/Makefile.in @@ -78,6 +78,7 @@ CPPSRCS = \ TestMinStringAPI.cpp \ TestStrings.cpp \ TestStorageStream.cpp \ + TestVersionComparator.cpp \ $(NULL) #CPPSRCS += TimerTest.cpp @@ -111,3 +112,8 @@ libs:: install:: $(SYSINSTALL) $(IFLAGS1) $(srcdir)/test.properties $(DESTDIR)$(mozappdir)/res +ifndef CROSS_COMPILE +libs:: + @echo "Running TestVersionComparator tests" + @$(PERL) -w $(srcdir)/TestVersionComparatorRunner.pl $(FINAL_TARGET)/TestVersionComparator$(BIN_SUFFIX) +endif diff --git a/mozilla/xpcom/tests/TestVersionComparator.cpp b/mozilla/xpcom/tests/TestVersionComparator.cpp new file mode 100755 index 00000000000..6be9e362078 --- /dev/null +++ b/mozilla/xpcom/tests/TestVersionComparator.cpp @@ -0,0 +1,63 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XPCOM. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg . + * + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsVersionComparator.h" + +#include + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + PRInt32 i = NS_CompareVersions(argv[1], argv[2]); + + char *format; + + if (i < 0) + format = "%s < %s\n"; + else if (i > 0) + format = "%s > %s\n"; + else + format = "%s = %s\n"; + + fprintf(stdout, format, argv[1], argv[2]); + return 0; +} + diff --git a/mozilla/xpcom/tests/TestVersionComparatorRunner.pl b/mozilla/xpcom/tests/TestVersionComparatorRunner.pl new file mode 100755 index 00000000000..b7dce2db932 --- /dev/null +++ b/mozilla/xpcom/tests/TestVersionComparatorRunner.pl @@ -0,0 +1,89 @@ +#!/usr/bin/perl -w +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Mozilla XPCOM Tests. +# +# The Initial Developer of the Original Code is +# Benjamin Smedberg . +# +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +my $executable = shift; + +@comparisons = ( + "1.0pre1", + "1.0pre2", + "1.0", + "1.1pre", + "1.1pre1a", + "1.1pre1", + "1.1pre10a", + "1.1pre10", + "1.1" +); + +@equality = ( + "1.1pre", + "1.1pre0", + "1.0+" +); + +# Do the comparisons in both directions + +sub run_testprog { + my ($executable, $args, $expected) = @_; + + my $result = `$executable $args`; + $result =~ s/\r|\n//g; + + if ($result ne $expected) { + print STDERR "Testing '$args' expected '$expected', got '$result'.\n"; + exit 1; + } +} + +for (my $i = 0; $i < scalar(@comparisons) - 1; ++$i) { + run_testprog($executable, + "$comparisons[$i] $comparisons[$i + 1]", + "$comparisons[$i] < $comparisons[$i + 1]"); + run_testprog($executable, + "$comparisons[$i + 1] $comparisons[$i]", + "$comparisons[$i + 1] > $comparisons[$i]"); +} + +for (my $i = 0; $i < scalar(@equality) - 1; ++$i) { + run_testprog($executable, + "$equality[$i] $equality[$i + 1]", + "$equality[$i] = $equality[$i + 1]"); +} + +print "All comparisons OK\n"; +exit 0;